Skip to content

Widget

Public chat and web-call widget endpoints (widget tokens only).

GET /api-keys/widget

Lists the active widget tokens of one chat agent by fingerprint (prefix and last 4 characters). The token itself can never be retrieved again. Rate limited (30 requests per minute by default).

Scope: agents:read

Parameters

Name In Type Required Description
organisation_id query string yes Your organisation ID. Must be the key’s own organisation.
agent_id query string yes The chat agent whose tokens to list.

Example request

Terminal window
curl -X GET "https://api.foan.ai/api/v1/api-keys/widget" \
-H "Authorization: Bearer $FOAN_API_KEY"

Response 200

{
"success": true,
"data": {
"keys": [
{
"id": "cmf3k2j9x0006abcd1234efgh",
"name": "Website widget",
"key_prefix": "a1b2c3d4",
"last4": "9f3e",
"scopes": [
"widget:bootstrap"
],
"created_at": "2026-09-20T10:15:30.000Z",
"last_used_at": null,
"revoked_at": null,
"organisation_id": "cmf3k2j9x0001abcd1234efgh",
"agent_id": "cmf3k2j9x0005abcd1234efgh",
"ai_host": null
}
],
"total": 1
}
}

Errors

Code When
400 organisation_id or agent_id missing
401 Missing, invalid or revoked API key, or the key’s owner is deactivated or no longer in the organisation
403 Missing agents:read scope, or organisation_id is not the key’s organisation
429 Rate limited

POST /api-keys/widget

Mints a public widget token (scope widget:bootstrap only) bound to one chat agent, for embedding the chat widget on your website. The key’s owner must be OWNER or ADMIN, the agent must be a CHAT agent in your organisation, and each agent may hold at most 3 active widget tokens. Rate limited (30 requests per minute by default).

Scope: agents:write

Body (application/json)

Field Type Required Description
organisation_id string yes Your organisation ID. Must be the key’s own organisation. Always send it (see notes).
agent_id string yes The CHAT agent the token is for.
name string no Label for the token. Defaults to “Website widget (<agent_id>)”.

Example request

Terminal window
curl -X POST "https://api.foan.ai/api/v1/api-keys/widget" \
-H "Authorization: Bearer $FOAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"organisation_id":"cmf3k2j9x0001abcd1234efgh","agent_id":"cmf3k2j9x0005abcd1234efgh","name":"Website widget"}'

Response 201

{
"success": true,
"data": {
"key": "foan_prod_a1b2c3d4_<32 hex characters>",
"id": "cmf3k2j9x0006abcd1234efgh",
"name": "Website widget",
"key_prefix": "a1b2c3d4",
"last4": "9f3e",
"scopes": [
"widget:bootstrap"
],
"created_at": "2026-09-20T10:15:30.000Z",
"last_used_at": null,
"revoked_at": null
},
"message": "Widget token created. It is public by design and only bootstraps this chat agent. Save it now - you won't be able to see it again."
}

Errors

Code When
400 scopes was passed, agent_id missing, name shorter than 3 or longer than 255 characters, or the agent is not a CHAT agent
401 Missing, invalid or revoked API key, or the key’s owner is deactivated or no longer in the organisation
403 Missing agents:write scope, organisation_id is not the key’s organisation, or the key’s owner is not OWNER/ADMIN
404 Agent not found in this organisation
409 The agent already has 3 active widget tokens; revoke one first
429 Rate limited (body is {success:false, message})

POST /api-keys/widget/revoke

Revokes one widget token of one chat agent. Only bootstrap-only tokens bound to the named agent can be revoked here; management keys are refused. Any member role may revoke. Rate limited (30 requests per minute by default).

Scope: agents:write

Body (application/json)

Field Type Required Description
organisation_id string yes Your organisation ID. Must be the key’s own organisation.
agent_id string yes The chat agent the token belongs to.
key_id string yes ID of the widget token (from the list endpoint).

Example request

Terminal window
curl -X POST "https://api.foan.ai/api/v1/api-keys/widget/revoke" \
-H "Authorization: Bearer $FOAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"organisation_id":"cmf3k2j9x0001abcd1234efgh","agent_id":"cmf3k2j9x0005abcd1234efgh","key_id":"cmf3k2j9x0006abcd1234efgh"}'

Response 200

{
"success": true,
"data": {
"id": "cmf3k2j9x0006abcd1234efgh",
"name": "Website widget",
"key_prefix": "a1b2c3d4",
"last4": "9f3e",
"scopes": [
"widget:bootstrap"
],
"created_at": "2026-09-20T10:15:30.000Z",
"last_used_at": null,
"revoked_at": "2026-09-20T10:15:30.000Z",
"organisation_id": "cmf3k2j9x0001abcd1234efgh",
"agent_id": "cmf3k2j9x0005abcd1234efgh",
"ai_host": null
},
"message": "Widget token revoked. The chat widget will stop loading on any page that still uses it."
}

Errors

Code When
400 organisation_id, agent_id or key_id missing, or the token is already revoked
401 Missing, invalid or revoked API key, or the key’s owner is deactivated or no longer in the organisation
403 Missing agents:write scope, or organisation_id is not the key’s organisation
404 No widget token with that id belongs to this agent (also returned for keys in other organisations and non-widget keys)
429 Rate limited

POST /widget/bootstrap

Returns the configuration the embedded chat widget needs for one CHAT agent in the key’s organisation. When roomName is sent it also opens a chat session (if one with that room name does not exist yet) and returns a 1-hour session token. A token bound to an agent only works for that agent. Rate limited (30 requests per minute by default).

Scope: widget:bootstrap

Body (application/json)

Field Type Required Description
agentId string yes The CHAT agent to load.
participantName string no Visitor’s name. Required when roomName is sent.
phoneNumber string no Visitor’s phone number. Required when roomName is sent.
roomName string no Conversation ID to open or resume a chat session under.
customVariables object no Values merged over the agent’s default custom variables.

Example request

Terminal window
curl -X POST "https://api.foan.ai/api/v1/widget/bootstrap" \
-H "Authorization: Bearer $FOAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agentId":"cmf3k2j9x0005abcd1234efgh","participantName":"Priya Sharma","phoneNumber":"+919876543210","roomName":"chat-7f3a9c2e","customVariables":{"orderId":"A1042"}}'

Response 200

{
"success": true,
"message": "Widget bootstrap successful",
"data": {
"metadata": {
"orgId": "cmf3k2j9x0001abcd1234efgh",
"agentId": "cmf3k2j9x0005abcd1234efgh",
"agentName": "Order confirmation",
"agentIdentity": "You are Nina, a friendly assistant for Sharma Foods.",
"agentTask": "Help visitors check order status.",
"agentPersonality": "Warm and concise.",
"pronunciation": "",
"escalationMessage": "",
"greetingMessage": "Hi, how can I help you today?",
"closingMessage": "Thank you for chatting with us.",
"voicemailMessage": "",
"agentLanguage": "en",
"callType": "chat",
"callDirection": "INBOUND",
"channel": "widget",
"participantName": "Priya Sharma",
"phone_number": "+919876543210",
"customVariables": {
"orderId": "A1042",
"participantName": "Priya Sharma",
"phoneNumber": "+919876543210"
},
"functionTools": {},
"roomName": "chat-7f3a9c2e",
"agentToken": "<1-hour session token>",
"webCallEnabled": true
}
}
}

Errors

Code When
400 agentId missing, agent is not a CHAT agent, or roomName sent without participantName and phoneNumber
401 Missing, invalid or revoked key (API keys only)
403 Missing widget:bootstrap scope, agent belongs to another organisation, or the token is bound to a different agent
404 Agent not found
429 Rate limited
500 Any other failure (errors are not mapped to specific statuses)

POST /widget/voice-session

Starts a billable in-browser voice call with a CHAT agent that has web calling enabled, and returns the room credentials for the browser. Each phone number (8 or more characters) may start 3 calls per organisation per 24 hours, and each IP address 10 when no number is given. Rate limited (30 requests per minute by default). The call is charged to the organisation’s wallet; a refusal for money is a 402 so the page can tell the visitor to try later rather than treating it as a crash.

Scope: widget:bootstrap

Body (application/json)

Field Type Required Description
agentId string yes The CHAT agent to talk to.
participantName string no
participantNumber string no Visitor’s phone number. Used for the per-number call cap and returning-caller memory.
roomName string no Accepted but currently has no effect.
customVariables object no Values merged over the agent’s default custom variables.

Example request

Terminal window
curl -X POST "https://api.foan.ai/api/v1/widget/voice-session" \
-H "Authorization: Bearer $FOAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agentId":"cmf3k2j9x0005abcd1234efgh","participantName":"Priya Sharma","participantNumber":"+919876543210"}'

Response 200

{
"success": true,
"message": "Web call session created",
"data": {
"success": true,
"callType": "web",
"roomName": "cmf3k2j9x0005abcd1234efgh_919876543210_1758363330000",
"sessionId": "66f1c2e8a4b5c6d7e8f90123",
"token": "<participant token>",
"wsUrl": "wss://realtime.example.com"
}
}

Errors

Code When
400 agentId missing, agent is not a CHAT agent, web calling is not enabled for the agent, or the agent is not active
401 Missing, invalid or revoked key (API keys only)
402 The organisation cannot pay for the call: wallet balance too low, account suspended, or the plan’s call limit reached
403 Missing widget:bootstrap scope, agent belongs to another organisation, or the token is bound to a different agent
404 Agent not found
409 The same call was requested again within a few seconds (same agent, visitor number and key owner) and is already being set up
429 Per-number/IP call cap reached, or rate limited
500 Any other unexpected failure
503 The realtime voice server is unavailable, or the Muncho wallet could not be checked; try again shortly