Messages

Send email from your mailboxes, list messages, reply to conversations, and retrieve individual messages by ID.

The message object

{ "object": "message", "id": "msg_abc123", "mailbox_id": "mbx_abc123", "thread_id": "thr_abc123", "subject": "Hello from shipmail", "from_address": "hello@example.com", "to_addresses": [{"address": "user@example.com"}], "cc_addresses": null, "bcc_addresses": null, "attachments": null, "source": "api", "status": "queued", "created_at": "2025-01-15T12:00:00.000Z", "updated_at": "2025-01-15T12:00:00.000Z" }
FieldTypeDescription
idstringUnique identifier, prefixed with msg_.
mailbox_idstringID of the mailbox this message belongs to.
thread_idstring | nullThread ID. Null for standalone messages.
subjectstring | nullEmail subject line.
from_addressstring | nullSender email address.
to_addressesrecipient[] | nullTo recipients. Each item: { address, name? }.
cc_addressesrecipient[] | nullCC recipients.
bcc_addressesrecipient[] | nullBCC recipients.
attachmentsarray | nullAttachment metadata. Each item: { filename, size, content_type }. Null if none.
sourcestringHow the message originated. See sources below.
statusstringDelivery status. See statuses below.
created_atstringISO 8601 timestamp.
updated_atstringISO 8601 timestamp.

Message statuses

StatusDescription
queuedAccepted for delivery
sentDelivered to recipient's mail server
deliveredConfirmed delivery
bouncedDelivery failed permanently
complainedRecipient marked as spam
failedInternal delivery failure

Message sources

SourceDescription
apiSent via the API
dashboardSent from the dashboard
inboundReceived from an external sender
smtpSent via SMTP/IMAP client

Send a message

POST /v1/messages

Scope: messages:write. Rate limit tier: send (100 / min).

Request body

FieldTypeRequiredDescription
mailbox_idstring**ID of the sending mailbox. Required if from is not set.
fromstring**Email address of the sending mailbox. Resolved to a mailbox ID server-side. Required if mailbox_id is not set.
torecipient[]YesAt least one recipient.
ccrecipient[]NoCC recipients.
bccrecipient[]NoBCC recipients.
reply_torecipientNoReply-to address.
subjectstringYesEmail subject. Max 998 characters.
htmlstring*HTML body. Max 512 KB.
textstring*Plain text body. Max 256 KB.
in_reply_tostringNoMessage-ID to reply to.
referencesstring[]NoMessage-ID references for threading.
attachmentsarrayNoBase64-encoded file attachments. Each item: { filename, content, content_type? }. Max 20 attachments, 3 MB per file, 3 MB total.

* At least one of html or text is required. Total recipients (to + cc + bcc) must not exceed 50.

** One of mailbox_id or from is required.

Recipient format

Recipients can be an object or a string:

// Object format {"address": "user@example.com", "name": "Jane Doe"} // String formats "user@example.com" "Jane Doe <user@example.com>"

Example

curl -X POST https://shipmail.to/api/v1/messages \ -H "Authorization: Bearer sm_live_..." \ -H "Content-Type: application/json" \ -d '{ "from": "hello@example.com", "to": ["user@example.com"], "subject": "Hello from shipmail", "text": "This is a test email." }'

Returns the message object with status 201.

Example with attachment

curl -X POST https://shipmail.to/api/v1/messages \ -H "Authorization: Bearer sm_live_..." \ -H "Content-Type: application/json" \ -d '{ "from": "billing@yourcompany.com", "to": [{ "address": "client@example.com" }], "subject": "Invoice #1234", "html": "<p>Please find your invoice attached.</p>", "attachments": [ { "filename": "invoice-1234.pdf", "content": "JVBERi0xLjQK...", "content_type": "application/pdf" } ] }'

List messages

GET /v1/messages?mailbox_id=mbx_abc123

Scope: messages:read. Rate limit tier: read.

The mailbox_id query parameter is required. Supports cursor and limit pagination parameters. Returns a flat list of messages (not grouped by thread).

Retrieve a message

GET /v1/messages/:id

Scope: messages:read. Returns the message object or 404.

Reply to a message

POST /v1/messages/:id/reply

Scope: messages:write. Rate limit tier: send. Looks up the message's thread and sends a reply using the same mailbox.

Uses the same request body as POST /v1/threads/:id/reply. Returns the message object with status 201.