Inboxes
Give an AI agent its own email address. Mail to it arrives as threads, with a webhook for each message, and the agent replies from the same address.
An inbox is an email address of an environment, usually one per agent
(or per user an agent works for). Mail sent to it is kept as threads, conversations of
messages, and each message that arrives sends an inbox.message.received
webhook. The agent reads the thread and replies from the inbox's address; the
reply lands in the same thread, and so does the answer to it.
| Concept | What it is |
|---|---|
| Inbox | An address, username@domain, at coss.com's inbound domain or one of your receiving domains. |
| Thread | A conversation: the messages that answer one another. |
| Message | One email in a thread: inbound (received) or outbound (sent from the inbox). |
Inboxes build on receiving and sending: an inbound message is a received email, an outbound one is an email, with its usual delivery events.
Quickstart
Create an inbox. Without a domain, its address is at the environment's own domain under
coss.com's inbound domain, which needs no DNS setup:
const { : } = await ..({
: "support-agent",
: "Acme Support",
: "agent-42", // your own id: creating it again returns this inbox
});
.(?.); // support-agent@k3j9x2m7qp4l.inbound.coss.comThen handle inbox.message.received (subscribe a webhook endpoint to it, or run
coss listen while you develop): read the thread and reply.
const = await (await .(), ., );
if (. === "inbox.message.received" && !..) {
const { , , } = .;
const { : } = await ...(, );
// `extracted_text` is each message's own words, without the quoted conversation.
const = (?. ?? [])
.(() => `${. === "inbound" ? . : "You"}: ${.}`)
.("\n\n");
await ...(
,
,
{ : await () },
{ : `reply-${}` }, // a redelivered webhook won't reply twice
);
}The reply goes to the sender (their Reply-To, when they set one) with Re: and the headers mail
clients thread by. reply_all: true also answers everyone else on the message. To start a
conversation instead, send a message from the inbox:
const { : } = await ...(, {
: "jane@example.com",
: "Your order",
: "Hi Jane, your order has shipped. Reply here with any questions.",
});
.(?., ?.);Addresses and sending
| Inbox at | Receives | Sends from live environments |
|---|---|---|
coss.com's inbound domain (…@k3j9x2m7qp4l.inbound.coss.com) | Yes | No |
| A receiving domain under one of your verified domains | Yes | Yes |
- Live environments send only from your own verified domains: to send from
an inbox, set up receiving on a subdomain of a verified domain
(e.g.
agents.acme.com) and create the inbox there withdomain: "agents.acme.com". An inbox'scan_sendsays whether it can send. - Sandbox environments (
coss_test_…keys) send from every inbox and deliver nothing, like every sandbox send. Mail sent to a sandbox inbox is still received, so you can test the whole loop with your own mail client. - Usernames are lower-case letters, digits,
.,_and-. Mail tousername+anything@domainreaches the inbox too, so an agent can hand out one address per task. - Messages from an inbox are ordinary emails: they count against the send quota and your plan's emails, appear in the environment's emails and logs, and are never tracked (no pixel, no rewritten links).
- An environment can have up to 1,000 inboxes.
Inboxes and received emails
Every inbound message is also a received email of the environment: email.received fires too, and
the email shows under Received emails. Subscribe to inbox.message.received for inbox mail
only. Deleting an inbox deletes its threads, not their emails; mail to its address is then
received like any other mail to the environment's domain.
Messages follow the retention of their emails: inbound messages are deleted with their received email, outbound ones with their email, and a thread whose messages are all gone disappears.