Mail

Give an agent its own email address — disposable inboxes for sign-ups and verification codes, persistent ones that send, reply, and forward, with a person approving first messages to new recipients.

Agent mail is rolling out and is not yet available to every organization. When it is on for yours, the mail__* tools appear in tools/list; until then they are absent. If it is ever paused for your organization, the tools disappear and your persistent inboxes stop being charged; they keep their addresses and keep receiving mail until it is back on.

Mail is a CoreSpeed-hosted capability: your agent gets real email addresses of its own, with nothing to sign up for and no mailbox credentials to hold. There are two kinds of inbox:

  • Disposable — lives up to 7 days (ttl_hours ≤ 168), receive-only, and deletes itself when it expires. For sign-ups, verification codes and one-off replies.
  • Persistent — lives until you delete it (or for up to a year with ttl_hours), and can also send, reply, and forward.

An agent's inboxes are its own; pass shared: true to make one visible to every agent and member of the organization. A member sees all of the organization's inboxes.

Tool names follow mail__<action>. The wire names and exact parameters come from tools/list; the tables below are the map.

Tools

Inboxes

ToolDoes
mail__create_inboxCreate an inbox and return its address. ttl_hours picks disposable or persistent; allow_senders limits who can write to it (inbound only).
mail__list_inboxesThe inboxes you can use.
mail__get_inboxOne inbox: address, kind, whether it can send, expiry.
mail__update_inboxRename it or replace its sender allowlist.
mail__delete_inboxDelete it. Irreversible — the address is never issued again.

Reading

ToolReturns
mail__list_messagesMessages in one inbox, newest first, with filters (text, sender, subject, unread, label, time). Each summary carries any verification codes found.
mail__search_messagesFull-text search across every inbox you can see.
mail__read_messageOne message in full: cleaned text, extracted codes, links classified as verify / login / reset / unsubscribe, and attachments.
mail__get_threadA whole conversation.
mail__wait_for_messageWaits up to 50 seconds for a matching message and returns it — the way to catch a code right after signing up.
mail__get_attachmentStores an attachment as a private file in your Drive under tmp/mail/ (7 days; drive__move keeps it) that feeds Media understanding, connector uploads, and mail__send.
mail__update_messageMark read or unread; add or remove labels.
mail__list_labelsAn inbox's labels with counts.

Sending

ToolDoes
mail__check_recipientsWithout sending, tells you how each address would be treated and whether a send would need approval.
mail__sendA new message to up to 10 recipients, with optional attachments.
mail__replyA reply in the thread — to the sender, or everyone with reply_all.
mail__forwardForward a message, with its attachments by default.

Attachments are passed as a Drive path or file id — an attachment you stored, a Media output, an upload — or a public https URL — up to 10 files per message. The whole message, attachments included, must fit in 5 MiB once encoded for sending. Disposable inboxes cannot send.

Catching a verification code

mail__create_inbox { "ttl_hours": 1 }                       → inbox address
  … the agent signs up with that address …
mail__wait_for_message { "inbox_id": "inb_…", "from": "@example.com" }
                                                            → message with codes[]

Without since, a matching unread message that already arrived is returned at once, so the order of sign-up and wait does not matter. The returned message is marked read; calling again waits for the next one. A wait that times out returns message: null — call it again to keep waiting.

First messages to new people need a person

A send to someone new outside your organization — not a member, not on your organization's allowlist, and not already written to from this inbox — waits for a person's approval, whatever your approval policy says. That includes the first reply to someone who wrote in and every forward to a new address: receiving mail from an address never makes it trusted, because a "From" can be forged. The call returns Approval required with an approval_id; the agent calls manage__approval_wait with it at once, and the message is sent the moment it is approved. The card goes to the agent's owner like every Smart Approvals card. If Smart Approvals is not available to your organization, such a send is refused with approval_required and nothing is sent. Mail to your organization's own members, to addresses on the organization allowlist (set by an admin), and to addresses this inbox has already written to needs no approval. An inbox's allow_senders only filters what it receives; it never lets a send skip approval.

Sending limits also protect every inbox's reputation: at most 10 recipients per message, an hourly cap per inbox, daily caps that grow with the inbox's age and with the time since your organization first sent, and an automatic pause if too many messages bounce or are marked as spam.

Mail content is untrusted

Everything in a message — subject, body, sender name, links, even the codes — was written by whoever sent it. Every result carrying mail opens with a notice that says so and is marked untrusted_content: true (and _meta["io.corespeed/untrusted-content"]), so agents treat it as data and never as instructions, and says that sender names and addresses are not verified. When a message explicitly failed an email authentication check (SPF, DKIM, DMARC) the result says so too, because a forged "From" is how phishing aimed at agents begins.

Pricing and holds

WhatCharge
Disposable inbox5 credits, once, when created
Persistent inbox300 credits per 30 days while it exists, the first period when created
Sending1 credit per recipient (to + cc + bcc)
Receiving, reading, searching, waitingFree

Pass idempotency_key on mail__create_inbox and the send tools when you might retry: a repeat returns the first result and is not charged again. A failed or refused call never charges. Charges land in the organization ledger as mail/inbox-disposable, mail/inbox-persistent and mail/send; see Billing & credits. A persistent inbox keeps being charged each period until it is deleted — deleting it stops the charge, and the current period is not refunded. An organization billing hold stops mail calls before they run, as it does every metered tool, while its inboxes keep receiving. mail__delete_inbox still runs during a hold, so you can always stop a recurring charge.

Controls

Mail appears as Agent mail in Dashboard → Tools. Turning it off hides every mail__* tool from tools/list for that member; see Capability controls.