API
Endpoint reference
Generated from the app’s Zod schemas — always in sync with the code.
Base URL: https://YOUR-INSTANCE/api/v1 · Machine-readable spec: /api/openapi.json on every instance.
Inboxes
/inboxes scope: readList inboxes
Query parameters
q string | |
tag string | |
agent string | |
include_expired boolean | |
limit integer | Default: 50 Max: 200 |
cursor string |
curl -X GET "https://app.squadmail.dev/api/v1/inboxes" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/inboxes scope: writeCreate an inbox
Omit `local_part` for a random readable address. Set `ttl_minutes` for a disposable inbox; `null` for a permanent one.
JSON body
local_part string | Local part before the @. Omit for a random, readable name like swift-otter-4821. |
domain string | Domain to use. Defaults to the first available domain. |
name string | Display name for the inbox. |
ttl_minutes integer | null | Minutes until the inbox expires and stops accepting mail. null = permanent (if allowed). |
agent_name string | Name of the agent using this inbox; shown in the dashboard. |
tags string[] | |
max_emails integer | null | |
overflow "drop_oldest" | "reject" | |
allow_senders string[] | Only accept mail from these addresses/domains. |
block_senders string[] | Reject mail from these addresses/domains. |
forward_to string (email) | null | Forward a copy of every incoming email to this address (counts as a sent email). |
curl -X POST "https://app.squadmail.dev/api/v1/inboxes" \
-H "Authorization: Bearer $SQUADMAIL_KEY" \
-H "content-type: application/json" -d '{}'/inboxes/{id} scope: readGet an inbox
`{id}` accepts the inbox id or its full address.
curl -X GET "https://app.squadmail.dev/api/v1/inboxes/$ID" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/inboxes/{id} scope: writeUpdate an inbox
Use `extend_minutes` to push the expiry out, `ttl_minutes: null` to make it permanent.
JSON body
name string | Display name for the inbox. |
ttl_minutes integer | null | Minutes until the inbox expires and stops accepting mail. null = permanent (if allowed). |
agent_name string | Name of the agent using this inbox; shown in the dashboard. |
tags string[] | |
max_emails integer | null | |
overflow "drop_oldest" | "reject" | |
allow_senders string[] | Only accept mail from these addresses/domains. |
block_senders string[] | Reject mail from these addresses/domains. |
forward_to string (email) | null | Forward a copy of every incoming email to this address (counts as a sent email). |
extend_minutes integer | Push expiry out by N minutes from now. Max: 525600 |
curl -X PATCH "https://app.squadmail.dev/api/v1/inboxes/$ID" \
-H "Authorization: Bearer $SQUADMAIL_KEY" \
-H "content-type: application/json" -d '{}'/inboxes/{id} scope: writeDelete an inbox and all its mail
curl -X DELETE "https://app.squadmail.dev/api/v1/inboxes/$ID" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
Emails
/inboxes/{id}/emails scope: readList emails of an inbox
Query parameters
q string | Search in sender, subject and preview text. |
label string | Only emails carrying this label key. |
unread boolean | |
since string (date-time) | Only emails received after this ISO timestamp. |
limit integer | Default: 25 Max: 100 |
cursor string |
curl -X GET "https://app.squadmail.dev/api/v1/inboxes/$ID/emails" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/inboxes/{id}/wait scope: readWait for the next email (long-poll)
Blocks up to `timeout` seconds (max 120) and returns the first matching email, or `204 No Content` on timeout. Mail that arrived shortly before the call (since `since`) is returned immediately.
Query parameters
timeout integer | Seconds to wait (max 120). Default: 30 Max: 120 |
from string | Sender must contain this string. |
subject string | Subject must match this case-insensitive regex. |
since string (date-time) | Consider emails received at/after this time. Defaults to "now" (only new mail). |
curl -X GET "https://app.squadmail.dev/api/v1/inboxes/$ID/wait" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/inboxes/{id}/stream scope: readServer-Sent Events stream
Events: `email.received`, `email.labeled`, `email.updated`, `email.deleted`, `mail.rejected`.
curl -X GET "https://app.squadmail.dev/api/v1/inboxes/$ID/stream" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/emails scope: readSearch emails across all inboxes
Query parameters
inbox string | Inbox id or address. Omit to search across all inboxes. |
q string | Search in sender, subject and preview text. |
label string | Only emails carrying this label key. |
unread boolean | |
since string (date-time) | Only emails received after this ISO timestamp. |
limit integer | Default: 25 Max: 100 |
cursor string |
curl -X GET "https://app.squadmail.dev/api/v1/emails" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/emails/{id} scope: readGet an email
Includes text/html bodies, headers, attachments, labels and `extracted` (codes & links). Add `?mark_read=true` to mark it read.
curl -X GET "https://app.squadmail.dev/api/v1/emails/$ID" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/emails/{id} scope: writeUpdate read/starred state or manual labels
JSON body
read boolean | |
starred boolean | |
labels string[] | Replace manual labels with these label keys. |
curl -X PATCH "https://app.squadmail.dev/api/v1/emails/$ID" \
-H "Authorization: Bearer $SQUADMAIL_KEY" \
-H "content-type: application/json" -d '{}'/emails/{id} scope: writeDelete an email
curl -X DELETE "https://app.squadmail.dev/api/v1/emails/$ID" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/emails/{id}/raw scope: readDownload the raw MIME message (.eml)
curl -X GET "https://app.squadmail.dev/api/v1/emails/$ID/raw" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/emails/{id}/attachments/{attachmentId} scope: readDownload an attachment
curl -X GET "https://app.squadmail.dev/api/v1/emails/$ID/attachments/$ATTACHMENTID" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
Outbox
/inboxes/{id}/send scope: sendSend an email from this inbox
Returns 200 with status `sent`, or 202 with status `pending` when the organization requires human approval. Poll `/outbox/{id}` (or pass `?wait=`) for the decision. Add a `reason` to help the approver.
JSON body
to required string (email)[] | |
cc string (email)[] | |
subject required string | |
text required string | |
html string | |
in_reply_to string | Email id this message replies to (sets threading headers). |
reason string | Why this email should be sent. Shown to the human approver when approvals are on. |
curl -X POST "https://app.squadmail.dev/api/v1/inboxes/$ID/send" \
-H "Authorization: Bearer $SQUADMAIL_KEY" \
-H "content-type: application/json" -d '{}'/outbox scope: readList outgoing emails
Filter with `?status=pending|sent|rejected|failed|expired`.
curl -X GET "https://app.squadmail.dev/api/v1/outbox" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/outbox/{id} scope: readGet the status of an outgoing email
Add `?wait=60` to block until a pending email is approved or rejected (max 120 s).
curl -X GET "https://app.squadmail.dev/api/v1/outbox/$ID" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/outbox/{id}/decision scope: adminApprove or reject a pending email
Owners and admins (dashboard session) only. Optionally edit `subject`/`text` before approving.
JSON body
decision required "approve" | "reject" | |
note string | |
subject string | |
text string |
curl -X POST "https://app.squadmail.dev/api/v1/outbox/$ID/decision" \
-H "Authorization: Bearer $SQUADMAIL_KEY" \
-H "content-type: application/json" -d '{}'Labels
/labels scope: readList labels
curl -X GET "https://app.squadmail.dev/api/v1/labels" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/labels scope: adminCreate a label
JSON body
key required string | |
name required string | |
color "violet" | "sky" | "emerald" | "amber" | "rose" | "fuchsia" | "lime" | "orange" | "slate" | "cyan" | Default: "violet" |
instructions string | Yes/no question Clef answers for each email, e.g. "Is this a job application?". Empty = rules only. Default: "" |
threshold number | Default: 0.7 Max: 0.99 |
rules object | Default: {} |
enabled boolean | Default: true |
curl -X POST "https://app.squadmail.dev/api/v1/labels" \
-H "Authorization: Bearer $SQUADMAIL_KEY" \
-H "content-type: application/json" -d '{}'/labels/{key} scope: adminUpdate a label
JSON body
name string | |
color "violet" | "sky" | "emerald" | "amber" | "rose" | "fuchsia" | "lime" | "orange" | "slate" | "cyan" | Default: "violet" |
instructions string | Yes/no question Clef answers for each email, e.g. "Is this a job application?". Empty = rules only. Default: "" |
threshold number | Default: 0.7 Max: 0.99 |
rules object | Default: {} |
enabled boolean | Default: true |
curl -X PATCH "https://app.squadmail.dev/api/v1/labels/$KEY" \
-H "Authorization: Bearer $SQUADMAIL_KEY" \
-H "content-type: application/json" -d '{}'/labels/{key} scope: adminDelete a label
curl -X DELETE "https://app.squadmail.dev/api/v1/labels/$KEY" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/labels/test scope: readDry-run labels against a sample
Runs rules and (if active) Clef without storing anything.
JSON body
from string | Default: "someone@example.com" |
subject string | Default: "" |
text string | Default: "" |
email_id string | Use a stored email instead of from/subject/text. |
curl -X POST "https://app.squadmail.dev/api/v1/labels/test" \
-H "Authorization: Bearer $SQUADMAIL_KEY" \
-H "content-type: application/json" -d '{}'Webhooks
/webhooks scope: readList webhook endpoints
curl -X GET "https://app.squadmail.dev/api/v1/webhooks" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/webhooks scope: adminCreate a webhook endpoint
The response contains the signing secret once.
JSON body
url required string (uri) | |
events "email.received" | "email.labeled" | "inbox.created" | "inbox.expired" | "outbound.pending" | "outbound.sent" | "outbound.rejected" | "outbound.failed"[] | Default: ["email.received"] |
inbox_ids string[] | |
label_keys string[] | |
enabled boolean |
curl -X POST "https://app.squadmail.dev/api/v1/webhooks" \
-H "Authorization: Bearer $SQUADMAIL_KEY" \
-H "content-type: application/json" -d '{}'/webhooks/{id} scope: adminUpdate a webhook endpoint
JSON body
url string (uri) | |
events "email.received" | "email.labeled" | "inbox.created" | "inbox.expired" | "outbound.pending" | "outbound.sent" | "outbound.rejected" | "outbound.failed"[] | Default: ["email.received"] |
inbox_ids string[] | |
label_keys string[] | |
enabled boolean |
curl -X PATCH "https://app.squadmail.dev/api/v1/webhooks/$ID" \
-H "Authorization: Bearer $SQUADMAIL_KEY" \
-H "content-type: application/json" -d '{}'/webhooks/{id} scope: adminDelete a webhook endpoint
curl -X DELETE "https://app.squadmail.dev/api/v1/webhooks/$ID" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/webhooks/{id}/deliveries scope: readRecent deliveries
curl -X GET "https://app.squadmail.dev/api/v1/webhooks/$ID/deliveries" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/webhooks/{id}/deliveries/{deliveryId}/replay scope: adminReplay a delivery
curl -X POST "https://app.squadmail.dev/api/v1/webhooks/$ID/deliveries/$DELIVERYID/replay" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/webhooks/{id}/test scope: adminSend a test event
curl -X POST "https://app.squadmail.dev/api/v1/webhooks/$ID/test" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
API keys
/keys scope: adminList API keys
curl -X GET "https://app.squadmail.dev/api/v1/keys" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/keys scope: adminCreate an API key
The plain key (`sqm_…`) is returned once.
JSON body
name required string | |
kind "agent" | "ci" | "personal" | Default: "agent" |
scopes "read" | "write" | "send" | "admin"[] | Default: ["read","write"] |
expires_in_days integer | null | |
require_approval boolean | Default: false |
curl -X POST "https://app.squadmail.dev/api/v1/keys" \
-H "Authorization: Bearer $SQUADMAIL_KEY" \
-H "content-type: application/json" -d '{}'/keys/{id} scope: adminTurn approvals on or off for an agent key
With `require_approval: true`, emails sent with this key wait for a human approval.
JSON body
require_approval required boolean |
curl -X PATCH "https://app.squadmail.dev/api/v1/keys/$ID" \
-H "Authorization: Bearer $SQUADMAIL_KEY" \
-H "content-type: application/json" -d '{}'/keys/{id} scope: adminRevoke an API key
curl -X DELETE "https://app.squadmail.dev/api/v1/keys/$ID" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
Organization
/domains scope: readDomains available for new inboxes
curl -X GET "https://app.squadmail.dev/api/v1/domains" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/stats scope: readUsage, activity and recent events
curl -X GET "https://app.squadmail.dev/api/v1/stats" \ -H "Authorization: Bearer $SQUADMAIL_KEY"
/me scope: readInspect the current credential and entitlements
curl -X GET "https://app.squadmail.dev/api/v1/me" \ -H "Authorization: Bearer $SQUADMAIL_KEY"