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

get /inboxes scope: read

List 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"
post /inboxes scope: write

Create 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 '{}'
get /inboxes/{id} scope: read

Get 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"
patch /inboxes/{id} scope: write

Update 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 '{}'
delete /inboxes/{id} scope: write

Delete an inbox and all its mail

curl -X DELETE "https://app.squadmail.dev/api/v1/inboxes/$ID" \
  -H "Authorization: Bearer $SQUADMAIL_KEY"

Emails

get /inboxes/{id}/emails scope: read

List 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"
get /inboxes/{id}/wait scope: read

Wait 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"
get /inboxes/{id}/stream scope: read

Server-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"
get /emails scope: read

Search 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"
get /emails/{id} scope: read

Get 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"
patch /emails/{id} scope: write

Update 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 '{}'
delete /emails/{id} scope: write

Delete an email

curl -X DELETE "https://app.squadmail.dev/api/v1/emails/$ID" \
  -H "Authorization: Bearer $SQUADMAIL_KEY"
get /emails/{id}/raw scope: read

Download the raw MIME message (.eml)

curl -X GET "https://app.squadmail.dev/api/v1/emails/$ID/raw" \
  -H "Authorization: Bearer $SQUADMAIL_KEY"
get /emails/{id}/attachments/{attachmentId} scope: read

Download an attachment

curl -X GET "https://app.squadmail.dev/api/v1/emails/$ID/attachments/$ATTACHMENTID" \
  -H "Authorization: Bearer $SQUADMAIL_KEY"

Outbox

post /inboxes/{id}/send scope: send

Send 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 '{}'
get /outbox scope: read

List 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"
get /outbox/{id} scope: read

Get 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"
post /outbox/{id}/decision scope: admin

Approve 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

get /labels scope: read

List labels

curl -X GET "https://app.squadmail.dev/api/v1/labels" \
  -H "Authorization: Bearer $SQUADMAIL_KEY"
post /labels scope: admin

Create 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 '{}'
patch /labels/{key} scope: admin

Update 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 '{}'
delete /labels/{key} scope: admin

Delete a label

curl -X DELETE "https://app.squadmail.dev/api/v1/labels/$KEY" \
  -H "Authorization: Bearer $SQUADMAIL_KEY"
post /labels/test scope: read

Dry-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

get /webhooks scope: read

List webhook endpoints

curl -X GET "https://app.squadmail.dev/api/v1/webhooks" \
  -H "Authorization: Bearer $SQUADMAIL_KEY"
post /webhooks scope: admin

Create 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 '{}'
patch /webhooks/{id} scope: admin

Update 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 '{}'
delete /webhooks/{id} scope: admin

Delete a webhook endpoint

curl -X DELETE "https://app.squadmail.dev/api/v1/webhooks/$ID" \
  -H "Authorization: Bearer $SQUADMAIL_KEY"
get /webhooks/{id}/deliveries scope: read

Recent deliveries

curl -X GET "https://app.squadmail.dev/api/v1/webhooks/$ID/deliveries" \
  -H "Authorization: Bearer $SQUADMAIL_KEY"
post /webhooks/{id}/deliveries/{deliveryId}/replay scope: admin

Replay a delivery

curl -X POST "https://app.squadmail.dev/api/v1/webhooks/$ID/deliveries/$DELIVERYID/replay" \
  -H "Authorization: Bearer $SQUADMAIL_KEY"
post /webhooks/{id}/test scope: admin

Send a test event

curl -X POST "https://app.squadmail.dev/api/v1/webhooks/$ID/test" \
  -H "Authorization: Bearer $SQUADMAIL_KEY"

API keys

get /keys scope: admin

List API keys

curl -X GET "https://app.squadmail.dev/api/v1/keys" \
  -H "Authorization: Bearer $SQUADMAIL_KEY"
post /keys scope: admin

Create 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 '{}'
patch /keys/{id} scope: admin

Turn 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 '{}'
delete /keys/{id} scope: admin

Revoke an API key

curl -X DELETE "https://app.squadmail.dev/api/v1/keys/$ID" \
  -H "Authorization: Bearer $SQUADMAIL_KEY"

Organization

get /domains scope: read

Domains available for new inboxes

curl -X GET "https://app.squadmail.dev/api/v1/domains" \
  -H "Authorization: Bearer $SQUADMAIL_KEY"
get /stats scope: read

Usage, activity and recent events

curl -X GET "https://app.squadmail.dev/api/v1/stats" \
  -H "Authorization: Bearer $SQUADMAIL_KEY"
get /me scope: read

Inspect the current credential and entitlements

curl -X GET "https://app.squadmail.dev/api/v1/me" \
  -H "Authorization: Bearer $SQUADMAIL_KEY"
Edit this page on GitHub