Skip to content
Skip to content

Chat API

The Chat API lets you send messages to your deployed AI agents and receive responses programmatically. It supports both synchronous responses and real-time streaming via Server-Sent Events.

Endpoint

POST /api/v1/chat

Authentication

Requires a valid API key passed as a Bearer token. See the Authentication docs for details.

Authorization: Bearer clw_your_api_key_here

Request Parameters

ParameterTypeRequiredDescription
messagestringYesThe user message to send. Maximum size: 100KB.
agentstringNoSlug or ID of the agent to handle the message. Defaults to the first deployed agent.
session_idstringNoAlphanumeric identifier for conversation continuity. Max 128 characters. Messages with the same session_id share conversation history.
streambooleanNoSet to true to receive the response as a real-time SSE stream. Defaults to false.

Standard Response

When stream is false (the default), the API returns a complete JSON response once the agent finishes generating:

{
  "response": "I can help you with that. Here's what you need to know...",
  "agent": "support-bot",
  "request_id": "req_abc123def456"
}

Streaming Response

When stream is true, the API returns a text/event-stream response. Each chunk of the agent's response is sent as an SSE event:

data: {"content": "I can "}

data: {"content": "help you "}

data: {"content": "with that."}

data: [DONE]

The stream ends with data: [DONE] to signal completion. Concatenate allcontent values to reconstruct the full response.

Error Codes

StatusCodeDescription
400BAD_REQUESTMissing or invalid message parameter, or message exceeds 100KB
401INVALID_KEYAPI key is missing, malformed, or revoked
403PLAN_REQUIREDAccount does not have an active Pro or Ultra plan
404AGENT_NOT_FOUNDThe specified agent slug or ID does not exist or is not deployed
429RATE_LIMITEDKey has exceeded its requests-per-minute limit. Check the Retry-After header.
502AGENT_ERRORThe agent encountered an internal error while processing the message
504TIMEOUTThe agent did not respond within the timeout window (60 seconds)

Code Examples

cURL — Standard Request

curl -X POST https://app.clawhq.tech/api/v1/chat \
  -H "Authorization: Bearer clw_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "What are your business hours?",
    "agent": "support-bot",
    "session_id": "user_12345"
  }'

cURL — Streaming Request

curl -X POST https://app.clawhq.tech/api/v1/chat \
  -H "Authorization: Bearer clw_your_api_key_here" \
  -H "Content-Type: application/json" \
  -N \
  -d '{
    "message": "Explain your return policy",
    "stream": true
  }'

Python (requests)

import requests

API_KEY = "clw_your_api_key_here"
BASE_URL = "https://app.clawhq.tech/api/v1"

# Standard request
response = requests.post(
    f"{BASE_URL}/chat",
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    },
    json={
        "message": "What are your business hours?",
        "agent": "support-bot",
        "session_id": "user_12345",
    },
)

data = response.json()
print(data["response"])

# Streaming request
response = requests.post(
    f"{BASE_URL}/chat",
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    },
    json={
        "message": "Explain your return policy",
        "stream": True,
    },
    stream=True,
)

for line in response.iter_lines():
    if line:
        text = line.decode("utf-8")
        if text.startswith("data: ") and text != "data: [DONE]":
            import json
            chunk = json.loads(text[6:])
            print(chunk["content"], end="", flush=True)

JavaScript (fetch)

const API_KEY = "clw_your_api_key_here";
const BASE_URL = "https://app.clawhq.tech/api/v1";

// Standard request
const response = await fetch(`${BASE_URL}/chat`, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    message: "What are your business hours?",
    agent: "support-bot",
    session_id: "user_12345",
  }),
});

const data = await response.json();
console.log(data.response);

// Streaming request
const stream = await fetch(`${BASE_URL}/chat`, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    message: "Explain your return policy",
    stream: true,
  }),
});

const reader = stream.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  const text = decoder.decode(value);
  for (const line of text.split("\n")) {
    if (line.startsWith("data: ") && line !== "data: [DONE]") {
      const chunk = JSON.parse(line.slice(6));
      process.stdout.write(chunk.content);
    }
  }
}

Tip: Use session_id to maintain conversation context across multiple requests. The agent will remember previous messages within the same session, enabling natural multi-turn conversations.

Next Steps