Skip to main content

Widget Authentication

Secure your embedded chat widget with token-based authentication. ChatterMate supports both public and authenticated access modes to fit your application’s needs.

Authentication Modes

ChatterMate offers two authentication modes for your widget:

Public Access Mode

The default mode allows anonymous visitors to start conversations without authentication.How it works:
  • Token is automatically generated when the widget initializes
  • Visitors can chat immediately without signing in
  • Email collection is optional (based on chat style settings)
  • Conversation history is linked to the generated token
Best for:
  • Public support websites
  • Documentation assistants
  • General Q&A interfaces
  • Lead generation chatbots

How Token Authentication Works

Authenticated mode uses server-to-server token generation. Your backend calls ChatterMate’s /generate-token endpoint with a Widget App API key and the user’s details. ChatterMate creates (or matches) a customer record, then returns a short-lived JWT that the widget uses to start the chat.
You do not sign your own JWTs. ChatterMate issues and signs the token — that’s how it registers the token for revocation and links the conversation to a stored customer. All you provide is your API key and the user’s email/name. (Your CONVERSATION_SECRET_KEY is an internal server secret and is never used by integrators.)

What you need

1

Create a Widget App (API key)

In the ChatterMate dashboard, open Widget Apps and create an app. Copy the API key — it is shown only once. Treat it as a server-side secret.
2

Require authentication (optional)

Set require_token_auth: true on your agent to reject anonymous visitors so a token is always required.

Token flow

1

Generate a token (server-side)

When a signed-in user opens a page with the widget, your backend calls POST /api/v1/generate-token with your API key and the user’s email and name.
2

Pass the token to the widget

Return the token to your page and set window.chattermateToken before the widget script loads.
3

ChatterMate links the customer

ChatterMate stores the email and name as a customer (matched by email) and links the conversation to it — so the user’s email and name appear in the agent inbox, and their history reloads automatically.

Implementation

1. Generate a token on your backend

Call /generate-token with your Widget App API key in the Authorization header. ChatterMate returns a signed token bound to the customer.
curl -X POST https://api.chattermate.chat/api/v1/generate-token \
  -H "Authorization: Bearer YOUR_WIDGET_APP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "widget_id": "YOUR_WIDGET_ID",
    "customer_email": "user@example.com",
    "customer_name": "John Doe",
    "ttl_seconds": 3600
  }'
async function generateWidgetToken(email, name) {
  const res = await fetch('https://api.chattermate.chat/api/v1/generate-token', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.CHATTERMATE_WIDGET_APP_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      widget_id: 'YOUR_WIDGET_ID',
      customer_email: email,   // stored as the customer + shown in the inbox
      customer_name: name,
      ttl_seconds: 3600,       // 60–86400 (default 3600)
    }),
  });
  const { data } = await res.json();
  return data.token;
}
import os, requests

def generate_widget_token(email: str, name: str) -> str:
    res = requests.post(
        "https://api.chattermate.chat/api/v1/generate-token",
        headers={"Authorization": f"Bearer {os.environ['CHATTERMATE_WIDGET_APP_API_KEY']}"},
        json={
            "widget_id": "YOUR_WIDGET_ID",
            "customer_email": email,   # stored as the customer + shown in the inbox
            "customer_name": name,
            "ttl_seconds": 3600,        # 60–86400 (default 3600)
        },
    )
    return res.json()["data"]["token"]
The response contains the token and its expiry:
{
  "success": true,
  "data": {
    "token": "eyJhbGci...",
    "widget_id": "YOUR_WIDGET_ID",
    "expires_in": 3600,
    "expires_at": "2026-07-06T18:00:00+00:00",
    "created_at": "2026-07-06T17:00:00+00:00"
  },
  "message": "Token generated successfully. Expires in 3600 seconds."
}
customer_email is optional — omit it and ChatterMate creates an anonymous customer. Passing it is what links the conversation to a named customer in the inbox, and if the same email returns later the existing customer (and their history) is reused. customer_name updates the stored name when it changes.

Passing extra customer metadata

Pass custom_data to attach arbitrary fields to the customer — for example a student’s name and coaching center for a tutoring app, or an account tier and plan for a SaaS app. ChatterMate stores these on the customer record and shows them to agents in the chat inbox, right alongside the name and email.
{
  "widget_id": "YOUR_WIDGET_ID",
  "customer_email": "parent@example.com",
  "customer_name": "Priya Krishnan",
  "custom_data": {
    "student_name": "Aarav Krishnan",
    "center_name": "Special Academy U12"
  },
  "ttl_seconds": 3600
}
custom_data is capped at 20 keys and 4KB serialized. Calling /generate-token again for the same customer merges new keys into what’s already stored — existing keys are overwritten if present in the new call, and any keys you don’t send are left untouched.

2. Pass the token to the widget

Set window.chattermateToken before the loader script runs:
<script>
  window.chattermateId = 'YOUR_WIDGET_ID';
  window.chattermateToken = 'GENERATED_TOKEN';   // from /generate-token
</script>
<script src="https://app.chattermate.chat/webclient/chattermate.min.js"></script>
The widget reads window.chattermateToken, sends it as a Bearer token, and ChatterMate resolves it back to the stored customer for the whole conversation.

What’s inside the token

You don’t build this yourself — ChatterMate signs it — but for reference the issued token carries:
FieldDescription
sub / customer_idChatterMate customer id (derived from the email)
widget_idThe widget the token is bound to
customer_emailEmail you supplied (stored on the customer)
customer_nameName you supplied
custom_dataExtra fields you supplied (merged into the customer’s stored metadata)
jtiToken id, used for revocation
expExpiration timestamp

Security Features

Organization Isolation

Tokens are scoped to your organization. Cross-organization access is prevented.

Signature Verification

All tokens are cryptographically signed and verified on each request.

Widget Binding

Tokens are bound to specific widgets, preventing cross-widget token reuse.

Revocable & Short-Lived

Every token has a JTI and a TTL (60s–24h), so it can be revoked and expires quickly.
Never expose your Widget App API key in client-side code. Call /generate-token only from your backend, and hand the browser just the short-lived token it returns.

Best Practices

  1. Token Expiration
    • Keep ttl_seconds short (default 1 hour); the range is 60s–24h
    • Request a fresh token per page load or session rather than reusing long-lived ones
    • Handle expired-token errors by re-requesting a token
  2. Secure Generation
    • Call /generate-token server-side only, with the API key in an environment variable
    • Regenerate the key from Widget Apps if it is ever exposed
  3. Customer Identification
    • Always pass customer_email so conversations are attributed to a named customer in the inbox
    • Keep the same email for a returning user so their history and customer record are reused
    • Pass customer_name to show a friendly name to your agents
    • Use custom_data for context agents need at a glance (e.g. account tier, plan, or in a tutoring app the student’s name and center) — it shows up in the inbox next to the customer’s name and email

Troubleshooting

  • Confirm the Authorization: Bearer <API_KEY> header uses a valid Widget App key (not your account password or the widget id)
  • Make sure the key hasn’t been regenerated/deactivated in the dashboard
  • Check the widget_id in the body belongs to the same organization as the API key
  • The agent has require_token_auth: true, so window.chattermateToken must be set before the loader script runs
  • Verify the token isn’t expired (check expires_at)
  • Check the browser console for JavaScript errors
  • You must pass customer_email (and ideally customer_name) to /generate-token — a self-signed JWT or a token without an email won’t create a named customer
  • Reuse the same email for the same user so the existing customer is matched instead of a new one being created

What’s Next?

After configuring authentication:
  1. Set up your widget integration
  2. Configure chat customization options
  3. Test with authenticated and anonymous users

Widget Integration

Learn how to integrate the widget into your website