Skip to main content

Email Channel

An agent with the email channel turned on has an address, <slug>@<inbound domain>. It answers every email it receives in the same thread, and each thread is one conversation. The address is issued on the first save and never changes. Settings are stored on the agent’s channel row; there is no separate secret.
All API requests require a valid JWT token in the Authorization: Bearer <token> header. The API Gateway decodes the JWT and forwards auth context (user-id, organization-id, user-email, x-platform-role, x-org-role) as headers to downstream services.
Both endpoints need manage access to the agent: an org owner, admin or member, a viewer with a grant, or a platform superadmin. Another organization’s agent answers 404.

Get Email Settings

Response (200)

boolean
Whether the agent answers email now.
string | null
The address’s local part. null until the first save.
string | null
The full address. null without a slug, or when the platform has no inbound domain.
boolean
false until a platform admin sets RESEND_EMAIL_API_KEY, RESEND_EMAIL_WEBHOOK_SECRET and EMAIL_INBOUND_DOMAIN. The channel cannot be turned on before then.
string
The name on the From line. The agent’s name when none is set.
string
anyone or allowlist.
string[]
Lowercased addresses ([email protected]) and domains (@example.com). Used only in allowlist mode.

Update Email Settings

Only the fields you send change. allowedSenders, when sent, replaces the whole list. The first call creates the address, whether or not it turns the channel on. Every change is written to the organization’s audit log as email_channel.update.
boolean
Turn answering on or off. Turning on needs the platform keys (see platformConfigured).
string
Display name on replies. Up to 100 characters; no line breaks, quotes, <, > or \. An empty string means “use the agent’s name”.
string
anyone, or allowlist to accept email only from allowedSenders. Other senders get one short refusal per day.
string[]
Up to 500 entries, each a full address or @domain (exact domain — subdomains do not match). Trimmed, lowercased and de-duplicated.

Response (200)

The updated settings, in the same shape as Get Email Settings.

Errors

Inbound Webhook (Resend)

Public, no user authentication. Resend calls it for the email.received event; you do not call it yourself. The Svix signature (svix-id, svix-timestamp, svix-signature), checked against RESEND_EMAIL_WEBHOOK_SECRET on the exact bytes received, is the only gate. The webhook carries no body; the worker fetches the email from Resend, then answers it in the thread. Automatic emails (auto-replies, bounces, mailing lists, no-reply senders, other agents on the platform) are never answered.