POST /api/v1/chat

/ Send a message. Get back the reply, streamed, plus signals about what the customer wants.

Request

FieldTypeRequiredDescription
agentIdstringYesThe agent's public ID
messagestringYesThe customer's message. 4,000 characters max
sessionIdstringNoYour own ID for this browser session. Auto-generated if omitted
visitorIdstringNoStable hashed ID for a known user. Enables cross-session memory on Scale and Delegate plans. 1 to 255 characters
historyarrayNo{ role: "user" | "assistant", content: string }[]. Last 10 turns used, the rest dropped
const res = await fetch("https://app.humaner.ai/api/v1/chat", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    agentId: "ag_demo123",
    sessionId: crypto.randomUUID(),
    message: "Where is my order?",
  }),
});

// Responses stream as SSE — { delta } chunks

Response: SSE stream

The response is text/event-stream. Each event is JSON on a "data:" line. Render text as delta events arrive, then read the final event for usage, metadata, and handoff.

Event 1..N: text deltas

data: {"delta":"Your order shipped "}

data: {"delta":"this morning..."}

Final event

{
  "usage": {
    "inputTokens": 1240,
    "outputTokens": 87,
    "grounded": true,
    "sessionId": "sess_xxx",
    "visitorId": null,
    "model": "claude-sonnet-4-6",
    "routedModel": "sonnet",
    "cacheHit": false,
    "langCacheSimilarity": 0.72,
    "cacheReadInputTokens": 890,
    "cacheCreationInputTokens": null
  },
  "metadata": {
    "intent": "order_status",
    "confidence": 0.94,
    "escalate": false,
    "urgency": "low",
    "medicalTopic": false,
    "cancellationIntent": false,
    "suggestedProductId": null,
    "bookingContext": null,
    "modelUsed": "sonnet",
    "cacheHit": false,
    "verticalVersion": "1.2.0"
  },
  "handoff": null
}

Terminal event

data: [DONE]

Reading metadata

FieldWhen setWhat to do
intentAlways. One of a per-vertical taxonomy (order_status, return_request, etc.)Render UI for the intent, or ignore it
suggestedProductIdRetail. An upsell was identifiedShow a cross-sell card, or ignore it
escalate: trueThe turn was ungrounded, or the model asked for a handoffCheck the handoff object. A ticket may already exist
cancellationIntent: trueThe customer wants to cancelTrigger your own retention flow
bookingContextDates, room, or class details were extractedPre-fill your booking flow
urgency: "critical"Emergency pattern matchAlert your team now
medicalTopic: trueA medical question (Wellness vertical)Add a disclaimer in your own UI

The handoff object

Non-null only when the agent could not resolve the turn. Shape: { humanDesk: boolean, email: string | null }. humanDesk is true when a ticket-creation flow should show, which needs Human Desk enabled on a Refined+ plan. email is a fallback contact address.

Errors

StatusMeaning
400Invalid JSON body, or agentId / message missing
401Missing or invalid API key, or no Origin header and no key
403Origin not on the allowed-domains list, or the plan lacks API access
404Agent not found
413message over 4,000 characters
429Message quota exceeded, or rate limit hit (Retry-After header set)
502The model call failed
503Anthropic not configured, or the model is temporarily overloaded