Public API
These are the endpoints the embedded widget itself calls. They are public — no user login — and authenticated by your site key. You can use them directly to build a custom chat UI.
Authentication
Send your site key as a header. Requests are also checked against your domain allowlist, so a leaked key cannot be used from another site.
X-Site-Key: your-site-keyGet widget config
GET /public/widget-configReturns appearance settings. Used by the widget on load.
{
"widgetPosition": "bottom_right",
"widgetPrimaryColor": "#075CE5",
"widgetFontFamily": "inherit",
"widgetLogoUrl": null,
"widgetAssistantName": "Minaya",
"widgetWelcomeMessage": "Hi, I am Minaya your AI assistant...",
"widgetHeaderTextColor": "#FFFFFF",
"widgetBotBubbleColor": "#F1F1F3",
"widgetBotTextColor": "#18181B",
"widgetUserTextColor": "#FFFFFF",
"widgetOpenByDefault": false,
"widgetPathMode": "all",
"widgetPathRules": [],
"widgetCustomCss": null
}widgetAssistantName is resolved server-side — it is always a string, never null.
widgetPathMode and widgetPathRules say where the widget should appear (all, include or exclude, with path patterns such as /blog/*). The bundled widget applies them; a custom client should too.
Caching
Read endpoints are cached server-side and cleared the moment the underlying settings change, so a saved change is live on the next request. Responses carry anX-Cache header (HIT or MISS); send Cache-Control: no-cache to bypass the cache for one request.
Send a message
POST /public/chat{
"message": "Do you ship to Canada?",
"sessionId": "optional-existing-session",
"visitorIdentifier": "optional-stable-visitor-id",
"stream": false,
"origin": "https://example.com",
"country": "CA"
}Omit sessionId to start a conversation; the response returns one to reuse for follow-ups.
{ "sessionId": "…", "reply": "Yes — 3 to 5 business days…", "messageId": "…" }With stream: true the reply arrives as server-sent events, each carrying a content delta and a final done event.
Get history
GET /public/chat/history/:sessionIdReturns the messages in a session, scoped to your business so one site's widget can never read another's conversations. Used to restore a conversation when a visitor reopens the widget.
Rate a message
POST /public/chat/feedback{ "messageId": "…", "feedback": "up" }Accepts up or down, and only for assistant messages. Ratings appear in your dashboard analytics.
Analytics events
POST /public/track-click
POST /public/track-page-viewFired when the widget is opened and when a page loads. Both accept an optional sessionId, visitorIdentifier, origin, and country.
Rate limits and caps
- Chat requests are rate-limited per site key.
- 50 messages per session.
- 500 characters per message.
- Free-tier businesses have a daily message cap.
- Paid plans have a monthly allowance — 2,000 messages on Starter, 10,000 on Pro — counted across every conversation and every domain the widget runs on, from renewal to renewal.
- On Minaya’s AI, a reply that takes an action — records a lead or calls an MCP tool — counts as 3 messages from the allowance. With your own key every reply counts as one.
- A daily ceiling on paid plans, set at three times the plan’s daily average, stops a runaway loop from spending the whole month in a day.
Exceeding a limit returns a normal reply explaining the situation rather than an error, so a custom UI can display it like any other message.
Dashboard API
Managing knowledge sources, appearance, and MCP servers uses authenticated endpoints under the same host, documented in the OpenAPI spec at /api/docs on your deployment.