---
title: "Traffic"
description: "Every operation in this group: what it accepts, what it returns and the errors it can answer with."
url: "https://nextmail.sh/docs/api/reference/traffic"
area: "API"
category: "Reference"
---

# Traffic

Every operation in this group: what it accepts, what it returns and the errors it can answer with.

## Operations

What happened to every message at the edge of the workspace, one entry for each message and recipient at each step: the mail that arrived for your addresses and where it went, and the mail you sent and what the receiving server said. It is the Traffic tab of a domain in the app, kept for 30 days. Reading outbound entries needs `emails:read` and inbound ones `threads:read`.

### `GET /traffic`

List traffic

Every step a message took in or out of the workspace, newest first. Inbound, each recipient of a message that arrived gets one entry saying where it went: `filed` in the inbox, `spam`, `routed` to a webhook, `forwarded` without a copy kept, `refused` with a bounce back to the sender, or `dropped` without one, and `reason` says why mail was refused or dropped. Outbound, each recipient of a message you sent or forwarded gets an entry for each answer from the receiving server: `delivered`, `deferred` while it keeps trying, `bounced`, `complained`, `suppressed` when it was never tried, `rejected` when it was refused before it left, and `failed` for a forward that could not be relayed. A deferred recipient is followed by a delivery or a bounce for the same message.

An entry never changes once it is written, and the same step always keeps the same id, so reading a page again is safe. Entries are kept for 30 days. The sender and the server's reply are stored encrypted and cannot be searched; filter by `address`, `recipient`, `outcome`, `direction`, `domainId` and the time instead.

A key with `emails:read` and no `threads:read` sees outbound entries alone, and one with `threads:read` alone sees inbound ones. A key or an app narrowed to particular addresses or domains sees the entries of the addresses it reaches and, for a whole domain it holds, every entry of that domain, including mail for addresses that do not exist.

Requires the `emails:read` scope, or `threads:read` in its place.

- Scopes: `emails:read`.

**Query parameters**

- `domainId` (`string`): Keeps one domain, by the id `GET /domains` returns. A domain of another workspace, or one a narrowed key does not reach, is a 404.
- `direction` (`string`, one of `"inbound"`, `"outbound"`): `inbound` for mail that arrived, `outbound` for mail the workspace sent or forwarded. Left out, both, as far as the scopes reach.
- `outcome` (`string`): One outcome or several separated by commas, such as `bounced,deferred`: `delivered`, `deferred`, `bounced`, `suppressed`, `complained`, `rejected`, `failed`, `forwarded`, `filed`, `spam`, `routed`, `refused`, `dropped`, `report`. A name outside that list is a 422 `invalid_parameter`.
- `address` (`string`, up to 320 characters): Keeps one of your addresses: the one the mail arrived for, or the one it was sent from. Case does not matter.
- `recipient` (`string`, up to 320 characters): Keeps one recipient, matched whole and without regard to case: the person you wrote to on an outbound entry, the address in the envelope on an inbound one.
- `since` (`string`, format `date-time`): Keeps entries at or after this ISO 8601 instant.
- `until` (`string`, format `date-time`): Keeps entries before this ISO 8601 instant. It must be later than `since`.
- `limit` (`integer`, at least 1, at most 100, default `25`): Rows per page, 1 to 100.
- `cursor` (`string`): The previous page's `nextCursor`, passed back as it came. It is opaque: it holds where the last row sat in this list's order, so a row deleted or edited between pages never breaks the walk, and the next page starts at the first row that sorts after it. A value this list did not hand out is a 400 `invalid_cursor`.

**Returns**

- `200` `TrafficEventList`: A page of traffic, newest first.

**Errors**

- `404`: `not_found`: the `domainId` names no domain this key reaches.
- `422`: `invalid_parameter` for an outcome, a direction or a time it cannot read.
- The errors every operation can return: `400`, `401`, `403`, `429`, `500`, described in the [error catalog](https://nextmail.sh/docs/api/errors).

Also available in: TypeScript [`traffic.list()`](https://nextmail.sh/docs/sdk/reference/traffic#list), [`traffic.listAll()`](https://nextmail.sh/docs/sdk/reference/traffic#listAll), [`traffic.iterate()`](https://nextmail.sh/docs/sdk/reference/traffic#iterate); Python [`traffic.list()`](https://nextmail.sh/docs/python/reference/traffic#list), [`traffic.list_all()`](https://nextmail.sh/docs/python/reference/traffic#listAll), [`traffic.iterate()`](https://nextmail.sh/docs/python/reference/traffic#iterate); Ruby [`traffic.list`](https://nextmail.sh/docs/ruby/reference/traffic#list), [`traffic.list_all`](https://nextmail.sh/docs/ruby/reference/traffic#listAll), [`traffic.iterate`](https://nextmail.sh/docs/ruby/reference/traffic#iterate); PHP [`traffic->list`](https://nextmail.sh/docs/php/reference/traffic#list), [`traffic->listAll`](https://nextmail.sh/docs/php/reference/traffic#listAll), [`traffic->iterate`](https://nextmail.sh/docs/php/reference/traffic#iterate); Go [`Traffic.List`](https://nextmail.sh/docs/go/reference/traffic#list), [`Traffic.ListAll`](https://nextmail.sh/docs/go/reference/traffic#listAll), [`Traffic.Iterate`](https://nextmail.sh/docs/go/reference/traffic#iterate); Java [`traffic().list`](https://nextmail.sh/docs/java/reference/traffic#list), [`traffic().listAll`](https://nextmail.sh/docs/java/reference/traffic#listAll), [`traffic().iterate`](https://nextmail.sh/docs/java/reference/traffic#iterate); C# [`Traffic.ListAsync`](https://nextmail.sh/docs/csharp/reference/traffic#list), [`Traffic.ListAllAsync`](https://nextmail.sh/docs/csharp/reference/traffic#listAll), [`Traffic.IterateAsync`](https://nextmail.sh/docs/csharp/reference/traffic#iterate); CLI [`nextmail traffic list`](https://nextmail.sh/docs/cli/reference/traffic#traffic-list); MCP [`listTraffic`](https://nextmail.sh/docs/mcp/tools/domains#listTraffic).

### Objects

#### `TrafficEvent`

`object`

- `object` (`string`, required, one of `"traffic_event"`)
- `id` (`string`, required): The same step of the same message always has this id.
- `direction` (`string`, required, one of `"inbound"`, `"outbound"`)
- `outcome` (`string`, required, one of `"delivered"`, `"deferred"`, `"bounced"`, `"suppressed"`, `"complained"`, `"rejected"`, `"failed"`, `"forwarded"`, `"filed"`, `"spam"`, `"routed"`, `"refused"`, `"dropped"`, `"report"`): Inbound: `filed`, `spam`, `routed`, `forwarded`, `refused`, `dropped`, or `report` for a DMARC report that was read. Outbound: `delivered`, `deferred`, `bounced`, `complained`, `suppressed`, `rejected`, `forwarded` and `failed`.
- `reason` (`string`, required, nullable, one of `"unknown_recipient"`, `"address_limits"`, `"blocked_sender"`, `"rule"`, `"group_policy"`, `"unreadable"`, `"too_large"`, `"report_refused"`): Why mail was refused or dropped: `unknown_recipient` for an address that does not exist, `address_limits` for the limits of the address, `blocked_sender`, `rule` for one of your rules, `group_policy` for who may write to a group, `unreadable` for a message that could not be read, `too_large` for a forward over the size it can relay, and `report_refused` for a DMARC report that was unreadable, about another domain, or over the limit the domain keeps.
- `category` (`string`, required, nullable): How the receiving side classed a bounce, a complaint or a delay, such as `Permanent/General` or `abuse`.
- `status` (`string`, required, nullable): The status code from the reply, enhanced (`5.1.1`) when it carries one, otherwise the SMTP code (`550`).
- `detail` (`string`, required, nullable): The reply of the receiving server, or what went wrong, as written.
- `sender` (`string`, required, nullable): The envelope sender of inbound mail, or your address on outbound mail.
- `recipient` (`string`, required): Who the step was for: the person you wrote to, or the address in the envelope of mail that arrived.
- `address` (`string`, required): Your address the mail arrived for or was sent from, after aliases are resolved.
- `addressId` (`string`, required, nullable): Its id, when the address exists.
- `domain` (`string`, required): Your domain the step belongs to.
- `domainId` (`string`, required, nullable)
- `emailId` (`string`, required, nullable): The sent email, as `GET /emails/{id}` reads it, or the message filed in the mailbox.
- `threadId` (`string`, required, nullable): The thread the message belongs to.
- `messageId` (`string`, required, nullable): The Message-ID header.
- `providerMessageId` (`string`, required, nullable): The id the sending or receiving service gave the message, for a support request.
- `sendingIp` (`string`, required, nullable): The IP address the message left from.
- `remoteMta` (`string`, required, nullable): The IP address of the receiving server.
- `reportingMta` (`string`, required, nullable): The server that wrote the report.
- `processingMs` (`integer`, required, nullable): How long delivery took, from accepting the message to the answer, in milliseconds.
- `verdicts` (`object`, required, nullable): The checks run on inbound mail as it arrived. Null on outbound entries.
  - `spf` (`string`, required, nullable): The SPF verdict for the sender, such as `pass` or `fail`.
  - `dkim` (`string`, required, nullable): The DKIM verdict for its signature.
  - `dmarc` (`string`, required, nullable): The DMARC verdict for the From domain.
  - `spam` (`string`, required, nullable): The spam verdict of the scan.
  - `virus` (`string`, required, nullable): The virus verdict of the scan.
  - `arc` (`string`, required, nullable): The ARC verdict for the chain of servers that forwarded the message on its way here: `pass` when every seal checks out, `fail` when one does not, `none` when it carried no ARC headers, `temperror` when a seal could not be checked yet, and null for an entry written before ARC was checked.
- `size` (`integer`, required, nullable): The size of the message in bytes.
- `createdAt` (`string`, required, format `date-time`): When the step happened.

#### `TrafficEventList`

`object`

- `object` (`string`, one of `"list"`)
- `data` (`TrafficEvent[]`)
- `hasMore` (`boolean`): True when another page follows. Pass `nextCursor` back as `cursor` to read it.
- `nextCursor` (`string`, nullable): An opaque cursor for the next page, or null on the last page. Pass it back unchanged.
