A valid request URL is required to generate request examples{
"messages": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"source": "campaign",
"title": "<string>",
"channel": "<string>",
"category": "<string>",
"status": "<string>",
"suppress_reason": "<string>",
"attempts": 123,
"last_error": "<string>",
"tracked": true,
"delivered_at": "2023-11-07T05:31:56Z",
"opened_at": "2023-11-07T05:31:56Z",
"clicked_at": "2023-11-07T05:31:56Z",
"bounced_at": "2023-11-07T05:31:56Z",
"read_at": "2023-11-07T05:31:56Z",
"kind": "action",
"created_at": "2023-11-07T05:31:56Z"
}
]
}{
"error": {
"code": "forbidden",
"message": "your role does not allow this action"
}
}{
"error": {
"code": "forbidden",
"message": "your role does not allow this action"
}
}{
"error": {
"code": "forbidden",
"message": "your role does not allow this action"
}
}{
"error": {
"code": "forbidden",
"message": "your role does not allow this action"
}
}Everything this person was sent
Requires customers:read. One ordered read over the three things that send: campaigns, in-app notifications, and email — transactional email included, so a magic link and a six-digit code are here beside the marketing.
It is deliberately not messaging:manage: composing a campaign and answering “did the code arrive?” are different jobs, and the second belongs to whoever may already see the person.
Read tracked before you read the four timestamps. When it is false, nothing was ever going to report on that message — no delivery webhook is configured for the sending domain — so delivered_at, opened_at, clicked_at and bounced_at are null because nobody measured them, not because the message failed. Render that as not tracked. When it is true, null means not yet.
A campaign’s email appears once, as the campaign send that claimed it: that is the only row that can say suppressed and why. suppress_reason is empty on everything else.
status is the furthest point a message is known to have reached. For email: queued (claimed, the provider never acknowledged it), sent, delivered, bounced. For a campaign send: pending, sent, failed, suppressed. A pending campaign send with attempts above zero is waiting on a backoff rather than on its due date, and last_error says what it is waiting out. An in-app notification is delivered by existing, so it reports sent and carries read_at instead.
The 100 most recent, newest first.
A valid request URL is required to generate request examples{
"messages": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"source": "campaign",
"title": "<string>",
"channel": "<string>",
"category": "<string>",
"status": "<string>",
"suppress_reason": "<string>",
"attempts": 123,
"last_error": "<string>",
"tracked": true,
"delivered_at": "2023-11-07T05:31:56Z",
"opened_at": "2023-11-07T05:31:56Z",
"clicked_at": "2023-11-07T05:31:56Z",
"bounced_at": "2023-11-07T05:31:56Z",
"read_at": "2023-11-07T05:31:56Z",
"kind": "action",
"created_at": "2023-11-07T05:31:56Z"
}
]
}{
"error": {
"code": "forbidden",
"message": "your role does not allow this action"
}
}{
"error": {
"code": "forbidden",
"message": "your role does not allow this action"
}
}{
"error": {
"code": "forbidden",
"message": "your role does not allow this action"
}
}{
"error": {
"code": "forbidden",
"message": "your role does not allow this action"
}
}Authorizations
A staff session token, uk_st_…. Minted by sign-up, sign-in or the two-factor exchange. Only a 401 means it is spent; not_a_member (403) is about the organization named in X-Organization-Id and leaves the token good for the others.
Headers
The organization the caller is acting on — the org_… code that appears in the panel URL. It identifies; the membership JOIN is what authorizes, so a forged code reads nothing: the answer is not_a_member (403), which does not mean the session is over. Absent, the session's default organization answers, or — if that membership was revoked while the session was open — any other one the caller still holds.
Path Parameters
Query Parameters
Which environment to act in. A view parameter, valid only on the staff surface — a machine credential never chooses its environment, it is resolved from the key.
live, test Response
What was sent, newest first.
Show child attributes
Show child attributes