A valid request URL is required to generate request examples{
"campaign_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"sends": {
"sent": 123,
"suppressed": 123,
"failed": 123,
"pending": 123,
"retrying": 123
},
"delivery": {
"tracked": 123,
"delivered": 123,
"opened": 123,
"clicked": 123,
"bounced": 123
},
"outcomes": {
"window_days": 123,
"reached": 123,
"upgraded": 123,
"reactivated": 123,
"paid": 123
}
}{
"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"
}
}What a campaign did
Requires messaging:manage. A read, so it stays free on every plan — a downgrade may hide what you can do and must never hide what already happened.
The numbers come from three different kinds of source, and the difference matters when you read them.
sends is the claim. One row per person per occasion was written before anything left, so sent and suppressed cannot disagree with what went out. suppressed is the number that makes an unsubscribe visible as an outcome instead of as a gap.
delivery is the mail provider’s answer, and tracked is the field to read first. It is how many of these sends anything was ever going to report on: if no delivery webhook is configured for the sending domain, tracked is 0 and the four counts beside it stay 0 forever. Zero-of-zero-tracked means we are not measuring; zero-of-nine-hundred means nobody opened it. They are the same percentage and different facts, which is why no rate is computed here — a rate whose denominator is unmeasured is a reassurance, and a reassurance is what stops somebody checking.
outcomes is a join, not a record. Subscriptions and invoices are matched against the people this campaign reached, inside window_days after their message went out. It measures coincidence in a window and never causation: somebody who was going to pay anyway is counted here. That is the honest thing a campaign report can offer, and it is why the window is a parameter rather than a stored number — the question is yours.
reached is the denominator of the three outcome counts and is deliberately not sent + suppressed: a suppressed send reached nobody, and crediting it with an upgrade would make honouring an unsubscribe look like marketing that worked.
A valid request URL is required to generate request examples{
"campaign_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"sends": {
"sent": 123,
"suppressed": 123,
"failed": 123,
"pending": 123,
"retrying": 123
},
"delivery": {
"tracked": 123,
"delivered": 123,
"opened": 123,
"clicked": 123,
"bounced": 123
},
"outcomes": {
"window_days": 123,
"reached": 123,
"upgraded": 123,
"reactivated": 123,
"paid": 123
}
}{
"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
How long after a message an outcome still counts. Clamped rather than refused: a report that will not draw because somebody typed 365 is worse than one drawn over 90 days.
1 <= x <= 90