Developers
API reference
EasyFastAI exposes a REST API for managing instances, sending messages, provisioning widgets and reading conversation data.
Base URL
All endpoints are relative to your API host.
https://easyfastai.com/apiAuthentication
Requests are authorised with a Firebase identity token in the Authorization header. Tokens are short-lived — refresh them rather than storing them long term.
curl https://easyfastai.com/api/instances \
-H "Authorization: Bearer <ID_TOKEN>"Browser sessions may instead present the __session cookie, which the server validates on every protected route.
Health
Unauthenticated. Used by our status page.
- GET
/api/healthReturns service health. A non-200 response indicates degraded service.
Instances
An instance is one connected channel — a WhatsApp number or a web widget.
- GET
/api/instancesList every instance on your account.
- POST
/api/instancesCreate an instance. Accepts
instanceName,instanceDescriptionandchannel. - PUT
/api/instances/:idUpdate an instance's name, description or assistant configuration.
- DELETE
/api/instances/:idDelete an instance and its associated data.
- GET
/api/instances/:id/analyticsMessage volume, response times and resolution metrics.
- GET
/api/instances/:id/conversationsPaginated conversation history for an instance.
- GET
/api/instances/:id/leadsLeads captured by the assistant.
Connection lifecycle and outbound messaging.
- GET
/api/whatsapp/:instanceId/statusCurrent connection state for the instance.
- POST
/api/whatsapp/:instanceId/connectStart a connection session and return pairing details.
- POST
/api/whatsapp/:instanceId/sendSend a message. Accepts a recipient number and message body.
- POST
/api/whatsapp/:instanceId/broadcastQueue a broadcast to many recipients, with configurable delays.
- POST
/api/whatsapp/:instanceId/disconnectEnd the session and release the connection.
Widgets
Embeddable web chat. The public endpoints are called by the widget itself.
- GET
/api/widgetsList web chat widgets on your account.
- PUT
/api/widgets/:idUpdate appearance, behaviour and allowed domains.
- GET
/api/widgets/publicPublic widget configuration, fetched by the embed script.
- POST
/api/widgets/chatSend a visitor message and receive the assistant's reply.
- POST
/api/widgets/chat/streamSame as above, streamed token by token over Server-Sent Events.
- POST
/api/widgets/handoff/requestEscalate a conversation to a human agent.
CRM
Contacts and aggregate reporting.
- GET
/api/crm/contactsSearch and filter contacts by instance and status.
- GET
/api/crm/statsTotals across instances, contacts and messages.
- GET
/api/crm/analyticsTime-series analytics for a chosen period.
- GET
/api/crm/exportExport contacts for use in another system.
Embedding the chat widget
The embed snippet from the widget designer is all a page needs. A page that wants to control placement, colour mode or the visitor's identity can set window.EasyFastAI before the script loads. Colours and branding are configured by the widget owner in the designer and cannot be changed from the page.
<script>
window.EasyFastAI = {
position: 'bottom-left', // bottom-right | bottom-left | top-right | top-left | center
theme: {
launcher: { offsetX: 24, offsetY: 96, hideOnMobile: false, zIndex: 2000 },
window: { colorMode: 'auto' }, // light | dark | auto
},
dir: 'rtl', // auto | ltr | rtl
visitor: { name: 'Sara', email: '[email protected]' }, // pre-fills the pre-chat form
onReady: function (widget) { widget.open(); },
};
</script>
<script src="https://easyfastai.com/widget/<WIDGET_ID>/script.js" async></script>The same options are accepted as data-* attributes on the script tag for pages that cannot run inline script:
<script src="https://easyfastai.com/widget/<WIDGET_ID>/script.js" async
data-position="bottom-left" data-color-mode="dark" data-offset-y="96" data-dir="rtl"></script>Once loaded, window.EasyFastAIWidget is the runtime handle (it is also passed to onReady):
EasyFastAIWidget.open(); EasyFastAIWidget.close(); EasyFastAIWidget.toggle();
EasyFastAIWidget.setTheme({ window: { colorMode: 'dark' } }); // any option from the list above
EasyFastAIWidget.identify({ name: 'Sara', email: '[email protected]' });
const off = EasyFastAIWidget.on('unread', (count) => setBadge(count)); // 'ready' | 'open' | 'close' | 'unread' | 'message'
EasyFastAIWidget.on('message', ({ role }) => track('chat_turn', role)); // role only, never the text
off(); // unsubscribeRate limits and errors
Public endpoints are rate limited and return 429 when exceeded. Errors use standard HTTP status codes with a JSON body containing an error message. Need something that isn't documented here? Email [email protected].