---
title: "Chat with an AI agent"
method: POST
path: "/api/v1/ai-agents/{id}/chat"
tags: ["ai_agents"]
---

# Chat with an AI agent

`POST /api/v1/ai-agents/{id}/chat`

## Request

- Base URL: `https://app.blueticked.com`
- URL: `https://app.blueticked.com/api/v1/ai-agents/{id}/chat`
- Auth: HTTP bearer

Converse with a live agent from your own surface: the agent as a headless channel.

STATELESS by design: the API stores nothing your end user types. `history` (max 12 turns, oldest first) is everything the agent remembers, and `session_id` survives only as a one-way hash in the billing ledger. Send the prior turns back on every call.

Each reply is charged from the prepaid wallet: R2.50, or its real model cost plus 20% when a very long reply costs more (ai.api_chat, the same price as every AI reply). An empty wallet answers 402 insufficient_balance; the workspace's shared API-chat ceiling (R25 a day of model cost, about 100 typical replies) answers 402 spend_cap_reached and resets at midnight UTC.

`handoff_recommended: true` means the reply scored below the agent's own confidence threshold, the same rule the autonomy ladder applies on WhatsApp. You own the surface, so the handoff is yours to route.

Show `disclosure` to your end user when present. Telling people they are talking to an AI is the merchant's stated policy, and in most jurisdictions the law.

Only a `live` or `testing` agent answers. A paused or draft one returns enable_requires_dashboard: enabling an autonomous responder is a human act.

Browser callers use a PUBLISHABLE key (`blu_pub_…`, minted at Developers → API keys → New widget key, which appears once two-step verification is on): safe to ship in page source because it only works on this endpoint and only from the exact origins it was minted for. The ready-made widget (`<script src="https://app.blueticked.com/widget.js" data-agent="…" data-key="blu_pub_…" async></script>`) is a client of this endpoint, nothing more.

## Path parameters

- `id` string, required

## Request body

- object
  - `message` string, required
  - `session_id` string, required
  - `history` object[]
    - `role` 'customer' | 'agent', required
    - `body` string, required

## Response `200`

Success

- object
  - `ok` boolean, required
  - `reply` string, required
  - `handoff_recommended` boolean, required
  - `disclosure` string, required

## Other responses

- `400`: Validation failed
- `401`: Unauthorized: missing or invalid API key
- `402`: Insufficient wallet balance
- `403`: Forbidden: scope, plan limit, or suspension
- `404`: Not found
- `409`: Conflict (idempotency-key reuse or resource in use)
- `413`: Request body above the endpoint's size limit
- `422`: Understood but refused: the request is well-formed, the action is not permitted for this resource
- `429`: Rate limited
- `500`: Internal error
- `502`: An upstream provider refused or failed the request
- `503`: Channel or send queue unavailable

---

[API](https://skmtc.dev/blueticked/apis/blueticked-api.md) · [All operations](https://skmtc.dev/blueticked/apis/blueticked-api/llms.txt) · [OpenAPI document](https://skmtc.dev/blueticked/apis/blueticked-api/revisions/07132284f4ff?raw)
