Skip to main content
Email and SMS hang off an identity — the persona is decided by where a message arrived, not by who sent it. Deliverability comes from a verified domain.
An inbox and a phone number are identity-level; the domain behind an inbox is org-level. One identity may hold several endpoints, and everything that arrives at any of them lands in the same message feed.

Email inboxes

The inbox object

string
Unique id (e.g. eml_01H...).
string
Always email_inbox.
string
The persona that owns the address.
string
The domain it is hosted on.
string
The full address, e.g. ava-sales@mail.acme.dev.
string
The part before the @.
string
The agent mail to this address wakes, as this persona, billed to your credits. Each message that passes the guards starts one session. The agent must hold the persona. Fixed when the inbox is created.
boolean
Whether mail to this address wakes owning_agent_id. true for a new inbox. An inbox made before inbound mail woke agents is false until you turn it on with Update an inbox; its mail is still stored.
string
active or disabled.
string
Creation timestamp.

Create an inbox

POST /v1/identities/{id}/emails — scope agents:write Give either an explicit address or a domain_id — with domain_id the localpart is derived from the agent’s name (lowercased, hyphenated, capped at 32 characters, then suffixed -2, -3, … against what is taken).
string
required
The agent inbound mail is for (agt_…).
boolean
default:"true"
Whether mail wakes that agent. false stores mail without starting a session.
string
A full address to claim. The localpart must match [a-z0-9._-]{2,64}. Mutually exclusive with domain_id.
string
Host on this domain and auto-derive the localpart. Mutually exclusive with address.
Errors — validation_failed (400) for a malformed localpart, or for supplying both address and domain_id; not_found (404) for an unknown identity, domain, or agent; conflict (409) when the address is already claimed.

List inboxes

GET /v1/identities/{id}/emails — scope agents:read. Returns a paginated list of inbox objects; accepts limit.

Update an inbox

PATCH /v1/identities/{id}/emails/{eid} — scope agents:write. Turns the wake on or off: whether mail to the address starts a session for its agent. Audited as email.updated. Answers the inbox.
boolean
required
true to wake the agent on each message that passes the guards; false to store mail only.

Delete an inbox

DELETE /v1/identities/{id}/emails/{eid} — scope agents:write. Mail to the address stops being accepted.

Send email

POST /v1/identities/{id}/emails/{eid}/send — scope sessions:write Gated on the domain’s dns_status. A send attempted before SPF/DKIM are provisioned is refused with a retryable job_not_ready — verify the domain and try again.
string[]
required
Recipient addresses.
string
required
Subject line.
string
required
Plain-text body.
Answers 202 with a receipt, not a message object — the provider’s own message id is deliberately not surfaced. Once the provider accepts it, the message is kept as an outbound message.
Errors — job_not_ready (409, retryable) while the domain is unverified; validation_failed (400); insufficient_credits (402).

Phone numbers

The phone number object

string
Unique id (e.g. pho_01H...).
string
Always phone_number.
string
The persona that owns the number.
string
The number in E.164 form, e.g. +14155550123.
string
ISO country code.
object
sms_inbound is live the moment the number is bought. sms_outbound is true iff campaign_status is approved. voice is always false — voice is not supported, and the field exists so its absence is explicit.
string
sole_prop or standard — the carrier registration tier.
string
none, pending_verification, verified, or rejected.
string
none, pending, approved, or rejected. Gates outbound.
string | null
The agent inbound texts wake, as this persona, billed to your credits. null when none is set (bought without one, or its agent was deleted). The agent must hold the persona. Set or clear it with Update a number; texts that arrived with no agent set are never woken.
string | null
When the carrier released the number.
string
Creation timestamp.

Provision a number

POST /v1/identities/{id}/phones — scope billing:write A number is a recurring charge, which is why this needs billing:write and not agents:write.
string
required
sole_prop or standard.
The registering entity, as the carrier will see it.
string
ISO country code. Defaults to US.
string
standard tier only. Write-through: handed to the carrier and never stored.
string
sole_prop only — the handset that receives the verification passcode. Never stored.
string
Request a specific number instead of the next available one.
string
The agent inbound texts wake (agt_…). It must hold this persona. Checked before the purchase; if the agent is deleted mid-purchase, the number comes back with owning_agent_id: null.
Answers 202, not 201: the number exists and can receive immediately, but outbound waits on a carrier decision. Errors — validation_failed (400) when a tier-specific field is missing or supplied for the wrong tier, or owning_agent_id is not an agent id or names an agent that does not hold this persona; insufficient_credits (402); insufficient_scope (403) without billing:write; not_found (404) when owning_agent_id names no agent in this organization — nothing is bought.

List numbers

GET /v1/identities/{id}/phones — scope agents:read. Returns a paginated list; accepts limit.

Update a number

PATCH /v1/identities/{id}/phones/{pid} — scope agents:write. Returns the number. Recorded in the audit log as phone.updated.
string | null
required
The agent inbound texts to this number are for (agt_…), or null to clear it.
The body is strict: any other field is 400 validation_failed. Errors — validation_failed (400) for another field, or an owning_agent_id that is not an agent id or names an agent that does not hold this persona; not_found (404) when this identity holds no such number, or owning_agent_id names no agent in this organization.

Release a number

DELETE /v1/identities/{id}/phones/{pid} — scope billing:write. Stops the recurring charge. The number returns to the carrier and cannot be reclaimed.

Send SMS

POST /v1/identities/{id}/phones/{pid}/send — scope sessions:write
string
required
Recipient in E.164 form.
string
required
Message body.
Refused with compliance_pending until campaign_status is approved. That is a carrier rule, not a platform one — no scope or plan bypasses it, and inbound keeps working the whole time.

List inbound messages

GET /v1/identities/{id}/messages — scope agents:write. It holds strangers’ words and addresses, so a hosted app’s own read-only key can’t reach it. Everything that arrived for this persona, both channels unless one is named.
string
email or sms. Omit for both.
integer
Page size. See Pagination.
string
Unique id (e.g. inb_01H...).
string
email or sms.
string
The eml_/pho_ endpoint it arrived at.
string
Sender address or number.
string
The endpoint address or number.
string | null
Email subject; null for SMS.
string
Plain-text body.
object
SPF/DKIM/DMARC results for mail, carrier origin for SMS — kept for the audit of why the message was accepted.
string | null
The session this message woke, or null: a guard held it (guard_reason), the endpoint has no owning agent, or the agent couldn’t start (it doesn’t hold the persona, or the balance is too low). A wake that couldn’t start is retried for 15 minutes, so this can still fill in.
string | null
The wake guard that held the message, or null. A held message is stored and never wakes an agent.
string
Arrival timestamp.
string | null
When it was marked read; null while unread.
Inbound arrives at the platform’s own receivers — see Inbound receivers for how a message becomes a message object.

Mark a message read

POST /v1/identities/{id}/messages/{mid}/read — scope agents:write
boolean
required
true to mark it read, false to put it back to unread.
Returns the message. Marking a read message read again keeps the time it was first read.
Errors — validation_failed (400) when read is missing or not a boolean; not_found (404) when this identity holds no such message.

List sent messages

GET /v1/identities/{id}/sent — scope agents:write Everything the persona sent, newest first: through Send email and through its agent’s own email.send tool alike. Returns a paginated list; accepts limit.
string
Unique id (e.g. out_01H...).
string
Always outbound_message.
string
email. Texts are not kept yet.
string
The eml_ inbox it was sent from.
string
The sending address.
string[]
Recipient addresses.
string | null
Subject line.
string
Plain-text body.
string | null
The agent that sent it with its tool; null for a send through the API.
object | null
The key or person that sent it through the API; null when an agent sent it.
string
When the provider accepted it.

Identities

The persona these endpoints hang off.