Base URL: https://api.inboxrider.com/api/v1
Auth: Authorization: Bearer ir_…
Browser and mobile apps keep using user JWTs on /api/* — this API is for servers and scripts.
1. Authentication
Authorization: Bearer ir_<8hex>_<secret>
Keys are organization-scoped. They do not impersonate a teammate. Invalid or revoked keys return 401.
Create a key
In the app: Settings → Company → API & integrations. The full secret is shown once.
POST /api/organization/api-keys
Authorization: Bearer <user JWT>
Content-Type: application/json
{ "name": "Production integration", "scopes": ["channels:read","conversations:read","conversations:write","messages:read","messages:send","webhooks:manage"] }
- List:
GET /api/organization/api-keys - Revoke:
DELETE /api/organization/api-keys/:id
2. Scopes
| Scope | Access |
|---|---|
channels:read | GET /channels |
conversations:read | GET /conversations, GET /conversations/:id |
conversations:write | POST /conversations/resolve |
messages:read | GET /conversations/:id/messages |
messages:send | POST /messages/send |
webhooks:manage | Webhook create / list / deactivate |
Missing scope → 403 with SCOPE_DENIED.
3. List channels
GET /api/v1/channels
Authorization: Bearer ir_…
{
"channels": [
{
"id": "ch_…",
"email": "sales@example.com",
"provider": "gmail",
"status": "connected",
"canSend": true,
"inboxId": "inb_…"
}
]
}
OAuth tokens and mailbox passwords are never returned. Prefer canSend: true for outbound.
4. Send a message
POST /api/v1/messages/send
Authorization: Bearer ir_…
Idempotency-Key: campaign-42-step-1
Content-Type: application/json
{
"channelId": "ch_…",
"to": "alex@acme.com",
"toName": "Alex",
"subject": "Quick question",
"body": "<p>Hi Alex…</p>"
}
Idempotency-Key is required (max 191 characters).
Reply in a thread
{
"channelId": "ch_…",
"conversationId": "conv_…",
"body": "<p>Thanks for the reply…</p>",
"subject": "Re: Quick question"
}
Do not set In-Reply-To / References yourself — InboxRider derives threading. If channelId cannot send, you get CHANNEL_NOT_SENDABLE (no silent fallback).
Response
{
"idempotencyKey": "campaign-42-step-1",
"messageId": "msg_…",
"conversationId": "conv_…",
"accepted": true,
"deliveryStatus": "sent",
"providerMessageId": null,
"warning": null
}
Rate limit: ~30 sends / minute / API key (plus ~300 req/min/IP globally).
5. Search / list conversations
GET /api/v1/conversations?q=acme&from=@gmail.com&status=OPEN&limit=25
Authorization: Bearer ir_…
| Query | Meaning |
|---|---|
q | Subject, contact, company, or body |
from | Contact or message from-address |
subject | Subject contains |
status | OPEN | WAITING | RESOLVED | TRASH | SPAM |
inboxId | Limit to one inbox |
includeDrafts | true to include drafts |
limit | 1–100 (default 25) |
cursor | From prior nextCursor |
6. Resolve conversations
Marks threads RESOLVED only (not trash, spam, or delete). Max 100 ids per request.
POST /api/v1/conversations/resolve
Authorization: Bearer ir_…
Content-Type: application/json
{ "conversationIds": ["conv_1", "conv_2"] }
{ "requested": 2, "resolved": 2, "status": "RESOLVED" }
7. Get conversation / messages
GET /api/v1/conversations/:id
GET /api/v1/conversations/:id/messages
8. Idempotency
| Scenario | Result |
|---|---|
| First request | Process + store response |
| Same key + same body | Replay stored response |
| Same key + different body | 409 IDEMPOTENCY_CONFLICT |
| Concurrent same key | 409 IDEMPOTENCY_IN_PROGRESS |
Keys are kept for 7 days, then purged. Missing header → IDEMPOTENCY_KEY_REQUIRED.
9. Errors
{
"error": {
"code": "CHANNEL_NOT_SENDABLE",
"message": "The requested channel cannot currently send email."
}
}
Common codes: API_KEY_REQUIRED, SCOPE_DENIED, IDEMPOTENCY_KEY_REQUIRED, CHANNEL_NOT_FOUND, CHANNEL_NOT_SENDABLE, EMAIL_UNVERIFIED, IDEMPOTENCY_CONFLICT, SEND_FAILED, NOT_FOUND, VALIDATION_ERROR, RATE_LIMITED.
10. Quick start
KEY=ir_…
CHANNEL=ch_…
curl -sS https://api.inboxrider.com/api/v1/channels \
-H "Authorization: Bearer $KEY"
curl -sS https://api.inboxrider.com/api/v1/messages/send \
-H "Authorization: Bearer $KEY" \
-H "Idempotency-Key: demo-001" \
-H "Content-Type: application/json" \
-d "{
\"channelId\": \"$CHANNEL\",
\"to\": \"alex@acme.com\",
\"toName\": \"Alex\",
\"subject\": \"Quick question\",
\"body\": \"<p>Hi Alex — wanted to share a short note.</p>\"
}"
Inbound events: Webhooks guide.