Skip to main content
This guide takes you from an empty React app to a working Digital Worker chat embedded in your product.

Prerequisites

  • A React 18 or 19 application.
  • A publishable key for your tenant (pk_live_… or pk_test_…). Create one in Portals → Developer keys (see Portals overview).
  • A published Portal in your tenant — its portal_id scopes the SDK session.
  • Your customers sign in to your app through your tenant’s identity provider (Clerk), so you can obtain a signed JWT for the current user.

1. Install

Import the stylesheet once, near your app’s entry point:

2. Mint a session token

Before the SDK can talk to Statisfy, your app exchanges the signed-in user’s identity for a Statisfy session token. Do this against POST /sdk/auth, sending the user’s JWT as the bearer, your publishable key as a header, and the target portal_id in the body:
The returned token is short-lived (default 1 hour, see expires_in). Cache it and re-mint before it expires — getToken (next step) is the natural place to do that.
The user’s email must belong to a customer (a person on an account) of your tenant — that’s how the gateway binds the session to a customer_id. If the email isn’t a customer, /sdk/auth returns 403 not_a_customer.

3. Wrap your app in StatisfyProvider

StatisfyProvider supplies the gateway URL and authentication to every SDK component via React context. Set it up once, high in your tree:
Pass a stable getToken (wrap it in useCallback). The provider memoizes its context value on getToken identity, so an inline arrow function would re-render every consumer on each render.

4. Render your first component

Now any SDK component works anywhere beneath the provider — no connection props needed.
That’s a fully working chat: streaming replies, conversation history, unread tracking, and inline forms. See Digital Worker Chat for every prop and the headless client. To show a customer’s onboarding project instead, render the Project Module:

5. Theming (optional)

The SDK’s styles are self-contained and prefixed (dw:) so they won’t collide with your app’s CSS. Override the look with --dw-* CSS variables on any ancestor of the SDK components:

Troubleshooting

The bearer token’s signature didn’t verify. Make sure getToken returns the session token from /sdk/auth (not the raw Clerk JWT), that it hasn’t expired, and that you minted it against the same tenant/environment your gateway points at.
The signed-in user’s email isn’t a person on any account in your tenant. Add them as a contact, or sign in as a known customer.
An SDK component is mounted outside the provider. Move it beneath <StatisfyProvider>.