Events & logs

Every state change a message goes through is recorded as an event.

Every state change a message goes through is recorded as an event. Query history through the API or stream events in realtime via webhooks.

How far back the log reaches

Event history follows your plan’s data-retention window: 30 days on Free, 12 months on paid plans (the free workspace inside a paid organisation inherits the organisation’s 12 months). A since older than your window simply returns no earlier events — nothing errors. Suppression and unsubscribe records are kept indefinitely regardless of plan, and webhooks deliver every event in realtime if you want your own permanent archive. The same numbers are listed on the Limits page.

Need the log as a file instead of pages? Export events generates a full CSV of any window within retention — warehouse syncs, audits and data portability without a pagination loop.

GET /v3/events

Query parameters

ParameterTypeRequiredDescription
eventstringOptionalFilter by type: queued, sent, delivered, opened, clicked, bounced, complained, unsubscribed, delayed, rejected, failed.
recipientstringOptionalFilter by recipient address (exact match).
tagstringOptionalOnly count events carrying this tag (event or parent message).
message_idstringOptionalAll events for a single message.
metadata[key]stringOptionalMetadata search: metadata[order_id]=1234 matches events whose message carries that metadata key/value (attached at send). Up to 3 filters per request; keys ≤64 chars (letters, digits, dot, dash, underscore), values ≤200 chars, exact match. Combines with all other filters.
sinceISO-8601OptionalOnly events at or after this timestamp.
untilISO-8601OptionalOnly events at or before this timestamp.
limitintegerOptionalPage size, 1–300. Default 25.
cursorstringOptionalPass the next_cursor from a previous response to fetch the next page.

Cursor pagination

Results are ordered newest-first and paginated with an opaque keyset cursor rather than page numbers, so pages stay stable while new events stream in. Each response returns items, has_more, next_cursor (or null on the last page) and total_count (the total matching the filters, independent of the cursor). Keep requesting with cursor=next_cursor until has_more is false.

Retention

Events follow your plan’s data retention: 30 days on Free, 12 months on paid plans. The same window applies to webhook delivery history — if a webhook consumer missed events, you don’t need to re-derive them from this feed: resend the deliveries themselves (up to 90 days back) and your endpoint receives the original payloads again.

Responses

StatusDescription
200OK. A cursor-paginated page of events with items, has_more, next_cursor and total_count.
400Invalid query parameters.
401Missing or invalid API key.

Code examples

cURL
curl -G https://api.wemail.io/v3/events \
  -H "Authorization: Bearer afn_live_…" \
  --data-urlencode "tag=welcome" \
  --data-urlencode "event=delivered" \
  --data-urlencode "since=2026-05-01"
Node.js
const events = await wemail.events.list({
  tag: "welcome",
  event: "delivered",
  since: "2026-05-01",
});
for (const e of events) console.log(e.recipient, e.timestamp);
Python
events = wemail.events.list(tag="welcome", event="delivered", since="2026-05-01")
PHP
$events = $wemail->events->list(['tag' => 'welcome', 'event' => 'delivered']);
Ruby
events = wemail.events.list(tag: "welcome", event: "delivered")
Go
events, _ := client.Events.List(ctx, &wemail.EventParams{Tag: "welcome", Event: "delivered"})
Java
wemail.events().list(EventParams.builder().tag("welcome").event("delivered").build());
.NET
var events = await wemail.Events.ListAsync(new EventParams { Tag = "welcome", Event = "delivered" });
ResponseExample response
{
  "items": [
    {
      "id": "evt_01HBYE7Q…",
      "type": "delivered",
      "message_id": "msg_01HBYE7K9Z4PMQDR3W",
      "recipient": "alex@example.com",
      "timestamp": "2026-05-10T09:42:21.000Z",
      "tags": ["welcome", "v2"],
      "metadata": null,
      "created_at": "2026-05-10T09:42:21.412Z"
    }
  ],
  "has_more": true,
  "next_cursor": "2026-05-10T09:42:21.000Z|evt_01HBYE7Q…",
  "total_count": 1842
}