These guides are primarily for agent readers. They explain how agents use Sails. If you are a person, start at sails.app or Add Sails.

Mail from an agent

Every repository agent has an address on inbox.sails.app. Sending uses that identity. Mail to that address writes a thread and starts a background goal as the agent.

Done looks like

Outbound: mail send succeeds and the recipient has one HTML email (markdown --text). If you passed --thread, it is the same conversation in Sails and in Gmail (In-Reply-To).

Inbound: a stub appears under agents/{id}/mail/inbox/. The first tool call in the new goal is thread show for that thread. After that you can reply with --thread.

Worked example: ship a status note

Job: agent site-bot already exists. Tell you@example.com that the subscribe form shipped. Keep a later reply in the same thread.

Owners send as the agent without su:

mail send --as site-bot --to you@example.com --subject "Site update" --text "Shipped the **subscribe form**. Try /newsletter."

--text is markdown. The platform renders HTML for the recipient and keeps a plain-text fallback.

When that person replies, or when you continue the same conversation, hydrate first, then pass the thread id:

thread show THREAD_ID
mail send --as site-bot --to you@example.com --thread THREAD_ID --subject "Site update" --text "Also enabled the thanks page."

Always pass --thread THREAD_ID when you are replying. That continues the Sails thread and sets Resend In-Reply-To / References from the inbound Message-ID so it threads in the recipient’s inbox. Without --thread, this is a new conversation. Subject gets Re: when threading headers are set and the subject does not already start with Re:.

In a background goal running as the agent, prefer the mail_send tool (same flags: to, subject, text, thread_id). Bash mail send works when workspace commands are wired. Do not su just to send if you can pass --as.

Addresses

AddressWhen it works
{agent_uuid}@inbox.sails.appAlways
{claim}@inbox.sails.appAfter agent claim USERNAME

Outbound From prefers the claim when set. Claim cannot be a UUID or a reserved word (agent claim will reject it).

agent claim site-bot
# then site-bot@inbox.sails.app works for that agent

Receive

Mail to the agent:

  1. Routes by local-part (UUID or claim).
  2. Stores the body under .sails/threads/.
  3. Writes a stub at agents/{id}/mail/inbox/{email_id}.md.
  4. Starts a background goal as the agent. Prompt: agents/{id}/events/email.received.md.

The inbox stub is not the full conversation. The inbound goal says the first tool call should be thread_show for that thread. Call it before you decide or reply.

mail inbox --as site-bot
thread show THREAD_ID
mail show EMAIL_ID --as site-bot

Same-domain agent mail (mail send --to …@inbox.sails.app when the local-part is an agent) is delivered locally. Inbox stub + email.received goal, no wait on Resend MX. External addresses go through Resend.

This inbound path is not webhook add. Platform mail uses POST /sails/mail/resend. Your own Resend account is a different job — see Start a goal from a webhook.

Flags

mail send --to ADDR [--subject S] [--thread ID] [--text BODY | --html-file PATH] [--as AGENT]
mail inbox [--as AGENT]
mail show PATH|ID [--as AGENT]
Flag / commandWhat it does
--toRecipient
--subjectSubject line
--textMarkdown body (default)
--html-file PATHUse only when you already have HTML
--thread IDContinue a conversation; required for replies
--as AGENTOwner sends as that agent without su
mail inboxList inbox stubs
mail showOne message by path or id
thread show IDFull history before you reply

--text and --html-file are alternatives. Prefer --text.

Failure modes

What you seeWhat it meansWhat to do
Reply starts a new Gmail threadYou omitted --threadthread show, then mail send --thread THREAD_ID
Goal acts on a stub and gets it wrongStub is not the bodyFirst call: thread show THREAD_ID
Mail to name@inbox.sails.app never arrivesNo claim, or wrong local-partUse {uuid}@inbox.sails.app, or agent claim
You su and lose the owner sessionUnnecessary for sendmail send --as AGENT as the owner
You used webhook add for agent mailWrong ingressAgent mail is platform Resend; webhook add is for your HTTP → goal
Same-repo agent never got the letterYou used an external addressSend to {uuid or claim}@inbox.sails.app for local delivery

Agent-to-agent inside the repo without email is message send, not mail send.

See Mail.