---
title: "client.Traffic"
description: "Every method in this namespace: its signature, its parameters, what it returns and an example."
url: "https://nextmail.sh/docs/go/reference/traffic"
area: "Go"
category: "Reference"
---

# client.Traffic

Every method in this namespace: its signature, its parameters, what it returns and an example.

## Methods

What happened to every message at the edge of the workspace: where the mail that arrived for your addresses went, and what the receiving server said about the mail you sent.

### `Traffic.List`

List one page of the traffic log

```go
List(ctx context.Context, opts ...nextmail.RequestOption) (*nextmail.Page, error)
```

Returns one page of the traffic log, newest first: one entry for each message and recipient at each step it took in or out of the workspace. `ListAll` collects every page and `Iterate` walks them lazily.

Inbound, each recipient of a message that arrived gets an 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.

An entry never changes once it is written, and the same step keeps the same id. Entries are kept for 30 days. `detail` holds the reply of the receiving server and `remoteMta`, `reportingMta` and `sendingIp` the servers on each side, and inbound entries carry the SPF, DKIM, DMARC, spam and virus `verdicts` the message arrived with.

Scopes: `emails:read`.

**Parameters**

- `nextmail.WithDomainID` (`string`): Keeps one domain, by the id `Domains.List` returns. A domain the key does not reach is a 404.
- `nextmail.WithDirection` (`string`): `inbound` for mail that arrived, `outbound` for mail the workspace sent or forwarded. Left out, both, as far as the key's scopes reach. `constants.TrafficDirectionsValues` holds the values.
- `nextmail.WithOutcomes` (`...string`): Keeps these outcomes, such as `bounced` and `deferred`. `constants.TrafficOutcomesValues` holds the values.
- `nextmail.WithAddress` (`string`): Keeps one of your addresses: the one the mail arrived for, or the one it was sent from.
- `nextmail.WithRecipient` (`string`): Keeps one recipient, matched whole: the person you wrote to on an outbound entry, the address in the envelope on an inbound one.
- `nextmail.WithSince` (`time.Time`): Keeps entries at or after this instant, as a `time.Time`.
- `nextmail.WithUntil` (`time.Time`): Keeps entries before this instant. It must be later than `nextmail.WithSince`.
- `nextmail.WithLimit` (`int`): Page size, from 1 to 100. The server defaults to 25.
- `nextmail.WithCursor` (`string`): The `NextCursor` of the previous page. Leave it out for the first page.
- `nextmail.WithAPIKey` (`string`): Overrides the client API key for this call only.

**Returns**

The `*nextmail.Page` with `Items`, `HasMore` and `NextCursor`. Each item has `direction`, `outcome`, `reason`, `status`, `detail`, `sender`, `recipient`, `address`, `domain`, the ids of the email and thread it belongs to, the servers on each side, `verdicts`, `size` and `createdAt`.

**Example**

```go
page, err := client.Traffic.List(ctx,
	nextmail.WithDirection(constants.TrafficDirectionsOutbound),
	nextmail.WithOutcomes(constants.TrafficOutcomesBounced, constants.TrafficOutcomesDeferred),
	nextmail.WithSince(time.Now().Add(-24*time.Hour)),
)
if err != nil {
	return err
}

for _, entry := range page.Items {
	fmt.Println(entry.String("createdAt"), entry.String("recipient"), entry.String("outcome"), entry.String("detail"))
}
```

**Notes**

- Outbound entries need `emails:read` and inbound ones `threads:read`. A key with only one of them sees that direction alone, and asking for the other direction is a 403 `insufficient_scope`.
- 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.
- The sender and the reply are stored encrypted, so they cannot be searched. Filter by address, recipient, outcome, direction, domain and time.
- The cursor is opaque and holds where the last row sat. A cursor this list did not hand out is a 400 `invalid_cursor`.

Also available in: API [`GET /traffic`](https://nextmail.sh/docs/api/reference/traffic#get-traffic); TypeScript [`traffic.list()`](https://nextmail.sh/docs/sdk/reference/traffic#list); Python [`traffic.list()`](https://nextmail.sh/docs/python/reference/traffic#list); Ruby [`traffic.list`](https://nextmail.sh/docs/ruby/reference/traffic#list); PHP [`traffic->list`](https://nextmail.sh/docs/php/reference/traffic#list); Java [`traffic().list`](https://nextmail.sh/docs/java/reference/traffic#list); C# [`Traffic.ListAsync`](https://nextmail.sh/docs/csharp/reference/traffic#list); CLI [`nextmail traffic list`](https://nextmail.sh/docs/cli/reference/traffic#traffic-list).

### `Traffic.ListAll`

Collect the traffic log into one slice

```go
ListAll(ctx context.Context, opts ...nextmail.RequestOption) ([]nextmail.Object, error)
```

Walks every page of `List` and returns with every entry that matches, newest first. One request per page, with the same filters on each, so narrow it with `nextmail.WithSince`, `nextmail.WithDomainID` or `nextmail.WithOutcomes` before collecting a busy workspace.

Scopes: `emails:read`.

**Parameters**

- `nextmail.WithDomainID` (`string`): Keeps one domain, by the id `Domains.List` returns. A domain the key does not reach is a 404.
- `nextmail.WithDirection` (`string`): `inbound` for mail that arrived, `outbound` for mail the workspace sent or forwarded. Left out, both, as far as the key's scopes reach. `constants.TrafficDirectionsValues` holds the values.
- `nextmail.WithOutcomes` (`...string`): Keeps these outcomes, such as `bounced` and `deferred`. `constants.TrafficOutcomesValues` holds the values.
- `nextmail.WithAddress` (`string`): Keeps one of your addresses: the one the mail arrived for, or the one it was sent from.
- `nextmail.WithRecipient` (`string`): Keeps one recipient, matched whole: the person you wrote to on an outbound entry, the address in the envelope on an inbound one.
- `nextmail.WithSince` (`time.Time`): Keeps entries at or after this instant, as a `time.Time`.
- `nextmail.WithUntil` (`time.Time`): Keeps entries before this instant. It must be later than `nextmail.WithSince`.
- `nextmail.WithLimit` (`int`): Page size for each request, from 1 to 100. The server defaults to 25.
- `nextmail.WithCursor` (`string`): Starts the walk after this cursor instead of the first page.
- `nextmail.WithAPIKey` (`string`): Overrides the client API key for every page of this walk.

**Returns**

A `[]nextmail.Object` holding every matching entry.

**Example**

```go
since := time.Date(2026, time.October, 1, 0, 0, 0, 0, time.UTC)

bounced, err := client.Traffic.ListAll(ctx, nextmail.WithOutcomes(constants.TrafficOutcomesBounced), nextmail.WithSince(since), nextmail.WithLimit(100))
if err != nil {
	return err
}

recipients := map[string]bool{}
for _, entry := range bounced {
	recipients[entry.String("recipient")] = true
}

fmt.Println(len(recipients))
```

**Notes**

- If any page fails the call fails and the entries already fetched are discarded.
- Outbound entries need `emails:read` and inbound ones `threads:read`, as on `List`.

Also available in: API [`GET /traffic`](https://nextmail.sh/docs/api/reference/traffic#get-traffic); TypeScript [`traffic.listAll()`](https://nextmail.sh/docs/sdk/reference/traffic#listAll); Python [`traffic.list_all()`](https://nextmail.sh/docs/python/reference/traffic#listAll); Ruby [`traffic.list_all`](https://nextmail.sh/docs/ruby/reference/traffic#listAll); PHP [`traffic->listAll`](https://nextmail.sh/docs/php/reference/traffic#listAll); Java [`traffic().listAll`](https://nextmail.sh/docs/java/reference/traffic#listAll); C# [`Traffic.ListAllAsync`](https://nextmail.sh/docs/csharp/reference/traffic#listAll).

### `Traffic.Iterate`

Stream the traffic log one entry at a time

```go
Iterate(ctx context.Context, opts ...nextmail.RequestOption) *nextmail.Iterator
```

Returns an iterator that yields one entry at a time, newest first, and requests the next page only once the current one is drained. Nothing is fetched until you consume it, and breaking out of the loop stops the requests.

Scopes: `emails:read`.

**Parameters**

- `nextmail.WithDomainID` (`string`): Keeps one domain, by the id `Domains.List` returns. A domain the key does not reach is a 404.
- `nextmail.WithDirection` (`string`): `inbound` for mail that arrived, `outbound` for mail the workspace sent or forwarded. Left out, both, as far as the key's scopes reach. `constants.TrafficDirectionsValues` holds the values.
- `nextmail.WithOutcomes` (`...string`): Keeps these outcomes, such as `bounced` and `deferred`. `constants.TrafficOutcomesValues` holds the values.
- `nextmail.WithAddress` (`string`): Keeps one of your addresses: the one the mail arrived for, or the one it was sent from.
- `nextmail.WithRecipient` (`string`): Keeps one recipient, matched whole: the person you wrote to on an outbound entry, the address in the envelope on an inbound one.
- `nextmail.WithSince` (`time.Time`): Keeps entries at or after this instant, as a `time.Time`.
- `nextmail.WithUntil` (`time.Time`): Keeps entries before this instant. It must be later than `nextmail.WithSince`.
- `nextmail.WithLimit` (`int`): Page size for each request, from 1 to 100. The server defaults to 25.
- `nextmail.WithCursor` (`string`): Starts the walk after this cursor instead of the first page.
- `nextmail.WithAPIKey` (`string`): Overrides the client API key for every page of this walk.

**Returns**

The `*nextmail.Iterator` yielding one entry per step.

**Example**

```go
entries := client.Traffic.Iterate(ctx,
	nextmail.WithDirection(constants.TrafficDirectionsInbound),
	nextmail.WithOutcomes(constants.TrafficOutcomesRefused, constants.TrafficOutcomesDropped),
)

for entry, err := range entries.All() {
	if err != nil {
		return err
	}

	fmt.Println(entry.String("recipient"), entry.String("reason"), entry.String("detail"))
}
```

**Notes**

- The iterator is lazy, so an abandoned loop costs only the pages you consumed.
- Outbound entries need `emails:read` and inbound ones `threads:read`, as on `List`.

Also available in: API [`GET /traffic`](https://nextmail.sh/docs/api/reference/traffic#get-traffic); TypeScript [`traffic.iterate()`](https://nextmail.sh/docs/sdk/reference/traffic#iterate); Python [`traffic.iterate()`](https://nextmail.sh/docs/python/reference/traffic#iterate); Ruby [`traffic.iterate`](https://nextmail.sh/docs/ruby/reference/traffic#iterate); PHP [`traffic->iterate`](https://nextmail.sh/docs/php/reference/traffic#iterate); Java [`traffic().iterate`](https://nextmail.sh/docs/java/reference/traffic#iterate); C# [`Traffic.IterateAsync`](https://nextmail.sh/docs/csharp/reference/traffic#iterate).
