43 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
12
Messages
6
Drafts
8
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=50 (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.
curl https://api.inbox-api.com/api/email/accounts \
-H 'Authorization: Bearer cw_...'
Response:
[
{
"id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
"displayName": "Work Email",
"emailAddress": "me@company.com",
"provider": "imap",
"syncStatus": "synced",
"lastSyncAt": "2026-03-25T14:30:00Z"
}
]
Scope: accounts.read
GET /api/email/accounts/:id
Get details for a specific account.
curl https://api.inbox-api.com/api/email/accounts/a1b2c3d4-... \
-H 'Authorization: Bearer cw_...'
Scope: accounts.read
GET /api/email/accounts/info
Lightweight account list with message counts (safe for dashboards).
curl https://api.inbox-api.com/api/email/accounts/info \
-H 'Authorization: Bearer cw_...'
Response:
[
{
"id": "a1b2c3d4-...",
"displayName": "Work Email",
"emailAddress": "me@company.com",
"provider": "imap",
"messageCount": 1247,
"unreadCount": 23
}
]
Scope: accounts.read
POST /api/email/accounts
Connect a new email account via IMAP/SMTP.
curl -X POST https://api.inbox-api.com/api/email/accounts \
-H 'Authorization: Bearer cw_...' \
-H 'Content-Type: application/json' \
-d '{
"displayName": "Work Email",
"emailAddress": "me@company.com",
"imapHost": "imap.company.com",
"imapPort": 993,
"imapUseSsl": true,
"smtpHost": "smtp.company.com",
"smtpPort": 587,
"smtpUseSsl": true,
"password": "app-password"
}'
Scope: accounts.read
PUT /api/email/accounts/:id
Update an existing email account. Only non-null fields are updated.
curl -X PUT https://api.inbox-api.com/api/email/accounts/a1b2c3d4-... \
-H 'Authorization: Bearer cw_...' \
-H 'Content-Type: application/json' \
-d '{"displayName": "Updated Name"}'
Scope: accounts.read
DELETE /api/email/accounts/:id
Disconnect and remove an email account.
curl -X DELETE https://api.inbox-api.com/api/email/accounts/a1b2c3d4-... \
-H 'Authorization: Bearer cw_...'
Scope: accounts.read
POST /api/email/accounts/test-connection
Test IMAP/SMTP credentials without saving.
curl -X POST https://api.inbox-api.com/api/email/accounts/test-connection \
-H 'Authorization: Bearer cw_...' \
-H 'Content-Type: application/json' \
-d '{
"host": "imap.gmail.com",
"port": 993,
"useSsl": true,
"username": "me@gmail.com",
"password": "app-password"
}'
Scope: accounts.read
GET /api/email/accounts/providers
List supported email providers with IMAP/SMTP presets.
curl https://api.inbox-api.com/api/email/accounts/providers \
-H 'Authorization: Bearer cw_...'
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/messages
List messages with filtering and pagination.
curl 'https://api.inbox-api.com/api/email/messages?accountId=a1b2c3d4-...&isRead=false&pageSize=20' \
-H 'Authorization: Bearer cw_...'
Query parameters:
accountId Filter by account
folderId Filter by folder
isRead true/false
hasAttachments true/false
startDate ISO 8601 date
endDate ISO 8601 date
page Page number (default: 1)
pageSize Results per page (default: 50, 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.
curl https://api.inbox-api.com/api/email/messages/msg_abc123/body \
-H 'Authorization: Bearer cw_...'
Response:
{
"textBody": "Hi, please find the Q3 report attached.
Best, Alice",
"htmlBody": "<p>Hi, please find the Q3 report attached.</p>"
}
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/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/search
Full-text search across all email accounts (BM25 ranking).
curl 'https://api.inbox-api.com/api/email/search?q=invoice&pageSize=10' \
-H 'Authorization: Bearer cw_...'
Query parameters:
q Search query (required)
accountId Limit to specific account
page Page number (default: 1)
pageSize Results per page (default: 50, 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
page Page number (default: 1)
pageSize Results per page (default: 50, 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
page Page number (default: 1)
pageSize Results per page (default: 50)
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
POST /api/email/webhooks
Register a webhook subscription. The signing secret is returned only once.
curl -X POST https://api.inbox-api.com/api/email/webhooks \
-H 'Authorization: Bearer cw_...' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://your-app.com/webhooks/inbox",
"events": ["message.received", "message.sent"],
"description": "Notify on new emails"
}'
Response includes:
{
"id": "wh_abc123",
"secret": "whsec_..." ← save this, shown only once
}
Scope: webhooks.manage
GET /api/email/webhooks
List webhook subscriptions.
curl https://api.inbox-api.com/api/email/webhooks \
-H 'Authorization: Bearer cw_...'
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
PUT /api/email/webhooks/:id
Update a webhook. Only non-null fields are updated.
curl -X PUT https://api.inbox-api.com/api/email/webhooks/wh_abc123 \
-H 'Authorization: Bearer cw_...' \
-H 'Content-Type: application/json' \
-d '{"events": ["message.received"]}'
Scope: webhooks.manage
DELETE /api/email/webhooks/:id
Delete a webhook and all delivery records.
curl -X DELETE https://api.inbox-api.com/api/email/webhooks/wh_abc123 \
-H 'Authorization: Bearer cw_...'
Scope: webhooks.manage
POST /api/email/webhooks/:id/regenerate-secret
Generate a new signing secret. The old secret stops working immediately.
curl -X POST https://api.inbox-api.com/api/email/webhooks/wh_abc123/regenerate-secret \
-H 'Authorization: Bearer cw_...'
Response:
{ "secret": "whsec_new_..." }
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
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