Skip to main content

Data Export API

The Data Export API allows you to search for data inside Turn by a given range of dates.

It is a two-step approach:

  1. Create a cursor with the required parameters to start getting data.
  2. Request data in a paginated fashion using the cursor.

The following type of data is available through the Data Export API:

  • messages
  • contact details
  • message statuses

Required parameters

  • from date and time indicating the timestamp from which data should be retrieved.
  • until date and time indicating the timestamp up to which data should be retrieved.

Optional parameters

  • ordering indicates if the result set should be ordered ascending or descending.
  • page_size indicates the number of records wanted in the result set.
  • scrubbing_rules set of possible rules to remove sensitive information from specific fields in the JSON response for messages and contacts only. The rules currently supported are a search and replace rule with support for Regular Expressions, and a hashing rule.

Export Message Data

Create a cursor for messages

To create a cursor to start searching for messages, make the following request:

$ curl -X POST "https://whatsapp.turn.io/v1/data/messages/cursor" \
-H "Authorization: Bearer token" \
-H "Content-Type: application/json" \
-H "accept: application/vnd.v1+json" \
-d '
{
"from": "2021-08-02T01:55:00.272Z",
"until": "2021-08-20T01:55:00.272Z",
"ordering": "desc",
"page_size": 10,
"scrubbing_rules": {
"inbound": {
"messages.text.body": {
"type": "regex",
"search": "world",
"replace": "XXXX"
},
"messages.from": {
"type": "hash"
},
"contacts.profile.name": {
"type": "hash"
}
},
"outbound": {
"text.body": {
"type": "regex",
"search": "world",
"replace": "XXXX"
},
"from": {
"type": "hash"
}
}
}
}'
> {
"cursor": "<cursor>",
"expires_at": "2021-08-30T17:47:18.318218Z"
}

Get messages

To retrieve messages, make the following request:

$ curl -X GET "https://whatsapp.turn.io/v1/data/messages/cursor/<cursor>" \
-H 'Authorization: Bearer token' \
-H "Accept: application/vnd.v1+json" \
> {
"data": [
{
"contacts": [
{
"profile": {
"name": "SFMyNTY.KzMxNjIzNDU2NzAw.GSl886dfZXJ70DkFsUy39ij4QgYSceBw5UdV76Ugek0"
},
"wa_id": "01234567891"
}
],
"messages": [
{
"_vnd": {
"v1": {
"author": {},
"chat": {
"assigned_to": null,
"owner": "+01234567891",
"permalink": "https://whatsapp.turn.io/app/col/63f0f404-08ee-423e-b571-01de718d4683",
"state": "OPEN",
"state_reason": null,
"unread_count": 0,
"uuid": "63f0f404-08ee-423e-b571-01de718d4683",
"contact_uuid": "b5b8f845-c526-4993-a8d3-464407ff3595",
"inserted_at": "2021-08-02T22:54:44.715101Z",
"updated_at": "2021-08-02T22:54:44.715101Z"
},
"direction": "inbound",
"faq_uuid": null,
"in_reply_to": null,
"inserted_at": "2021-08-02T22:54:44.715101Z",
"labels": [],
"rendered_content": null,
"uuid": "b2f8ed7f-09b4-fbad-57bb-81a42e37ba6c",
"last_status": "read",
"last_status_timestamp": "2021-08-02T22:54:44.721779Z",
"on_fallback_channel": false
}
},
"from": "SFMyNTY.MzE2MjM0NTY3MDA.nbfRbPvYvAqpKMOy19SwjrFZCz0Jb4IIxxaIc_4rx7s",
"id": "PksTrDovmBIG8SK8",
"text": {
"body": "hello XXXX 0"
},
"timestamp": "1627944884",
"type": "text"
}
]
},
{
"_vnd": {
"v1": {
"author": {},
"chat": {
"assigned_to": null,
"owner": "+01234567891",
"permalink": "https://whatsapp.turn.io/app/col/63f0f404-08ee-423e-b571-01de718d4683",
"state": "OPEN",
"state_reason": null,
"unread_count": 0,
"uuid": "63f0f404-08ee-423e-b571-01de718d4683",
"contact_uuid": "422d9799-68cb-45c0-bcd4-71c3a2e9350f",
"inserted_at": "2021-08-02T22:54:44.715101Z",
"updated_at": "2021-08-02T22:55:44.715101Z"
},
"direction": "outbound",
"faq_uuid": null,
"in_reply_to": null,
"inserted_at": "2021-08-02T22:54:44.721779Z",
"labels": [],
"rendered_content": null,
"uuid": "244b5651-4add-47f3-bdaf-8458848cb29a",
"last_status": "read",
"last_status_timestamp": "2021-08-02T22:55:44.721779Z",
"on_fallback_channel": false
}
},
"from": "SFMyNTY.MjcxMjM0NTY3MDA.JUHQXxo5G9gnokpMisKqGz2uzhmx106k49ZcI8k_qC0",
"id": "h4UBvhwAdZvgwXhi",
"preview_url": false,
"recipient_type": "individual",
"text": {
"body": "hello XXXX 1"
},
"timestamp": "1627944884",
"to": null,
"type": "text"
},
...
],
"paging": {
"expires_at": "2021-08-30T18:49:26.761537Z",
"next": "<next cursor>"
}
}

Original WhatsApp messages are returned but include the Turn's vendor-specific _vnd key in each message payload with supplementary information Turn has on a record.

If there is more data on the next page, a next cursor will be provided to continue getting results. If not, it means you have reached all results for the given search criteria.

Export Contact Details

Create a cursor for contact details

The contact details data export differs in behavior from the message export endpoint in one crucial way. Messages are created once and are not updated - once a message has been logged in the database, its properties do not change. Thus, we paginate by the inserted_at field.

However, contacts and their fields (for example, a custom field called current_savings) will change over time. If we paginated by inserted_at, you would need to paginate over all contacts every time, in order to get updated data. Instead, we paginate by when contacts were updated.

This means that the expected behavior would be to request data on a daily, or weekly basis for a time period of a day or a week respectively - this will then include all updated information since you last requested the contact data. You should not need to request the data using the time span of the number for up-to-date contact data unless you are requesting it for the first time.

To create a cursor to start searching for contact details, make the following request:

$ curl -X POST "https://whatsapp.turn.io/v1/data/contacts/cursor" \
-H "Authorization: Bearer token" \
-H "Content-Type: application/json" \
-H "accept: application/vnd.v1+json"
-d '
{
"from": "2021-08-02T01:55:00.272Z",
"until": "2021-08-20T01:55:00.272Z",
"ordering": "desc",
"page_size": 10,
"scrubbing_rules": {
"contact": {
"details.name": {
"type": "regex",
"search": "Efrain",
"replace": "XXXX"
},
"details.surname": {
"type": "hash"
}
}
}
}'
> {
"cursor": "<cursor>",
"expires_at": "2021-08-30T17:47:18.318218Z"
}

Get contact details

To retrieve contact details, make the following request:

$ curl -X GET "https://whatsapp.turn.io/v1/data/contacts/cursor/<cursor>" \
-H 'Authorization: Bearer token' \
-H "Accept: application/vnd.v1+json" \
> {
"data": [
{
"details": {
"birthday": "1988-06-14T18:15:35.873852Z",
"language": "ben",
"location": null,
"name": "XXXX",
"opted_in": false,
"opted_in_at": null,
"surname": "SFMyNTY.UnVzc2Vs.fuONeooDjnkkCEtnLnT06Acs6xeuxnPZqhmscquTC-Y",
"whatsapp_id": "31623456700",
"whatsapp_profile_name": "pfannerstill"
},
"id": 1,
"inserted_at": "2022-02-03T20:58:38.000000Z",
"number_id": 1,
"updated_at": "2022-02-03T20:58:38.000000Z",
"uuid": "f6c4e666-81ad-430e-aea5-1ba33e6f4c35"
},
...
],
"paging": {
"expires_at": "2021-08-30T18:49:26.761537Z",
"next": "<next cursor>"
}
}

If there is more data on the next page, a next cursor will be provided to continue getting results. If not, it means you have reached all results for the given search criteria.

Export Message Status Data

Create a cursor for message statuses

To create a cursor to start fetching message statuses, make the following request:

$ curl -X POST "https://whatsapp.turn.io/v1/data/statuses/cursor" \
-H "Authorization: Bearer token" \
-H "Content-Type: application/json" \
-H "accept: application/vnd.v1+json" \
-d '
{
"from": "2021-08-02T01:55:00.272Z",
"until": "2021-08-20T01:55:00.272Z",
"ordering": "desc",
"page_size": 10
}'
> {
"cursor": "<cursor>",
"expires_at": "2021-08-30T17:47:18.318218Z"
}

Get Message Statuses

The status payload is structured as received from the Cloud API. This means that each individual status is the same structure as would be forwarded to a webhook that receives webhook updates.

To retrieve statuses, once you've created your cursor, make the following request:

$ curl -X GET "https://whatsapp.turn.io/v1/data/statuses/cursor/<cursor>" \
-H 'Authorization: Bearer token' \
-H "Accept: application/vnd.v1+json" \
> {
"data": [
{
"statuses": [
{
"conversation": {
"id": "51cbaq7cccb833f28931358fce32e2e9",
"origin": {
"type": "service"
}
},
"id": "wamid.Kn3rwvPdIVrT0AuGhicCs99I08nVpcz2fbQlFaXyFUdYKdyQUvFY",
"pricing": {
"billable": true,
"category": "service",
"pricing_model": "CBP"
},
"recipient_id": "27123456789",
"status": "delivered",
"timestamp": 1727849284
}
]
},
{
"statuses": [
{
"errors": [
{
"code": 131053,
"error_data": {
"details": "Unsupported Video mime type image/jpeg. Please use one of video/3gpp, video/mp4."
},
"message": "Media upload error",
"title": "Media upload error"
}
],
"id": "wamid.HpXNjw1u8XuqA9FocBjWPTHKh1UzyjifPhezyBhvC7ewPmNZD7GL==",
"recipient_id": "27123456789",
"status": "failed",
"timestamp": 1724284299
}
]
},
{
"statuses": [
{
"id": "wamid.HzgKORVuA2NzewdveXA84WphzsZr3qTg29QQXltRFnjjVIB4OCyn",
"recipient_id": "44123456789",
"status": "read",
"timestamp": 1727849706
}
]
},
{
"statuses": [
{
"conversation": {
"expiration_timestamp": 1727935500,
"id": "51cbae7cccb766f28239878fce32e2e9",
"origin": {
"type": "service"
}
},
"id": "wamid.lSTtUA5G9Ya8s67tSvyGMfpRhXryTzF3UR3NF2VnwJxD9dtIO08F",
"pricing": {
"billable": true,
"category": "service",
"pricing_model": "CBP"
},
"recipient_id": "2345672654423",
"status": "sent",
"timestamp": 1727849284
}
]
},
{
"statuses": [
{
"id": "wamid.WX1Jpd4r2rV7vUlOgpttUHlsWNYxIouxcuVDB5ZuW2VW2kNLLmEs",
"message": {
"recipient_id": "38110000008"
},
"status": "read",
"timestamp": 1728016987
}
]
}
],
"paging": {
"expires_at": "2021-08-30T18:49:26.761537Z",
"next": "<next cursor>"
}
}