Skip to main content
When a person asks what you have stored about them, you can fetch it over the API, apart from what is not included. The result is suited as the basis for a GDPR Article 15 request (a subject access request). Your organization reviews the material before handing it out: a ticket can also hold what other people wrote. You need an API key. A read-only key is enough.

What is included

Your agents’ internal notes and real-time live chats with an agent are not available in the API. Inline images in an email body are not listed as attachments. Erased contacts and tickets are not returned.

The steps

1

Find the contact

GET /v1/contacts?email= with the person’s email address, or ?externalId= with your own user ID for them.
2

Read the contact card

Each contact in the list is the full card. Fetch it again later with GET /v1/contacts/{id}.
3

List the chat sessions

4

List the tickets

GET /v1/tickets?contactId={id}&sort=createdAt. You get the tickets where the contact is the requester and the ones where they take part in a conversation. Compare requester.id with the contact’s ID to tell which. The survey answer is the ticket’s rating.
5

Fetch the messages

GET /v1/conversations/{id}/messages for every entry in each ticket’s conversations.
6

Download the attachments

GET /v1/attachments/{id}/content for every entry in each message’s attachments. Follow the redirect.
Every list is paginated. Follow nextCursor until hasMore is false.

Good to know

  • One email address can match several contacts. Only a verified address is unique. An address a visitor merely typed creates a separate contact with email.verified: false. Export every contact the lookup returns and judge whether it is the same person.
  • A contact has one email address. A person who wrote from two addresses is two contacts. Look up each address.
  • Use sort=createdAt on the ticket list. With the default sort, a ticket that is updated while you page can be skipped. With sort=createdAt a new ticket shows up at the end, and nothing is skipped or repeated.
  • A large export is many calls. You make one call per conversation and one per file, and each counts toward the rate limit. On 429, wait the number of seconds in Retry-After and try again.
  • Only your own data. An ID that is unknown and an ID from another organization behave the same: 404 or an empty list.

Complete script

Save as export-contact.mjs and run REPLYFUL_API_KEY=rfl_live_... node export-contact.mjs [email protected]. It needs Node.js 18 or later. It writes one folder per matching contact, with an export.json and the attachments.
Node.js