List and retrieve
Find messages, and see what became of one.
Runs any of 3 calls on your workspace.
Listing
GET /emails, newest first. Filter with status (comma-separated), from, and broadcastId, which keeps the copies of one broadcast, one per person it reached. Pagination is keyset, not offset: pass the nextCursor you were given. Offset paging silently skips rows when new messages arrive while you page.
{ "object": "list", "data": [ … ], "hasMore": true, "nextCursor": "msg_01j8…" }A row that was tracked also carries a compact tracking object: opens, clicks, opened, clicked, openCount, clickCount, firstOpenAt. A row that was not carries no tracking key at all: openCount: 0 on a message that never held a pixel reads as "nobody opened it", which is a claim we are in no position to make.
scheduledFrom and scheduledTo, ISO 8601 instants with a zone, keep the messages scheduled inside a window. With status=scheduled,queued that is what is waiting to go out, as the calendar of the app shows it.
A bounce moves a message on after it was sent: it reads bounced once every recipient has bounced, so nobody has it, and partial when only some did. status=bounced,partial finds every message that did not reach everybody, and retrieving one shows which recipient bounced and why.
since and until keep the messages made inside a window, recipient keeps the ones that went to one address as a to, cc or bcc recipient, and tag keeps the ones sent with a tag: plan for any value, plan:pro for one. Tags are stored encrypted and matched through a keyed index, so the match is exact and case-sensitive. Every email webhook carries the tags of its send too.
Retrieving one
GET /emails/{id} returns the message with per-recipient delivery state, and the FULL tracking report rather than the list summary, since one retrieve can afford the per-recipient breakdown and the links. An id that does not exist is a 404, never a fabricated success.
| Recipient status | Means |
|---|---|
| pending | Not yet transmitted. |
| delivered | Handed to the transport for this address. |
| failed | The transport refused it. |
| uncertain | A transport failed part-way and cannot say which recipients it reached. Shown as itself rather than guessed either way. |
| bounced | The receiving server refused it after it left. error carries the reason. |
Events
GET /emails/{id}/events returns the trail, oldest first: email.accepted, email.queued, email.scheduled, email.sent, email.failed, email.cancelled, email.rescheduled, and, on a tracked message, email.opened, email.clicked and email.downloaded as they happen. It pages like every other list, limit and cursor in and hasMore and nextCursor out, because a widely read message records an event for every counted open. To be told rather than to poll for them, register a webhook.
Google Workspace