Agent inboxes
Provision isolated agent mailboxes, least-privilege keys, reviewed drafts, and communication guardrails.
Loading documentation…
Provision isolated agent mailboxes, least-privilege keys, reviewed drafts, and communication guardrails.
Loading documentation…
An organization is the billing and human-team boundary. A tenant is an optional isolation boundary for a customer, agent fleet, or workflow. A tenant API key can never access another tenant; an inbox key can only access one mailbox.
Use clientId for your own stable ID when creating tenants, mailboxes, and drafts. Repeating the same
request returns the resource that was already created instead of creating a duplicate.
const tenant = await mail.createTenant({ name: "Acme", clientId: "customer_acme" });
const inbox = await mail.createMailbox({
domainId: "dom_123",
tenantId: tenant.id,
clientId: "acme-support-v1",
localPart: "support",
displayName: "Acme Support",
visibility: "private",
metadata: { customerId: "customer_acme", agent: "support" },
});
Domains must still be verified before an address can be provisioned. Create a domain with createDomain,
publish its returned DNS records, then call verifyDomain until it reports verified; create as many
addresses as the verified domain needs.
Create the runtime key in Settings → Agent access after provisioning the mailbox. Select that
mailbox as the resource boundary and grant only mailboxes:read, mail:read, mail:send,
drafts:read, drafts:write, and drafts:send as needed. The secret is returned exactly once.
Store it in your server-side secret manager, never in agent instructions, source code, or browser code.
API keys cannot create more API keys. This prevents a leaked provisioning credential from expanding its own authority; key creation remains an authenticated administrator action in the web app.
Capabilities define the allowed operations inside the key's organization, tenant, or inbox boundary. Use one key per workload and grant only the operations it needs.
Create drafts for human review, set sendAt (milliseconds since Unix epoch) for a scheduled delivery, or
call sendDraft to queue it immediately. Scheduled drafts are claimed atomically by the Worker cron job,
so repeat cron execution cannot duplicate a send.
const draft = await mail.createDraft(inbox.id, {
to: ["customer@example.com"],
subject: "Re: Your request",
text: "Here is the update you requested.",
});
// A human can inspect or amend it, then approve the send:
await mail.sendDraft(inbox.id, draft.id);
Add mailbox policies to constrain automated communication. A block always wins; if an inbox has an allow list, addresses not on it are denied. Policies are evaluated for outbound sends and for inbound mail, including replies as a distinct direction.
await mail.createMailboxPolicy(inbox.id, {
direction: "send",
action: "allow",
entry: "customer.example",
});