API reference
Chat
One guarded turn with an agent, as plain JSON or streamed as server-sent events, and the answers to client tools.
POST /agents/{agent_id}/chat
Chat with an agent
Send the visitor's message and get the agent's answer. With "stream": true the answer arrives as server-sent events (delta, sources, outcome, done, or error), the same events the website widget receives, with a : keep-alive comment line while the agent is thinking. A new conversation counts against the workspace's monthly conversations the moment it gets its first answer; when the month is full the agent answers with its capacity note and limit is monthly. Twenty chat calls per key per minute. Idempotency-Key is honoured on the plain call; a stream cannot be replayed, so a streamed call ignores it. With contact, a conversation proven to be one person's is never continued as another's: that call answers 409 identity_mismatch and no turn runs.
Scope: chat
Parameters
agent_idrequired in the path ·string
Request body
messagesrequiredChatMessage[]The last entry must be the visitor's new message (role user). Earlier entries are ignored when conversation_id is set: the stored conversation is the context.
conversation_idoptionalstringContinue this conversation; omit to start one.
conversation_tokenoptionalstringWith a publishable key: the
conversation_tokenthe conversation's first answer gave. Required to continue it (the id alone answers 404 conversation_not_found), because a publishable key ships inside the app and conversation ids are not secret.streamoptionalbooleantrue answers text/event-stream.
localeoptionalstringReserved: a hint for the reply language.
contactoptionalobjectWho the visitor is, in either identity shape: {"token": a JWT signed with the agent's identity secret} or {"user_id", "user_hash"}. Verified, it links the conversation to that contact (and its memory); one that does not verify answers 401 identity_rejected. A conversation proven to be one person's is never continued as another: send a different verified contact with its conversation_id and the call answers 409 identity_mismatch (omit conversation_id to start that person's own conversation).
client_toolsoptionalstring[]The client tools your app can run (snake_case names, up to 20). Only the owner's declared client tools among them are offered, and only on a streamed call: the agent asks with a
client_toolevent and your app answers on POST /agents/{agent_id}/chat/tool-results.
Returns ChatResponse
conversation_idrequiredstringSend it back to continue this conversation.
conversation_tokenoptionalstringPublishable keys only, on the answer that starts a conversation: send it back with conversation_id to continue it. Shown once; keep it with the id.
messageoptionalChatMessageOutThe agent's answer; null when a person has taken over.
outcomeoptionalstringOutcome
refusedrequiredbooleanRefused
sourcesrequired[]Sources
stateoptionalstringState
lead_capturedrequiredbooleanLead Captured
limitoptionalstringmonthlywhen the month's conversations are used up.degradedrequiredbooleanDegraded
Responses
200The answer.application/jsonby default;text/event-streamwhenstreamis true.401Missing, invalid, revoked or expired key. Leaving the workspace, or being removed from it, revokes the keys a teammate made; a key whose maker's membership ended any other way answerskey_maker_left.403The plan has no API, the key lacks the scope, or the role of the teammate who made the key no longer allows it (maker_role_limit; a publishable key saysinsufficient_scope).404Nothing by that id in this workspace.413The request body is larger than this route accepts (1 MB; 3 MB for a text source). On a source:plan_text_limit, the agent's plan cannot hold more text (limit_chars,used_chars).422The request did not validate;detailslists the fields.429Rate limit reached; waitRetry-Afterseconds.500Our fault; quoterequest_idto support.409agent_unavailable: the agent is paused.identity_mismatch: the conversation is another verified contact's; start a new one for this contact.idempotency_in_progress: the first request with this Idempotency-Key is still running.410conversation_expired: the conversation is over; start a new one.503identity_unavailable: the agent's identity secret cannot be read right now, socontactcannot be verified; retry afterRetry-Afterseconds.
curl -X POST https://www.bidii.ai/api/v2/agents/AGENT_ID/chat \
-H "Authorization: Bearer bidi_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"messages": [{"role": "user", "content": "..."}]}'POST /agents/{agent_id}/chat/tool-results
Answer a client tool call
Your app ran the client tool a streamed chat asked for (the client_tool event) and says how it went. Only the conversation the call belongs to can answer it, once, before its timeout_ms; a second answer, or a late one, is 409 call_closed, and a call this conversation never had is 404 unknown_call. Needs the actions feature on the server (404 otherwise).
Scope: chat
Parameters
agent_idrequired in the path ·string
Request body
conversation_idrequiredstringThe conversation the
client_toolevent belongs to.conversation_tokenoptionalstringThe event's
conversation_token(publishable keys).call_idrequiredstringThe event's
call_id.okrequiredbooleanfalse when your tool failed; the agent is told it did not work.
resultoptionalobjectWhat the tool returned, as JSON (at most 8,000 characters). The agent reads it as data, never as instructions.
erroroptionalstringA short reason when ok is false (120 characters are kept).
Returns ChatToolResultOut
okrequiredbooleanOk
Responses
200Successful Response401Missing, invalid, revoked or expired key. Leaving the workspace, or being removed from it, revokes the keys a teammate made; a key whose maker's membership ended any other way answerskey_maker_left.403The plan has no API, the key lacks the scope, or the role of the teammate who made the key no longer allows it (maker_role_limit; a publishable key saysinsufficient_scope).404Nothing by that id in this workspace.413The request body is larger than this route accepts (1 MB; 3 MB for a text source). On a source:plan_text_limit, the agent's plan cannot hold more text (limit_chars,used_chars).422The request did not validate;detailslists the fields.429Rate limit reached; waitRetry-Afterseconds.500Our fault; quoterequest_idto support.409call_closed: the call was already answered or ran out of time.
curl -X POST https://www.bidii.ai/api/v2/agents/AGENT_ID/chat/tool-results \
-H "Authorization: Bearer bidi_sk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"conversation_id": "...", "call_id": "...", "ok": true}'