46 endpoints
REST API
A unified REST API that normalizes every email provider into a single consistent interface. Send, read, search, and manage email across Gmail, Outlook, and any IMAP provider.
9
Accounts
16
Messages
6
Drafts
10
Webhooks
Overview
Base URL: https://api.inbox-api.com
All endpoints return JSON. Requests with a body must send Content-Type: application/json.
Pagination defaults: page=1, pageSize=10 (max 100).
Interactive documentation available at:
/docs — Scalar API explorer (requires running API)
Authentication
All requests require an API token in the Authorization header.
Authorization: Bearer cw_a1b2c3d4e5f6...
API tokens are prefixed with cw_ and can be restricted to specific
scopes and email accounts. Create tokens from the dashboard or via
the /api/email/tokens endpoint.
Available scopes:
messages.read Read messages, threads, search, attachments
messages.send Send, reply, forward emails
drafts.manage Create, update, send, delete drafts
accounts.read List accounts, folders, providers
folders.read List email folders
webhooks.manage Manage webhook subscriptions
Error Handling
Errors return standard HTTP status codes with a JSON body:
{
"error": "Account not found",
"code": "ACCOUNT_NOT_FOUND"
}
Common status codes:
200 Success
201 Created
204 No content (successful delete)
400 Validation error
401 Invalid or missing token
403 Insufficient permissions or scope
404 Resource not found
429 Rate limited (check Retry-After header)
Email-specific codes:
410 Message no longer exists on server
502 IMAP/SMTP authentication failed
503 Email server unavailable
504 Email server timeout
GET /api/email/accounts
List all connected email accounts with pagination, filtering, and sorting.
curl 'https://api.inbox-api.com/api/email/accounts?provider=gmail&status=connected' \
-H 'Authorization: Bearer cw_...'
Query parameters:
provider Filter by email provider (e.g., gmail, outlook, imap)
status Filter: connected, error, disconnected
sort Sort by: name (default), email
page Page number (default: 1)
pageSize Results per page (default: 10, max: 100)
Response:
{
"items": [{
"id": "a1b2c3d4-...",
"displayName": "Work Email",
"emailAddress": "me@company.com",
"provider": "imap",
"messageCount": 1247,
"unreadCount": 23
}],
"totalCount": 3,
"page": 1,
"pageSize": 10
}
Scope: accounts.read
GET /api/email/accounts/:id/folders
List email folders for an account.
curl https://api.inbox-api.com/api/email/accounts/a1b2c3d4-.../folders \
-H 'Authorization: Bearer cw_...'
Response:
[
{
"id": "f1a2b3c4-...",
"name": "INBOX",
"fullPath": "INBOX",
"messageCount": 1247,
"unreadCount": 23
}
]
Scope: folders.read
GET /api/email/accounts/:id/health
Check IMAP connection health and sync status for an account.
curl https://api.inbox-api.com/api/email/accounts/a1b2c3d4-.../health \
-H 'Authorization: Bearer cw_...'
Scope: accounts.read
GET /api/email/messages
List messages with filtering, sorting, pagination, and optional full-text search.
curl 'https://api.inbox-api.com/api/email/messages?accountId=a1b2c3d4-...&isRead=false&sort=date' \
-H 'Authorization: Bearer cw_...'
Query parameters:
q Full-text search query (enables BM25 ranking)
accountId Filter by account
folderId Filter by folder
isRead true/false
isStarred true/false
hasAttachments true/false
startDate ISO 8601 date
endDate ISO 8601 date
sort date (default), date_asc, subject, from, relevance
page Page number (default: 1)
pageSize Results per page (default: 10, max: 100)
Response:
{
"items": [{
"id": "msg_abc123",
"accountId": "a1b2c3d4-...",
"fromEmail": "alice@example.com",
"fromName": "Alice",
"subject": "Q3 Report",
"snippet": "Please find the report...",
"sentAt": "2026-03-25T14:30:00Z",
"isRead": false,
"isStarred": false,
"hasAttachments": true
}],
"totalCount": 47,
"page": 1,
"pageSize": 20,
"totalPages": 3
}
Scope: messages.read
GET /api/email/messages/:id
Get a single message with metadata.
curl https://api.inbox-api.com/api/email/messages/msg_abc123 \
-H 'Authorization: Bearer cw_...'
Scope: messages.read
GET /api/email/messages/:id/body
Fetch the full message body from the mail server.
Query parameters:
format Optional. Values: raw (default) or llm
Raw format (default):
curl https://api.inbox-api.com/api/email/messages/msg_abc123/body \
-H 'Authorization: Bearer cw_...'
{
"textBody": "Hi, please find the Q3 report attached.\nBest, Alice",
"htmlBody": "<p>Hi, please find the Q3 report attached.</p>"
}
LLM format — optimized for AI/LLM consumption:
curl https://api.inbox-api.com/api/email/messages/msg_abc123/body?format=llm \
-H 'Authorization: Bearer cw_...'
{
"markdown": "Hi, please find the Q3 report attached.",
"metadata": {
"signatureStripped": true,
"replyChainCollapsed": false,
"originalFormat": "html"
}
}
The format=llm transform pipeline:
1. HTML to Markdown — converts HTML emails to clean markdown
2. Reply chain collapsing — removes quoted replies (blockquotes, Gmail quotes, > lines)
3. Signature stripping — removes email signatures (RFC 3676 -- delimiter, "Sent from my iPhone", etc.)
4. Whitespace normalization — collapses excessive blank lines
5. HTML sanitization — sanitizes input before processing
6. Size protection — HTML bodies over 512KB fall back to plain text extraction
Metadata flags indicate which transforms were applied, so your application
can decide whether to show additional context.
Results are cached separately from raw bodies for fast repeated access.
Scope: messages.read
GET /api/email/messages/:id/attachments
List attachments for a message.
curl https://api.inbox-api.com/api/email/messages/msg_abc123/attachments \
-H 'Authorization: Bearer cw_...'
Scope: messages.read
GET /api/email/messages/:messageId/attachments/:attachmentId/download
Download an attachment as a binary stream.
curl -o report.pdf \
https://api.inbox-api.com/api/email/messages/msg_abc123/attachments/att_xyz789/download \
-H 'Authorization: Bearer cw_...'
Returns binary content with appropriate Content-Type header.
Scope: messages.read
PATCH /api/email/messages/:id
Update message flags (read/unread, starred/unstarred).
curl -X PATCH https://api.inbox-api.com/api/email/messages/msg_abc123 \
-H 'Authorization: Bearer cw_...' \
-H 'Content-Type: application/json' \
-d '{"isRead": true, "isStarred": false}'
Scope: messages.read
POST /api/email/messages/:id/move
Move a message to a different folder.
curl -X POST https://api.inbox-api.com/api/email/messages/msg_abc123/move \
-H 'Authorization: Bearer cw_...' \
-H 'Content-Type: application/json' \
-d '{"folderId": "f1a2b3c4-..."}'
Scope: messages.read
POST /api/email/messages/:id/archive
Archive a message (moves to archive folder).
curl -X POST https://api.inbox-api.com/api/email/messages/msg_abc123/archive \
-H 'Authorization: Bearer cw_...'
Scope: messages.read
DELETE /api/email/messages/:id
Delete a message.
curl -X DELETE https://api.inbox-api.com/api/email/messages/msg_abc123 \
-H 'Authorization: Bearer cw_...'
Scope: messages.read
POST /api/email/messages/batch/mark-read
Batch mark multiple messages as read or unread.
curl -X POST https://api.inbox-api.com/api/email/messages/batch/mark-read \
-H 'Authorization: Bearer cw_...' \
-H 'Content-Type: application/json' \
-d '{
"messageIds": ["msg_abc123", "msg_def456"],
"isRead": true
}'
Scope: messages.read
POST /api/email/messages/batch/archive
Batch archive multiple messages.
curl -X POST https://api.inbox-api.com/api/email/messages/batch/archive \
-H 'Authorization: Bearer cw_...' \
-H 'Content-Type: application/json' \
-d '{
"messageIds": ["msg_abc123", "msg_def456"]
}'
Scope: messages.read
POST /api/email/messages/batch/move
Batch move multiple messages to a folder.
curl -X POST https://api.inbox-api.com/api/email/messages/batch/move \
-H 'Authorization: Bearer cw_...' \
-H 'Content-Type: application/json' \
-d '{
"messageIds": ["msg_abc123", "msg_def456"],
"folderId": "f1a2b3c4-..."
}'
Scope: messages.read
GET /api/email/messages/digest
Get an email digest across all or specific accounts.
curl 'https://api.inbox-api.com/api/email/messages/digest?since=24h&maxPerAccount=25' \
-H 'Authorization: Bearer cw_...'
Query parameters:
since Time window: shorthand (6h, 24h, 7d) or ISO 8601 duration
accountId Limit to a specific account
maxPerAccount Max messages per account (default: 25)
Scope: messages.read
POST /api/email/send
Send a new email.
curl -X POST https://api.inbox-api.com/api/email/send \
-H 'Authorization: Bearer cw_...' \
-H 'Content-Type: application/json' \
-d '{
"accountId": "a1b2c3d4-...",
"to": [{"email": "alice@example.com", "name": "Alice"}],
"cc": [{"email": "bob@example.com"}],
"subject": "Weekly Update",
"textBody": "Hi team, here is the weekly update.",
"htmlBody": "<h1>Weekly Update</h1><p>Hi team...</p>"
}'
Scope: messages.send
POST /api/email/messages/:id/reply
Reply to an existing message.
curl -X POST https://api.inbox-api.com/api/email/messages/msg_abc123/reply \
-H 'Authorization: Bearer cw_...' \
-H 'Content-Type: application/json' \
-d '{
"textBody": "Thanks, looks great!",
"replyAll": false
}'
Scope: messages.send
POST /api/email/messages/:id/forward
Forward a message to new recipients. All original attachments are preserved.
curl -X POST https://api.inbox-api.com/api/email/messages/msg_abc123/forward \
-H 'Authorization: Bearer cw_...' \
-H 'Content-Type: application/json' \
-d '{
"to": [{"email": "bob@example.com"}],
"additionalText": "FYI — see the message below."
}'
Body parameters:
to [{email, name?}] (required)
cc [{email, name?}]
bcc [{email, name?}]
additionalText Text prepended to the forwarded message
Scope: messages.send
GET /api/email/messages?q=...
Full-text search across all email accounts (BM25 ranking). Search is integrated
into the messages endpoint via the q parameter.
curl 'https://api.inbox-api.com/api/email/messages?q=invoice&sort=relevance' \
-H 'Authorization: Bearer cw_...'
Query parameters:
q Search query (required)
accountId Limit to specific account
isRead Filter by read status
isStarred Filter by starred status
hasAttachments Filter by attachment presence
startDate ISO 8601 date
endDate ISO 8601 date
sort relevance (default for search), date, date_asc, subject, from
page Page number (default: 1)
pageSize Results per page (default: 10, max: 100)
Returns the same paginated format as list messages.
Scope: messages.read
GET /api/email/threads
List conversation threads.
curl 'https://api.inbox-api.com/api/email/threads?accountId=a1b2c3d4-...' \
-H 'Authorization: Bearer cw_...'
Query parameters:
accountId Filter by account
startDate Filter threads by start date (ISO 8601)
endDate Filter threads by end date (ISO 8601)
unreadOnly Show only unread threads (true/false)
sort Sort order
page Page number (default: 1)
pageSize Results per page (default: 10, max: 100)
Scope: threads.read
GET /api/email/threads/:id
Get a full thread with all messages (oldest first).
curl https://api.inbox-api.com/api/email/threads/thr_xyz789 \
-H 'Authorization: Bearer cw_...'
Response:
{
"id": "thr_xyz789",
"subject": "Q3 Report",
"messageCount": 3,
"unreadCount": 1,
"lastMessageAt": "2026-03-25T14:30:00Z",
"messages": [/* array of MessageDto, oldest first */]
}
Scope: threads.read
GET /api/email/drafts
List saved drafts.
curl 'https://api.inbox-api.com/api/email/drafts?accountId=a1b2c3d4-...' \
-H 'Authorization: Bearer cw_...'
Query parameters:
accountId Filter by account
startDate Filter by creation date (ISO 8601)
endDate Filter by creation date (ISO 8601)
sort Sort order
page Page number (default: 1)
pageSize Results per page (default: 10, max: 100)
Scope: drafts.manage
POST /api/email/drafts
Create a new draft.
curl -X POST https://api.inbox-api.com/api/email/drafts \
-H 'Authorization: Bearer cw_...' \
-H 'Content-Type: application/json' \
-d '{
"accountId": "a1b2c3d4-...",
"to": [{"email": "alice@example.com"}],
"subject": "Draft Proposal",
"textBody": "Hi Alice, here is the draft..."
}'
Scope: drafts.manage
GET /api/email/drafts/:id
Get a draft with its body content.
curl https://api.inbox-api.com/api/email/drafts/draft_abc123 \
-H 'Authorization: Bearer cw_...'
Scope: drafts.manage
PUT /api/email/drafts/:id
Update an existing draft.
curl -X PUT https://api.inbox-api.com/api/email/drafts/draft_abc123 \
-H 'Authorization: Bearer cw_...' \
-H 'Content-Type: application/json' \
-d '{"subject": "Updated Subject", "textBody": "Updated body..."}'
Scope: drafts.manage
POST /api/email/drafts/:id/send
Send a saved draft.
curl -X POST https://api.inbox-api.com/api/email/drafts/draft_abc123/send \
-H 'Authorization: Bearer cw_...'
Scope: drafts.manage
DELETE /api/email/drafts/:id
Discard a draft.
curl -X DELETE https://api.inbox-api.com/api/email/drafts/draft_abc123 \
-H 'Authorization: Bearer cw_...'
Scope: drafts.manage
GET /api/email/contacts
List frequency-ranked contacts extracted from message headers.
curl 'https://api.inbox-api.com/api/email/contacts?search=alice&sort=frequency' \
-H 'Authorization: Bearer cw_...'
Query parameters:
since Time window: shorthand (6h, 24h, 7d) or ISO 8601 duration
accountId Filter by account
search Search by email address or name
sort Sort order
page Page number (default: 1)
pageSize Results per page (default: 10)
Scope: messages.read
GET /api/email/webhooks
List webhook subscriptions with filtering and sorting.
curl 'https://api.inbox-api.com/api/email/webhooks?isActive=true&sort=date' \
-H 'Authorization: Bearer cw_...'
Query parameters:
isActive Filter by active status (true/false)
sort Sort: date (default), date_asc, url
page Page number (default: 1)
pageSize Results per page (default: 10, max: 100)
Scope: webhooks.manage
GET /api/email/webhooks/:id
Get webhook details with delivery statistics.
curl https://api.inbox-api.com/api/email/webhooks/wh_abc123 \
-H 'Authorization: Bearer cw_...'
Scope: webhooks.manage
GET /api/email/webhooks/:id/deliveries
List delivery history for a webhook.
curl 'https://api.inbox-api.com/api/email/webhooks/wh_abc123/deliveries?status=failed' \
-H 'Authorization: Bearer cw_...'
Query parameters:
status Filter: success, failed, pending
eventType Filter by event type
page Page number
pageSize Results per page
Scope: webhooks.manage
GET /api/email/webhooks/:webhookId/deliveries/:deliveryId
Get a single webhook delivery by ID.
curl https://api.inbox-api.com/api/email/webhooks/wh_abc123/deliveries/del_xyz \
-H 'Authorization: Bearer cw_...'
Scope: webhooks.manage
POST /api/email/webhooks/:webhookId/deliveries/:deliveryId/retry
Retry a failed webhook delivery.
curl -X POST https://api.inbox-api.com/api/email/webhooks/wh_abc123/deliveries/del_xyz/retry \
-H 'Authorization: Bearer cw_...'
Scope: webhooks.manage