Embeddable Chat Widget
A lightweight, customizable chat widget that drops right into any website. Click the chat button in the bottom-right corner to try it out.
Site API Key
Each website gets a unique API key. Passed in every request via X-Api-Key header so your backend knows which tenant is calling.
Anonymous Sessions
Visitors get a random session ID stored in a cookie. No signup required. Chat history persists across page refreshes.
Your Backend
All messages route through your REST API. You control storage, AI responses, moderation, and everything else.
Accessible
Built with ARIA labels, keyboard navigation, and screen reader support out of the box.
How Authentication Works
GET /chat/history
X-Api-Key: pk_abc123 # Identifies the website / tenant
X-Session-Id: a1b2c3d4e5f6... # Identifies the anonymous visitor
Content-Type: application/jsonThe site owner embeds the widget with their API key (public, tied to allowed domains). Each visitor automatically receives a session ID stored as a browser cookie for 30 days. No accounts, no passwords, no tokens to manage.
Backend API Contract
Your backend needs to implement these two endpoints. The widget handles everything else.
// Response 200 OK
{
"messages": [
{
"id": "msg_001",
"text": "Hi there!",
"isUser": true,
"timestamp": "2:35 PM"
},
{
"id": "msg_002",
"text": "Hello! How can I help?",
"isUser": false,
"timestamp": "2:35 PM"
}
]
}// Request body
{ "text": "I need help with my order" }
// Response 200 OK
{
"userMessage": {
"id": "msg_003",
"text": "I need help with my order",
"isUser": true,
"timestamp": "2:36 PM"
},
"reply": {
"id": "msg_004",
"text": "Sure! Can you share your order number?",
"isUser": false,
"timestamp": "2:36 PM"
}
}Embed Code
<!-- Add this before </body> -->
<script
src="https://cdn.your-portier.com/widget.js"
data-api-key="pk_YOUR_API_KEY"
async>
</script>Replace pk_YOUR_API_KEY with the API key from your Portier dashboard.