> ## Documentation Index
> Fetch the complete documentation index at: https://help.statisfy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Statisfy SDK Overview

> Embed Statisfy Digital Workers and onboarding Projects into your own web app with the @statisfy/digital-workers-react SDK.

The Statisfy SDK (`@statisfy/digital-workers-react`) lets you embed Statisfy experiences — a **Digital Worker chat** and a **Project (onboarding) module** — directly into your own React application or customer portal. Your customers interact with their Statisfy data without ever leaving your product.

<Note>
  The SDK is the programmatic counterpart to [Portals](/portals/overview). A Portal is a Statisfy-hosted site; the SDK lets you build the same experiences inside an app you host yourself.
</Note>

## What you can build

<CardGroup cols={2}>
  <Card title="Digital Worker chat" icon="comments">
    A full chat widget that talks to one of your Digital Workers — streaming replies, inline forms, conversation history, unread badges, and live replies from a human CSM.
  </Card>

  <Card title="Project module" icon="list-check">
    A read/write view of a customer's onboarding project: milestones, tasks, progress, and editable fields — as a pre-built component or composable primitives.
  </Card>
</CardGroup>

## Package

|                       |                                                                    |
| --------------------- | ------------------------------------------------------------------ |
| **Name**              | `@statisfy/digital-workers-react`                                  |
| **Module format**     | ES Module                                                          |
| **Peer dependencies** | `react` and `react-dom` (18 or 19)                                 |
| **Styles**            | Ships a stylesheet at `@statisfy/digital-workers-react/styles.css` |

The SDK is built with React and TypeScript and is fully typed — every component, hook, and client method ships with type definitions.

## How it fits together

```text theme={null}
Your app (React)
│
├─ <StatisfyProvider baseUrl publishableKey getToken>   ← connection + auth, set once
│   │
│   ├─ <DigitalWorkerChat workerId=… />                 ← chat with a Digital Worker
│   └─ <ProjectModule projectId? />                     ← onboarding project view
│
└─ Statisfy Gateway (api.statisfy.app)
    ├─ /sdk/dw/v1/workers/{id}/…   (chat: messages, stream, conversations)
    └─ /sdk/v1/…                   (projects: config, projects, tasks)
```

You wrap your app once in [`<StatisfyProvider>`](/sdk/v0/getting_started), which supplies the gateway URL and authentication. Every SDK component reads that shared config — they never take connection props themselves.

<Note>
  Inside a Statisfy-hosted Portal, components can take their settings from the portal's `portal.runtime.json` rather than props — pass a `configId` instead of a `workerId`. See [Portal Runtime Config](/sdk/v0/portal_config).
</Note>

## Authentication model

The SDK authenticates each request with two pieces:

* **A bearer token** — a short-lived HS256 JWT, signed with your workspace's JWT secret. Your app supplies it through the provider's `getToken` callback; the SDK never mints or stores it.
* **A publishable key** — `pk_live_…` / `pk_test_…`, safe to ship in client-side code. It identifies your Statisfy tenant.

**Where that token comes from depends on how you're using the SDK** — the SDK itself doesn't care, it just calls `getToken`.

<Tabs>
  <Tab title="In your own app (vendored)">
    **Your backend mints the token.** It signs a short-lived HS256 JWT with your workspace's **JWT secret** and hands it to your frontend, which returns it from `getToken`. There is no Statisfy exchange endpoint in this path.

    The claims Statisfy requires are the standard `iat` / `exp` plus the end user's `email`, which is how the gateway resolves who is asking. Because your backend mints the token, the long-lived secret never leaves your server — see [Publishable Keys & Secrets](/admin/publishable_keys).
  </Tab>

  <Tab title="In a Statisfy Portal">
    **Statisfy mints the token.** A hosted portal has no backend of its own, so the browser exchanges the signed-in user's identity (your tenant's Clerk/IdP JWT) at `POST /sdk/auth` and gets back a session token.

    That token carries `tenant_id`, `customer_id`, and `portal_id` claims, so the gateway scopes every request to exactly that customer — it never trusts a customer id sent from the browser.
  </Tab>
</Tabs>

<Warning>
  Only the **portal** path produces a token with a `customer_id` claim, and the project endpoints (`/sdk/v1/*`) require one — a vendor-minted token without it is rejected with `401 not_a_portal_session`. The Digital Worker chat endpoints work with either. So `ProjectModule` and `useProject` are portal-session features today; chat is available to both.
</Warning>

<Warning>
  In the portal path, the bearer is **not** the raw Clerk/IdP JWT — it's the Statisfy session token returned by `/sdk/auth`. Never sign tokens in the browser: only the publishable key is safe client-side.
</Warning>

The full token lifecycle, headers, and error codes are in the [API Reference](/sdk/v0/api_reference).

## Next steps

<CardGroup cols={2}>
  <Card title="Getting Started" icon="rocket" href="/sdk/v0/getting_started">
    Install, wire up the provider, mint a token, and render your first component.
  </Card>

  <Card title="Digital Worker Chat" icon="comments" href="/sdk/v0/digital_worker_chat">
    Embed the chat widget, render inline forms, and use the headless client.
  </Card>

  <Card title="Project Module" icon="list-check" href="/sdk/v0/projects">
    Show and update a customer's onboarding project.
  </Card>

  <Card title="Portal Runtime Config" icon="sliders" href="/sdk/v0/portal_config">
    Configure components from `portal.runtime.json` and resolve per-customer `$field` values.
  </Card>

  <Card title="API Reference" icon="code" href="/sdk/v0/api_reference">
    Endpoints, headers, error codes, and TypeScript types.
  </Card>
</CardGroup>
