SDK & Widget · Mobile
SDK REST API
The HTTP endpoints behind every Inboxi chat client. Use them to build a native chat in Flutter, Swift, Kotlin or anything else.
All endpoints live under https://inboxi.app/api/widget/sdk, accept and return JSON, and answer with "success": true on success. init uses your API key; every other endpoint uses the session token it returns (see Authentication).
| Endpoint | Auth | Purpose |
|---|---|---|
POST /sdk/init | X-API-Key | Open a session, get the widget config |
POST /sdk/identify | Bearer | Attach user details, get the chat ID |
POST /sdk/messages | Bearer | Send a message |
GET /sdk/messages/:chatId | Bearer | Message history |
GET /sdk/conversations | Bearer | The visitor's conversations |
POST /sdk/device-token | Bearer | Register a push token |
Init
/api/widget/sdk/initOpen an SDK sessionRequires an API key with the widget permission. Returns a 24-hour session token and the widget appearance.
| Parameter | Type | Required | Description |
|---|---|---|---|
appId | string | optional | Your App ID. The workspace is taken from the API key; send it anyway for clarity. |
platform | string | optional | react_native | flutter | ios | android. |
appVersion | string | optional | Your app version, for your own diagnostics. |
userId | string | optional | Your user ID. Becomes the visitorId so the user gets the same conversation on every session. Omit for anonymous visitors (an sdk_… ID is generated). |
widgetId | string | optional | If your workspace runs several widgets, the one this session belongs to. Also accepted as context.widgetId. Defaults to your first active website widget. |
curl -X POST https://inboxi.app/api/widget/sdk/init \
-H "X-API-Key: inx_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "appId": "YOUR_APP_ID", "platform": "android", "appVersion": "1.4.0", "userId": "user_123" }'{
"success": true,
"sessionToken": "eyJhbGciOiJIUzI1NiIs...",
"visitorId": "user_123",
"socketUrl": "https://inboxi.app",
"organizationId": 1234,
"config": {
"primaryColor": "#6366f1",
"headerColor": "#0f172a",
"headerTextColor": "#ffffff",
"backgroundColor": "#f0f2f5",
"botMessageBackgroundColor": "#ffffff",
"botMessageTextColor": "#1f2937",
"userMessageTextColor": "#ffffff",
"welcomeMessage": "Hi! How can we help?",
"businessName": "Your Business",
"logoUrl": "https://...",
"language": "en",
"aiEnabled": true
}
}Keep visitorId and organizationId: the socket needs both.
Identify
/api/widget/sdk/identifyAttach user details to the sessionCall after your user logs in. Inboxi finds or creates the visitor's conversation, matching on email or phone first so the same person on a new device lands on the same contact.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | required | Display name shown in the inbox. |
userId | string | optional | Your user ID, stored on the contact as the external user ID. |
email | string | optional | Email address. |
phone | string | optional | Phone in international format. |
data | object | optional | Custom fields shown to your team (plan, city, last order…). |
curl -X POST https://inboxi.app/api/widget/sdk/identify \
-H "Authorization: Bearer $SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "userId": "user_123", "name": "Mohamed Ali", "email": "mohamed@example.com", "phone": "+201234567890", "data": { "plan": "premium" } }'{ "success": true, "visitorId": "user_123", "chatId": 456, "isNewChat": false }Send a message
/api/widget/sdk/messagesSend a visitor message over RESTWorks without a socket, which makes it the right choice for background sends and simple clients. The message appears in the inbox, notifies your team, and triggers the AI agent if the widget has AI enabled. A resolved conversation is reopened.
| Parameter | Type | Required | Description |
|---|---|---|---|
text | string | optional | Message text. Required unless mediaUrl is set; becomes the caption when it is. |
mediaUrl | string | optional | Public https URL of an image, video, audio or document you uploaded yourself. A message whose text is only such a link is treated as media too. |
mediaType | string | optional | image | video | audio | document | file. Detected from the URL when omitted. |
mimetype | string | optional | MIME type of the attachment. |
curl -X POST https://inboxi.app/api/widget/sdk/messages \
-H "Authorization: Bearer $SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "text": "Hello, I need help with my order" }'{ "success": true, "messageId": 789, "chatId": 456, "timestamp": "2026-04-09T12:00:00.000Z" }widget_message, or you can poll the history endpoint.Message history
/api/widget/sdk/messages/:chatIdMessages in one conversation| Parameter | Type | Required | Description |
|---|---|---|---|
chatId | integer (path) | required | From identify, send or conversations. Must belong to the session visitor. |
page | integer | optional | Page number, default 1. |
limit | integer | optional | Page size, default 50, maximum 100. |
{
"success": true,
"messages": [
{ "id": 1, "content": "Hello", "sender": "customer", "timestamp": "...", "mediaUrl": null, "mediaType": null },
{ "id": 2, "content": "Hi! How can I help?", "sender": "agent", "timestamp": "...", "mediaUrl": null, "mediaType": null }
],
"pagination": { "page": 1, "limit": 50, "total": 2, "totalPages": 1 }
}Messages are ordered oldest first. sender is customer, agent or system. mediaUrl is always an absolute URL you can load directly.
Conversations
/api/widget/sdk/conversationsAll conversations of the session visitor{
"success": true,
"conversations": [
{
"id": 456,
"customerName": "Mohamed Ali",
"lastMessage": "Hi! How can I help?",
"lastMessageAt": "2026-04-09T12:00:05.000Z",
"status": "open",
"unreadCount": 0
}
]
}Ordered by latest activity. Conversations merged into this visitor from another device are included.
Register a device token
/api/widget/sdk/device-tokenRegister an FCM / APNs token for push| Parameter | Type | Required | Description |
|---|---|---|---|
token | string | required | The device push token. |
platform | string | required | ios or android. |
{ "success": true, "deviceTokenId": 77, "isNew": true }A token is unique: registering a token that already exists moves it to the current visitor and reactivates it. Call this after every init and whenever Firebase rotates the token.