This is a technical reference for developers writing a mail collector. If you only want to forward mail to your brain, see your email; it needs nothing from this page.
- The address chooses the brain; the brain verifies its forwarders. A mail item may enter a brain only from an address on that brain’s forwarder list, the addresses its members have proved with a code. Any brain can hold such a list. The door checks this in code before anything is stored, and refuses everything else with a 422. No hint and no
?brain=changes which brain; in a client brain,?partition=or the address’s+keynames the client and the participants’ domains decide otherwise. - The mail is never kept. A mail item is created with retention
none: its body exists only while the item waits to be filed, and is destroyed when filing ends (archive, reject, delete, or seven days unfiled). No archive copy, no downloadable original, no replay. What remains is the stub: subject, link, content hash, external id, the pages it was filed to, and the dates. - The skill is pinned to
ingest-email, at the door, whatever the caller asked for.
The shape
A markdown file: frontmatter, then the new messages of the thread, oldest first.
Rules for the body: only the new messages, oldest first. Quoted history is stripped by whatever produces the contract. Attachments are never sent, only named. Extra keys are allowed and preserved; unknown keys are ignored.
Where to send it
retain: none is implied for a kind: email contract whether or not you send it. It is worth sending anyway: it is the honest description of what you are asking for, and it applies to any item, not only mail.
Check the pairing before you send
A collector should verify its own configuration at startup rather than discovering a mistake at delivery. Callwhoami with the credential it will use:
- With a service credential, the response’s one brain carries
mail.forwarders, that brain’s verified forwarders, andmail.address, whether it has an inbound address. Refuse to run unless the mailbox you are about to read is in that list. - With an OAuth connection, every brain in the roster carries
mail.forwarders, andbriefon one brain carries the same block withmail.address.
What the door answers
Every refusal is a 422 with a message starting “Mail refused”, and nothing is stored: no item, no blob, no extracted text.
The agent route goes through the same door and gets the same refusal, so an agent cannot file mail into a brain whose list does not hold the mailbox, whatever it is asked. The core manual tells an agent to file into the personal brain by default and into a shared or client brain only when the user names it, confirming first.
Forwarders
A forwarder is an address proven to one brain. It is added and confirmed under the brain’s Settings, then Ingest sources, on the Forward mail card: Cortex sends a six-digit code to the address, valid for fifteen minutes and dead after five wrong entries, and the person types it back. Any member with write access to the brain can add an address they can read. The member who added it, or an Admin, removes it, with effect from the next delivery. Up to twenty-five per brain. A brain marked as someone’s own starts with their sign-in address on the list; addresses verified under the old per-account list were moved onto each owner’s own brain when that list was retired. The same list is on the API, so the command line and a scheduled job can manage it:
A service credential acts with the role it was issued. The code still has to be read from the mailbox by a person: nothing on the API returns it.
Once it is in
The item is pinned to theingest-email skill, named by the subject, and carries the link as its source reference. From there it is an ordinary inbox item: filed by your agent, by Cortex under the brain’s filing mode, or by you in the review queue. What the skill writes is described in how a thread is filed.
get_inbox_item and list_inbox report retention (none or keep) and bodyDestroyedAt. Once the body is gone, GET .../inbox/{itemId}/download answers 410, get_source_file answers with an error instead of the file, and the Sources record shows “Body not kept”. A rejected mail item is closed rather than re-queued.