Live on your website in minutes

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

Request Headers
GET /chat/history
X-Api-Key: pk_abc123            # Identifies the website / tenant
X-Session-Id: a1b2c3d4e5f6...   # Identifies the anonymous visitor
Content-Type: application/json

The 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.

GET/chat/history
// 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"
    }
  ]
}
POST/chat/messages
// 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

HTML Snippet
<!-- 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.