---
title: "Create a widget session"
method: POST
path: "/v1/workspaces/{workspaceId}/widget_sessions"
tags: ["WidgetSessionService", "Widget Sessions"]
---

# Create a widget session

`POST /v1/workspaces/{workspaceId}/widget_sessions`

Mints a session against a widget and returns the session bearer token (`spec.token`, returned only on creation) plus the authoritative widget hostname (`info.host`). Asserting a tenant upserts the tenant record; attached secrets flow to every conversation the session creates.

## Path parameters

- `workspaceId` string, required

## Request body

- CreateWidgetSessionRequest — Create widget session request.
  - `workspaceId` string, required — Workspace ID.
  - `metadata` CreateOperationMetadata — CreateOperationMetadata contains the user-provided fields for creating an operation. Read-only fields (id, account_id, workspace_id, created_at, profile_id) are excluded since they are set by the server.
    - `labels` object — Key-value pairs for categorization and filtering. Values are 0-63 alphanumeric characters with "-", "_", or "." allowed between; keys follow the same shape and additionally accept an optional DNS-subdomain prefix (e.g. "cadenya.com/") of at most 253 characters. Examples: {"priority": "high", "source": "api", "workflow": "onboarding"}
    - `externalId` string — External ID for the operation (e.g., a workflow ID from an external system)
  - `spec` WidgetSessionSpec, required — WidgetSessionSpec is the configuration of a session, fixed at mint.
    - `widgetId` string, required — Widget this session is minted against. Accepts the canonical `wgt_…` form or the `external_id:<value>` form.
    - `tenant` TenantAssertion — TenantAssertion identifies a tenant in the customer's own namespace — their org, company, or team identifier for an end user. Asserting a tenant upserts the tenant record in the workspace (keyed on `id` as the tenant's external_id) and associates the created resource with it.
      - `id` string, required — The tenant identifier in the customer's namespace (e.g. "acme-corp"). Stored as the tenant record's external_id; stable across requests.
      - `name` string — Optional human-readable name for the tenant. Updates the tenant record's name on every assertion that provides it.
    - `subject` SubjectAssertion — SubjectAssertion identifies a person within a tenant in the customer's own namespace — typically their user id. Asserting a subject upserts the subject record under the asserted tenant and associates the created resource with it. A subject assertion is only valid alongside a tenant assertion: subject identifiers are scoped to their tenant.
      - `id` string, required — The subject identifier in the customer's namespace (e.g. their user id). Stored as the subject record's external_id; unique within the tenant.
      - `name` string — Optional human-readable name for the subject. Updates the subject record's name on every assertion that provides it.
    - `expiresAt` string, date-time — Hard session expiry. Tokens never outlive it; after it passes the session transitions to STATE_EXPIRED. Defaults to a server-chosen horizon when unset.
    - `token` string — The session bearer token. Returned only on creation — subsequent reads omit it. The token is short-lived; the widget refreshes it at the widget host without involving the customer's backend.
    - `tokenExpiresAt` string, date-time — Expiry of the token returned in `token`. Distinct from `expires_at`, which bounds the session itself.
    - `pinnedParameters` object — Parameters forced onto tool calls made by this session's conversations. A pinned parameter is an overlay on a tool's JSON schema: the parameter is removed from what the LLM sees, and its value is always overwritten server-side with the pinned value — so the model cannot be tricked into calling a tool with a different id than the one the session was minted for (e.g. pin "workspaceId" for an OpenAPI tool with a /workspaces/{workspaceId} path). Flows to every objective the session creates.
  - `secrets` CreateWidgetSessionRequestSecret[] — Secrets to attach to the session.
    - `name` string
    - `value` string

## Response `200`

OK

- WidgetSession — WidgetSession is a delegated, narrowed credential for one visitor's use of a widget, minted server-to-server by the customer's backend. The session carries all customer-asserted context — tenant, subject, labels, secrets — and every conversation (objective) created through the widget inherits it. The bearer token returned at mint is short-lived and refreshed at the widget host; the session row is what makes revocation possible.
  - `metadata` OperationMetadata, required — Metadata for ephemeral operations and activities (e.g., objectives, executions, runs)
    - `id` string, required — Unique identifier for the operation (prefixed ULID, e.g., "obj_01HXK...")
    - `accountId` string, required — Account this operation belongs to for multi-tenant isolation (prefixed ULID)
    - `workspaceId` string, required — Workspace this operation belongs to for organizational grouping (prefixed ULID)
    - `labels` object — Key-value pairs for categorization and filtering. Values are 0-63 alphanumeric characters with "-", "_", or "." allowed between; keys follow the same shape and additionally accept an optional DNS-subdomain prefix (e.g. "cadenya.com/") of at most 253 characters. Examples: {"priority": "high", "source": "api", "workflow": "onboarding"}
    - `createdAt` string, date-time, required — Timestamp when this operation was created ULID includes timestamp information, but this explicit field enables easier querying
    - `externalId` string — External ID for the operation (e.g., a workflow ID from an external system)
    - `profileId` string, required — ID of the actor (user or service account) that created this operation
  - `spec` WidgetSessionSpec, required — WidgetSessionSpec is the configuration of a session, fixed at mint.
    - `widgetId` string, required — Widget this session is minted against. Accepts the canonical `wgt_…` form or the `external_id:<value>` form.
    - `tenant` TenantAssertion — TenantAssertion identifies a tenant in the customer's own namespace — their org, company, or team identifier for an end user. Asserting a tenant upserts the tenant record in the workspace (keyed on `id` as the tenant's external_id) and associates the created resource with it.
      - `id` string, required — The tenant identifier in the customer's namespace (e.g. "acme-corp"). Stored as the tenant record's external_id; stable across requests.
      - `name` string — Optional human-readable name for the tenant. Updates the tenant record's name on every assertion that provides it.
    - `subject` SubjectAssertion — SubjectAssertion identifies a person within a tenant in the customer's own namespace — typically their user id. Asserting a subject upserts the subject record under the asserted tenant and associates the created resource with it. A subject assertion is only valid alongside a tenant assertion: subject identifiers are scoped to their tenant.
      - `id` string, required — The subject identifier in the customer's namespace (e.g. their user id). Stored as the subject record's external_id; unique within the tenant.
      - `name` string — Optional human-readable name for the subject. Updates the subject record's name on every assertion that provides it.
    - `expiresAt` string, date-time — Hard session expiry. Tokens never outlive it; after it passes the session transitions to STATE_EXPIRED. Defaults to a server-chosen horizon when unset.
    - `token` string — The session bearer token. Returned only on creation — subsequent reads omit it. The token is short-lived; the widget refreshes it at the widget host without involving the customer's backend.
    - `tokenExpiresAt` string, date-time — Expiry of the token returned in `token`. Distinct from `expires_at`, which bounds the session itself.
    - `pinnedParameters` object — Parameters forced onto tool calls made by this session's conversations. A pinned parameter is an overlay on a tool's JSON schema: the parameter is removed from what the LLM sees, and its value is always overwritten server-side with the pinned value — so the model cannot be tricked into calling a tool with a different id than the one the session was minted for (e.g. pin "workspaceId" for an OpenAPI tool with a /workspaces/{workspaceId} path). Flows to every objective the session creates.
  - `info` WidgetSessionInfo — WidgetSessionInfo provides read-only server-derived data about a session.
    - `widget` BareMetadata — BareMetadata contains the minimal metadata for a resource: the ID and an optional human-readable name. These are used for reference fields where the full metadata (account scoping, timestamps, labels, external IDs) is not needed — e.g., the tool references inside an agent variation spec or the tools assigned to an objective. Both fields are server-populated; clients provide IDs through sibling fields rather than by constructing a BareMetadata themselves.
      - `id` string
      - `name` string — Human-readable name of the referenced resource, populated by the server on reads for convenience. Absent on references to resources that do not have a name (e.g., objective tasks).
    - `agent` BareMetadata — BareMetadata contains the minimal metadata for a resource: the ID and an optional human-readable name. These are used for reference fields where the full metadata (account scoping, timestamps, labels, external IDs) is not needed — e.g., the tool references inside an agent variation spec or the tools assigned to an objective. Both fields are server-populated; clients provide IDs through sibling fields rather than by constructing a BareMetadata themselves.
      - `id` string
      - `name` string — Human-readable name of the referenced resource, populated by the server on reads for convenience. Absent on references to resources that do not have a name (e.g., objective tasks).
    - `tenant` TenantReference — TenantReference is the read-only echo of a resource's tenant association, carrying both Cadenya's canonical id and the customer's own key.
      - `id` string, required — Cadenya's canonical tenant id.
      - `externalId` string, required — The tenant identifier in the customer's namespace, as asserted.
      - `name` string — Human-readable name of the tenant, when one has been asserted.
    - `subject` SubjectReference — SubjectReference is the read-only echo of a resource's subject association, carrying both Cadenya's canonical id and the customer's own key.
      - `id` string, required — Cadenya's canonical subject id.
      - `externalId` string, required — The subject identifier in the customer's namespace, as asserted. Unique within the subject's tenant.
      - `name` string — Human-readable name of the subject, when one has been asserted.
    - `host` string — The widget hostname this session's tokens are bound to. Authoritative — clients must use this value rather than constructing the hostname.
    - `messageCount` integer — Number of conversation messages created through this session, counted against the session's message cap.
    - `lastActiveAt` string, date-time — When the session last created a conversation, sent a message, or refreshed a token.
  - `state` 'STATE_UNSPECIFIED' | 'STATE_ACTIVE' | 'STATE_EXPIRED' | 'STATE_REVOKED' | 'STATE_EXHAUSTED', enum, required — The current lifecycle state of the session. Output only. Sessions are created STATE_ACTIVE; use :revoke to end one early.
  - `secrets` WidgetSessionSecret[] — Names of the secrets attached to the session. Values are write-only: provided at creation, encrypted at rest, and interpolated into tool-call headers server-side — never returned by any API.
    - `name` string

## Other responses

- `default` — Default error response

---

[API](https://skmtc.net/cadenya/apis/cadenya-api.md) · [All operations](https://skmtc.net/cadenya/apis/cadenya-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/cadenya/cadenya-api/revisions/ac1a7f084068/schema)
