Iris Docs

Dogfood contract. The REST/product API and realtime transport are implemented on the current non-PHI staging lane. Packaged client SDKs and outbound product webhooks remain preview surfaces and may change.

Quickstart

From zero to first message

Iris gives you three surfaces over one tenant: an embeddable widget, an operator portal, and a REST + realtime API. This guide gets a live conversation flowing in about five minutes.

You'll need a workspace. Create one free — your tenant slug and keys are issued instantly.

1

Embed the widget

Paste the snippet before </body>. It mounts inside a shadow DOM, so it never inherits or leaks your site's styles.

2

Mint a session token server-side

Exchange your secret key for a short-lived session. Tokens are never passed through query strings or exposed to the browser.

3

Answer from the console

Open the operator console. The moment a guest sends a message, a room appears in your queue with an Iris draft reply ready to send or edit.

Switching from Drift

Replace one tag. Keep your code.

Drift Chat and Drift Email shut down on January 31, 2027. Iris is a drop-in: the install tag changes, and page code written for window.drift keeps working.

1

Remove the Drift snippet

It is the inline <script> that mentions js.driftt.com and ends with drift.load("…"), or a Drift tag in Google Tag Manager.

2

Add the Iris tag with Drift compatibility on

Same place, same pages. In GTM, make it the tag's Custom HTML and publish the container: no site deploy.

3

Leave your drift.* calls alone

With data-drift-compat="true" the widget defines window.drift. The calls that affect chat do what they always did; sales-only calls are accepted and ignored so nothing throws.

Drift callNow
drift.api.openChat() · toggleChat() · startInteraction()Opens (or toggles) the chat
drift.api.widget.show() / .hide()Shows or hides the launcher
drift.identify(id, { email, name })Pre-fills the visitor's name and email
drift.reset()Forgets the visitor on this device: saved conversation, resume token and start form
drift.on('ready' | 'chatOpen' | 'chatClose' | 'startConversation' | 'message', fn)Fires as before
drift.page() · track() · config() · playbooks · meetingsAccepted, no effect

New code can call the native page API directly: window.UniChatWidget.open(), .close(), .identify({ name, email }), .on('chatOpen', fn). Your Admin console's Switch from Drift page renders this snippet with your workspace IDs filled in, plus a pasteable instruction block for a developer or coding agent.

Core concepts

A small vocabulary covers the whole platform.

  • Tenant — the isolated home for one workspace's data. Every API call is scoped to a tenant, enforced by row-level security.
  • Room — a single conversation thread between a guest (or verified user) and your operators.
  • Session — a short-lived, server-minted token that authorizes a specific end user inside a tenant.
  • Operator — a member of your team who answers rooms in the portal. Roles: owner, admin, operator, viewer.
  • Guest → linked identity — a conversation can start anonymous and upgrade to a verified Auth0/SSO identity mid-thread without losing history.

Authentication

Iris uses two key types. Know which one belongs where.

  • Publishable key (iris_pub_…) — browser-safe integration key. The current widget bootstrap uses your tenant ID.
  • Secret key (iris_sk_…) — server-side only. Authenticates your backend against the product API (/api/product/v1). Keep it out of client code.
  • Session token — short-lived bearer minted by signup/login/guest bootstrap; used by humans, the admin console, and the widget.

Never expose a secret key in client code. Mint session tokens from your backend and hand only the session token to the widget.

Authenticate REST calls with a bearer header:

# every server-side request
Authorization: Bearer <session-token>

REST API

Base path /api/v1 on the API host. JSON in, JSON out, conventional status codes.

Endpoints

POST/session/guestStart or resume a restricted guest chat session
POST/session/exchangeExchange an upstream identity token for a chat token
POST/session/linkLink a guest conversation to a signed-in identity
POST/session/refreshRotate an active chat token
GET/channelsList visible conversation channels
POST/channels/:id/messagesPost a message to a channel
GET/widget-configRead published public widget branding

Product API (server-to-server, API-key auth)

Base path /api/product/v1. Authenticate with a secret key — Authorization: Bearer iris_sk_… or X-API-Key. Your key's scopes gate each route; visibility is membership-scoped and tenant-isolated.

GET/meIntrospect the key: tenant, scopes, key id
POST/sessionsMint a chat session for one of your app users (stable identity)
POST/channelsCreate a channel from your backend
GET/channelsList channels your key created or joined
POST/channels/:id/membersAdd a member to a channel
POST/channels/:id/messagesPost a message server-side
GET/channels/:id/messagesRead message history

The full machine-readable contract — signup, team, keys, widget, and product API — lives at /llms.txt. Point your coding agent at it and it can set up Iris end to end.

Example — post a message

Realtime & WebSocket

Connect to the realtime socket for live delivery, presence, typing indicators, and read-state sync. The transport reconnects automatically and resumes from REST state.

const ws = new WebSocket("wss://unichat-staging-server.yellowforest-cd2ec69d.eastus.azurecontainerapps.io/ws", ["bearer", token]);
ws.onmessage = (e) => {
  const ev = JSON.parse(e.data);
  // ev.type: "message.new" | "presence.changed" | "typing.indicator"
  render(ev);
};

Realtime is read-optimized. Send messages over REST (POST /channels/:id/messages) — the socket echoes them back to subscribers.

Webhooks

Preview. Outbound product webhooks and webhook registration are not available yet. The event shapes below are directional and may change.

EventFires when
message.createdA guest or operator posts a message
channel.createdA new conversation channel is created
channel.archivedAn operator archives a channel
identity.linkedA guest upgrades to a verified identity
presence.changedAn operator goes online, away, or offline

Client SDKs

Drop-in libraries for the surfaces you build yourself.

Web / React
@irissays/react · preview

An <Iris /> component plus headless hooks for fully custom UIs.

iOS (Swift)
IrisKit · preview

Swift Package with a UIKit & SwiftUI chat surface and background reconnection.

Windows host
WebView2 · reference

A reference WebView2 host embedding the widget in desktop apps.

Server (Node)
@irissays/node · preview

Mint sessions, call the REST API, and verify webhook signatures.

Compliance

Iris was built inside a HIPAA-regulated imaging network. These controls are defaults, configured per tenant in Admin → Compliance.

  • PHI & BAA boundary — initial dogfood excludes PHI. Production BAA availability requires an explicit readiness review.
  • Tenant isolation — Postgres row-level security policies, verified by automated isolation checks on every deploy.
  • Append-only audit log — every message and admin action is recorded immutably and exportable to your SIEM.
  • Retention & evidence — per-tenant retention windows with scheduled purge drills that produce signed evidence bundles.

Need a security review or a signed BAA? Talk to our solutions team.