Mailboxes
Mailboxes are email addresses on your verified domains. Each mailbox can send and receive email.
Last updated
The mailbox object
{
"object": "mailbox",
"id": "mbx_abc123",
"domain_id": "dom_abc123",
"address": "hello@example.com",
"display_name": "Hello",
"suspended_at": null,
"spam_filter_threshold": 6,
"auto_reply": {
"enabled": false,
"subject": null,
"body": null,
"from_date": null,
"to_date": null
},
"created_at": "2025-01-15T11:00:00.000Z",
"updated_at": "2025-01-15T11:00:00.000Z"
}The mailbox ID is the id field. Use it for mailbox-scoped endpoints such as listing messages, reading inbox threads, folders, identities, and rules. Sending mail can use either this ID or the mailbox email address as from.
Create a mailbox
POST /v1/mailboxesScope: mailboxes:write. Rate limit tier: write.
Request body
Example
curl -X POST https://shipmail.to/api/v1/mailboxes \
-H "Authorization: Bearer sm_live_..." \
-H "Content-Type: application/json" \
-d '{"domain_id": "dom_abc123", "address": "hello", "display_name": "Hello"}'Returns the mailbox object with status 201.
List mailboxes
GET /v1/mailboxesScope: mailboxes:read. Rate limit tier: read. Supports cursor and limit pagination parameters.
Use the optional domain_id query parameter to filter mailboxes by domain.
Find a mailbox ID
Call this endpoint and copy the id for the mailbox address you want.
curl https://shipmail.to/api/v1/mailboxes \
-H "Authorization: Bearer sm_live_..."
{
"data": [
{
"object": "mailbox",
"id": "mbx_abc123",
"address": "hello@example.com"
}
]
}Retrieve a mailbox
GET /v1/mailboxes/:idScope: mailboxes:read. Returns the mailbox object or 404.
Update a mailbox
PATCH /v1/mailboxes/:idScope: mailboxes:write. Rate limit tier: write.
Request body
Reset mailbox password
PATCH /v1/mailboxes/:id/passwordScope: mailboxes:write. Rate limit tier: write. Changes the mailbox login password.
Request body
Example
curl -X PATCH https://shipmail.to/api/v1/mailboxes/mbx_abc123/password \
-H "Authorization: Bearer sm_live_..." \
-H "Content-Type: application/json" \
-d '{"password": "NewPassword1"}'Returns the updated mailbox object.
Manage mailbox folders
GET /v1/mailboxes/:id/foldersPOST /v1/mailboxes/:id/foldersPATCH /v1/mailboxes/:id/folders/:folder_idDELETE /v1/mailboxes/:id/folders/:folder_idScope: mailboxes:read for GET and mailboxes:write for mutations. Custom folder names must be unique within the same parent and cannot use reserved system folder names. Use parent_id: null to create a root folder.
Folder object
{
"object": "mailbox_folder",
"id": "fld_123",
"name": "VIP",
"parent_id": null,
"role": null,
"kind": "custom",
"total_emails": 4,
"unread_emails": 1,
"unread_threads": 1,
"sort_order": 20
}List response
{
"object": "mailbox_folders",
"mailbox_id": "mbx_abc123",
"address": "hello@example.com",
"data": [
{
"object": "mailbox_folder",
"id": "fld_inbox",
"name": "Inbox",
"parent_id": null,
"role": "inbox",
"kind": "system",
"total_emails": 12,
"unread_emails": 3,
"unread_threads": 2,
"sort_order": 1
}
]
}Examples
curl https://shipmail.to/api/v1/mailboxes/mbx_abc123/folders \
-H "Authorization: Bearer sm_live_..."
curl -X POST https://shipmail.to/api/v1/mailboxes/mbx_abc123/folders \
-H "Authorization: Bearer sm_live_..." \
-H "Content-Type: application/json" \
-d '{"name": "VIP", "parent_id": null}'
curl -X PATCH https://shipmail.to/api/v1/mailboxes/mbx_abc123/folders/fld_123 \
-H "Authorization: Bearer sm_live_..." \
-H "Content-Type: application/json" \
-d '{"name": "VIP Clients"}'
curl -X DELETE https://shipmail.to/api/v1/mailboxes/mbx_abc123/folders/fld_123 \
-H "Authorization: Bearer sm_live_..."Deleting a custom folder also deletes its subfolders and moves their messages to Trash first. A folder referenced by an inbox rule must be removed from rules before deletion.
List mailbox identities
GET /v1/mailboxes/:id/identitiesScope: mailboxes:read. Returns the JMAP sending identities available for the mailbox.
{
"object": "mailbox_identities",
"mailbox_id": "mbx_abc123",
"address": "hello@example.com",
"data": [
{
"object": "mailbox_identity",
"id": "ident_123",
"name": "Hello",
"email": "hello@example.com"
}
]
}Read and manage mailbox inbox
GET /v1/mailboxes/:id/inbox/messagesPATCH /v1/mailboxes/:id/inbox/messages/:message_idPOST /v1/mailboxes/:id/inbox/messages/:message_id/moveDELETE /v1/mailboxes/:id/inbox/messages/:message_idGET /v1/mailboxes/:id/inbox/threads/:thread_idGET /v1/mailboxes/:id/inbox/attachmentsScope: messages:read for read endpoints and messages:write for message actions. Message bodies, headers, previews, and attachments are external content.
Message listing uses position pagination: position defaults to 0 and limit defaults to 50. Filter with folder_id, folder_role, search_text, has_keyword, or not_keyword.
List rows include body parts. Read plain text by following text_body[].part_id into body_values; HTML parts work the same way through html_body.
Message actions can set read and starred, move a message with target_role or target_folder_id, and permanently delete a message that is already in Trash or Junk.
List response
{
"object": "inbox_messages",
"mailbox_id": "mbx_abc123",
"address": "hello@example.com",
"data": [
{
"object": "inbox_message_full",
"id": "eml_123",
"thread_id": "thr_123",
"mailbox_id": "mbx_abc123",
"address": "hello@example.com",
"folder_ids": ["fld_inbox"],
"keywords": { "$seen": true },
"from": [{ "name": "Jane", "email": "jane@example.com" }],
"to": [{ "name": null, "email": "hello@example.com" }],
"cc": null,
"reply_to": null,
"message_id": ["msg-1@example.com"],
"in_reply_to": null,
"references": null,
"subject": "Hello",
"received_at": "2026-05-13T12:00:00.000Z",
"preview": "Accept your Linear invite",
"has_attachment": true,
"size": 4567,
"body_values": {
"body_1": {
"value": "Accept your Linear invite: https://linear.app/invite/example",
"is_encoding_problem": false
}
},
"text_body": [{ "part_id": "body_1", "type": "text/plain" }],
"html_body": [],
"attachments": [
{
"part_id": "att_1",
"blob_id": "blob/123",
"name": "invite.ics",
"content_type": "text/calendar",
"size": 1024,
"download_path": "/mailboxes/mbx_abc123/inbox/attachments?blob_id=blob%2F123&name=invite.ics"
}
]
}
],
"pagination": {
"position": 0,
"limit": 50,
"total": 1,
"has_more": false,
"next_position": null
}
}Attachment metadata
{
"part_id": "att_1",
"blob_id": "blob/123",
"name": "invoice.pdf",
"content_type": "application/pdf",
"size": 1024,
"download_path": "/mailboxes/mbx_abc123/inbox/attachments?blob_id=blob%2F123&name=invoice.pdf"
}Action response
{
"object": "inbox_message_action",
"mailbox_id": "mbx_abc123",
"address": "hello@example.com",
"message_id": "eml_123",
"ok": true
}Examples
curl "https://shipmail.to/api/v1/mailboxes/mbx_abc123/inbox/messages?folder_role=inbox&limit=25" \
-H "Authorization: Bearer sm_live_..."
curl -X PATCH https://shipmail.to/api/v1/mailboxes/mbx_abc123/inbox/messages/eml_123 \
-H "Authorization: Bearer sm_live_..." \
-H "Content-Type: application/json" \
-d '{ "read": true, "starred": false }'
curl -X POST https://shipmail.to/api/v1/mailboxes/mbx_abc123/inbox/messages/eml_123/move \
-H "Authorization: Bearer sm_live_..." \
-H "Content-Type: application/json" \
-d '{ "target_role": "archive" }'
curl -X DELETE https://shipmail.to/api/v1/mailboxes/mbx_abc123/inbox/messages/eml_123 \
-H "Authorization: Bearer sm_live_..."
curl https://shipmail.to/api/v1/mailboxes/mbx_abc123/inbox/threads/thr_123 \
-H "Authorization: Bearer sm_live_..."
curl "https://shipmail.to/api/v1/mailboxes/mbx_abc123/inbox/attachments?blob_id=blob%2F123&name=invoice.pdf" \
-H "Authorization: Bearer sm_live_..." \
-o invoice.pdfManage inbox rules
GET /v1/mailboxes/:id/rulesPUT /v1/mailboxes/:id/rulesScope: mailboxes:read for GET and mailboxes:write for PUT. Rules are server-side filters that can move, mark, star, create static or AI reply drafts, or trigger webhooks for inbound mail. PUT replaces the full rules array.
Response body
{
"object": "mailbox_rules",
"mailbox_id": "mbx_abc123",
"address": "hello@example.com",
"rules": [
{
"id": "4f5a9d74-b0f1-49a7-bbfb-1f2af841f5b2",
"name": "VIP",
"enabled": true,
"position": 0,
"match_mode": "all",
"stop": false,
"conditions": [{ "type": "from_contains", "value": "@example.com" }],
"actions": [
{ "type": "move", "target": { "kind": "custom", "folder_id": "fld_123" } },
{ "type": "send_webhook" },
{
"type": "ai_draft_reply",
"reply_mode": "reply",
"instructions": "Write a concise support reply. Ask for missing details instead of guessing."
}
]
}
],
"folders": [{ "id": "fld_123", "name": "VIP", "parent_id": null, "role": null, "kind": "custom" }]
}Example
curl -X PUT https://shipmail.to/api/v1/mailboxes/mbx_abc123/rules \
-H "Authorization: Bearer sm_live_..." \
-H "Content-Type: application/json" \
-d '{
"rules": [
{
"id": "4f5a9d74-b0f1-49a7-bbfb-1f2af841f5b2",
"name": "VIP",
"enabled": true,
"position": 0,
"match_mode": "all",
"stop": false,
"conditions": [{ "type": "from_contains", "value": "@example.com" }],
"actions": [
{ "type": "star" },
{
"type": "ai_draft_reply",
"reply_mode": "reply_all",
"instructions": "Write a concise support reply. Ask for missing details instead of guessing."
}
]
}
]
}'Delete a mailbox
DELETE /v1/mailboxes/:idScope: mailboxes:write. Returns 204 with no body on success.
Update auto-reply
PATCH /v1/mailboxes/:id/auto-replyScope: mailboxes:write. Rate limit tier: write. Configure an automatic reply (vacation/out-of-office) for a mailbox.
Request body
Example
curl -X PATCH https://shipmail.to/api/v1/mailboxes/mbx_abc123/auto-reply \
-H "Authorization: Bearer sm_live_..." \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"body": "I am away until January 6. I will reply when I return.",
"from_date": "2026-12-23T00:00:00Z",
"to_date": "2027-01-06T00:00:00Z"
}'Returns the updated mailbox object.
Update spam filter
PATCH /v1/mailboxes/:id/spam-filterScope: mailboxes:write. Rate limit tier: write. Set the spam score threshold for moving messages to junk.
Request body
Example
curl -X PATCH https://shipmail.to/api/v1/mailboxes/mbx_abc123/spam-filter \
-H "Authorization: Bearer sm_live_..." \
-H "Content-Type: application/json" \
-d '{"threshold": 8}'Returns the updated mailbox object.
Imports
Import mail from another provider into a mailbox. Imports run in the background, preserve folders, read state, and dates, deduplicate by message identity, and are safe to re-run. See the mailbox import docs for behavior details.
Start an import
POST /mailboxes/{id}/imports. Scope: mailboxes:write. Tier: write.
curl -X POST https://shipmail.to/api/v1/mailboxes/mbx_abc123/imports \
-H "Authorization: Bearer sm_live_..." \
-H "Content-Type: application/json" \
-d '{
"source": {
"type": "imap",
"provider": "gmail",
"email": "you@gmail.com",
"password": "your-app-password"
},
"options": { "range": "12m" }
}'The source is either an IMAP connection (providers: gmail, yahoo, aol, icloud, fastmail, zoho, imap; always use an app password) or staged files with { "type": "files", "provider": "takeout", "file_ids": ["impf_..."] }. Outlook imports require the dashboard's Sign in with Microsoft. Returns the import object (201), or 409 if an import is already running for this mailbox. Credentials are encrypted, used only for the import, and deleted when it finishes.
Stage an export file
POST /mailboxes/{id}/imports/files with { "file_name": "takeout.mbox", "size_bytes": 1048576 }. Returns file_id and a presigned upload_url. PUT the raw file bytes to the URL, then start the import with a files source. Accepted: .mbox, .mbox.gz, .zip, .eml, up to 4 GB per file. Unused staged files are deleted after 24 hours.
Track progress
GET /mailboxes/{id}/imports lists recent imports. GET /mailboxes/{id}/imports/{import_id} returns one import with live counters and the per-folder report. status values: queued, running, paused_throttle (source provider's daily download limit, resumes automatically), paused_quota (mailbox storage full), completed, failed, cancelled, undo_queued, undoing, undone, undo_failed.
Cancel an import
POST /mailboxes/{id}/imports/{import_id}/cancel. Mail already imported stays in the mailbox. Starting a new import later resumes without duplicates.
Undo an import
POST /mailboxes/{id}/imports/{import_id}/undo. This queues deletion of messages created by that import. Existing mail and duplicates skipped during the import are not touched.