What a record holds
Every audited send stores the recipient and display name, the subject, both the plain-text and HTML bodies exactly as they were sent, the delivery outcome, and the timestamps. The status walks the whole delivery story, not just our side of it.pending, sent, and failed are recorded at the moment of sending — sent
means the mail provider accepted the message, which says nothing about arrival.
The rest comes back from the provider as it happens: delivered (the receiving
server took it), delayed (it is being deferred — a greylist, a full mailbox),
bounced (it can never arrive), and complained (the recipient marked it as
spam). A bounce or a failure also records why — “the recipient’s mailbox
does not exist” is the difference between a status you can act on and a label —
and a bounced or complained address is one your automations should stop
mailing. That includes suppression: after a hard bounce or complaint the mail
provider refuses further sends to that address on its own, and such a send
records failed with the suppression as its reason rather than pretending it
went out. Mail sent before delivery tracking existed stays at sent, so sent
must never be read as “not delivered”.
It also stores the address the message went out from, and the reply address
that went with it. That is worth recording rather than assuming, because the
sender is no longer fixed: an organization that has verified an email sending
domain has its agent outreach sent from its own address, while
Erdo’s product mail keeps coming from Erdo. Reading the from address back off the
record is how you tell, for any given message, which one it was — and how you can
see a domain take effect without waiting for someone to forward you a copy.
It also stores context — a small set of key/value tags describing what the
message was about. This is the part that makes the log genuinely queryable, and
it exists because the recipient is very often not the subject. A new-lead alert
is addressed to your sales desk, so filtering by recipient tells you nothing
about which lead it concerned. Tag the send instead:
Context values are flat text. Nested objects and arrays are dropped rather than
stored, because the lookup that reads them back matches on flat key/value pairs —
keeping them would advertise a query that could never work.
Reading the log
GET /v1/emails lists your organization’s mail, newest first, filtered by
recipient (to), by time (since, an RFC 3339 timestamp), or by subject text
(search). Bodies are omitted from the listing so a page of results doesn’t drag
a page of HTML documents with it.
POST /v1/emails-query — a query string can’t carry a
key/value map, so the structured probe travels in a JSON body. The probe is a
containment match: name only the keys you care about and rows carrying those
plus others still match.
GET /v1/emails/{emailID} returns one message in full, including both bodies as
they were sent.
Listings report a total alongside the page, so you can page without having to
discover the end by requesting an empty result.
Agents in the product read the same log with the list_sent_emails tool, so
“did the follow-up to that lead go out?” is a question you can ask in chat —
the agent checks the record rather than its own memory, which also covers sends
made by automations and other conversations.
Tagging what you send
Thesend_email action takes an optional context object, wherever you invoke
it — from an agent, from a script.run step on an event pipeline, or from a
scripted job:
Access
The log is scoped to the organization of the caller, enforced in the query itself. Requesting a message id belonging to another organization returns not found — identical to an id that doesn’t exist, so the endpoint can’t be used to probe for someone else’s mail.Related
Inboxes
The other direction — an address Erdo can receive at.
Event pipelines
Where lead-arrival alerts are usually sent from.
Email sending domains
Send outreach from your own domain instead of Erdo’s.

