Docs/Webhooks & events

Events

The event stream is every delivery and engagement event for your sent mail, queryable on demand. Where a webhook pushes each event to you as it happens, the events API lets you pull a window of history back whenever you need it.

Events vs webhooks

Both surfaces carry the same event types. They differ in how you consume them.

  • Webhooks push. Anypost POSTs each event to your endpoint as it happens. Best for reacting in real time. See Webhooks.
  • Events pull. You query the stored stream when you want it. Best for backfilling a gap, reconciling your own records, or one-off lookups.

The two compose. When a webhook endpoint is down long enough to be disabled, events that occur while it is disabled are not queued. Page the events API once the endpoint is healthy to recover that gap.

Event types

Only customer-facing events are returned. Operational events are excluded.

TypeEmitted when
email.sentAnypost accepted the message and handed it to the outbound mail system.
email.deliveredThe receiving server accepted the message.
email.delayedA delivery attempt failed temporarily and will be retried.
email.bouncedDelivery failed permanently.
email.complainedThe recipient marked the message as spam.
email.suppressedThe send was dropped because the address is on your suppression list.
email.unsubscribedThe recipient used a one-click unsubscribe link.
email.openedThe recipient opened the message.
email.clickedThe recipient clicked a tracked link.

Listing events

GET /v1/events returns events newest-first, with cursor pagination. The TypeScript list returns a page you can iterate to walk every page:

curl https://api.anypost.com/v1/events \
  -H "Authorization: Bearer $ANYPOST_API_KEY"

Events are read-only and not addressable by id — there is no GET /v1/events/{id}.

Time window

The start and end parameters take ISO 8601 timestamps. The default window is the last 24 hours. The window is clamped to your plan's event retention — 3, 7, or 30 days. A request for 30 days of history on a 3-day-retention plan silently narrows to the last 3 days rather than erroring, so the same call keeps working as you upgrade.

Filters

All filters are exact-match, except tags. A value that matches no stored row returns an empty page; there is no substring search.

ParameterRestricts to
event_typeOne of the nine event types above.
recipientOne exact recipient address, lowercased server-side.
email_idOne message's email_<uuidv7> id.
message_idAn exact Message-ID: header match.
domainA sending domain hostname (not the domain_<uuid> id). An unknown domain returns 400.
topicThe send-time topic the message was tagged with.
campaignThe send-time campaign value. Case-sensitive.
template_idThe template the originating send used.
tagsEvents carrying any of the given tags. Pass comma-separated (tags=a,b); up to 10.

Pass several at once to narrow further. To trace one message end to end, filter by its email_id:

curl -G https://api.anypost.com/v1/events \
  -H "Authorization: Bearer $ANYPOST_API_KEY" \
  --data-urlencode "email_id=email_019e1972-e87e-7000-bf74-ba09e0ed0d62" \
  --data-urlencode "limit=100"

The event object

Every event carries the same fields. The ones that do not apply to a given type are null rather than omitted: smtp_code is null on an open, bounce_type and bounce_classification are set only on email.bounced, attempt is null on non-delivery events, and tracking is null except on opens and clicks. The Events API reference lists every field.

The correlation dimensions — tags, topic, campaign, and template_id — travel onto every event for a message, engagement events included, so you can measure a campaign or template at open and click time, not just at send.

On an open or click, a non-null tracking object carries a bot block when the interaction came from a mailbox image proxy rather than the recipient's own client. Machine traffic that is pure noise — prefetchers and scanners — never becomes an event at all, so it cannot inflate a count here, in the dashboard, or on your webhooks. See Open & click tracking for the full model.

Where to go next