Getting Contact Activity via API
The Get contacts activity resource returns activity records for the messages sent to your contacts over a period you specify. Each record in the response carries a status — DELIVERED, UNDELIVERED, READ, CLICKED, UNSUBSCRIBED, SUBSCRIPTION_CHANGED, or SPAM — the time it happened, and the message and contact it belongs to. For UNDELIVERED, it also returns the reason.
Use it to bring message statuses, contact actions, and delivery failures into your own system, and to match them against the send requests your integration made.
Get contacts activity returns individual activity events for a period and covers many contacts at once; new events can take a few minutes to appear.
Get contact's message history returns the history of one contact, which the request must identify, and shows a send immediately — so use it for a check made right before sending again. The full comparison of the ways to get contact activity, including webhooks and the data export, is in section 6.
Get contacts activity is enabled on requestContact support to activate it for your account. Activation can take a few hours.
Data accumulates only after activation and is kept for 90 days. Earlier activity is not added retroactively, so connect the resource ahead of time.
1. Request
GET https://yespo.io/api/v2/contacts/activity
Requests use Basic HTTP authentication with the API key as the password. See API Keys.
dateFrom and dateTo are the only required parameters. Every other parameter is a filter that narrows the result.
| Parameter | Description |
|---|---|
dateFrom (required) | Start of the period. |
dateTo (required) | End of the period. |
email | Contact's email address. |
sms | Contact's phone number. |
webPushToken | Web Push token. |
mobPushToken | Mobile Push token. |
telegramToken | Telegram token. |
messageTag | Message tag. |
activityStatus | One of DELIVERED, UNDELIVERED, READ, UNSUBSCRIBED, CLICKED, SPAM. Filtering by a status narrows the response to that outcome: DELIVERED leaves out the messages that have no status yet or ended as UNDELIVERED. |
offset | Offset taken from the previous response, to continue reading. See Pagination. |
maxrows | Maximum number of entries in the response. Default — 25000. |
An example request for one contact over two weeks:
curl --request GET \
--url 'https://yespo.io/api/v2/contacts/activity?dateFrom=2026-08-01T00:00:00&dateTo=2026-08-14T23:59:59&[email protected]&maxrows=25000' \
--user 'YOUR_LOGIN:YOUR_API_KEY'2. The Date Range
- A value without a time part means midnight UTC of that date. To include activity from the current day, specify the time in ISO 8601 format — for example,
dateTo=2026-08-14T10:59:59. - Activity is kept for 90 days. If
dateFrompoints to an earlier date, records from outside that window are not in the response. For long-term storage, receive new events through webhooks or export them to BigQuery.
3. Pagination
One request returns at most maxrows entries. For the next page, send the same request with the offset value of the last entry you received. Continue until a response returns fewer entries than maxrows.
GET .../activity?dateFrom=...&dateTo=...&maxrows=25000
GET .../activity?dateFrom=...&dateTo=...&maxrows=25000&offset={last_offset}
Do not change the filters between pages: an offset is only valid within the original selection.
4. Response
The response is an array in which each entry describes one activity event for one message. Every entry also carries an offset value, used to continue reading.
The message
| Field | Description |
|---|---|
iid | ID of the sent message. |
imid | Immediate message ID. |
externalRequestId | The identifier you passed yourself in the send request. Returned only for messages sent with this field set. |
messageId | Message ID. |
messageInstanceId | Message instance ID. |
messageName | Message name. |
messageTag | Message label. |
messageLanguageCode | Language version the contact received. |
from | Sender. |
The contact
| Field | Description |
|---|---|
contactId | Contact ID. |
externalCustomerId | Your own contact identifier. |
email | Contact's email address. |
sms | Contact's phone number. |
webPushToken, mobPushToken, telegramToken | Channel tokens. |
The activity
| Field | Description |
|---|---|
mediaType | email, sms, viber, mobilepush, webpush, appinbox, widget, inapp, telegrambot. |
activityStatus | DELIVERED, UNDELIVERED, READ, UNSUBSCRIBED, SUBSCRIPTION_CHANGED, CLICKED, SPAM. |
activityDateTime | Date and time of the activity. |
statusDescription | Returned only for UNDELIVERED. Contains the reason — a response from the recipient's server, a system message about the message not being sendable, and so on. |
viewMessageLink | Link to the web version of the message. Email only. |
clickEventLink | The link the contact clicked. |
subscriptions | Subscription category keys. |
osType | Device type: Desktop or Mobile. |
osName | Operating system name — for example, Windows NT, iOS, Mac OS. |
Where the message came from
| Field | Description |
|---|---|
workflowId, workflowInstanceId, workflowBlockId | The workflow, the particular launch, and the block that sent the message. |
broadcastId | Broadcast ID. |
sourceEventKey, sourceEventTypeKey | The event that triggered the workflow — its key value and its event type. |
Note
SUBSCRIPTION_CHANGEDappears in responses but is not among the values accepted by theactivityStatusfilter.
An example entry:
[
{
"iid": "3f9a1c20-7624-11f1-a0dc-000000000000",
"externalRequestId": "order-48219",
"contactId": 451677871,
"externalCustomerId": "48219",
"email": "[email protected]",
"mediaType": "email",
"activityStatus": "DELIVERED",
"messageId": 3045908,
"messageInstanceId": 6694763,
"messageName": "Order confirmation",
"messageLanguageCode": "en",
"activityDateTime": "2026-08-14T14:41:54",
"imid": 29055000426,
"offset": "MjAyNi0wOC0xNFQxNDo0MTo1NA"
}
]5. Common Tasks
5.1 Match Activity to Your Own Send Request
This works only for messages sent with a resource that accepts externalRequestId: Send prepared message, which takes a separate value for each recipient, and Send email message, Send SMS message, and Send Viber message, which take one value for the whole request. Messages sent by a workflow, a broadcast, or an event carry no value in this field.
Pass your own externalRequestId when sending the message, then find it in the activity response — it ties the activity back to your send request. One request can carry several recipients under the same externalRequestId, so to identify the individual message also match on contactId, the address, or iid. See Using the Smartsend API Resource.
externalRequestId is not one of this resource's filter parameters — you match on it in a response you have already received.
5.2 Get Undelivered Messages and Their Reasons
Request the entries with activityStatus=UNDELIVERED and group the statusDescription values to identify invalid addresses, blocks on the recipient servers' side, or systemic delivery problems. See Deliverability Control Process.
6. Choosing Between Activity, Message History, Webhooks, and Export
| Get contacts activity | Get contact's message history | Webhooks | BigQuery export | |
|---|---|---|---|---|
| One record is | One activity event | One message with its current status, subject or text, and tags | One activity event | One activity event |
| Contact identifier in the request | Optional — one request can cover many contacts | Required: contactId, externalCustomerId, email, or phone | Not applicable | Not applicable |
| How you get the data | You request it | You request it | Sent to your endpoint as activity happens | On the export schedule you configure |
| Typical use | Pulling activity for a period, on demand | Reviewing one contact's message history | Reacting to activity as it occurs | Analytics and long-term storage |
| Freshness | A few minutes' lag | Immediate | Near real-time | As frequent as the export runs |
| How far back | 90 days | dateFrom no older than 1 year | Only from the moment you set it up | As far back as you keep it |
| Pagination | maxrows defaults to 25000; continue from the last entry's offset | maxrows defaults to 10, maximum 100; offset counts from the start of the list | Not applicable | Not applicable |
externalRequestId | Returned if it was set when sending | Not returned | Returned if it was set when sending | Check the schema of the export you configured |
There is no aggregated analytics endpoint: the figures you see in the reports can only be exported from the interface. To feed them into your own BI, build the dataset yourself — from webhooks, from this resource, or from the BigQuery export, which runs once a day.
Related Articles
- Get contacts activity — the full parameter and field reference
- Get contact's message history — one contact's message history
- Using the Smartsend API Resource — sending with your own
externalRequestId - Webhooks — receiving activity as it happens
- Google BigQuery Integration — exporting activity for analytics
Updated about 3 hours ago
