API Reference
Use the Clawbite chat API to send messages to a specific agent over REST or streaming.
Authentication
API access is controlled per agent. Turn on API access in the dashboard, then create an API key and send it in the Authorization header.
Authorization: Bearer clawbite_sk_...
Missing or malformed auth headers return 401. Revoked or invalid keys also return 401.
Endpoint
POST https://clawbite.com/api/v1/bot/{botId}/chatThe API uses your agent's botId. You can find it in the dashboard. The endpoint accepts CORS preflight requests and supports both standard JSON and SSE streaming responses.
Request Body
{
"messages": [
{ "role": "user", "content": "Hello, what can you do?" }
],
"stream": false,
"model": "anthropic/claude-sonnet-4-6",
"user": "customer-123"
}messages — Required. Must be a non-empty array of message objects.
role — Must be one of user, assistant, or system.
content — Required string content for each message.
stream — Optional. Set to true for Server-Sent Events streaming. Defaults to false.
model — Optional. Overrides the agent's current model for this request.
user — Optional passthrough identifier you can attach to the request.
The request body is limited to 100KB. Invalid or empty messages arrays return 400 invalid_request.
Response
Non-streaming responses use an OpenAI-style chat completions shape.
{
"id": "chatcmpl-...",
"object": "chat.completion",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "I can help you with..."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 48,
"total_tokens": 60
}
}Streaming
With stream: true, the endpoint returns text/event-stream. Each chunk contains a delta, followed by [DONE].
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"I "}}]}
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"can "}}]}
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"help"}}]}
data: [DONE]Some 429 responses may also include retry_after when the route can tell you how long to wait.
Error Codes
| Status | Code | Meaning |
|---|---|---|
| 401 | missing_api_key | Missing or malformed Authorization header |
| 401 | invalid_api_key / invalid_api_key_format | Invalid, revoked, or badly formatted API key |
| 403 | api_not_enabled | API access is turned off for this agent |
| 404 | bot_not_found | Bot not found or the key does not have access |
| 400 | invalid_request | Missing fields, empty messages array, or invalid roles |
| 413 | request_too_large | Request body is larger than 100KB |
| 429 | rate_limited / concurrent_limit / bot_rate_limited | User-level or agent-level rate/concurrency limits were hit |
| 503 | bot_offline / container_error | The agent is unavailable or the container could not be reached |
| 504 | timeout | The upstream request timed out after about 130 seconds |
| 500 | internal_error | Unexpected server-side error |
Examples
Curl
curl -X POST https://clawbite.com/api/v1/bot/YOUR_BOT_ID/chat \
-H "Authorization: Bearer clawbite_sk_..." \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "user", "content": "Hello!"}
],
"stream": false
}'JavaScript (streaming)
const res = await fetch("https://clawbite.com/api/v1/bot/YOUR_BOT_ID/chat", {
method: "POST",
headers: {
"Authorization": "Bearer clawbite_sk_...",
"Content-Type": "application/json"
},
body: JSON.stringify({
messages: [{ role: "user", content: "Hello!" }],
stream: true
})
});
const reader = res.body?.getReader();
const decoder = new TextDecoder();
while (reader) {
const { done, value } = await reader.read();
if (done) break;
console.log(decoder.decode(value));
}For a complete Node.js test script with streaming, non-streaming, and browser examples, see the API test script on GitHub.