Logs API
The dashboard Logs page shows every lifecycle event of every email you send. The Logs API returns the same stream so you can pull it into your own tooling: an alert when bounces spike, a nightly export into your warehouse, or a support view that shows what happened to one customer's mail. The log is the full lifecycle history, including the internal steps (queued, sending, retrying) that never reach a webhook, so it is the place to check what happened to a message and to reconcile after a webhook outage.
Scope
Reading the log needs the logs:read scope. It is not in the default set, so add it when you create the key (Dashboard, API Keys, Scopes). Keys you already have keep working for everything else and get a 403 from this endpoint until you mint one with the scope.
/v1/logsList email events for the team, newest first. Every parameter is optional; combine them freely.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| type | string | No | One event type or a comma-separated list: queued, scheduled, sending, retrying, sent, delivered, delivery_delayed, bounced, complained, opened, clicked, unsubscribed, suppressed, failed |
| since | string | No | ISO 8601. Only events at or after this time |
| until | string | No | ISO 8601. Only events at or before this time |
| recipient | string | No | Exact To address |
| domain | string | No | Sending domain name, e.g. acme.com |
| domain_id | string | No | Sending domain id, as an alternative to domain |
| tag | string | No | name:value, matched exactly against the tags the email was sent with |
| email_id | string | No | All events of one email, oldest at the bottom |
| limit | integer | No | Page size, 1 to 100, default 20 |
| after | string | No | Event id. Return events older than it (next page) |
| before | string | No | Event id. Return events newer than it (previous page) |
Response
{
"object": "list",
"has_more": true,
"data": [
{
"object": "event",
"id": "evt_01j9x3p2q7",
"type": "bounced",
"created_at": "2026-09-03T08:12:44.000Z",
"email_id": "em_01j9x3n8r1",
"from": "[email protected]",
"to": ["[email protected]"],
"subject": "Your September invoice",
"domain_id": "dom_xyz789",
"tags": [{ "name": "campaign", "value": "invoices" }],
"data": { "bounceType": "Permanent", "bounceSubType": "General" }
}
]
}Example
# newest 50 bounces and complaints from the last day curl "https://smtpfa.st/api/v1/logs?type=bounced,complained&since=$(date -u -d '1 day ago' +%FT%TZ)&limit=50" \ -H "Authorization: Bearer $SMTPFAST_API_KEY" # next page: pass the last id you saw as after curl "https://smtpfa.st/api/v1/logs?type=bounced,complained&after=evt_01j9x3p2q7" \ -H "Authorization: Bearer $SMTPFAST_API_KEY"
Notes
- Filters apply before paging, so has_more tells you whether more matching events exist, not whether more events exist at all.
- recipient is an exact match on the To address, lowercased. Use the Logs page for substring search.
- Webhooks carry a subset of these events (delivered, bounced, complained, opened, clicked and so on) in their own payload shape. Use webhooks to react and this log to look back.
- A parameter that is present but malformed returns 400; nothing is silently ignored.
- recipient matches up to the 5,000 most recent emails to that address (after the domain and tag filters, so combining them narrows the set); use since for older mail to a very busy address.
- The hosted MCP server exposes the endpoint as the list_logs tool.