Skip to main content
The Portal SDK lets an embedded portal show a customer their onboarding project — its fields, milestones, tasks, and comments — and let them make the changes you allow. It has two layers:

React SDK

@statisfy/digital-workers-react — drop-in components (<ProjectModule/>, <Comments/>) and headless hooks (useProject, useComments).

REST API

The /sdk/v1 endpoints the React SDK calls. Use them directly if you’re not on React.
Everything is scoped to the customer in the session token — the portal never sends a customer id, and a project or task that isn’t the session’s is reported as 404 (existence is never leaked).

Authentication

Every call needs a portal session token (a short-lived JWT) as a bearer, plus your publishable key:
Mint the session token by exchanging the signed-in user’s identity at your gateway’s token endpoint; the React SDK does this for you via <StatisfyProvider>. See Publishable keys to create a key.
Visibility is enforced server-side. A real (non-preview) external viewer only receives fields, tasks, and comments that have been shared with the customer — see External sharing. An internal preview session sees everything.

What the customer can see and edit

  • Fields marked Internal are removed from the response entirely.
  • Tasks hidden from the portal are dropped from the task list.
  • Comments that weren’t shared with the customer are filtered out; comments the customer posts are always shared.
  • Writes are gated by meta.can_edit and each field’s editable flag.

REST API

Base path: /sdk/v1. All responses are JSON. Error responses:

Resolve the onboarding project

Returns the customer’s onboarding project id under onboarding_project__c_, which you then read with GET /projects/{id}.

Read a project

Returns the project’s values, human-readable display strings, field schema, server-ordered tasks, and a progress meter.
Render display[key] ?? properties[key]; send only canonical properties back on writes. tasks is a flat, depth-first list — build the milestone → subtask tree client-side from parent_id, and never re-sort it.

Update a project or task

Body is the changed canonical values only:
Both return the refreshed project payload. A non-editable field or invalid option is rejected with a 400 (not_editable / invalid_option / invalid_type).

Comments

GET returns customer-visible comments oldest-first:
POST takes { "value": "..." } and returns the created comment. Portal-posted comments are always shared with the customer. PATCH (author only) edits the text.

React SDK

Install and wrap your app in <StatisfyProvider> (see Portals overview); it supplies the base URL, token minting, and publishable key to every hook and component.

<ProjectModule/>

The pre-assembled project view: header, progress, milestone journey, editable task list, project comments, and a task-detail drawer (with per-task comments).

<Comments/>

A standalone comment thread + composer — project-level, or task-level with a taskId. Used inside <ProjectModule/>, but also available on its own for custom layouts.

useProject(projectId?)

Headless data hook for custom layouts. Owns the config → project resolve, the milestone/subtask tree, and optimistic task/project writes with rollback.

useComments(projectId, taskId?)

Headless comments hook. Loads customer-visible comments and posts new ones (optimistically appended).

createProjectClient(config)

The React-unaware transport, if you want to call the API without hooks. Attaches the bearer token and publishable key on every request.