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/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