SDK & Widget · Mobile
Errors
How the SDK endpoints, the socket and the React Native client report problems, and what to do about each one.
Every SDK endpoint answers errors with a JSON body that has "success": false and a human-readable error. Some errors add a machine-readable code; branch on that when it is present, and on the HTTP status otherwise.
{
"success": false,
"error": "Human-readable message",
"code": "TOKEN_EXPIRED"
}HTTP errors
| Status | Typical error | What to do |
|---|---|---|
| 400 | name is required | identify: send a name. |
| 400 | text or mediaUrl is required | messages: send text, a media URL, or both. |
| 400 | token is required · platform must be "ios" or "android" | device-token: fix the body. |
| 401 | API key required. Pass it in X-API-Key header. | init: add the X-API-Key header. |
| 401 | Invalid or inactive API key · API key has expired | Create a new key in the Developer Hub. |
| 401 | SDK session token required… | Send Authorization: Bearer <sessionToken>. |
| 401 | code TOKEN_EXPIRED | Call /sdk/init again (same userId), then retry. |
| 401 | Invalid session token. | The token is malformed or from another environment. Re-init. |
| 403 | Missing permission: widget | Use a key that has the widget permission. |
| 403 | code FEATURE_LOCKED | Your plan does not include the feature. The body also has feature, currentTier and requiredPlan. |
| 404 | Chat not found · Workspace not found | The chatId does not belong to this visitor, or the workspace is unavailable. |
| 429 | Rate limit exceeded. Max 60 requests per minute. | Wait for Retry-After seconds. Call init once per launch, not per message. |
| 500 | Failed to … | Retry with backoff. If it persists, contact support with the time and endpoint. |
Handling an expired session
async function sdkFetch(path, options = {}) {
let res = await call(path, options);
if (res.status === 401) {
const body = await res.clone().json().catch(() => ({}));
if (body.code === 'TOKEN_EXPIRED') {
await initSession(); // POST /sdk/init with the same userId
res = await call(path, options); // retry once with the new token
}
}
return res;
}Socket errors
The socket reports problems with a widget_error event: { code, message }.
| code | Meaning | What to do |
|---|---|---|
JOIN_FAILED | The join could not be processed. | Retry widget_join after a short delay. |
SESSION_NOT_FOUND | A message arrived for a visitor that has not joined on this server. | Emit widget_join again, then resend the message (or send it over REST). |
INVALID_EMAIL | widget_set_email received an invalid address. | Validate the email and resend. |
React Native SDK errors
The SDK throws regular Error objects; wrap calls in try / catch.
| Message | Cause |
|---|---|
InboxiChat.init() requires appId and apiKey | One of the two was empty. |
Call InboxiChat.init() first | A method was called before init, or after logout. |
name is required for identify() | identify was called without a name. |
SESSION_EXPIRED | The session token expired. Call InboxiChat.init() again and retry. |
Init failed with status … | init was rejected: check the key, its permissions and your plan. |
The stock
ChatScreen renders a short notice instead of crashing when the SDK was never initialized, so a blank chat usually means init failed. Log the error it threw.