REST API
Read your orders, contacts, conversations and products, and send messages, over HTTPS with a scoped key.
Available · public v1 is read-only; write routes need write scopes
curl https://api.inboxy.chat/api/v1/public/company -H "Authorization: Bearer inboxy_YOUR_KEY"On this page
Who it is for
Developers and agencies connecting a store, CRM, ERP or internal tool to Inboxy.
What it can do
- A stable, read-only v1 under /api/v1/public: company, usage, contacts, conversations, messages, orders and products.
- With write scopes, the same key can call the dashboard routes listed in the live reference: send WhatsApp messages and templates, reply in any conversation, change conversation status, manage contacts, webhooks and more.
- Signed webhooks for events such as new messages and orders.
- An OpenAPI document that is generated from the running API, so the reference cannot drift.
Overview
Every request goes to https://api.inboxy.chat with an API key in the Authorization header. The key decides the company: there is no company id in any request.
Two layers: the public v1 contract (/api/v1/public/*, read-only, versioned) and the dashboard routes a key may call with the right scope. Both are in the live reference.
Authentication
- Sign in to Inboxy as a company admin and open Developers → API keys in the dashboard (/developer-center/keys).
- Choose "Create an API key" and give the key a name you will recognise (for example "Claude on my laptop").
- Tick only the scopes you need. There is no default set: a key without scopes cannot be created. The read tools need the ":read" scopes (contacts:read, orders:read, ...).
- Pick an expiry: 30, 90 (default), 180 or 365 days, or never. The default is 90 days.
- Copy the key when it is shown. It starts with "inboxy_". Store it in a secret manager or the OS keychain, never in a repository.
Send the key
Send it as a Bearer token. HTTPS only.
curl https://api.inboxy.chat/api/v1/public/company \
-H "Authorization: Bearer $INBOXY_API_KEY"import { InboxyClient } from '@inboxychat/sdk';
const inboxy = new InboxyClient({ apiKey: process.env.INBOXY_API_KEY! });
const { data } = await inboxy.getCompany();inboxy auth login # approve in the browser once
inboxy whoamiAuthorization: Bearer inboxy_YOUR_KEYGood to know
- Only a company admin can create keys. A key acts for its company only: no request takes a company id.
- A company can hold up to 10 live keys. Revoke a key from the same page.
- A key runs as the admin who created it. It stops working when it expires, is revoked, the company is paused, or its creator is no longer an admin.
- Every request a key makes is listed on the Developers → Request logs page.
Quickstart
Check the key, then read the five newest orders. Replace the key with yours (keep it in an environment variable).
export INBOXY_API_KEY="inboxy_YOUR_KEY"
curl -s https://api.inboxy.chat/api/v1/public/company \
-H "Authorization: Bearer $INBOXY_API_KEY"curl -s "https://api.inboxy.chat/api/v1/public/orders?limit=5" \
-H "Authorization: Bearer $INBOXY_API_KEY"Needs orders:read.
{
"success": true,
"data": [ { "id": "...", "orderNumber": "..." } ],
"meta": { "limit": 5, "hasMore": true, "nextCursor": "..." }
}How-to guides
Page through a list
Lists use cursors. Pass limit (1-100, default 20); while meta.hasMore is true, send meta.nextCursor back as cursor.
curl -s "https://api.inboxy.chat/api/v1/public/contacts?limit=100&cursor=NEXT_CURSOR" \
-H "Authorization: Bearer $INBOXY_API_KEY"Send a WhatsApp text
Needs messages:send and a connected WhatsApp number. A free-form text only goes out inside the 24-hour customer service window; outside it, send an approved template.
curl -s -X POST https://api.inboxy.chat/api/v1/whatsapp/messages/text \
-H "Authorization: Bearer $INBOXY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "to": "966500000000", "body": "Your order has shipped." }'Reply in a conversation
Works on any connected channel. Needs messages:send.
curl -s -X POST https://api.inboxy.chat/api/v1/inbox/conversations/CONVERSATION_ID/messages \
-H "Authorization: Bearer $INBOXY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "type": "text", "content": "Thanks, we are on it." }'Receive webhooks and verify them
Register an HTTPS endpoint (webhooks:write) with the events you want; the event list is at https://api.inboxy.chat/api/v1/webhooks/catalog. Every delivery carries X-Inboxy-Timestamp and X-Inboxy-Signature: sha256=HMAC-SHA256(secret, "<timestamp>.<raw body>"). Reject deliveries older than 300 seconds.
curl -s -X POST https://api.inboxy.chat/api/v1/webhooks \
-H "Authorization: Bearer $INBOXY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Order sync", "url": "https://example.com/webhooks/inboxy", "events": ["ecommerce.order.*"] }'import crypto from 'node:crypto';
export function verifyInboxy(rawBody, headers, secret) {
const ts = headers['x-inboxy-timestamp'];
const sig = headers['x-inboxy-signature'] || '';
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('hex');
const a = Buffer.from(sig);
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Reference
Public v1 (read-only)
All paths are under https://api.inboxy.chat/api/v1/public.
| Endpoint | Scope | Returns |
|---|---|---|
GET /company | — | The key, its company and its rate limits |
GET /usage | analytics:read | Plan usage against limits |
GET /contacts | contacts:read | List and search contacts |
GET /contacts/:id | contacts:read | Get a contact |
GET /conversations | conversations:read | List conversations |
GET /conversations/:id | conversations:read | Get a conversation |
GET /conversations/:id/messages | messages:read | Messages of one conversation |
GET /orders | orders:read | List orders |
GET /orders/:id | orders:read | Get an order |
GET /products | products:read | List catalog products |
GET /products/:id | products:read | Get a product |
GET /tickets | tickets:read | List customer tickets |
GET /tickets/:id | tickets:read | Get a ticket |
GET /tasks | tasks:read | List team tasks |
GET /tasks/:id | tasks:read | Get a task |
GET /campaigns | campaigns:read | List WhatsApp campaigns with results |
GET /campaigns/:id | campaigns:read | Get a campaign and its results |
GET /templates | templates:read | List WhatsApp (Meta) templates |
GET /appointments | meetings:read | List calendar appointments |
Key-callable dashboard routes (examples)
The full list, with bodies and query parameters, is in the live reference and the OpenAPI document.
| Route | Scope | Does |
|---|---|---|
POST /api/v1/whatsapp/messages/text | messages:send | Send a WhatsApp text message |
POST /api/v1/whatsapp/messages/template | messages:send | Send an approved WhatsApp template |
POST /api/v1/inbox/conversations/:conversationId/messages | messages:send | Reply in a conversation on any channel |
PATCH /api/v1/inbox/conversations/:conversationId/status | conversations:write | Change a conversation status (open, pending, closed) |
GET /api/v1/whatsapp/templates | templates:read | List WhatsApp templates |
POST /api/v1/webhooks | webhooks:write | Register a webhook |
GET /api/v1/webhooks/:webhookId/logs | webhooks:read | List webhook deliveries |
POST /api/v1/webhooks/:webhookId/test | webhooks:write | Send a test delivery |
Limits and safety
- 60 requests per minute per key, plus one budget per minute shared by all keys of a company. GET /api/v1/public/company returns both numbers.
- Over a limit you get 429 with a Retry-After header; wait that many seconds.
- Plan limits apply to keys exactly as they apply in the dashboard.
- Give each integration its own key with the fewest scopes and an expiry. Never put a key in browser code or a public repository.
Troubleshooting
Errors use one envelope: { "success": false, "error": { "code", "message", "details" } }. The CLI command inboxy doctor checks a key end to end.
| Status | Meaning | What to do |
|---|---|---|
401 | Key missing, unknown, revoked or expired | Create a new key |
403 INSUFFICIENT_PERMISSIONS | The key lacks the scope (named in details.requiredScope) | Create a key with that scope |
403 COMPANY_PAUSED | The company is paused | Contact Inboxy support |
404 | Not in this company, or a wrong id | Check the id and the key’s company |
429 | Rate limited (per key or per company) | Wait Retry-After seconds |
5xx | Our side | Retry later; send support the X-Request-Id header |
Links
Create an API key
Keys are created by a company admin on the Developers page of the dashboard.
