List messages with cursor pagination
Returns one cursor-paginated page of message summaries, aggregated to
one row per message. Results are ordered newest-first by sent_at.
When from and to are omitted the window defaults to the trailing
30 days; a from older than your plan's retention is rejected with
403 plan_retention_exceeded (the response carries a retention_days
extension), it is not silently clamped. Use this for dashboards,
reconciliation, and incremental export — page forward with the
next_cursor from the response (or follow the Link: <…>; rel="next"
header) until has_more is false.
Filters compose with AND. The recipient filter is PII-gated: passing
it without the analytics.search.recipients scope returns
403 invalid_scope, not a silently-dropped filter.
Query parameters
limit integer optional Page size (1–200). Default 50.
cursor string optional Opaque cursor returned from the previous page.
from string<date-time> optional Window start (RFC 3339). Defaults to 30 days ago.
to string<date-time> optional Window end (RFC 3339). Defaults to now.
channel string<uuid> optional Filter by channel UUID. Malformed values return 422 validation_failed.
status string enum optional Filter by current message status. Values are SES event-type names
(capitalized): Send, Delivery, Bounce, Complaint, Reject,
Open, Click, DeliveryDelay. Applied as an exact match on the
terminal status of each message.
template string optional Filter by exact template name (the SES template slug, not a display name).
identity string optional Filter by sending identity. Accepts a full email address (the local-part is ignored — only the domain matches) or a bare domain.
recipient string<email> optional analytics.search.recipients Filter by exact recipient address (case-sensitive). Requires the
analytics.search.recipients scope — calls without that scope
return 403 invalid_scope.
Responses
code is internal_error. The
request_id field can be quoted to SendOps support to investigate.
application/problem+json