OpenMail CLI & API Reference
Base URL:https://api.openmail.sh
Authentication: Authorization: Bearer
All responses are JSON.
CLI commands
Send email
--to(required) — recipient address--subject(required unless--thread-idis set) — email subject--body(required) — plain text or HTML (HTML is auto-detected and rendered)--thread-id— reply in an existing thread (quotes previous message by default)--no-quote— send only your reply text, skip quoted history--attach— file path to attach (repeatable)--inbox-id— override default inbox
Threads
Messages
Inboxes
Attachments
openclaw openmail -- to run it with the channel’s credentials.
REST API
All endpoints requireAuthorization: Bearer .
POST /v1/inboxes//send
Send an email.Idempotency-Key header (UUID) is optional; pass one to make retries safe.
body accepts plain text or HTML. HTML is auto-detected and rendered; a
plain-text fallback is generated automatically. The optional bodyHtml field
is for advanced API use only — when the plain-text and HTML versions must differ.
When threadId is set, the API appends a quoted copy of the previous message to
the body by default. Pass "includeQuote": false to send only your reply text.
replyTo is optional. When set, the email’s Reply-To header is populated
with that address so replies route there instead of to the sending inbox.
cc and bcc are optional arrays. bcc addresses receive the message but are
hidden from the To and Cc recipients — use it for CRM logging addresses. Every
to, cc, bcc, and replyTo address is checked against the inbox’s outbound
sender rules; one denied address rejects the whole send with 403 recipient_not_permitted.
- Free plan:
replyTomust match the address of an inbox you own in OpenMail. Create the destination inbox first, then reference it here. - Pro plan or higher:
replyTocan be any valid email address, including external addresses on domains you don’t control.
replyTo return 403 feature_requires_paid_plan with feature: "external_reply_to".
GET /v1/inboxes//threads
PATCH /v1/threads/
GET /v1/threads//messages
Returns messages in a thread, sorted oldest-first.GET /v1/inboxes//messages
GET /v1/attachments//
Returns attachment data. Signed URL included in message payload — fetch promptly, URLs expire.Rate limits
Idempotency
The send endpoint accepts an optionalIdempotency-Key header. Without it the API generates one and sends once. If your code retries on timeouts, pass a unique UUID per send attempt: retrying with the same key within 24 hours returns the original response without resending.
The CLI generates idempotency keys automatically. For direct API calls, generate a UUID: