Monetization & Access

Bring Your Own Auth (Pre-Authenticated Sessions)

Sign users into your Chipp app from your own backend -- no Chipp login screen -- with server-side identity that works across devices and inside iframe embeds.

| View as Markdown
Hunter Hodnett
Hunter Hodnett CPTO at Chipp
| 1 min read
# authentication # sso # embed # api # security # sessions

If your application already authenticates its users (WorkOS, Auth0, Clerk, Okta, a custom SSO, or your own signed links), you do not need to make them sign in again inside Chipp. Your backend can mint a Chipp session for a user it has already verified, and the chat opens pre-authenticated: no login screen, no OTP, no Chipp password.

This is the recommended pattern for white-label deployments, portals behind your own login, and governed workflows (for example, sending a patient or client a protected link that opens a pre-authenticated chat).

ℹ️

Because the consumer identity created this way lives on Chipp’s servers (keyed by email), it is portable across devices: any device where your backend mints a token for the same email is the same consumer, with the same conversation history.

How It Works

plaintext
User opens your app or your protected link
    1. Your backend verifies the user (your auth, your signature checks)
    2. Your backend calls POST /api/v1/apps/{appId}/consumers/auth
       -> Chipp finds or creates the consumer and returns a bearer token
    3. Your page passes the token to the embedded chat
       -> the user is signed in, no Chipp login screen

Chipp never sees or validates your credentials or signed links. Your backend is the authority: it decides who gets a token, and Chipp trusts the Builder API call because it carries your secret API key.

Step 1: Mint a Token on Your Server

Call the Builder API endpoint POST /api/v1/apps/{appId}/consumers/auth from your backend. It requires a Builder API key with consumers:write scope (ask the Alchemist: “Create a Builder API key for this app”).

bash
curl -X POST https://build.chipp.ai/api/v1/apps/YOUR_APP_ID/consumers/auth \
  -H "Authorization: Bearer chipp_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane@example.com",
    "name": "Jane Doe",
    "metadata": { "accountTier": "enterprise", "projectId": "PRJ-4821" }
  }'

Response:

json
{
  "data": {
    "token": "eyJhbGciOi...",
    "consumer": { "id": "...", "email": "jane@example.com", "name": "Jane Doe" },
    "expires_at": "2026-08-16T10:00:00Z"
  }
}

What happens server-side: Chipp finds or creates the consumer by email (lower-cased and trimmed), applies any name and metadata you send, creates a session, and returns a bearer token for it.

Token lifetime: sessions last 30 days by default. When HIPAA mode is enabled on the app, sessions last 4 hours instead. Either way, the simplest robust pattern is to mint a fresh token on every page load: the call is idempotent, cheap, and metadata is upserted per key on each call.

⚠️

Never call this endpoint from the browser. The Builder API key must stay on your server — anyone holding it can mint a session for any email on your app.

Users Without a Real Email

The email is the identity key, not a delivery address. If your users should not be identified by their real email (or do not have one), use a stable synthetic email per user, for example user-8f3a@yourdomain.com. As long as your backend always maps the same user to the same synthetic address, their identity and history stay consistent.

Step 2: Pass the Token to the Chat

For the embed widget, call ChippWidget.setUser once the widget is loaded:

javascript
ChippWidget.setUser({
  email: "jane@example.com",
  name: "Jane Doe",
  token: "eyJhbGciOi..." // from your backend
});

The token authenticates the user inside the chat iframe without cookies, so it works reliably in cross-origin iframe embeds even under Safari ITP and Chrome third-party cookie restrictions.

Auth Modes

Server-side tokens work with every auth mode. The mode only controls what a user sees when no token is present:

Auth modeWithout a tokenWith a server-minted token
OpenAnonymous chatSigned in as the identified user
EncouragedInline sign-in card, can dismissSigned in, no card
Required / RestrictedFull-screen sign-in gateSigned in, no gate

For governed deployments where nobody should ever chat anonymously, use Required: if your token wiring fails, users hit a login gate instead of silently chatting as anonymous consumers.

Cross-Device Behavior and Session Continuity

Understanding what is and is not continuous across devices:

  • Identity and history are server-side. The same email on any device is the same consumer. All of their past conversations are available in the in-chat history panel on every device.
  • A new visit starts a fresh conversation thread by default. Within the same browser tab, an in-progress session is restored automatically, but opening the app on a new device (or after the idle timeout) starts a new thread. The user can reopen any prior conversation from history.
  • There is no session-addressing parameter. You cannot pass a session ID in the URL or embed configuration to force the chat to open a specific conversation, and the embed does not expose session IDs to the parent page via postMessage.

If your application needs to continue a structured workflow mid-stream across devices (for example, a multi-step interview), the supported pattern is to keep workflow state in your backend and have the agent reconstruct it: pass your own reference ID on the arrival URL, have a custom action fetch current progress on the first turn (or seed it via the metadata field when minting the token), and treat each Chipp session as an execution context rather than the source of truth.

Tracking Sessions From Your Backend

You do not need anything in-conversation to learn which Chipp session belongs to which of your users:

  • Session webhooks send your endpoint a signed session.created event the moment any session starts, containing the sessionId, consumerId, externalId, and all captured URL query params. This is the deterministic way to build a your-user-id -> chipp-session-id mapping, with no model involvement.
  • ?chipp_external_id= on the arrival URL is promoted to a first-class externalId field on the session (colon-free values only) and appears in the Conversations tab, session webhooks, the Sessions API, and all exports. Use it to stamp sessions with your own user or case reference.
  • The Sessions API lets your backend fetch any session’s transcript by sessionId at any time, and the Org Export API covers org-wide retrieval.

Per-User Context for the Agent

The optional metadata object on the mint call is upserted per key onto the consumer and rendered under an ## About this user block in the agent’s system prompt on every session. Use it for things your backend already knows (role, account tier, project, internal IDs) so the agent has them from the first message, with no custom action round-trip. Full schema and limits: Authenticate a Consumer (Server-Side).

Chipp apps also support email magic links: POST /consumer/YOUR_APP_SLUG/auth/magic-link with an email causes Chipp to email that user a single-use sign-in link (valid 7 days). Opening it signs them in with the same server-side, cross-device identity, no password. This is useful when you want Chipp to handle link delivery. The server-side identify flow above is strictly more flexible for white-label integrations because your backend controls exactly when and for whom sessions are created, and nothing depends on email delivery.