Blits.ai API Documentation
Connect your own apps, websites and channels to Blits.ai bots and agents over REST or WebSocket
API Overview
There are two ways in. The REST API handles one request and one response at a time. The WebSocket API keeps a connection open in both directions, which is what you need for streaming audio and live transcription.
REST API
Plain HTTP endpoints: send a message, get the bot's answer back. A good fit when each call stands on its own.
- Works with any HTTP client
- Stateless communication
- JSON request/response format
WebSocket API
Keeps one connection open in both directions for voice streaming, live transcription and immediate replies.
- Streaming audio in real time (TTS/STT)
- Persistent connection for multiple messages
- Live conversation state management
Web Widget
Put the full Blits.ai chat on your website with one script snippet. Behavior, branding and security are set in the Blits.ai Platform dashboard.
- One script snippet that works on any website or web app
- Theme, behavior and security are all set in one place, the dashboard
- Voice, files, multiple languages and detailed behavior settings
Base URLs
Use the general endpoint, or pick the regional endpoint closest to your users for better performance.
General Endpoint
https://platform.blits.ai/wss://platform.blits.ai/Regional endpoints are there when you have geographic requirements.
Website Widget
Add the Blits.ai chat widget to your website with a ready made script snippet. You set its look and behavior in the Blits.ai Platform dashboard.
Embed Chat Widget on Your Website
The quickest way to put Blits.ai on your website is our ready made chat widget. Copy the snippet below and paste it into your HTML.
Quick Embed Code
Add this code snippet to your website's HTML, preferably just before the closing </body> tag:
<!-- Blits.ai Chat Widget -->
<script defer src="https://platform.blits.ai/assets/chat-widget.js"></script>
<script>
window.addEventListener('load', function () {
window.ChatWidget.mount({
token: "YOUR_API_TOKEN",
code: "YOUR_BUBBLE_CODE",
backendUrl: "https://platform.blits.ai",
websocketUrl: "wss://platform.blits.ai",
// Optional: provide your own stable userId instead of the auto-generated one
// userId: "YOUR_USER_ID",
debug: false
});
});
</script>Chat Widget Configuration
The ChatWidget.mount() function accepts the following configuration options:
| Parameter | Type | Required | Description |
|---|---|---|---|
token | string | Yes | One JWT token (Bot or Agent). With an Agent token, the widget reads the payload and switches to LLM mode by itself. |
code | string | Yes | Your chat bubble unique code from Bot Settings → Configuration → Chat Bubble |
backendUrl | string | Yes | Backend URL (use general endpoint or regional: eu, qa, sg, uae, us, au) |
websocketUrl | string | Yes | WebSocket URL (wss://platform.blits.ai or regional) |
userId | string | No | Optional fixed user identifier. If you set it, the chat session uses this ID and does not generate a userId of its own. |
debug | boolean | No | Enable debug mode for console logging (default: false) |
- Login to platform.blits.ai
- Navigate to Bot Settings → Configuration → Chat Bubble
- Create a new chat bubble or select an existing one
- Copy the API token and bubble code from the settings
- Paste them into the embed code above
Chat Widget Customization
You change how the widget looks and behaves in the Blits.ai Platform dashboard. These are the settings you can change there:
Appearance
- • Custom bot avatar
- • Chat bubble icon
- • Main color theme (default Blits.ai color or custom HEX)
- • Text color customization
- • Title and branding
- • "Powered by Blits.ai" label on/off
- • Custom CSS for advanced styling overrides
Behavior
- • Bubble position (top/bottom, left/right/center)
- • Screen size (big/small)
- • Microphone enable/disable
- • File upload button
- • Popup messages (enable/disable, timing and delay)
- • Start chatbot automatically or only after button click
Security
- • Authorized origins whitelist
- • Domain restrictions
- • CORS configuration
Features
- • Voice interaction support
- • Support for multiple languages
- • File/image sharing
- • Notification messages when the bot answers on initialization
- • Button activation mode
Advanced Web Widget Integration (via code)
If you need more control, use the Blits.ai JavaScript API (documented in chat-bubble-via-code). From code you can initialize and render chat instances, override the userId, start a specific subflow or put several widgets on one page. None of this needs Direct Line.
Basic initialization and render
Load the bundle, then initialize the chat widget in JavaScript. Pass your own userId if you want the same identifier every time instead of a generated one. To test a subflow in staging while production keeps running untouched, pass useStagingVersion and, if you like, a flowName.
<!-- Blits advanced chat bubble integration -->
<script src="https://platform.blits.ai/assets/chat-widget.js"></script>
<script>
window.BlitsBotChat.init({
botId: "YOUR_BOT_ID",
code: "YOUR_BUBBLE_CODE",
// Optional: provide your own stable userId
userId: "YOUR_USER_ID",
// Optional: use the latest staging version of your bot instead of production
useStagingVersion: true,
// Optional: start the conversation from a specific subflow (for testing)
flowName: "YOUR_SUBFLOW_NAME"
});
// Render the widget into a specific element
window.BlitsBotChat.render(
{
botId: "YOUR_BOT_ID",
code: "YOUR_BUBBLE_CODE",
userId: "YOUR_USER_ID",
useStagingVersion: true,
flowName: "YOUR_SUBFLOW_NAME"
},
document.getElementById("blits-chat-container")
);
</script>Multiple widget instances
To run more than one chat widget on a page, give each instance its own id.
<script>
// First instance
window.BlitsBotChat.init({
id: "first",
botId: "YOUR_BOT_ID",
code: "YOUR_BUBBLE_CODE"
});
// Second instance with its own id
window.BlitsBotChat.init({
id: "second",
botId: "YOUR_BOT_ID",
code: "YOUR_BUBBLE_CODE"
});
// Render a specific instance into a DOM element
window.BlitsBotChat.render(
{
id: "second",
botId: "YOUR_BOT_ID",
code: "YOUR_BUBBLE_CODE"
},
document.getElementById("second-chat-container")
);
</script>REST API
With the Blits.ai REST API you connect your own channels to the Blits.ai platform. You authenticate with a JWT token and talk to bots and Agents by voice or text.
https://platform.blits.aiAll REST API endpoints use Bearer token authentication with your JWT token.Introduction
The Blits.ai Client (REST) API is for teams that want to connect their own channels to the Blits.ai platform. Your website, app or any other channel can then send the bot voice or text and get its answers back.
The JWT token both authenticates you and tells the API which bot and tenant you mean. The Authentication section explains how to get your JWT token.
You need an active account on the Blits.ai Platform. Log in at platform.blits.ai/login or custom endpoint.
Quick Start
- Obtain your JWT token from Bot Settings (bot token) or Agent Settings (agent token)
- Call initialize to open a conversation and get its conversation ID
- Get the opening message from the bot (if configured)
- Send text, voice, or file messages using the conversation ID
API Endpoints
Initialize New Conversation
POST /api/external/initializeCreates a new conversation ID for talking to the chatbot. Every later API call needs this ID. The platform uses it to keep the conversation context together: earlier blocks, the blocks that follow, user messages and bot responses.
Headers:
Authorization: Bearer {{authToken}}
Content-Type: application/jsonRequest Body (Optional):
{
"userId": "custom-user-id"
}| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | No | Optional user identifier of your own. If you leave it out, we generate a random ID |
conversationId or to set the conversation language up front via setCurrentLanguageTo, use the WebSocket initialize command. The REST initialize endpoint only accepts userId. Response:
{
"conversationId": "63525c75-7734-44b6-8a65-96d1d16ac06b",
"botId": "bot-12345",
"userId": "user-67890",
"currentLanguage": "en",
"availableLanguages": ["en", "ar", "es", "nl"],
"channel": "externalApi",
"chatHistory": []
}Example:
curl --location --request POST 'https://platform.blits.ai/api/external/initialize' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"userId": "user-123"
}'Check Conversation is Active
POST /api/external/is-active/:conversationIdTells you whether a conversation is still open and the bot can take new messages.
Headers:
Authorization: Bearer {{authToken}}Path Parameters:
| Parameter | Description |
|---|---|
conversationId | The conversation ID you got back from the initialize endpoint |
Example:
curl --location --request POST 'https://platform.blits.ai/api/external/is-active/{{conversationId}}' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN'Erase Conversation Data
POST /api/external/erase Deletes everything the platform holds for one user, one conversation, or both: message history, conversation state, handover state, long term memories and goals, and the decision log. At least one of userId and conversationId is required.
Headers:
Authorization: Bearer {{authToken}}
Content-Type: application/jsonRequest Body:
{
"userId": "user-123",
"conversationId": "conversation-abc"
}| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | No | Erase all data of this end user, including their long term memories and goals |
conversationId | string | No | Erase the data of this conversation |
Response:
{
"botId": "bot-12345",
"conversationId": "conversation-abc",
"userId": "user-123",
"deletedHistory": 14,
"deletedStates": 1,
"deletedMemories": 3
}Example:
curl --location --request POST 'https://platform.blits.ai/api/external/erase' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"userId": "user-123",
"conversationId": "conversation-abc"
}'Requesting Opening Message
POST /api/external/messages/:conversationId/text Asks the bot for its opening message(s). If you want audio back instead of text, set the speech-response header to true.
Headers:
Authorization: Bearer {{authToken}}
Content-Type: application/json
speech-response: falseRequest Body:
{
"type": "NEW",
"language": "EN"
}| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Set to "NEW" to request the opening message(s) from the bot |
language | string | No | Optional language code (e.g., "EN", "AR") for the opening message |
Response:
{
"conversationToken": "63525c75-7734-44b6-8a65-96d1d16ac06b",
"expectUserResponse": true,
"response": ["Hi! This is the 'Welcome Message'"]
}Example:
curl --location 'https://platform.blits.ai/api/external/messages/{{conversationId}}/text' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--header 'Content-Type: application/json' \
--data '{ "type": "NEW" }'Sending Text Message
POST /api/external/messages/:conversationId/textSends a text message to the bot and returns its reply.
Headers:
Authorization: Bearer {{authToken}}
Content-Type: application/json
speech-response: false
text-response: truespeech-response: true: you get audio as well as texttext-response: true: you get the text reply (default: true)
Request Body:
{
"message": "Hello, how are you?",
"userId": "user-123",
"language": "EN"
}| Parameter | Type | Required | Description |
|---|---|---|---|
message | string | Yes | The text message to send to the bot |
userId | string | No | Optional user identifier, used for tracking |
language | string | No | Optional language code (e.g., "EN", "AR") |
Response:
{
"conversationToken": "63525c75-7734-44b6-8a65-96d1d16ac06b",
"expectUserResponse": true,
"response": ["I'm doing great! How can I help you today?"],
"language": "en"
}Example:
curl --location 'https://platform.blits.ai/api/external/messages/{{conversationId}}/text' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"message": "Hello, how are you?",
"userId": "user-123"
}'Sending Files or Images
POST /api/external/messages/:conversationId/text Sends a file or image to the bot. Use the text conversation type, because the speech type is only for audio input. The call only works when the bot is waiting for a file or image.
Headers:
Authorization: Bearer {{authToken}}
Content-Type: multipart/form-dataForm Data:
| Field | Required | Description |
|---|---|---|
attachments | Yes | The file to upload (images, documents, etc.) |
Example:
curl --location 'https://platform.blits.ai/api/external/messages/{{conversationId}}/text' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--form 'attachments=@"/path/to/file"'Sending Speech
POST /api/external/messages/:conversationId/speech Sends audio to the bot. The reply comes back as text, or as audio when you set the speech-response header to true.
Headers:
Authorization: Bearer {{authToken}}
Content-Type: audio/wav
speech-response: trueaudio/wav: WAV (recommended, it works with the most setups)audio/mpegoraudio/mp3: MP3
WAV and MP3 both work. The API picks up the format from the Content-Type header, or from the file itself.
Request Body:
Binary audio data in WAV or MP3 format
Response:
{
"conversationToken": "63525c75-7734-44b6-8a65-96d1d16ac06b",
"expectUserResponse": true,
"response": ["I understood your voice message!"],
"speechData": "base64-encoded-audio-response"
}Example (WAV):
curl --location 'https://platform.blits.ai/api/external/messages/{{conversationId}}/speech' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--header 'Content-Type: audio/wav' \
--header 'speech-response: true' \
--data-binary '@/path/to/audio.wav'Example (MP3):
curl --location 'https://platform.blits.ai/api/external/messages/{{conversationId}}/speech' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--header 'Content-Type: audio/mpeg' \
--header 'speech-response: true' \
--data-binary '@/path/to/audio.mp3'Analyze Message (NLU)
GET /api/external/analyze-messageRuns Natural Language Understanding (NLU) on one message and returns the intents, entities and other language features it finds. No conversation is started.
Headers:
Authorization: Bearer {{authToken}}Query Parameters:
| Parameter | Required | Description |
|---|---|---|
message | Yes | The message text to analyze (URL encoded) |
Example:
curl --location 'https://platform.blits.ai/api/external/analyze-message?message=Hello%20there' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN'Get External Settings
GET /api/external/settings/:codeGET /api/external/settings Returns the external configuration settings of the bot. Pass a code to get one configuration. Leave it out and you get every configuration the authenticated bot has.
Headers:
Authorization: Bearer {{authToken}}Path Parameters:
| Parameter | Required | Description |
|---|---|---|
code | No | The settings code you want. Leave it out to get all configurations. |
Example:
curl --location 'https://platform.blits.ai/api/external/settings/{{code}}' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN'Run Agent (LLM)
POST /api/llm/runRuns an Agent (LLM) and streams the answer back as NDJSON chunks. Send a plain prompt, the message history and, if needed, attachments as context.
Headers:
Authorization: Bearer YOUR_AGENT_OR_JWT_TOKEN
Content-Type: application/jsonllmId is resolved from the Agent token payload (type: "llm" + llmId), so it is not required in the URL. Request Body:
{
"query": "Summarize the attached document",
"history": [],
"attachments": [
{
"id": "att-1",
"type": "file",
"filename": "notes.txt",
"title": "notes.txt",
"mediaType": "text/plain",
"url": "https://example.com/notes.txt",
"textContent": "Optional extracted text..."
}
]
}Streamed Response (NDJSON):
{"type":"message_chunk","content":"Hello","messageId":1}
{"type":"reasoning_chunk","content":"..."}
{"type":"status_update","event":"info","message":"..."}
{"type":"generated_file","file":{"fileId":"...","filename":"report.txt","link":"https://..."}}
{"type":"end"}Example:
curl --location 'https://platform.blits.ai/api/llm/run' \
--header 'Authorization: Bearer YOUR_AGENT_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"query": "Create a short summary",
"history": []
}'Trigger Agentic Workflow
POST /api/tenant/agentic-workflows/:workflowId/runStarts an agentic workflow run from your own systems. You authenticate with a workflow API token, which you generate per workflow in the platform under Agentic Workflows. Whatever you put in the request body becomes the workflow input.
Headers:
Authorization: Bearer YOUR_WORKFLOW_TOKEN
Content-Type: application/jsonRequest Body (Optional):
{
"orderId": "12345",
"reason": "customer request"
}Any JSON object. It is handed to the workflow run as input.
Response:
{
"executionId": "exec-9f2c1a",
"workflowId": "wf-12345",
"status": "queued",
"input": { "orderId": "12345", "reason": "customer request" }
}The run executes in the background. Results and the full run history are visible in the platform.
Example:
curl --location 'https://platform.blits.ai/api/tenant/agentic-workflows/{{workflowId}}/run' \
--header 'Authorization: Bearer YOUR_WORKFLOW_TOKEN' \
--header 'Content-Type: application/json' \
--data '{ "orderId": "12345" }'Tenant Metering (Usage & Billing)
GET /api/public/tenant/:tenantId/interactionsReturns the metered interaction counts and billing figures of a tenant, so you can feed them into your own reporting or billing. With no query parameters you get the current billable period, the same window you see under Configuration → Subscription in the platform.
Headers:
x-blits-metering-key: YOUR_METERING_KEYThe metering key is issued by Blits.ai. Contact support to receive one for your organization.
Query Parameters:
| Parameter | Required | Description |
|---|---|---|
rolling | No | Set to true to request the current billable period explicitly (the default behavior) |
month + year | No | A specific calendar month, for example month=4&year=2026 |
startDate + endDate | No | A custom date range, for example startDate=2026-04-01&endDate=2026-04-30 |
Use one mode at a time: rolling, month and year, or a date range.
Response:
{
"tenantId": "tenant-123",
"usageWindow": "subscription_tab",
"interactions": 12480,
"interactionMetrics": {
"botInteractions": 9200,
"agentInteractions": 2400,
"workflowInteractions": 560,
"knowledgeBaseInteractions": 320
},
"hasInteractionDomainBreakdown": true,
"subscriptionAdditionalCharges": { "monthlySubscriptionFeeEur": 1500, "maxFreeInteractions": 10000 },
"billing": {
"licenseFeeEur": 1500,
"interactionOverageEur": 248.0,
"totalAdditionalChargesEur": 248.0,
"totalPeriodEur": 1748.0
}
}Example:
curl --location 'https://platform.blits.ai/api/public/tenant/{{tenantId}}/interactions?month=4&year=2026' \
--header 'x-blits-metering-key: YOUR_METERING_KEY'MCP Server (Hosted)
POST /api/mcp/:serverIdEach hosted MCP server you create in the platform has its own URL. External MCP clients (Claude, IDEs, other agent platforms) connect there and see the same tools your own agents use. The endpoint speaks the MCP Streamable HTTP profile: send JSON RPC messages via POST and receive JSON responses.
Headers:
Authorization: Bearer YOUR_MCP_SERVER_KEY
Content-Type: application/json The x-api-key header is accepted as an alternative. Generate the key per MCP server in the platform under Tools.
Example (list tools):
curl --location 'https://platform.blits.ai/api/mcp/{{serverId}}' \
--header 'Authorization: Bearer YOUR_MCP_SERVER_KEY' \
--header 'Content-Type: application/json' \
--data '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }'A2A Agent Endpoint (Agent2Agent)
GET /api/a2a/:publicationId/.well-known/agent-card.jsonPOST /api/a2a/:publicationId/api/a2a/:publicationId/v1/... Agents published over the Agent2Agent (A2A) protocol get their own endpoint. The agent card is public for discovery and needs no key. Messages go through the JSON RPC binding (such as message/send and streaming) or the HTTP and JSON binding under /v1/.
Headers (message endpoints):
Authorization: Bearer YOUR_A2A_KEY
Content-Type: application/json The x-api-key header is accepted as an alternative. The key is generated in the platform when you publish the agent.
https://platform.blits.ai/api/a2a/<publicationId>/ (with the trailing slash, because SDK clients resolve the agent card relative to it) and it finds the bindings and capabilities by itself. Example (fetch the agent card):
curl --location 'https://platform.blits.ai/api/a2a/{{publicationId}}/.well-known/agent-card.json'Response Formats
- • With
speech-response: false(default) you get JSON with the text reply - • With
speech-response: trueandtext-response: falseyou get audio/mp3 binary - • With
speech-response: trueandtext-response: trueyou get multipart/mixed (JSON and audio) - • Maximum file upload size: 10 MB
WebSocket API
The WebSocket API keeps a two way connection open between your application and Blits.ai. Use it for voice apps, live chat and any case where you want the answer streamed as it is produced.
Connection
Connect to the WebSocket server at the general endpoint:
wss://platform.blits.ai/After you connect, the server sends an acknowledgment first. Only then can you send commands. For regional endpoints, see the for details.
NLU Analysis (REST)
To pull intents and entities from a message without opening a WebSocket conversation, call the REST endpoint:
GET /api/external/analyze-message?message=...Audio Formats: Streaming vs Files
You can send audio in two ways, and each one expects a different format:
Sending Complete Audio Files
For a whole audio file (sent over the REST API, or with the WebSocket message command and speechData):
- Supported formats:
WAVandMP3 - Send the whole file, base64 encoded or as binary
- Use it for recorded audio, file uploads and batch jobs
- We detect the format from the Content-Type header or the file content
Streaming Audio (Real Time)
For audio streamed in chunks while the user talks (WebSocket streamUserSpeech command):
- Input format: Raw PCM audio chunks (typically PCM16)
- Keep sending small chunks for as long as the user speaks
- Use it for live voice input, live transcription and spoken back and forth
- Transcription updates come back while the user is still speaking
Receiving Audio Responses (TTS)
Audio replies from the bot arrive like this:
- Streaming mode: PCM16 format chunks via
generateSpeechevents - Without streaming: one file in the format named in
speechDataFormat(usually "mp3" or "wav") - You switch streaming on in the bot settings, or with
enableStreamingin the initialize command
Available Commands
initialize
Required FirstOpens a new conversation session. Send it first, right after you connect.
Request:
{
"command": "initialize",
"authToken": "{{authToken}}",
"conversationId": "optional-existing-conversation-id",
"userId": "optional-user-identifier",
"environment": "production",
"setCurrentLanguageTo": "en",
"enableStreaming": true,
"requestId": "optional-request-id"
}Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
command | string | Yes | Must be "initialize" |
authToken | string | Yes | Your API authentication token (JWT) |
conversationId | string | No | Reconnects to an existing conversation. Without it, you get a new conversation |
userId | string | No | Your own user identifier. If you leave it out, we generate a random hash |
environment | string | No | "test" or "production" (default: "production") |
setCurrentLanguageTo | string | No | Language code for speech recognition and TTS (e.g., "en", "ar", "nl") |
enableStreaming | boolean | No | Overrides the streaming setting of the bot. true turns on streaming TTS (you get PCM16 audio chunks), false turns it off. Leave it out and the bot settings from the platform apply. |
requestId | string | No | Optional identifier for matching each response to its request |
channel | string | No | Optional client declared channel label, so a custom surface gets its own channel in analytics. The value is mapped through a backend allowlist; unknown values keep the default channel. |
Response:
{
"command": "initialize",
"conversationId": "c2dc951f-9631-44ef-9826-abcd1234efgh",
"botId": "bot-12345",
"userId": "user-67890",
"channel": "externalApi",
"currentLanguage": "en",
"availableLanguages": ["en", "ar", "es", "nl"],
"chatHistory": [],
"supportsSttStreaming": true,
"requestId": "optional-request-id"
}message
Core CommandSends a text or voice message to the AI and returns its reply.
Request (Text Message):
{
"command": "message",
"authToken": "{{authToken}}",
"conversationId": "{{conversationId}}",
"message": "Hello, how can you help me?",
"speechResponse": false,
"type": "NEW",
"requestId": "msg-001"
}Request (Voice Message):
{
"command": "message",
"authToken": "{{authToken}}",
"conversationId": "{{conversationId}}",
"speechData": "base64-encoded-audio-data",
"speechResponse": true,
"requestId": "msg-002"
}Key Parameters:
| Parameter | Type | Description |
|---|---|---|
message | string | Text message to send (required if speechData not provided) |
speechData | string | A whole audio file (WAV or MP3), base64 encoded. Use it for recorded audio. To stream audio while the user talks, use the streamUserSpeech command instead. |
speechResponse | boolean | Set to true to get audio back (in speechData) |
type | string | Set to "NEW" to start the welcome dialog |
fileData | string | File attachment, base64 encoded |
fileExtension | string | File extension for fileData (pdf, jpg, png, etc.) |
location | array | GPS coordinates [latitude, longitude] |
llmAdditionalInput | string | Extra context passed to the LLM |
Response:
{
"command": "message",
"conversationId": "{{conversationId}}",
"messageType": "message",
"response": "I can help you with...",
"language": "en-us",
"emotions": ["neutral"],
"speechData": "base64-encoded-audio-response",
"speechDataFormat": "mp3",
"isPartOfMainContent": true,
"requestId": "msg-001"
}speechDataFormatis only present when streaming is off and indicates the audio format (e.g., "mp3", "wav")- When streaming is enabled, audio chunks are sent via
generateSpeechevents in PCM16 format - Streaming is configured in bot settings but can be overridden with
enableStreamingin the initialize command messageTypeis"message"by default and"error"for error responses. Use it to render error bubbles separately.
streamUserSpeech
Streaming STT Streams audio chunks for speech to text while the user is talking. Use it for live voice input. Whole audio files go through the message command instead.
- streamUserSpeech: raw PCM audio chunks, sent while the user speaks (for live transcription)
- message with speechData: a whole WAV/MP3 file, base64 encoded (for recorded audio)
Request:
{
"command": "streamUserSpeech",
"authToken": "{{authToken}}",
"conversationId": "{{conversationId}}",
"chunk": "base64-encoded-audio-chunk",
"isFinal": false,
"requestId": "stream-001"
}- The
chunkshould contain raw PCM audio data (typically PCM16 format) - Send small chunks at a steady pace (e.g., every 100-500ms) while the user speaks
- Whole WAV/MP3 files do not go here. Send those with the
messagecommand andspeechData
Response (Live Transcription):
{
"command": "streamUserSpeech",
"conversationId": "{{conversationId}}",
"transcript": "Hello, I would like...",
"isFinal": false
}Note: Set isFinal: true in the request when the audio stream ends. The response then carries the final transcription with isFinal: true.
isActive
Tells you whether the bot is busy with a message or waiting for the user.
Request:
{
"command": "isActive",
"authToken": "{{authToken}}",
"conversationId": "{{conversationId}}",
"requestId": "active-check-001"
}Response:
{
"command": "isActive",
"active": true,
"requestId": "active-check-001"
}loadHistory
Returns the conversation history of one user.
Request:
{
"command": "loadHistory",
"authToken": "{{authToken}}",
"conversationId": "{{conversationId}}",
"userId": "user-12345",
"requestId": "history-001"
}Response:
{
"command": "loadHistory",
"conversationId": "{{conversationId}}",
"chatHistory": [
{
"type": "user",
"message": "Hello",
"timestamp": "2024-01-15T10:30:00Z"
},
{
"type": "bot",
"message": "Hi! How can I help you?",
"timestamp": "2024-01-15T10:30:01Z"
}
]
}deleteHistory
Deletes the conversation history of one user, one conversation, or both. It does the same as the REST /api/external/erase endpoint.
Request:
{
"command": "deleteHistory",
"authToken": "{{authToken}}",
"conversationId": "{{conversationId}}",
"userId": "user-12345",
"requestId": "delete-001"
}Response:
{
"command": "deleteHistory",
"conversationId": "{{conversationId}}",
"userId": "user-12345",
"requestId": "delete-001"
}stateVariables
Sets state variables on the conversation, so the bot can use them as context.
Request:
{
"command": "stateVariables",
"authToken": "{{authToken}}",
"conversationId": "{{conversationId}}",
"userId": "user-12345",
"variables": {
"customerName": "John Doe",
"accountNumber": "ACC-123456",
"preferredLanguage": "en"
},
"requestId": "vars-001"
}Response:
{
"command": "stateVariables"
}debug
DevelopmentReturns the full conversation state and the bot settings, for debugging.
Request:
{
"command": "debug",
"authToken": "{{authToken}}",
"conversationId": "{{conversationId}}",
"userId": "user-12345",
"requestId": "debug-001"
}Response:
{
"command": "debug",
"conversationId": "{{conversationId}}",
"state": {
"id": "{{conversationId}}",
"botId": "bot-12345",
"currentLanguage": "en",
"variables": {},
"_ts": 1705315200
},
"botSettings": {
"speechToTextStreaming": true,
"splitSpeechAndText": false
}
}Special Response Events
recognizeSpeech
Sent as soon as voice input is recognized. It carries the transcribed text, before the AI starts on its answer.
Response:
{
"command": "recognizeSpeech",
"requestMessage": "What is the weather today?",
"requestId": "msg-002"
}generateSpeech / generateSpeechDone
Carries streamed TTS audio when streaming is on (set with enableStreaming: true in initialize, or in the bot settings).
Speech Chunk Response:
{
"command": "generateSpeech",
"speechDataChunk": "base64-audio-chunk",
"format": "pcm16",
"sampleRate": 24000,
"responseId": "tts-123",
"requestId": "msg-001"
}sampleRate field gives the sample rate in Hz (usually 24000), which you need to play it back at the right speed. Completion Response:
{
"command": "generateSpeechDone"
}statusUpdate
Status messages sent while the bot is still working on a reply.
Response:
{
"command": "statusUpdate",
"response": {
"status": "processing",
"message": "Analyzing your request..."
}
}awaitingUserInput
Sent when the bot has finished its reply and is waiting for the user again.
Response:
{
"command": "awaitingUserInput",
"requestId": "qKvznGR4h2cXwITJ"
}Additional message fields
Bot messages and the initialize response can carry these optional fields:
sources (source citations):
When source citations are enabled on the agent, answers grounded in the knowledge base include the sources they cite. Citations are also replayed with the chat history on reconnect.
{
"sources": [
{
"kind": "file",
"title": "Pricing sheet 2026.pdf",
"link": "https://...",
"linkKind": "signed",
"date": "2026-06-01T00:00:00.000Z",
"score": 0.91
}
]
}sender: "agent" (live agent handover):
When a human agent takes over the conversation, messages written by the agent carry "sender": "agent" so your client can render them distinctly from bot messages.
hideSpeechTranscript (initialize response):
When the bot is configured to hide voice transcripts, the initialize response contains "hideSpeechTranscript": true. Clients should then show a voice message placeholder instead of the recognized text.
Error Handling
An error comes back as a JSON object with a readable message:
{
"error": "External API timed out",
"errorHint": "conversationId expired. Initialize a new conversation",
"active": false,
"conversationId": "{{conversationId}}"
}API Endpoints
Blits.ai runs a regional endpoint in each of its six managed regions: the EU, Qatar, Singapore, the UAE, the US and Australia. Pick the one closest to your users, or use the general endpoint and let it route requests for you.
General Endpoint
The general endpoint sends each request to the best server for your location. Unless you have a reason to pick a region, use this one.
REST API
https://platform.blits.aiWebSocket API
wss://platform.blits.ai/Regional Endpoints
If your data has to stay in a certain region, for example for data residency rules, use the regional endpoint for that region. In any other country, Blits.ai runs in your private cloud or fully on premises.
🇪🇺 Europe
Hosted in EU data centers
https://eu.platform.blits.aiwss://eu.platform.blits.ai/🇶🇦 Qatar
Hosted in Qatar data centers
https://qa.platform.blits.ai/wss://qa.platform.blits.ai/🇸🇬 Singapore
Hosted in Singapore data centers
https://sg.platform.blits.ai/wss://sg.platform.blits.ai/🇦🇪 United Arab Emirates
Hosted in UAE data centers
https://uae.platform.blits.ai/wss://uae.platform.blits.ai/🇺🇸 United States
Hosted in US data centers
https://us.platform.blits.aiwss://us.platform.blits.ai/🇦🇺 Australia
Hosted in Australian data centers
https://au.platform.blits.ai/wss://au.platform.blits.ai/Performance Tips
- • The general endpoint routes for you and gives the best performance overall
- • Pick a regional endpoint when you have data residency requirements
- • With a regional endpoint, your data stays in that region
- • Every endpoint has the same features and the same API
- • Latency is usually lowest on the endpoint nearest your users
Authentication
Every API request needs a JWT (JSON Web Token). Send your token with each call.
Getting Your API Token
- Log in to your Blits.ai dashboard
- Navigate to Bot Settings → Configuration → API Channel (for bot tokens) or Agent Settings (for agent tokens)
- Press the ... button and select "settings"
- Generate a new API key or copy an existing one
- Keep the API key somewhere safe
Token Types
There are bot tokens and agent tokens. Both are JWTs and you send them the same way.
Bot Token
Used for bot endpoints such as /api/external/* and bot widget sessions.
Agent Token
Used for Agent endpoints such as /api/llm/run.
{
"llmId": "800-7193e98f-df24-4b99-8de8-988bf1a0683c",
"type": "llm"
}Using Authentication
REST API
Put the token in the Authorization header:
Authorization: Bearer YOUR_JWT_TOKENWebSocket API
Put the token in the authToken field of each command:
{
"command": "initialize",
"authToken": "YOUR_JWT_TOKEN",
...
}Security Tips
- • The API token only gives access to bot conversations
- • Rotate your API keys regularly
- • Keep an eye on your API usage for anything unusual
Integration Examples
Working code to copy for your first Blits.ai API calls.
Embed Chat Widget on Your Website
Paste one snippet into your HTML and our ready made chat widget shows up on your site. It is the fastest way to add Blits.ai.
Quick Embed Code
Add this code snippet to your website's HTML, preferably just before the closing </body> tag:
<!-- Blits.ai Chat Widget -->
<script defer src="https://platform.blits.ai/assets/chat-widget.js"></script>
<script>
window.addEventListener('load', function () {
window.ChatWidget.mount({
token: "YOUR_API_TOKEN",
code: "YOUR_BUBBLE_CODE",
backendUrl: "https://platform.blits.ai",
websocketUrl: "wss://platform.blits.ai",
debug: false
});
});
</script>Chat Widget Configuration
The ChatWidget.mount() function accepts the following configuration options:
| Parameter | Type | Required | Description |
|---|---|---|---|
token | string | Yes | The API JWT token you copied from Bot Settings |
code | string | Yes | Your chat bubble unique code from Bot Settings → Configuration → Chat Bubble |
backendUrl | string | Yes | Backend URL (use general endpoint or regional: eu, qa, sg, uae, us, au) |
websocketUrl | string | Yes | WebSocket URL (wss://platform.blits.ai or regional) |
debug | boolean | No | Enable debug mode for console logging (default: false) |
- Login to platform.blits.ai
- Navigate to Bot Settings → Configuration → Chat Bubble
- Create a new chat bubble or select an existing one
- Copy the API token and bubble code from the settings
- Paste them into the embed code above
Chat Widget Customization
Look and behavior of the widget are managed in the Blits.ai Platform dashboard. You can change the following there:
Appearance
- • Custom bot avatar
- • Chat bubble icon
- • Main color theme
- • Text color customization
- • Title and branding
Behavior
- • Bubble position (top/bottom, left/right/center)
- • Screen size (big/small)
- • Microphone enable/disable
- • File upload button
- • Popup messages
Security
- • Authorized origins whitelist
- • Domain restrictions
- • CORS configuration
Features
- • Voice interaction support
- • Support for multiple languages
- • File/image sharing
- • Notification messages
- • Button activation mode
JavaScript / Node.js WebSocket Client
const WebSocket = require('ws');
const API_TOKEN = 'your-jwt-token-here';
// Use general endpoint (recommended) or choose a regional endpoint
const WS_URL = 'wss://platform.blits.ai/'; // or eu, us, uae
// Connect to WebSocket
const ws = new WebSocket(WS_URL);
ws.on('open', () => {
console.log('Connected to Blits.ai');
// Initialize conversation
ws.send(JSON.stringify({
command: 'initialize',
authToken: API_TOKEN,
userId: 'user-123',
setCurrentLanguageTo: 'en',
enableStreaming: false
}));
});
ws.on('message', (data) => {
const response = JSON.parse(data.toString());
console.log('Received:', response);
if (response.command === 'initialize') {
console.log('Conversation ID:', response.conversationId);
// Send a message
ws.send(JSON.stringify({
command: 'message',
authToken: API_TOKEN,
conversationId: response.conversationId,
message: 'Hello! How are you today?',
speechResponse: false,
requestId: 'msg-001'
}));
}
if (response.command === 'message') {
console.log('Bot response:', response.response);
}
});
ws.on('error', (error) => {
console.error('WebSocket error:', error);
});
ws.on('close', () => {
console.log('Disconnected from Blits.ai');
});Python WebSocket Client
import asyncio
import websockets
import json
API_TOKEN = 'your-jwt-token-here'
# Use general endpoint (recommended) or choose a regional endpoint
WS_URL = 'wss://platform.blits.ai/' # or eu, us, uae
async def chat_with_blits():
async with websockets.connect(WS_URL) as ws:
print('Connected to Blits.ai')
# Wait for connection acknowledgment
connect_msg = await ws.recv()
print('Connection:', json.loads(connect_msg))
# Initialize conversation
await ws.send(json.dumps({
'command': 'initialize',
'authToken': API_TOKEN,
'userId': 'user-123',
'setCurrentLanguageTo': 'en'
}))
init_response = json.loads(await ws.recv())
print('Initialized:', init_response)
conversation_id = init_response['conversationId']
# Send a message
await ws.send(json.dumps({
'command': 'message',
'authToken': API_TOKEN,
'conversationId': conversation_id,
'message': 'Hello! How are you today?',
'speechResponse': False,
'requestId': 'msg-001'
}))
message_response = json.loads(await ws.recv())
print('Bot response:', message_response['response'])
# Run the async function
asyncio.run(chat_with_blits())Browser JavaScript Example
class BlitsClient {
constructor(apiToken, endpoint = 'platform.blits.ai') {
this.apiToken = apiToken;
this.ws = null;
this.conversationId = null;
this.endpoint = endpoint;
}
connect() {
return new Promise((resolve, reject) => {
// Use general endpoint or regional: eu.platform.blits.ai, us.platform.blits.ai, etc.
const wsUrl = `wss://${this.endpoint}/`;
this.ws = new WebSocket(wsUrl);
this.ws.onopen = () => {
console.log('Connected to Blits.ai');
resolve();
};
this.ws.onmessage = (event) => {
const response = JSON.parse(event.data);
this.handleMessage(response);
};
this.ws.onerror = (error) => {
console.error('WebSocket error:', error);
reject(error);
};
});
}
async initialize(userId = 'web-user') {
return new Promise((resolve) => {
const initHandler = (response) => {
if (response.command === 'initialize') {
this.conversationId = response.conversationId;
resolve(response);
}
};
this.messageHandlers.push(initHandler);
this.ws.send(JSON.stringify({
command: 'initialize',
authToken: this.apiToken,
userId: userId,
setCurrentLanguageTo: 'en'
}));
});
}
sendMessage(text, options = {}) {
return new Promise((resolve) => {
const messageHandler = (response) => {
if (response.command === 'message' &&
response.requestId === options.requestId) {
resolve(response);
}
};
this.messageHandlers.push(messageHandler);
this.ws.send(JSON.stringify({
command: 'message',
authToken: this.apiToken,
conversationId: this.conversationId,
message: text,
speechResponse: options.speechResponse || false,
requestId: options.requestId || Date.now().toString()
}));
});
}
handleMessage(response) {
console.log('Received:', response);
this.messageHandlers.forEach(handler => handler(response));
}
}
// Usage
// Use general endpoint (recommended) or specify regional endpoint
const client = new BlitsClient('your-jwt-token', 'platform.blits.ai');
// Or use regional: 'eu.platform.blits.ai', 'us.platform.blits.ai', etc.
await client.connect();
await client.initialize('user-123');
const response = await client.sendMessage('Hello!');
console.log('Bot said:', response.response);Voice Message Example (Browser)
// Record audio and send complete file to Blits.ai
// Note: This example sends a complete audio file (WAV or MP3).
// For real-time streaming transcription, use the streamUserSpeech command instead.
async function recordAndSend() {
// Get microphone access
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const mediaRecorder = new MediaRecorder(stream);
const audioChunks = [];
mediaRecorder.ondataavailable = (event) => {
audioChunks.push(event.data);
};
mediaRecorder.onstop = async () => {
// Create blob from chunks (WAV or MP3 format)
// MediaRecorder typically produces WebM, but you can convert to WAV/MP3
const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
// Convert to base64
const reader = new FileReader();
reader.readAsDataURL(audioBlob);
reader.onloadend = () => {
const base64Audio = reader.result.split(',')[1];
// Send complete audio file to Blits.ai
// Supports both WAV and MP3 formats
ws.send(JSON.stringify({
command: 'message',
authToken: API_TOKEN,
conversationId: conversationId,
speechData: base64Audio, // Base64-encoded WAV or MP3 file
speechResponse: true,
requestId: 'voice-msg-001'
}));
};
};
// Start recording
mediaRecorder.start();
console.log('Recording...');
// Stop after 5 seconds (or when user stops)
setTimeout(() => {
mediaRecorder.stop();
console.log('Recording stopped');
stream.getTracks().forEach(track => track.stop());
}, 5000);
}
// Handle voice response
ws.onmessage = (event) => {
const response = JSON.parse(event.data);
if (response.command === 'message' && response.speechData) {
// Play audio response
const audio = new Audio('data:audio/mp3;base64,' + response.speechData);
audio.play();
// Also show text
console.log('Bot said:', response.response);
}
};Need API Access?
Sign up for a Blits.ai account, get your API credentials and make your first call.