API reference
These are the endpoints the widget itself calls. You won't normally call these directly — the script tag does it for you — but they're documented here for anyone building a custom integration.
No API key in the browser
POST /api/qualify
Scores a lead and stores it. Used by the Lead Qualifier widget.
POST /api/qualify
Content-Type: application/json
{
"widget_id": "a1b2c3d4e5",
"visitor_name": "Jane Doe",
"visitor_email": "jane@example.com",
"visitor_phone": "+1 555 0100",
"business_type": "E-commerce",
"monthly_revenue": "$20k–$50k",
"main_problem": "Losing carts overnight with no follow-up."
}{
"success": true,
"score": "Hot",
"reason": "Confirmed budget and an urgent, well-defined problem.",
"recommended_action": "Follow up within the hour.",
"lead_id": 142
}POST /api/chat
Sends a message and gets a reply. Conversation history is tracked server-side by session_id — the widget generates a random one per page load. Used by the Support Bot widget.
POST /api/chat
Content-Type: application/json
{
"widget_id": "a1b2c3d4e5",
"session_id": "sess-a1b2c3d4e5-x7k2p9",
"message": "Do you ship internationally?"
}{
"success": true,
"reply": "Yes — we ship to most countries. Rates are calculated at checkout.",
"message_count": 4
}POST /api/process-doc
Uploads a file and returns structured data. Used by the Document Processor widget. The uploaded file is deleted from the server immediately after processing.
POST /api/process-doc
Content-Type: multipart/form-data
document: <file> (PDF, TXT, DOC, or DOCX, max 10MB)
widget_id: a1b2c3d4e5{
"success": true,
"document_id": 88,
"filename": "invoice-1042.pdf",
"processing_time_ms": 2140,
"extracted": {
"summary": "Invoice for AI widget integration services, $3,000 due.",
"key_points": ["Net 15 payment terms", "Bank transfer requested"],
"entities": {
"names": [], "dates": ["March 3, 2026"],
"amounts": ["$3,000.00"], "organizations": ["Northwind Traders"]
},
"action_items": ["Pay invoice by due date"],
"document_type": "invoice"
}
}GET /api/config/:widgetId
Returns your public widget configuration. Called automatically on page load — no request body, no auth required, and no sensitive fields (like your AI key) are ever included.
GET /api/config/:widgetId
{
"widget_id": "a1b2c3d4e5",
"widget_type": "support-bot",
"name": "Acme Co",
"brand_color": "#0F766E",
"icon_url": null,
"font_family": "Inter",
"widget_position": "bottom-right",
"border_radius": 12,
"button_text": "Chat with us",
"widget_language": "auto",
"widget_theme": "classic",
"voice_enabled": 0,
"hide_branding": false
}Errors
Every error response follows the same shape.
{ "error": "Human-readable message" }
// Validation errors also include:
{ "errors": [{ "msg": "...", "path": "...", "location": "body" }] }| Status | Meaning |
|---|---|
| 400 | Missing or invalid fields in the request body. |
| 401 | Missing or expired auth token (dashboard/admin routes only). |
| 403 | Account suspended, or a permission you don't have. |
| 404 | widget_id doesn't match an active widget. |
| 422 | File uploaded but no readable text could be extracted. |
| 429 | Rate limit exceeded — 100 requests/minute per IP on client routes. |
| 500 | Something failed server-side. Retry, or check back shortly. |
| 503 | A dependent service (like the AI provider) isn't configured yet. |