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
list(domain_id: nil, direction: nil, outcomes: nil, address: nil, recipient: nil, since: nil, until: nil, limit: nil, cursor: nil, api_key: nil) -> Nextmail::PageReturns 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. list_all 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.
Parameters
domain_idStringKeeps one domain, by the id
domains.listreturns. A domain the key does not reach is a 404.directionStringinboundfor mail that arrived,outboundfor mail the workspace sent or forwarded. Left out, both, as far as the key's scopes reach.Nextmail::TRAFFIC_DIRECTIONSholds the values.outcomesArray<String>Keeps these outcomes, such as
["bounced", "deferred"].Nextmail::TRAFFIC_OUTCOMESholds the values.addressStringKeeps one of your addresses: the one the mail arrived for, or the one it was sent from.
recipientStringKeeps one recipient, matched whole: the person you wrote to on an outbound entry, the address in the envelope on an inbound one.
sinceTime, DateTime, Date or StringKeeps entries at or after this instant. A Time is sent as a UTC ISO 8601 instant, and a String must already be one.
untilTime, DateTime, Date or StringKeeps entries before this instant. It must be later than
since.limitIntegerPage size, from 1 to 100. The server defaults to 25.
cursorStringThe
next_cursorof the previous page. Leave it out for the first page.api_keyStringOverrides the client API key for this call only.
Returns
The Nextmail::Page of Hashes, with items, has_more? and next_cursor. 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
page = client.traffic.list(direction: "outbound", outcomes: ["bounced", "deferred"], since: Time.now - 86_400) page.items.each { |entry| puts [entry[:createdAt], entry[:recipient], entry[:outcome], entry[:detail]].join(" ") }Notes
Outbound entries need
emails:readand inbound onesthreads:read. A key with only one of them sees that direction alone, and asking for the otherdirectionis a 403insufficient_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,outcomes,direction,domain_idand the 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- TypeScript
traffic.list()- Python
traffic.list()- PHP
traffic->list- Go
Traffic.List- Java
traffic().list- C#
Traffic.ListAsync- CLI
nextmail traffic list
traffic.list_all
Collect the traffic log into one array
list_all(domain_id: nil, direction: nil, outcomes: nil, address: nil, recipient: nil, since: nil, until: nil, limit: nil, cursor: nil, api_key: nil) -> Array<Hash>Walks every page of list and returns every entry that matches in one Array, newest first. One request per page, with the same filters on each, so narrow it with since, domain_id or outcomes before collecting a busy workspace.
Parameters
domain_idStringKeeps one domain, by the id
domains.listreturns. A domain the key does not reach is a 404.directionStringinboundfor mail that arrived,outboundfor mail the workspace sent or forwarded. Left out, both, as far as the key's scopes reach.Nextmail::TRAFFIC_DIRECTIONSholds the values.outcomesArray<String>Keeps these outcomes, such as
["bounced", "deferred"].Nextmail::TRAFFIC_OUTCOMESholds the values.addressStringKeeps one of your addresses: the one the mail arrived for, or the one it was sent from.
recipientStringKeeps one recipient, matched whole: the person you wrote to on an outbound entry, the address in the envelope on an inbound one.
sinceTime, DateTime, Date or StringKeeps entries at or after this instant. A Time is sent as a UTC ISO 8601 instant, and a String must already be one.
untilTime, DateTime, Date or StringKeeps entries before this instant. It must be later than
since.limitIntegerPage size for each request, from 1 to 100. The server defaults to 25.
cursorStringStarts the walk after this cursor instead of the first page.
api_keyStringOverrides the client API key for every page of this walk.
Returns
An Array of Hashes holding every matching entry, each with the fields list returns.
Example
bounced = client.traffic.list_all(outcomes: ["bounced"], since: "2026-10-01T00:00:00Z", limit: 100) puts bounced.map { |entry| entry[:recipient] }.uniqNotes
If any page fails, the error is raised and the entries already fetched are discarded.
Outbound entries need
emails:readand inbound onesthreads:read, as onlist.
Also available in
- API
GET /traffic- TypeScript
traffic.listAll()- Python
traffic.list_all()- PHP
traffic->listAll- Go
Traffic.ListAll- Java
traffic().listAll- C#
Traffic.ListAllAsync
traffic.iterate
Stream the traffic log one entry at a time
iterate(domain_id: nil, direction: nil, outcomes: nil, address: nil, recipient: nil, since: nil, until: nil, limit: nil, cursor: nil, api_key: nil, &block) -> Enumerator<Hash>Returns an Enumerator 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. Given a block, it yields each entry to the block instead.
Parameters
domain_idStringKeeps one domain, by the id
domains.listreturns. A domain the key does not reach is a 404.directionStringinboundfor mail that arrived,outboundfor mail the workspace sent or forwarded. Left out, both, as far as the key's scopes reach.Nextmail::TRAFFIC_DIRECTIONSholds the values.outcomesArray<String>Keeps these outcomes, such as
["bounced", "deferred"].Nextmail::TRAFFIC_OUTCOMESholds the values.addressStringKeeps one of your addresses: the one the mail arrived for, or the one it was sent from.
recipientStringKeeps one recipient, matched whole: the person you wrote to on an outbound entry, the address in the envelope on an inbound one.
sinceTime, DateTime, Date or StringKeeps entries at or after this instant. A Time is sent as a UTC ISO 8601 instant, and a String must already be one.
untilTime, DateTime, Date or StringKeeps entries before this instant. It must be later than
since.limitIntegerPage size for each request, from 1 to 100. The server defaults to 25.
cursorStringStarts the walk after this cursor instead of the first page.
api_keyStringOverrides the client API key for every page of this walk.
Returns
An Enumerator of Hashes, one entry per step (or yields each one to a block).
Example
client.traffic.iterate(direction: "inbound", outcomes: ["refused", "dropped"]) do |entry| puts [entry[:recipient], entry[:reason], entry[:detail]].join(" ")endNotes
The Enumerator is lazy, so an abandoned loop costs only the pages you consumed.
Outbound entries need
emails:readand inbound onesthreads:read, as onlist.
Also available in
- API
GET /traffic- TypeScript
traffic.iterate()- Python
traffic.iterate()- PHP
traffic->iterate- Go
Traffic.Iterate- Java
traffic().iterate- C#
Traffic.IterateAsync
Google Workspace