Skip to content

REST API ​

Everything the admin panel does goes through a REST API at /api/v1 on your server, and you can use it too: to sync leads into a CRM, export conversations, manage bots from a script, or handle data requests.

Your server describes the API in full, with every request and response shape:

  • https://chat.example.com/api/docs: an interactive reference (OpenAPI UI);
  • https://chat.example.com/api/openapi.json: the OpenAPI 3.1 document, for code generators.

(Replace https://chat.example.com with your server's address.) This page covers how to authenticate and lists the endpoints with who may call them.

Authentication ​

API tokens are for programs. An admin creates them in the admin panel (Settings, API tokens), choosing a name, the scopes and an optional expiry; the token (wft_...) is shown once. Send it as a bearer token:

sh
curl -H "Authorization: Bearer wft_xxxxxxxx_yyyyyyyy" https://chat.example.com/api/v1/leads

A bad, expired or revoked token gets 401; a token without the scope an endpoint needs gets 403. Revoking a token takes effect at once.

Sessions are for people: the admin panel signs in with POST /api/v1/auth/login, which sets an httpOnly cookie (it lasts 14 days, renewed as you use it). Requests that change something with a session cookie must also send the CSRF token from the login response (or GET /api/v1/me) in an X-CSRF-Token header. Some endpoints only work with a session, because they act as a person: creating API tokens, managing the team, and replying in conversations.

Scopes ​

A token can only call endpoints its scopes cover. Each scope also stands in for a role, and a token acts with the highest role its scopes imply (so endpoints that need the admin role also need an admin-level scope).

ScopeActs asEndpoints
bots:readviewer16
bots:writeadmin10
conversations:readviewer4
conversations:writeagent3
leads:readviewer2
leads:writeagent3
knowledge:writeadmin5
analytics:readviewer5
providers:writeadmin4
tools:writeadmin12
webhooks:writeadmin8
privacy:writeadmin3
settings:readviewer1

Examples ​

sh
TOKEN=wft_xxxxxxxx_yyyyyyyy
API=https://chat.example.com/api/v1

# the newest conversations of one bot (conversations:read)
curl -H "Authorization: Bearer $TOKEN" "$API/conversations?botId=bot_01K...&limit=20"

# a transcript as Markdown (conversations:read)
curl -H "Authorization: Bearer $TOKEN" "$API/conversations/cnv_01K.../export?format=md"

# leads as CSV (leads:read)
curl -H "Authorization: Bearer $TOKEN" -o leads.csv "$API/leads.csv"

# change a bot's draft, then publish it (bots:write)
curl -X PATCH -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"patch": {"identity": {"instructions": "Help visitors with orders and returns."}}}' \
  "$API/bots/bot_01K..."
curl -X POST -H "Authorization: Bearer $TOKEN" "$API/bots/bot_01K.../publish"

Lists are newest first. To page, pass the nextBefore value of one answer as before in the next request.

Errors ​

Errors are JSON with a stable code:

json
{ "error": { "code": "invalid", "message": "identity.agentName: Too small: expected string to have >=1 characters" } }

Common codes: bad_request and invalid (400 or 422, the message names the field), unauthorized (401), forbidden and csrf (403), not_found (404), conflict (409, e.g. a bot changed by someone else since you read it: send the revision you read when you patch), rate_limited (429, with Retry-After) and internal (500).

Live updates ​

The admin panel follows conversations as they happen over a WebSocket at /api/v1/live. It takes a signed-in session (not an API token); for your own systems, use webhooks. Each message is { "type": "...", "data": { ... } }: first hello ({ workspaceId }), then the workspace's events as they happen. An open socket also marks its user as available for hand-offs; the panel can send { "t": "presence", "presence": "away" } (or "online").

Eventdata (every one also has workspaceId)
conversation.started{ botId: string; conversationId: string; visitorId: string }
conversation.updated{ conversationId: string; patch: Record<string, unknown> }
conversation.ended{ botId: string; conversationId: string; reason: string }
message.created{ botId: string; conversationId: string; message: { id: string; seq: number; role: string; text: string; modality: string; createdAt: number; authorName?: string | null; visibility: string; attachments?: unknown[] } }
message.delta{ conversationId: string; messageId: string; responseId: string; delta: string }
agent.status{ conversationId: string; state: string; tool?: { name: string; label: string } }
visitor.typing{ conversationId: string; active: boolean }
lead.captured{ botId: string; conversationId: string | null; leadId: string; fields: Record<string, string> }
handoff.requested{ botId: string; conversationId: string; handoffId: string; reason: string | null; summary: string | null }
handoff.accepted{ botId: string; conversationId: string; handoffId: string; userId: string; userName: string }
handoff.resolved{ botId: string; conversationId: string; handoffId: string | null; by: string }
feedback.received{ botId: string; conversationId: string; messageId: string | null; kind: 'thumb' | 'csat'; value: number; comment?: string }
bot.published{ botId: string; version: number }
tool.called{ conversationId: string; name: string; isError: boolean; durationMs: number }

Endpoints ​

"Access" is the scope an API token needs, or signed-in user (with the lowest role) for endpoints that only take a session. "(and the admin role)" means the token also needs a scope that acts as admin, such as bots:write. The server's /api/docs has the request and response shapes.

Sign-in and setup ​

MethodPathAccess
GET/api/v1/setupWhether first-run setup is needed, and how people can sign inpublic
POST/api/v1/setupCreate the first owner account and workspacepublic
POST/api/v1/auth/loginSign in with email and password (sets a session cookie)public
POST/api/v1/auth/logoutSign outsigned-in user
GET/api/v1/meThe signed-in user, workspace, CSRF token and this serversigned-in user
POST/api/v1/me/passwordChange your passwordsigned-in user (viewer)
GET/api/v1/invites/{token}What an invitation is forpublic
POST/api/v1/invites/{token}/acceptJoin a workspacepublic

Providers ​

MethodPathAccess
GET/api/v1/providers/catalogThe services that can be connectedany token or signed-in user
GET/api/v1/providersConnected providersbots:read
POST/api/v1/providersConnect a provider with an API key (checked before it is saved)providers:write
PATCH/api/v1/providers/{id}Rename a connection or replace its keyproviders:write
DELETE/api/v1/providers/{id}Remove a connectionproviders:write
POST/api/v1/providers/{id}/testCheck the key againproviders:write
GET/api/v1/providers/{id}/modelsModels this key can use (cached for a day; refresh=1 to re-ask)bots:read
GET/api/v1/providers/{id}/voicesVoices this key can use, with preview URLsbots:read
GET/api/v1/providers/{id}/voices/{voiceId}/previewA short audio sample of a voicebots:read

Bots ​

MethodPathAccess
GET/api/v1/bots/templatesStarting points for new botsbots:read
GET/api/v1/botsAll botsbots:read
POST/api/v1/botsCreate a bot (as a draft)bots:write
GET/api/v1/bots/{id}A bot: its draft and published configbots:read
PATCH/api/v1/bots/{id}Edit the draft: a deep patch, or a whole configbots:write
DELETE/api/v1/bots/{id}Delete a botbots:write
POST/api/v1/bots/{id}/duplicateCopy a botbots:write
POST/api/v1/bots/{id}/publishPublish the draft (live widgets switch to it)bots:write
GET/api/v1/bots/{id}/versionsPublished versionsbots:read
POST/api/v1/bots/{id}/versions/{version}/restoreCopy a version into the draftbots:write
POST/api/v1/bots/{id}/statusPause or resume a botbots:write
POST/api/v1/bots/{id}/identity-secretMake a new identity-verification secret (shown once)bots:write
POST/api/v1/bots/{id}/previewA token to preview the draft in a widgetbots:read
GET/api/v1/bots/{id}/embedWhat the embed snippets needbots:read

Custom faces ​

MethodPathAccess
GET/api/v1/facesCustom faces made from photosbots:read
POST/api/v1/facesUpload a face (image + 468 landmarks from skinFromPhoto)bots:write
DELETE/api/v1/faces/{id}Delete a custom facebots:write

Conversations ​

MethodPathAccess
GET/api/v1/conversationsConversations, newest first (pass nextBefore as before for the next page)conversations:read
GET/api/v1/conversations/{id}A transcript with tool calls and attachmentsconversations:read
GET/api/v1/conversations/{id}/exportDownload a transcriptconversations:read
POST/api/v1/conversations/{id}/tagsSet tagsconversations:write
POST/api/v1/conversations/{id}/closeClose a conversationconversations:write
DELETE/api/v1/conversations/{id}Delete a conversation and its filesconversations:write (and the admin role)
GET/api/v1/attachments/{id}An image from a conversationconversations:read
POST/api/v1/conversations/{id}/takeoverTake over a conversation (the AI goes quiet)signed-in user (agent)
POST/api/v1/conversations/{id}/messagesReply as yourself (or add an internal note)signed-in user (agent)
POST/api/v1/conversations/{id}/typingShow the visitor you are typingsigned-in user (agent)
POST/api/v1/conversations/{id}/releaseHand the conversation back to the AIsigned-in user (agent)

Leads ​

MethodPathAccess
GET/api/v1/leadsLeads, newest firstleads:read
GET/api/v1/leads.csvLeads as CSVleads:read
POST/api/v1/leadsAdd a lead (from your own systems)leads:write
PATCH/api/v1/leads/{id}Change a lead's statusleads:write
DELETE/api/v1/leads/{id}Delete a leadleads:write (and the admin role)

Tools, MCP servers and secrets ​

MethodPathAccess
GET/api/v1/tools/httpHTTP toolsbots:read
POST/api/v1/tools/httpAdd an HTTP tooltools:write
PATCH/api/v1/tools/http/{id}Change an HTTP tooltools:write
DELETE/api/v1/tools/http/{id}Delete an HTTP tooltools:write
POST/api/v1/tools/http/{id}/testCall an HTTP tool with sample argumentstools:write
GET/api/v1/tools/mcpMCP servers and their toolsbots:read
POST/api/v1/tools/mcpConnect an MCP server (its tools are listed straight away)tools:write
PATCH/api/v1/tools/mcp/{id}Change an MCP server (headers and env replace the old ones unless keepHeaders/keepEnv)tools:write
POST/api/v1/tools/mcp/{id}/refreshList the server's tools againtools:write
POST/api/v1/tools/mcp/{id}/testCall one of the server's toolstools:write
DELETE/api/v1/tools/mcp/{id}Remove an MCP servertools:write
GET/api/v1/secretsSecret names (values are never shown)tools:write
PUT/api/v1/secrets/{name}Set a secrettools:write
DELETE/api/v1/secrets/{id}Delete a secrettools:write

Knowledge ​

MethodPathAccess
GET/api/v1/knowledgeKnowledge sourcesbots:read
POST/api/v1/knowledgeAdd a source: text, a page, a sitemap, or a site to crawl (files: POST /knowledge/files)knowledge:write
POST/api/v1/knowledge/filesUpload a document (PDF, Markdown, text or HTML)knowledge:write
PATCH/api/v1/knowledge/{id}Change a sourceknowledge:write
POST/api/v1/knowledge/{id}/reindexFetch and index againknowledge:write
DELETE/api/v1/knowledge/{id}Remove a sourceknowledge:write
GET/api/v1/knowledge/{id}/documentsThe pages or files a source hasbots:read
POST/api/v1/knowledge/searchTry a search (what the agent would find)bots:read
GET/api/v1/knowledge/gapsQuestions the knowledge base couldn't answeranalytics:read

Analytics ​

MethodPathAccess
GET/api/v1/analytics/summaryTotals for a period (default: the last 30 days)analytics:read
GET/api/v1/analytics/timeseriesPer dayanalytics:read
GET/api/v1/analytics/toolsTool useanalytics:read
GET/api/v1/analytics/usageProvider usage and estimated costanalytics:read

Webhooks ​

MethodPathAccess
GET/api/v1/webhooksWebhook endpointswebhooks:write
POST/api/v1/webhooksAdd an endpoint (the signing secret is shown once)webhooks:write
PATCH/api/v1/webhooks/{id}Change an endpointwebhooks:write
POST/api/v1/webhooks/{id}/secretA new signing secretwebhooks:write
POST/api/v1/webhooks/{id}/testSend a test event nowwebhooks:write
GET/api/v1/webhooks/{id}/deliveriesRecent deliverieswebhooks:write
POST/api/v1/webhooks/deliveries/{id}/redeliverSend a delivery againwebhooks:write
DELETE/api/v1/webhooks/{id}Remove an endpointwebhooks:write

Workspace, team and API tokens ​

MethodPathAccess
GET/api/v1/tokensAPI tokenssigned-in user (admin)
POST/api/v1/tokensCreate an API token (shown once)signed-in user (admin)
DELETE/api/v1/tokens/{id}Revoke a tokensigned-in user (admin)
GET/api/v1/membersPeople in the workspace, and open invitationssigned-in user (viewer)
POST/api/v1/members/inviteInvite someone (returns the link to send them)signed-in user (admin)
DELETE/api/v1/members/invites/{id}Cancel an invitationsigned-in user (admin)
PATCH/api/v1/members/{id}Change a rolesigned-in user (admin)
DELETE/api/v1/members/{id}Remove someonesigned-in user (admin)
PUT/api/v1/me/presenceOnline, away or offline (for handoffs)signed-in user (agent)
GET/api/v1/settingsWorkspace settingssettings:read
PATCH/api/v1/settingsChange workspace settingssigned-in user (admin)
DELETE/api/v1/workspaceDelete this hosted workspace and everything in itsigned-in user (owner)
GET/api/v1/auditWho did whatsigned-in user (admin)

Visitors (data requests) ​

MethodPathAccess
GET/api/v1/visitorsFind visitors by email or your user idprivacy:write
GET/api/v1/visitors/{id}/exportEverything stored about a visitor (data request)privacy:write
DELETE/api/v1/visitors/{id}Erase a visitor and their conversationsprivacy:write

Wireface Chat 0.1.0. These docs are served by your own server.