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

  1. Sign in to Inboxy as a company admin and open Developers → API keys in the dashboard (/developer-center/keys).
  2. Choose "Create an API key" and give the key a name you will recognise (for example "Claude on my laptop").
  3. 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, ...).
  4. Pick an expiry: 30, 90 (default), 180 or 365 days, or never. The default is 90 days.
  5. 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
curl https://api.inboxy.chat/api/v1/public/company \
  -H "Authorization: Bearer $INBOXY_API_KEY"
Node SDK
import { InboxyClient } from '@inboxychat/sdk';

const inboxy = new InboxyClient({ apiKey: process.env.INBOXY_API_KEY! });
const { data } = await inboxy.getCompany();
CLI
inboxy auth login   # approve in the browser once
inboxy whoami
Header
Authorization: Bearer inboxy_YOUR_KEY

Good 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).

Who am I?
export INBOXY_API_KEY="inboxy_YOUR_KEY"
curl -s https://api.inboxy.chat/api/v1/public/company \
  -H "Authorization: Bearer $INBOXY_API_KEY"
Five newest orders
curl -s "https://api.inboxy.chat/api/v1/public/orders?limit=5" \
  -H "Authorization: Bearer $INBOXY_API_KEY"

Needs orders:read.

Response shape
{
  "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.

Next page
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.

Send text
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.

Reply
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.

Register
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.*"] }'
Verify (Node.js)
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.

EndpointScopeReturns
GET /company—The key, its company and its rate limits
GET /usageanalytics:readPlan usage against limits
GET /contactscontacts:readList and search contacts
GET /contacts/:idcontacts:readGet a contact
GET /conversationsconversations:readList conversations
GET /conversations/:idconversations:readGet a conversation
GET /conversations/:id/messagesmessages:readMessages of one conversation
GET /ordersorders:readList orders
GET /orders/:idorders:readGet an order
GET /productsproducts:readList catalog products
GET /products/:idproducts:readGet a product
GET /ticketstickets:readList customer tickets
GET /tickets/:idtickets:readGet a ticket
GET /taskstasks:readList team tasks
GET /tasks/:idtasks:readGet a task
GET /campaignscampaigns:readList WhatsApp campaigns with results
GET /campaigns/:idcampaigns:readGet a campaign and its results
GET /templatestemplates:readList WhatsApp (Meta) templates
GET /appointmentsmeetings:readList calendar appointments

Key-callable dashboard routes (examples)

The full list, with bodies and query parameters, is in the live reference and the OpenAPI document.

RouteScopeDoes
POST /api/v1/whatsapp/messages/textmessages:sendSend a WhatsApp text message
POST /api/v1/whatsapp/messages/templatemessages:sendSend an approved WhatsApp template
POST /api/v1/inbox/conversations/:conversationId/messagesmessages:sendReply in a conversation on any channel
PATCH /api/v1/inbox/conversations/:conversationId/statusconversations:writeChange a conversation status (open, pending, closed)
GET /api/v1/whatsapp/templatestemplates:readList WhatsApp templates
POST /api/v1/webhookswebhooks:writeRegister a webhook
GET /api/v1/webhooks/:webhookId/logswebhooks:readList webhook deliveries
POST /api/v1/webhooks/:webhookId/testwebhooks:writeSend 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.

StatusMeaningWhat to do
401Key missing, unknown, revoked or expiredCreate a new key
403 INSUFFICIENT_PERMISSIONSThe key lacks the scope (named in details.requiredScope)Create a key with that scope
403 COMPANY_PAUSEDThe company is pausedContact Inboxy support
404Not in this company, or a wrong idCheck the id and the key’s company
429Rate limited (per key or per company)Wait Retry-After seconds
5xxOur sideRetry later; send support the X-Request-Id header

Create an API key

Keys are created by a company admin on the Developers page of the dashboard.