Skip to content

Reports API - Contact Activity

Use the contact activity report to retrieve one contact’s email history: which messages they were sent and what they did with each one (delivered, bounced, opened, clicked which links, unsubscribed), with a summary across all of them.


Method URL Description
GET https://e1.envoke.com/v2/reports/contacts/{ID} Return the activity of the contact with this Envoke contact ID.
GET https://e1.envoke.com/v2/reports/contacts?email={email} Return the activity of the contact with this email address.
GET https://e1.envoke.com/v2/reports/contacts?remote_id={remote_id} Return the activity of the contact with this remote ID.

Authentication is via HTTP Basic Auth using your API ID and API Key.


GET https://e1.envoke.com/v2/reports/contacts/{ID}

Returns one JSON object with three parts: contact (who), summary (counts across every message), and messages (one entry per message, newest first, paged with limit and skip). Replace {ID} with the Envoke contact ID, the id of the Contact API.

A contact that does not exist, belongs to another account, or has been deleted returns [] with HTTP 200. A contact who has never been sent a message returns the object with every count 0, every time null, and messages [].

This report covers email messages only: form submissions and other contact events are not included.

Accounts restricted from contact-level email activity. On an account restricted from seeing contacts associated with email activity (the setting that hides a contact’s Email sending history in Envoke), this endpoint and Find a Contact’s Activity return HTTP 403; see Errors. The message reports are not affected.

Parameter Type Default Description
activity_from string — Count only activity on or after this date or time. See Date parameters.
activity_to string — Count only activity on or before this date or time.
limit integer 10 Maximum number of entries in messages; values above 100 return 100.
skip integer 0 Number of messages entries to skip.

limit and skip apply only to the messages array; contact and summary are always complete. Any other parameter, including sent_from and sent_to, returns HTTP 400 (Parameter 'sent_from' is not valid).


Find a Contact’s Activity by Email or Remote ID

Section titled “Find a Contact’s Activity by Email or Remote ID”
GET https://e1.envoke.com/v2/reports/contacts?email={email}
GET https://e1.envoke.com/v2/reports/contacts?remote_id={remote_id}

Returns the same object as Get a Contact’s Activity for the contact found by email or by remote_id. Give exactly one of the two, plus any of activity_from, activity_to, limit, and skip. URL-encode the value (@ is %40).

The value is compared as a whole, exactly as the Contact API’s filter[email] and filter[remote_id] compare it, so a value the Contact API finds is found here. Letter case does not matter: MAYA.CHEN@EXAMPLE.ORG finds the contact maya.chen@example.org, and a remote ID is matched the same way. An empty value is an error rather than a match for every contact without an email address or remote ID. When no contact matches, the response is [] with HTTP 200. When more than one contact matches, the request fails with HTTP 400 rather than choosing one; use the contact’s id instead. More than one match is possible for remote_id, and for email on accounts that allow several contacts to share an address.


Field Type Description
id string Envoke contact ID.
email string The contact’s email address.
remote_id string The contact’s remote ID, or "" when it has none.

Counts of messages, across every message in the report (not only the current page of messages), inside the activity window when one is given:

Field Type Description
sends integer Messages the contact was sent.
delivered integer Messages with delivered true.
bounces integer Messages with bounced true.
opens integer Messages with opened true.
clicks integer Messages with clicked true.
unsubscribes integer Messages with unsubscribed true.
last_send_time string or null The most recent time the contact was sent a message.
last_open_time string or null The most recent open record.
last_click_time string or null The most recent click record.

Envoke records a contact’s first open of a message in each email client and their first click on each link, never a repeat (see Times and time zone). So last_open_time is the latest of those first opens: a contact who reopens an old message in the same email client does not move it, but opening a new message, or the same message in another client, does. last_click_time works the same way for links.

One entry per message the contact was sent, ordered by sent_time, newest first, then by message id, highest first. A message is included when the contact has a send record for it and, when an activity window is given, at least one activity record for it inside the window. Messages the contact was selected for but skipped (no consent, invalid address) are not included. A message is listed whatever its status today, as on the contact page: a transactional message, or a message sent and later returned to draft, appears here even though the message reports do not answer for it.

Field Type Description
id string Message ID; the Message API id.
name string The message’s internal name.
sent_time string When this contact was sent the message. For an automated message, the time of this contact’s send, not the message’s set-up date.
delivered boolean true when the contact was sent the message and has no bounce record for it. With an activity window, the send must be inside the window; a bounce counts whenever it arrived.
bounced boolean true when the contact has any bounce record for the message, including a temporary deferral.
opened boolean true when the contact opened the message.
first_open_time string or null The contact’s first open of the message, or null.
opens integer The number of email clients the contact opened the message in; not the number of times they opened it.
clicked boolean true when the contact clicked any tracked link in the message.
clicks integer The number of different links the contact clicked; not the number of clicks.
links array { "id", "url", "first_click_time" } for each link the contact clicked, most recent first.
unsubscribed boolean true when the contact revoked consent or used one-click unsubscribe from the message (the events counted in unsubscribes).

In links, id is the tracked link’s ID (the same as in the single-message report’s links) and url is the link as written in the message with Envoke’s tracking parameters removed, or "" for Envoke’s own links (view online, preferences, poll answers). Merge tags in a link are not replaced, so url can be or contain a merge tag ({@customfield-url_test}, https://example.org/show?seat={@seat|url}) rather than a valid URL. first_click_time is the contact’s first click on that link. For a message with an anonymous poll, poll-answer clicks are left out entirely, as in the Sent message report’s drill-downs: they are not listed in links, not counted in clicks, clicked, or the summary (clicks and last_click_time), and do not by themselves place the message inside an activity window.

Activity window. With activity_from or activity_to, every flag and count reflects only the records inside the window, except sent_time, which is always the contact’s send. A contact sent the message before the window who opened it inside the window shows opened true and delivered false, because the send is outside the window. delivered follows the message-level delivered: with a window it needs a send inside the window and no bounce for the message at any time.

Relation to the contact page. Each entry matches the row for the same message in the contact’s Email sending history in Envoke (https://e1.envoke.com/contacts/{id}/delivery-history.json, .campaigns[] | {campaign_id, flags}): bounced, opened, and clicked equal its bounce, open, and click flags, except that on a message with an anonymous poll a contact whose only clicks were poll answers has clicked false where the page shows a click. A message the page lists from opens or clicks alone, with no send record for the contact, is not in this report. The app and this report both show times in your account’s time zone.

{
"contact": {
"id": "1004",
"email": "maya.chen@example.org",
"remote_id": "MRCT-0412"
},
"summary": {
"sends": 3,
"delivered": 3,
"bounces": 0,
"opens": 2,
"clicks": 1,
"unsubscribes": 0,
"last_send_time": "2026-05-14 09:31:07",
"last_open_time": "2026-05-14 12:02:44",
"last_click_time": "2026-05-14 12:03:10"
},
"messages": [
{
"id": "2004",
"name": "Pirates Opening Night",
"sent_time": "2026-05-14 09:31:07",
"delivered": true,
"bounced": false,
"opened": true,
"first_open_time": "2026-05-14 12:02:44",
"opens": 1,
"clicked": true,
"clicks": 1,
"links": [
{ "id": "88125", "url": "https://example.org/tickets/pirates", "first_click_time": "2026-05-14 12:03:10" }
],
"unsubscribed": false
},
{
"id": "2001",
"name": "Spring Season Announcement",
"sent_time": "2026-04-15 10:00:52",
"delivered": true,
"bounced": false,
"opened": true,
"first_open_time": "2026-04-15 10:04:19",
"opens": 2,
"clicked": false,
"clicks": 0,
"links": [],
"unsubscribed": false
},
{
"id": "2006",
"name": "Welcome to Maple Ridge",
"sent_time": "2025-11-03 08:00:12",
"delivered": true,
"bounced": false,
"opened": false,
"first_open_time": null,
"opens": 0,
"clicked": false,
"clicks": 0,
"links": [],
"unsubscribed": false
}
]
}

Invalid requests return HTTP 400 with the validation envelope (see Error Responses). Besides the shared date, limit, skip, and unknown-parameter errors:

Error Cause
One of the parameters 'email' or 'remote_id' must be provided GET /v2/reports/contacts without either.
Only one of the parameters 'email' or 'remote_id' may be provided Both were given.
Invalid 'email': '' email (or remote_id: Invalid 'remote_id': '') was given with an empty value.
More than one contact found for 'remote_id': 'MRCT-0412' Several contacts have this remote ID (or, with email, this address: More than one contact found for 'email': 'maya.chen@example.org').
Parameter 'email' is not valid email or remote_id given on GET /v2/reports/contacts/{ID}, where the path already names the contact.
Response Cause
[] with HTTP 200 The contact does not exist, belongs to another account, or is deleted; or no contact has this email or remote_id.
HTTP 404, 404 Not Found {ID} is not a number.
HTTP 403, Contact-level email activity is not available on this account The account is restricted from seeing contacts associated with email activity. Returned by both contact activity endpoints.

The 403 body:

{
"success": false,
"result_text": "Contact-level email activity is not available on this account",
"result_data": []
}

One contact’s activity, ten most recent messages

Section titled “One contact’s activity, ten most recent messages”
Terminal window
curl -X GET -gs -u "$API_ID:$API_KEY" \
"https://e1.envoke.com/v2/reports/contacts/1004"
Terminal window
curl -X GET -gs -u "$API_ID:$API_KEY" \
"https://e1.envoke.com/v2/reports/contacts?email=maya.chen%40example.org"
Terminal window
curl -X GET -gs -u "$API_ID:$API_KEY" \
"https://e1.envoke.com/v2/reports/contacts?remote_id=MRCT-0412&activity_from=2026-05-01&activity_to=2026-05-31"

Response (only 2004 had activity for this contact in May):

{
"contact": {
"id": "1004",
"email": "maya.chen@example.org",
"remote_id": "MRCT-0412"
},
"summary": {
"sends": 1,
"delivered": 1,
"bounces": 0,
"opens": 1,
"clicks": 1,
"unsubscribes": 0,
"last_send_time": "2026-05-14 09:31:07",
"last_open_time": "2026-05-14 12:02:44",
"last_click_time": "2026-05-14 12:03:10"
},
"messages": [
{
"id": "2004",
"name": "Pirates Opening Night",
"sent_time": "2026-05-14 09:31:07",
"delivered": true,
"bounced": false,
"opened": true,
"first_open_time": "2026-05-14 12:02:44",
"opens": 1,
"clicked": true,
"clicks": 1,
"links": [
{ "id": "88125", "url": "https://example.org/tickets/pirates", "first_click_time": "2026-05-14 12:03:10" }
],
"unsubscribed": false
}
]
}
Terminal window
curl -X GET -gs -u "$API_ID:$API_KEY" \
"https://e1.envoke.com/v2/reports/contacts/1007?limit=1"

Response:

{
"contact": {
"id": "1007",
"email": "r.osei@example.org",
"remote_id": ""
},
"summary": {
"sends": 2,
"delivered": 1,
"bounces": 1,
"opens": 1,
"clicks": 0,
"unsubscribes": 0,
"last_send_time": "2026-03-10 18:00:41",
"last_open_time": "2025-09-02 08:47:15",
"last_click_time": null
},
"messages": [
{
"id": "2002",
"name": "Auditions Open",
"sent_time": "2026-03-10 18:00:41",
"delivered": false,
"bounced": true,
"opened": false,
"first_open_time": null,
"opens": 0,
"clicked": false,
"clicks": 0,
"links": [],
"unsubscribed": false
}
]
}

summary covers both messages; limit=1 returns only the newest in messages.


Note: The curl examples above are formatted for readability. All requests must use properly encoded URLs.

Full reference, OpenAPI description, and Postman collection: developers.envoke.com.