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