Documentation menu

API reference

Owner API (P0 display Sessions; P1 interactive Sessions). Request bodies are limited to 256 KiB; a Surface measure (UTF-8 bytes of the canonical Surface JSON) above 131072 bytes is rejected with 413 PAYLOAD_TOO_LARGE. Every table row must have the same key set. Every JSON response carries Cache-Control: no-store, no-transform. Interactive Sessions: active → responded (one accepted response per revision, response_policy first) → active (the owner publishes the next revision) … → completed (terminal).

On this page
Base URL
https://api.sess.si
Contract
Sess owner API, version 0.1.0, OpenAPI 3.1.0
Contract SHA-256
8d4c04593b1137cc9730e3836b77173c463e03c7fe1b6cc53a0d51de5890cc65

This page is generated at build time from the same OpenAPI document that the API build checks for drift (packages/spec/openapi.json). It lists only implemented operations.

The running API serves this same document at https://api.sess.si/openapi.json.

Operations

GET /app/confirm/{token}

Operation ID signInConfirmPage

The page the emailed link opens (the token is a single-use secret; never log it). It only shows a Sign in button (with ?continue=key, a link requested to finish a key creation: "Continue creating your key"); it consumes nothing.

Authentication: None (public)

Parameters

Parameters of GET /app/confirm/{token}
NameInTypeRequiredDescription
tokenpathstringyes

Responses

Responses of GET /app/confirm/{token}
StatusDescriptionBodyHeaders
200The confirm page.——

POST /app/confirm/{token}

Operation ID signInConfirm

Consumes the link once (same-origin requests only) and sets the account-page cookie: HttpOnly, Secure, SameSite=Strict, host-only, Path=/app, 12 hours. When the same browser holds a pending key creation of the same account (the key-intent cookie, set by a create post with an expired session of that account), the key is created now with that label and expiry, once, and the response is the one-time reveal; the intent cookie is cleared. A pending creation of another account creates nothing.

Authentication: None (public)

Parameters

Parameters of POST /app/confirm/{token}
NameInTypeRequiredDescription
tokenpathstringyes

Responses

Responses of POST /app/confirm/{token}
StatusDescriptionBodyHeaders
200Signed in; the pending key was not created because the expiry date its form showed is no longer the date a key created now would get (a new UTC day began): the keys page with a fresh form.——
201Signed in and the pending key created: the keys page with it, shown once.——
303Signed in: to /app/keys (/app/keys?resume=elsewhere when the link was for a key creation started in another browser), with Set-Cookie.——
400SIGN_IN_LINK_INVALID: expired, used or replaced by a newer link.——
403ACTION_NOT_ALLOWED: not a same-origin request.——
409Signed in; the pending key was not created: KEY_LIMIT_REACHED (the account has 10 active keys).——

GET /app/keys

Operation ID apiKeysPage

The account page listing the workspace’s API keys (label, fingerprint, created, last used, expiry, state). Without a live account session: 303 to /app/sign-in.

Authentication: None (public)

Responses

Responses of GET /app/keys
StatusDescriptionBodyHeaders
200The keys page.——
303To /app/sign-in.——

POST /app/keys

Operation ID createApiKey

Creates an owner API key (sess_sk_…) of the developer workspace and shows it once, in one post of the keys page’s create form. The form states each expiry choice’s exact date and carries a single-use nonce bound to the account session (15 minutes); creating consumes it, so a refresh or repeat never creates a second key or shows the secret again. The stored expiry has the date the form showed (rendered_at, bound to the nonce); when that date is no longer true the form is shown again (400). Form fields: csrf (the page’s token), nonce, rendered_at, label (optional, ≤ 64 characters, no control characters), expires_in_days (30, 90, 365 or never; required). Same-origin requests with the session’s CSRF token only. At most 10 active keys per account. With an expired account session (same-origin posts only), a valid label and expiry choice, bound to that account, is kept in a key-intent cookie (HMAC-protected, HttpOnly, Secure, SameSite=Strict, host-only, Path=/app, 15 minutes) and the answer is 303 to /app/sign-in ("Verify it’s you"); the key is created only after the email link is confirmed in the same browser. Revoke: POST /app/keys/{id}/revoke (same rules), immediate. Sign out: POST /app/sign-out.

Authentication: None (public)

Responses

Responses of POST /app/keys
StatusDescriptionBodyHeaders
201The keys page with the new key, shown once.——
303No live account session: to /app/sign-in (with the key-intent cookie for a valid choice).——
400INVALID_SCHEMA: an expiry that is not offered, an invalid label (the field shows the error), a form nonce that is missing, unknown, expired or issued to another account session, a changed rendered_at, or expiry dates that changed since the form was shown.——
403ACTION_NOT_ALLOWED: cross-origin or a wrong CSRF token.——
409KEY_LIMIT_REACHED, or KEY_ALREADY_CREATED (the same create form again: no second key, and the secret is not shown again).——

POST /app/trials/claim

Operation ID claimTrial

Claims a no-signup trial for the signed-in developer account. Form fields: csrf (the page’s token) and management_credential (the trial’s sess_mg_… credential, in the form body only, never in a URL). Same-origin requests with the session’s CSRF token only; the human link can never claim. A claim records the account as the trial’s owner, once: nothing moves, the trial keeps its deadlines, limits and deletion time, its receipts stay as issued and its management credential keeps working. The account’s API keys can then read (only read) the trial’s Sessions with the owner read routes, each Session until its result_available_until (as with the management credential). Claiming the same trial again from the same account answers as the first claim.

Authentication: None (public)

Responses

Responses of POST /app/trials/claim
StatusDescriptionBodyHeaders
303Claimed (or already claimed by this account): to /app/keys?claimed=1. No live account session: to /app/sign-in.——
400INVALID_SCHEMA: not a management credential.——
403ACTION_NOT_ALLOWED: cross-origin or a wrong CSRF token.——
404TRIAL_NOT_FOUND: no live trial for that credential (unknown, revoked, deleted or past its deletion time).——
409TRIAL_ALREADY_CLAIMED: another account claimed this trial.——

POST /v1/trial/sessions

Operation ID createTrialSession

The no-signup trial. Without Authorization: creates a trial workspace and its first interactive Session, and returns the management credential once, in the body. With Authorization: Bearer <management credential>: creates a further Session in that trial. Interactive Sessions only (mode interactive); no return channel, webhook or outbound endpoint exists for a trial. Trial limits (published, reversible): human link and action window 1 hour; result readable 24 hours after the action window; at most 3 active Sessions and 10 Sessions per trial within its 24-hour creation window; at most 3 new trials per client and 200 overall per rolling 24 hours. Any other credential, or a management credential that is unknown, expired, revoked or bound to one Session → 404 NOT_FOUND. An Idempotency-Key header is refused (400 INVALID_SCHEMA): the credential and the human link cannot be replayed.

Authentication: None, or Authorization: Bearer <credential> (managementCredential — The trial management credential (sess_mg_…), returned once at trial creation.)

Request body (required)

Content type application/json: TrialCreateSessionRequest

no additional properties

  • interaction object required

    no additional properties

    • mode "interactive" required

    • title string required

      min length 1 · max length 200 · pattern \S

    • description string optional

      max length 4000

    • source object required

      no additional properties

      • kind "sess_surface" required

      • components array of object required

        min items 1 · max items 100

        • type string required

          min length 1 · max length 64

    • actions array of object required

      min items 1 · max items 5

      no additional properties

      • id string required

        pattern ^[a-z][a-z0-9_]{0,31}$

      • label string required

        min length 1 · max length 200 · pattern \S

      • intent "submit" or "continue" or "approve" or "reject" or "request_change" optional

    • response_policy "first" optional

      One accepted response per revision (the only P1 policy; the default).

Responses

Responses of POST /v1/trial/sessions
StatusDescriptionBodyHeaders
201Session created at revision 1.TrialCreateSessionResponseETag, Location
400INVALID_SCHEMA or UNKNOWN_COMPONENTError—
404NOT_FOUND: the credential does not authorize a trial, an unknown /v1/trial path or a malformed trial URL (never 401)Error—
413PAYLOAD_TOO_LARGEError—
429RATE_LIMITED: a trial limit (active Sessions, Sessions per trial, new trials per client or overall); also after the trial creation window has ended. The message names the limit in plain words for people; the code and Retry-After are the stable contract, so clients never parse the message.ErrorRetry-After
500INTERNALError—
503TRIAL_UNAVAILABLE: the trial is not configured on this deploymentError—
Request example: interactive
{
  "interaction": {
    "mode": "interactive",
    "title": "Review three synthetic invoices",
    "description": "Synthetic data. Correct the amount if needed and select the invoices to approve.",
    "source": {
      "kind": "sess_surface",
      "components": [
        {
          "type": "record",
          "label": "INV-1",
          "fields": {
            "id": "INV-1",
            "vendor": "Acme",
            "amount": 120
          }
        },
        {
          "type": "record",
          "label": "INV-2",
          "fields": {
            "id": "INV-2",
            "vendor": "Globex",
            "amount": 75.5
          }
        },
        {
          "type": "record",
          "label": "INV-3",
          "fields": {
            "id": "INV-3",
            "vendor": "Initech",
            "amount": 990
          }
        },
        {
          "type": "field",
          "name": "inv_3_amount",
          "label": "INV-3 amount",
          "required": true,
          "schema": {
            "type": "number",
            "minimum": 0,
            "maximum": 100000
          },
          "value": 990
        },
        {
          "type": "field",
          "name": "approved",
          "label": "Invoices to approve",
          "schema": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "INV-1",
                "INV-2",
                "INV-3"
              ]
            },
            "maxItems": 3
          },
          "value": []
        }
      ]
    },
    "actions": [
      {
        "id": "submit",
        "label": "Submit review",
        "intent": "submit"
      }
    ]
  }
}
201 response example: created
{
  "id": "ses_01JABCDEFGHJKMNPQRSTVWXYZ0",
  "revision": 1,
  "human_url": "https://sess.example/s/{token}",
  "workspace_id": "wks_0123456789abcdef0123",
  "management_credential": "sess_mg_SYNTHETICxEXAMPLExNOTxAxCREDENTIALxxxxxxxxx",
  "action_expires_at": "2026-01-01T01:00:00.000Z",
  "result_available_until": "2026-01-02T01:00:00.000Z",
  "trial_expires_at": "2026-01-02T00:00:00.000Z"
}

GET /v1/trial/sessions/{id}

Operation ID getTrialSession

A trial Session and its accepted responses, read with the trial’s management credential, until result_available_until. Reading never consumes or changes it. A Session of another trial or workspace, an unknown, expired or revoked credential, a human link or an owner key → 404 NOT_FOUND (generic).

Authentication: Authorization: Bearer <credential> (managementCredential — The trial management credential (sess_mg_…), returned once at trial creation.)

Parameters

Parameters of GET /v1/trial/sessions/{id}
NameInTypeRequiredDescription
idpathstringyes

Responses

Responses of GET /v1/trial/sessions/{id}
StatusDescriptionBodyHeaders
200The Session with its trial timing.TrialSessionResponseETag
404NOT_FOUND: any credential or isolation failure, an unknown /v1/trial path or a malformed trial URL (never 401 or 400)Error—
500INTERNALError—
503TRIAL_UNAVAILABLE: the trial is not configured on this deploymentError—
200 response example: responded
{
  "id": "ses_01JABCDEFGHJKMNPQRSTVWXYZ0",
  "status": "responded",
  "revision": 1,
  "interaction": {
    "mode": "interactive",
    "title": "Review three synthetic invoices",
    "description": "Synthetic data. Correct the amount if needed and select the invoices to approve.",
    "source": {
      "kind": "sess_surface",
      "components": [
        {
          "type": "record",
          "label": "INV-1",
          "fields": {
            "id": "INV-1",
            "vendor": "Acme",
            "amount": 120
          }
        },
        {
          "type": "record",
          "label": "INV-2",
          "fields": {
            "id": "INV-2",
            "vendor": "Globex",
            "amount": 75.5
          }
        },
        {
          "type": "record",
          "label": "INV-3",
          "fields": {
            "id": "INV-3",
            "vendor": "Initech",
            "amount": 990
          }
        },
        {
          "type": "field",
          "name": "inv_3_amount",
          "label": "INV-3 amount",
          "required": true,
          "schema": {
            "type": "number",
            "minimum": 0,
            "maximum": 100000
          },
          "value": 990
        },
        {
          "type": "field",
          "name": "approved",
          "label": "Invoices to approve",
          "schema": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "INV-1",
                "INV-2",
                "INV-3"
              ]
            },
            "maxItems": 3
          },
          "value": []
        }
      ]
    },
    "actions": [
      {
        "id": "submit",
        "label": "Submit review",
        "intent": "submit"
      }
    ],
    "response_policy": "first"
  },
  "response_schema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
      "inv_3_amount": {
        "type": "number",
        "minimum": 0,
        "maximum": 100000
      },
      "approved": {
        "type": "array",
        "items": {
          "type": "string",
          "enum": [
            "INV-1",
            "INV-2",
            "INV-3"
          ]
        },
        "maxItems": 3,
        "uniqueItems": true
      }
    },
    "required": [
      "inv_3_amount"
    ],
    "additionalProperties": false
  },
  "responses": [
    {
      "event_id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ1",
      "sequence": 1,
      "revision": 1,
      "action_id": "submit",
      "data": {
        "inv_3_amount": 909,
        "approved": [
          "INV-1",
          "INV-3"
        ]
      },
      "actor": {
        "assurance": "link_holder"
      },
      "accepted_at": "2026-01-01T00:00:00.000Z",
      "receipt": "synthetic-protected-header.synthetic-claims.synthetic-signature"
    }
  ],
  "trial": {
    "workspace_id": "wks_0123456789abcdef0123",
    "action_expires_at": "2026-01-01T01:00:00.000Z",
    "result_available_until": "2026-01-02T01:00:00.000Z"
  }
}

POST /v1/sessions

Operation ID createSession

Creates a display Session (mode display, source.kind data) or an interactive one (mode interactive, source.kind sess_surface; components: SurfaceComponent). An unrecognized component type → 400 UNKNOWN_COMPONENT; a field-schema keyword outside the supported subset → 400 INVALID_SCHEMA. An Idempotency-Key header is refused (400 INVALID_SCHEMA): the human link cannot be replayed (it is stored only as a hash). Retention: the human link expires 720 hours after creation with the deployment owner key and 168 hours with a developer API key (free plan). The Session’s content, accepted results and receipts are purged 720 hours (owner key) or 168 hours (developer API key) after the earlier of its completion and its link’s expiry, and outstanding webhook deliveries are cancelled; afterwards every owner route answers 404 SESSION_NOT_FOUND. A webhook already delivered is not recalled.

Authentication: Authorization: Bearer <credential> (ownerKey — An owner credential: the deployment owner key (acts in the operator workspace) or a developer API key sess_sk_… from the account pages (acts only in its developer workspace; a revoked or expired key → 401 UNAUTHORIZED). A Session of another workspace is 404 SESSION_NOT_FOUND.)

Request body (required)

Content type application/json: CreateSessionRequest

no additional properties

  • interaction object or object required

Responses

Responses of POST /v1/sessions
StatusDescriptionBodyHeaders
201Session created at revision 1.CreateSessionResponseETag, Location
400INVALID_SCHEMA or UNKNOWN_COMPONENTError—
401UNAUTHORIZEDError—
413PAYLOAD_TOO_LARGEError—
500INTERNALError—
Request example: display
{
  "interaction": {
    "mode": "display",
    "title": "Synthetic example",
    "description": "Synthetic data.",
    "source": {
      "kind": "data",
      "data": {
        "reference": "REF-1",
        "profile": {
          "name": "Example",
          "active": true
        },
        "rows": [
          {
            "id": "r1",
            "amount": 1
          },
          {
            "id": "r2",
            "amount": 2
          }
        ]
      }
    }
  }
}
Request example: interactive
{
  "interaction": {
    "mode": "interactive",
    "title": "Review three synthetic invoices",
    "description": "Synthetic data. Correct the amount if needed and select the invoices to approve.",
    "source": {
      "kind": "sess_surface",
      "components": [
        {
          "type": "record",
          "label": "INV-1",
          "fields": {
            "id": "INV-1",
            "vendor": "Acme",
            "amount": 120
          }
        },
        {
          "type": "record",
          "label": "INV-2",
          "fields": {
            "id": "INV-2",
            "vendor": "Globex",
            "amount": 75.5
          }
        },
        {
          "type": "record",
          "label": "INV-3",
          "fields": {
            "id": "INV-3",
            "vendor": "Initech",
            "amount": 990
          }
        },
        {
          "type": "field",
          "name": "inv_3_amount",
          "label": "INV-3 amount",
          "required": true,
          "schema": {
            "type": "number",
            "minimum": 0,
            "maximum": 100000
          },
          "value": 990
        },
        {
          "type": "field",
          "name": "approved",
          "label": "Invoices to approve",
          "schema": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "INV-1",
                "INV-2",
                "INV-3"
              ]
            },
            "maxItems": 3
          },
          "value": []
        }
      ]
    },
    "actions": [
      {
        "id": "submit",
        "label": "Submit review",
        "intent": "submit"
      }
    ]
  }
}

GET /v1/sessions/{id}

Operation ID getSession

The Session. Interactive Sessions return status, the current revision, its response_schema and every accepted response bound to its revision; repeated reads of an unchanged Session are byte-identical. A developer API key also reads the Sessions of trials its account claimed (read-only), each until that Session’s result_available_until.

Authentication: Authorization: Bearer <credential> (ownerKey — An owner credential: the deployment owner key (acts in the operator workspace) or a developer API key sess_sk_… from the account pages (acts only in its developer workspace; a revoked or expired key → 401 UNAUTHORIZED). A Session of another workspace is 404 SESSION_NOT_FOUND.)

Parameters

Parameters of GET /v1/sessions/{id}
NameInTypeRequiredDescription
idpathstringyes

Responses

Responses of GET /v1/sessions/{id}
StatusDescriptionBodyHeaders
200The current revision of the Session.SessionResponse or InteractiveSessionResponseETag
400INVALID_SCHEMAError—
401UNAUTHORIZEDError—
404SESSION_NOT_FOUNDError—
500INTERNALError—
200 response example: interactive
{
  "id": "ses_01JABCDEFGHJKMNPQRSTVWXYZ0",
  "status": "responded",
  "revision": 1,
  "interaction": {
    "mode": "interactive",
    "title": "Review three synthetic invoices",
    "description": "Synthetic data. Correct the amount if needed and select the invoices to approve.",
    "source": {
      "kind": "sess_surface",
      "components": [
        {
          "type": "record",
          "label": "INV-1",
          "fields": {
            "id": "INV-1",
            "vendor": "Acme",
            "amount": 120
          }
        },
        {
          "type": "record",
          "label": "INV-2",
          "fields": {
            "id": "INV-2",
            "vendor": "Globex",
            "amount": 75.5
          }
        },
        {
          "type": "record",
          "label": "INV-3",
          "fields": {
            "id": "INV-3",
            "vendor": "Initech",
            "amount": 990
          }
        },
        {
          "type": "field",
          "name": "inv_3_amount",
          "label": "INV-3 amount",
          "required": true,
          "schema": {
            "type": "number",
            "minimum": 0,
            "maximum": 100000
          },
          "value": 990
        },
        {
          "type": "field",
          "name": "approved",
          "label": "Invoices to approve",
          "schema": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "INV-1",
                "INV-2",
                "INV-3"
              ]
            },
            "maxItems": 3
          },
          "value": []
        }
      ]
    },
    "actions": [
      {
        "id": "submit",
        "label": "Submit review",
        "intent": "submit"
      }
    ],
    "response_policy": "first"
  },
  "response_schema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
      "inv_3_amount": {
        "type": "number",
        "minimum": 0,
        "maximum": 100000
      },
      "approved": {
        "type": "array",
        "items": {
          "type": "string",
          "enum": [
            "INV-1",
            "INV-2",
            "INV-3"
          ]
        },
        "maxItems": 3,
        "uniqueItems": true
      }
    },
    "required": [
      "inv_3_amount"
    ],
    "additionalProperties": false
  },
  "responses": [
    {
      "event_id": "evt_01JABCDEFGHJKMNPQRSTVWXYZ1",
      "sequence": 1,
      "revision": 1,
      "action_id": "submit",
      "data": {
        "inv_3_amount": 909,
        "approved": [
          "INV-1",
          "INV-3"
        ]
      },
      "actor": {
        "assurance": "link_holder"
      },
      "accepted_at": "2026-01-01T00:00:00.000Z",
      "receipt": "synthetic-protected-header.synthetic-claims.synthetic-signature"
    }
  ]
}

PATCH /v1/sessions/{id}

Operation ID publishRevision

Publishes the next immutable Surface revision of an interactive Session, from responded or active (superseding the unanswered revision). The Session returns to active on the same Session ID and human link; a submission against an older revision is then refused with SESSION_REVISION_CONFLICT.

Authentication: Authorization: Bearer <credential> (ownerKey — An owner credential: the deployment owner key (acts in the operator workspace) or a developer API key sess_sk_… from the account pages (acts only in its developer workspace; a revoked or expired key → 401 UNAUTHORIZED). A Session of another workspace is 404 SESSION_NOT_FOUND.)

Parameters

Parameters of PATCH /v1/sessions/{id}
NameInTypeRequiredDescription
idpathstringyes
If-MatchheaderstringyesThe strong ETag from the latest GET (e.g. "2.3"). Required: absent or * → 428 PRECONDITION_REQUIRED. A weak tag (W/"…") never matches (strong comparison); a stale tag → 412 SESSION_REVISION_CONFLICT.
Idempotency-KeyheaderstringnoScoped to the owner credential, the operation and the Session. The same canonical request (body and If-Match) returns the original result (status, ETag, body); a different request with the same key → 409 IDEMPOTENCY_CONFLICT. Only successful results are recorded.

Request body (required)

Content type application/json: PatchSessionRequest

no additional properties

  • interaction object required

    no additional properties

    • mode "interactive" required

    • title string required

      min length 1 · max length 200 · pattern \S

    • description string optional

      max length 4000

    • source object required

      no additional properties

      • kind "sess_surface" required

      • components array of object required

        min items 1 · max items 100

        • type string required

          min length 1 · max length 64

    • actions array of object required

      min items 1 · max items 5

      no additional properties

      • id string required

        pattern ^[a-z][a-z0-9_]{0,31}$

      • label string required

        min length 1 · max length 200 · pattern \S

      • intent "submit" or "continue" or "approve" or "reject" or "request_change" optional

    • response_policy "first" optional

      One accepted response per revision (the only P1 policy; the default).

Responses

Responses of PATCH /v1/sessions/{id}
StatusDescriptionBodyHeaders
200The Session at its new revision.InteractiveSessionResponseETag
400INVALID_SCHEMA or UNKNOWN_COMPONENTError—
401UNAUTHORIZEDError—
403ACTION_NOT_ALLOWED: a Session of a claimed trial (read-only)Error—
404SESSION_NOT_FOUNDError—
409SESSION_COMPLETED, ACTION_NOT_ALLOWED (display Session) or IDEMPOTENCY_CONFLICTError—
412SESSION_REVISION_CONFLICT (If-Match does not match the current ETag)Error—
413PAYLOAD_TOO_LARGEError—
428PRECONDITION_REQUIREDError—
500INTERNALError—

POST /v1/sessions/{id}/complete

Operation ID completeSession

Completes an interactive Session explicitly. Terminal: a completed Session accepts no further submission or revision. No request body.

Authentication: Authorization: Bearer <credential> (ownerKey — An owner credential: the deployment owner key (acts in the operator workspace) or a developer API key sess_sk_… from the account pages (acts only in its developer workspace; a revoked or expired key → 401 UNAUTHORIZED). A Session of another workspace is 404 SESSION_NOT_FOUND.)

Parameters

Parameters of POST /v1/sessions/{id}/complete
NameInTypeRequiredDescription
idpathstringyes
If-MatchheaderstringyesThe strong ETag from the latest GET (e.g. "2.3"). Required: absent or * → 428 PRECONDITION_REQUIRED. A weak tag (W/"…") never matches (strong comparison); a stale tag → 412 SESSION_REVISION_CONFLICT.
Idempotency-KeyheaderstringnoScoped to the owner credential, the operation and the Session. The same canonical request (body and If-Match) returns the original result (status, ETag, body); a different request with the same key → 409 IDEMPOTENCY_CONFLICT. Only successful results are recorded.

Responses

Responses of POST /v1/sessions/{id}/complete
StatusDescriptionBodyHeaders
200The completed Session.InteractiveSessionResponseETag
400INVALID_SCHEMAError—
401UNAUTHORIZEDError—
403ACTION_NOT_ALLOWED: a Session of a claimed trial (read-only)Error—
404SESSION_NOT_FOUNDError—
409SESSION_COMPLETED, ACTION_NOT_ALLOWED (display Session) or IDEMPOTENCY_CONFLICTError—
412SESSION_REVISION_CONFLICTError—
428PRECONDITION_REQUIREDError—
500INTERNALError—

GET /v1/sessions/{id}/events

Operation ID listSessionEvents

Every Event of the Session in sequence order: response.accepted (actor link_holder, the revision it was accepted on, action_id and the typed data), revision.published and session.completed (actor owner). Append-only: Event IDs and sequences never change, and every accepted result stays listed after later revisions and completion. Not paginated in P1 (a Session has a few Events per round). Display Sessions have none. Cache-Control: no-store, no-transform.

Authentication: Authorization: Bearer <credential> (ownerKey — An owner credential: the deployment owner key (acts in the operator workspace) or a developer API key sess_sk_… from the account pages (acts only in its developer workspace; a revoked or expired key → 401 UNAUTHORIZED). A Session of another workspace is 404 SESSION_NOT_FOUND.)

Parameters

Parameters of GET /v1/sessions/{id}/events
NameInTypeRequiredDescription
idpathstringyes

Responses

Responses of GET /v1/sessions/{id}/events
StatusDescriptionBodyHeaders
200The Event log.SessionEventsResponse—
401UNAUTHORIZEDError—
404SESSION_NOT_FOUNDError—
500INTERNALError—

GET /v1/sessions/{id}/surfaces/{revision}

Operation ID getSurfaceRevision

One immutable Surface revision exactly as stored: the interaction (and, for an interactive Session, the response schema) that responses on that revision are bound to. Cache-Control: no-store, no-transform.

Authentication: Authorization: Bearer <credential> (ownerKey — An owner credential: the deployment owner key (acts in the operator workspace) or a developer API key sess_sk_… from the account pages (acts only in its developer workspace; a revoked or expired key → 401 UNAUTHORIZED). A Session of another workspace is 404 SESSION_NOT_FOUND.)

Parameters

Parameters of GET /v1/sessions/{id}/surfaces/{revision}
NameInTypeRequiredDescription
idpathstringyes
revisionpathstringyes

Responses

Responses of GET /v1/sessions/{id}/surfaces/{revision}
StatusDescriptionBodyHeaders
200The revision.SessionResponse or InteractiveSurfaceResponse—
400INVALID_SCHEMA (revision is not a positive integer)Error—
401UNAUTHORIZEDError—
404SESSION_NOT_FOUND, or NOT_FOUND for a revision that does not existError—
500INTERNALError—

POST /s/{token}

Operation ID submitHumanAction

The human form submission (the human link is the capability; never log it). Accepted only from the page itself: Sec-Fetch-Site same-origin, or without Fetch Metadata an Origin equal to the public origin. The server resolves action_id from the exact stored revision and validates data against its response_schema. Responses are HTML pages whose stable code is in a data-error-code attribute.

Authentication: None (public)

Parameters

Parameters of POST /s/{token}
NameInTypeRequiredDescription
tokenpathstringyes

Request body (required)

Content type application/x-www-form-urlencoded: HumanSubmissionForm

properties named ^data\.[a-z][a-z0-9_]{0,63}$: string · no additional properties

  • client_event_id string required

    pattern ^[A-Za-z0-9_-]{16,64}$

  • surface_revision string required

    pattern ^[1-9][0-9]{0,8}$

  • action_id string required

    pattern ^[a-z][a-z0-9_]{0,31}$

Responses

Responses of POST /s/{token}
StatusDescriptionBodyHeaders
200Accepted (with a signed decision receipt stored with its Event, returned by the owner GET and the Event log), or a repeated client_event_id with the same request (original result and the same receipt, never re-signed).——
400INVALID_SCHEMA or ACTION_NOT_FOUND.——
403ACTION_NOT_ALLOWED: not a same-origin submission.——
404Unknown, expired or revoked link (generic).——
405ACTION_NOT_ALLOWED: a display Session.——
409SESSION_REVISION_CONFLICT (the current revision, prefilled with the safe draft), RESPONSE_LIMIT_REACHED, SESSION_COMPLETED or IDEMPOTENCY_CONFLICT.——
413PAYLOAD_TOO_LARGE.——
415INVALID_SCHEMA: not application/x-www-form-urlencoded.——
422VALIDATION_FAILED: the form with field errors.——
503SERVICE_UNAVAILABLE: the receipt keys are not configured; nothing is accepted.——

GET /v1/webhook

Operation ID getWebhook

The endpoint, the signing secrets in force (key IDs only) and delivery counts with the age of the oldest pending delivery.

Authentication: Authorization: Bearer <credential> (ownerKey — An owner credential: the deployment owner key (acts in the operator workspace) or a developer API key sess_sk_… from the account pages (acts only in its developer workspace; a revoked or expired key → 401 UNAUTHORIZED). A Session of another workspace is 404 SESSION_NOT_FOUND.)

Responses

Responses of GET /v1/webhook
StatusDescriptionBodyHeaders
200The webhook state.WebhookResponse—
401UNAUTHORIZEDError—

PUT /v1/webhook

Operation ID registerWebhook

Registers the owner workspace’s webhook endpoint (one return channel). It replaces the current endpoint, whose pending deliveries are not redirected (they fail as endpoint_unavailable; redeliver explicitly), and receives nothing until verified. The first registration also creates the signing secret, returned once. 503 SERVICE_UNAVAILABLE while data-encryption keys are not configured.

Authentication: Authorization: Bearer <credential> (ownerKey — An owner credential: the deployment owner key (acts in the operator workspace) or a developer API key sess_sk_… from the account pages (acts only in its developer workspace; a revoked or expired key → 401 UNAUTHORIZED). A Session of another workspace is 404 SESSION_NOT_FOUND.)

Request body (required)

Content type application/json: WebhookRegisterRequest

no additional properties

  • url string required

    Absolute https:// URL on port 443, without user info or fragment. Registering replaces the current endpoint (which stops receiving new deliveries); the new one receives nothing until verified.

    min length 1 · max length 2048

Responses

Responses of PUT /v1/webhook
StatusDescriptionBodyHeaders
201Registered (pending).WebhookRegisterResponse—
400WEBHOOK_INVALID_URL (reason: not_https, port, credentials, fragment, non_public_address, malformed, too_long) or INVALID_SCHEMAError—
401UNAUTHORIZEDError—
503SERVICE_UNAVAILABLEError—

POST /v1/webhook/verify

Operation ID verifyWebhook

POSTs a fresh random challenge to the exact registered URL through the delivery egress policy; the endpoint is verified when it echoes it, for 30 days (verification_expires_at). Verifying again renews it; an expired verification reads as pending (no new deliveries; queued ones fail endpoint_unavailable). Every connection resolves the host and refuses non-public addresses.

Authentication: Authorization: Bearer <credential> (ownerKey — An owner credential: the deployment owner key (acts in the operator workspace) or a developer API key sess_sk_… from the account pages (acts only in its developer workspace; a revoked or expired key → 401 UNAUTHORIZED). A Session of another workspace is 404 SESSION_NOT_FOUND.)

Responses

Responses of POST /v1/webhook/verify
StatusDescriptionBodyHeaders
200Verified.——
401UNAUTHORIZEDError—
409WEBHOOK_NOT_CONFIGUREDError—
422WEBHOOK_VERIFICATION_FAILED (reason: egress_refused, redirect, rejected, bad_answer, timeout, connection, dns)Error—
503SERVICE_UNAVAILABLEError—

POST /v1/webhook/secrets/rotate

Operation ID rotateWebhookSecret

Creates a new signing secret (returned once). The previous one keeps signing for a 24-hour overlap, so deliveries carry both signatures until then.

Authentication: Authorization: Bearer <credential> (ownerKey — An owner credential: the deployment owner key (acts in the operator workspace) or a developer API key sess_sk_… from the account pages (acts only in its developer workspace; a revoked or expired key → 401 UNAUTHORIZED). A Session of another workspace is 404 SESSION_NOT_FOUND.)

Responses

Responses of POST /v1/webhook/secrets/rotate
StatusDescriptionBodyHeaders
201Rotated.WebhookRotateResponse—
401UNAUTHORIZEDError—
409WEBHOOK_NOT_CONFIGUREDError—
503SERVICE_UNAVAILABLEError—

GET /v1/sessions/{id}/deliveries

Operation ID listDeliveries

Every webhook delivery job of the Session’s accepted responses with every attempt (outcome and HTTP status), including permanent failures and exhausted retries.

Authentication: Authorization: Bearer <credential> (ownerKey — An owner credential: the deployment owner key (acts in the operator workspace) or a developer API key sess_sk_… from the account pages (acts only in its developer workspace; a revoked or expired key → 401 UNAUTHORIZED). A Session of another workspace is 404 SESSION_NOT_FOUND.)

Parameters

Parameters of GET /v1/sessions/{id}/deliveries
NameInTypeRequiredDescription
idpathstringyes

Responses

Responses of GET /v1/sessions/{id}/deliveries
StatusDescriptionBodyHeaders
200The delivery log.DeliveriesResponse—
401UNAUTHORIZEDError—
404SESSION_NOT_FOUNDError—

POST /v1/sessions/{id}/events/{event_id}/redeliver

Operation ID redeliverEvent

Queues the accepted Event for delivery again to the current verified endpoint, with a fresh retry budget. The message is the same bytes (same event_id and receipt). A delivery already pending for the Event to the current endpoint is returned instead; one pending for a replaced endpoint is ended (endpoint_unavailable) and a new one queued.

Authentication: Authorization: Bearer <credential> (ownerKey — An owner credential: the deployment owner key (acts in the operator workspace) or a developer API key sess_sk_… from the account pages (acts only in its developer workspace; a revoked or expired key → 401 UNAUTHORIZED). A Session of another workspace is 404 SESSION_NOT_FOUND.)

Parameters

Parameters of POST /v1/sessions/{id}/events/{event_id}/redeliver
NameInTypeRequiredDescription
idpathstringyes
event_idpathstringyes

Responses

Responses of POST /v1/sessions/{id}/events/{event_id}/redeliver
StatusDescriptionBodyHeaders
202Queued.——
401UNAUTHORIZEDError—
403ACTION_NOT_ALLOWED: a Session of a claimed trial (read-only)Error—
404NOT_FOUND (no such accepted Event in this Session)Error—
409WEBHOOK_NOT_CONFIGURED (no verified endpoint)Error—

GET /.well-known/sess-receipt-keys.json

Operation ID receiptKeys

The public decision-receipt verification keys as a JWK Set (Ed25519, alg EdDSA): the active signing key and every retained key of the rotation overlap. Verify a receipt (compact JWS, typ sess-receipt+jwt) with the key its protected header kid names, issuer = this origin, audience = the Session’s workspace (wks_operator for owner-API Sessions, the trial’s workspace_id for trial Sessions). No credential. 503 SERVICE_UNAVAILABLE while the receipt keys are not configured. Cache-Control: no-store, no-transform.

Authentication: None (public)

Responses

Responses of GET /.well-known/sess-receipt-keys.json
StatusDescriptionBodyHeaders
200The JWK Set.ReceiptKeysResponse—
503SERVICE_UNAVAILABLEError—

GET /openapi.json

Operation ID openApi

This document: the generated, CI-drift-checked contract of the artifact.

Authentication: None (public)

Responses

Responses of GET /openapi.json
StatusDescriptionBodyHeaders
200The OpenAPI 3.1 document.——

GET /health/live

Operation ID healthLive

Process liveness only: no dependency is called. Cache-Control: no-store.

Authentication: None (public)

Responses

Responses of GET /health/live
StatusDescriptionBodyHeaders
200The process is running.HealthOk—

GET /health/ready

Operation ID healthReady

Readiness, checked within a bound and never cached: the owner key and the decision-receipt signing keys are configured and usable, the build identity is complete and valid (git_sha, build_id and build_time are all non-null in /version), the database answers, and every migration bundled with the artifact is applied. Concurrent requests share the check in progress; the next request after it settles runs a new one. Never migrates and never calls a telemetry backend. Query parameters are ignored. Cache-Control: no-store.

Authentication: None (public)

Responses

Responses of GET /health/ready
StatusDescriptionBodyHeaders
200Ready to serve.HealthOk—
503Not ready: configuration, database or schema. No detail is disclosed.HealthUnavailable—

GET /version

Operation ID version

Non-secret build identity. Answers 200 even when readiness does not. git_sha, build_id and build_time are each null when not supplied or invalid (git_sha: SESS_GIT_SHA missing, empty or malformed; build_time also while it is more than 5 s in the future, checked per request); any null fails readiness (503). Cache-Control: no-store.

Authentication: None (public)

Responses

Responses of GET /version
StatusDescriptionBodyHeaders
200The build identity of the running artifact.VersionResponse—
200 response example: configured
{
  "git_sha": "0123456789abcdef0123456789abcdef01234567",
  "build_id": "synthetic-build-1",
  "build_time": "2026-01-01T00:00:00Z",
  "node_version": "v24.21.0"
}
200 response example: withoutGitSha
{
  "git_sha": null,
  "build_id": "synthetic-build-1",
  "build_time": "2026-01-01T00:00:00Z",
  "node_version": "v24.21.0"
}

Webhooks sent by Sess

Requests Sess sends to your registered, verified endpoint.

POST responseAccepted

Operation ID webhookResponseAccepted

Sent for every accepted response while the workspace has a verified endpoint. Signed per workspace (Standard Webhooks v1): webhook-id = event_id (stable across retries and redeliveries: deduplicate on it), webhook-timestamp (seconds), webhook-signature = space-separated v1,<base64 HMAC-SHA256(secret, id.timestamp.body)>, one per secret in force (two during a 24-hour rotation overlap), sess-webhook-key-ids = their key IDs. HTTPS on port 443, no redirects followed, 10-second timeout, response read up to 64 KiB. 2xx = accepted by the endpoint (not that the workflow resumed); 5xx, 429 (Retry-After honored up to 1 h), 408, 425, timeouts and disconnects are retried with jitter up to 12 attempts within 24 h (a job out of budget ends exhausted); 3xx and other 4xx (including 401/403) are permanent. Delivery is at least once.

Body: application/json: WebhookDelivery

POST endpointVerification

Operation ID webhookEndpointVerification

Sent by POST /v1/webhook/verify to the exact registered URL, signed like deliveries. Answer 2xx with a JSON body (at most 4 KiB) {"challenge": <the same value>}.

Body: application/json: WebhookVerification

Error codes

Errors use one envelope: {"error": {"code", "message", "request_id"}}. Branch on code, never on message. Quote request_id when you contact support.

  • INVALID_SCHEMA
  • PAYLOAD_TOO_LARGE
  • UNAUTHORIZED
  • SESSION_NOT_FOUND
  • NOT_FOUND
  • INTERNAL
  • UNKNOWN_COMPONENT
  • SESSION_REVISION_CONFLICT
  • IDEMPOTENCY_CONFLICT
  • PRECONDITION_REQUIRED
  • SESSION_COMPLETED
  • ACTION_NOT_ALLOWED
  • ACTION_NOT_FOUND
  • VALIDATION_FAILED
  • RESPONSE_LIMIT_REACHED
  • SERVICE_UNAVAILABLE
  • RATE_LIMITED
  • TRIAL_UNAVAILABLE
  • SIGN_IN_UNAVAILABLE
  • WEBHOOK_INVALID_URL
  • WEBHOOK_VERIFICATION_FAILED
  • WEBHOOK_NOT_CONFIGURED

Schemas

CreateSessionRequest

no additional properties

  • interaction object or object required

CreateSessionResponse

no additional properties

  • id string required

    pattern ^ses_[0-9A-HJKMNP-TV-Z]{26}$

  • revision integer required

    minimum 1

  • human_url string required

SessionResponse

no additional properties

  • id string required

    pattern ^ses_[0-9A-HJKMNP-TV-Z]{26}$

  • revision integer required

    minimum 1

  • interaction object required

    no additional properties

    • mode "display" required

    • title string required

      min length 1 · max length 200 · pattern \S

    • description string optional

      max length 4000

    • source object required

      no additional properties

      • kind "data" required

      • data map of string to string or number or boolean or null or map of string to string or number or boolean or null or array of map of string to string or number or boolean or null required

        min properties 1

InteractiveSessionResponse

no additional properties

  • id string required

    pattern ^ses_[0-9A-HJKMNP-TV-Z]{26}$

  • status "active" or "responded" or "completed" required

  • revision integer required

    The current Surface revision.

    minimum 1

  • interaction object required

    no additional properties

    • mode "interactive" required

    • title string required

      min length 1 · max length 200 · pattern \S

    • description string optional

      max length 4000

    • source object required

      no additional properties

      • kind "sess_surface" required

      • components array of object or object or object or object required

    • actions array of object required

      no additional properties

      • id string required

        pattern ^[a-z][a-z0-9_]{0,31}$

      • label string required

        min length 1 · max length 200 · pattern \S

      • intent "submit" or "continue" or "approve" or "reject" or "request_change" optional

    • response_policy "first" required

  • response_schema object required

    The JSON Schema 2020-12 the current revision’s responses are validated against.

  • responses array of object required

    Every accepted response, in sequence order, each bound to its revision.

    no additional properties

    • event_id string required

      pattern ^evt_[0-9A-HJKMNP-TV-Z]{26}$

    • sequence integer required

      Monotonic per-Session Event sequence.

      minimum 1

    • revision integer required

      The Surface revision it was accepted on.

      minimum 1

    • action_id string required

      pattern ^[a-z][a-z0-9_]{0,31}$

    • data object required

      The normalized typed result, valid against that revision’s response_schema.

    • actor object required

      no additional properties

      • assurance "link_holder" required

    • accepted_at string required

      ISO 8601 UTC time of acceptance.

    • receipt string or null required

      The signed decision receipt: a compact JWS (EdDSA/Ed25519, typ sess-receipt+jwt, kid) over the RFC 8785 canonical claims, verifiable with GET /.well-known/sess-receipt-keys.json. Issued once in the acceptance transaction and never re-signed. Its exp is at least 720 hours after acceptance and, for an owner-key Session that is purged automatically, no earlier than the Session’s latest possible purge (its human link’s expiry plus its retention after it ends). null only for responses accepted before receipts existed.

InteractiveSurfaceResponse

no additional properties

  • id string required

    pattern ^ses_[0-9A-HJKMNP-TV-Z]{26}$

  • revision integer required

    minimum 1

  • interaction object required

    no additional properties

    • mode "interactive" required

    • title string required

      min length 1 · max length 200 · pattern \S

    • description string optional

      max length 4000

    • source object required

      no additional properties

      • kind "sess_surface" required

      • components array of object or object or object or object required

    • actions array of object required

      no additional properties

      • id string required

        pattern ^[a-z][a-z0-9_]{0,31}$

      • label string required

        min length 1 · max length 200 · pattern \S

      • intent "submit" or "continue" or "approve" or "reject" or "request_change" optional

    • response_policy "first" required

  • response_schema object required

SessionEventsResponse

no additional properties

  • id string required

    pattern ^ses_[0-9A-HJKMNP-TV-Z]{26}$

  • events array of object required

    Every Event of the Session, in sequence order (append-only; never rewritten).

    no additional properties

    • event_id string required

      pattern ^evt_[0-9A-HJKMNP-TV-Z]{26}$

    • sequence integer required

      Monotonic per-Session sequence.

      minimum 1

    • type "response.accepted" or "revision.published" or "session.completed" required

    • revision integer required

      response.accepted: the revision the response was accepted on; revision.published: the revision published; session.completed: the current revision at completion.

      minimum 1

    • actor object required

      no additional properties

      • assurance "link_holder" or "owner" required

    • action_id string optional

      pattern ^[a-z][a-z0-9_]{0,31}$

    • data object optional

      response.accepted only: the typed result, valid against that revision.

    • created_at string required

      ISO 8601 UTC time the Event was recorded.

    • receipt string or null optional

      The signed decision receipt: a compact JWS (EdDSA/Ed25519, typ sess-receipt+jwt, kid) over the RFC 8785 canonical claims, verifiable with GET /.well-known/sess-receipt-keys.json. Issued once in the acceptance transaction and never re-signed. Its exp is at least 720 hours after acceptance and, for an owner-key Session that is purged automatically, no earlier than the Session’s latest possible purge (its human link’s expiry plus its retention after it ends). null only for responses accepted before receipts existed.

ReceiptKeysResponse

no additional properties

  • keys array of object required

    The active signing key and every retained verification key (rotation overlap). A receipt verifies with the key whose kid its protected header names; there is no fallback key.

    no additional properties

    • kty "OKP" required

    • crv "Ed25519" required

    • x string required

    • kid string required

      pattern ^[A-Za-z0-9._-]{1,64}$

    • alg "EdDSA" required

    • use "sig" required

WebhookRegisterRequest

no additional properties

  • url string required

    Absolute https:// URL on port 443, without user info or fragment. Registering replaces the current endpoint (which stops receiving new deliveries); the new one receives nothing until verified.

    min length 1 · max length 2048

WebhookRegisterResponse

no additional properties

  • endpoint object required

    no additional properties

    • id string required

      pattern ^whe_[0-9A-HJKMNP-TV-Z]{26}$

    • url string required

    • status "pending" or "verified" required

    • created_at string required

    • verified_at string or null required

    • verification_expires_at string or null required

      The verification lapses 30 days after it succeeds; after that the endpoint is pending again (no new deliveries; queued ones fail endpoint_unavailable) until re-verified.

  • signing_secret object or null required

    The workspace’s first signing secret when this registration created it, else null.

WebhookResponse

no additional properties

  • endpoint object or null required

  • signing_secrets array of object required

    Secrets in force, newest first (never the secret values).

    no additional properties

    • kid string required

    • active boolean required

    • retire_at string or null required

  • deliveries object required

    no additional properties

    • pending integer required

      minimum 0

    • failed integer required

      minimum 0

    • delivered integer required

      minimum 0

    • oldest_pending_age_seconds integer or null required

WebhookRotateResponse

no additional properties

  • signing_secret object required

    no additional properties

    • kid string required

      pattern ^wk_[0-9A-HJKMNP-TV-Z]{26}$

    • secret string required

      Shown once. Store it in the receiver; Sess keeps it only encrypted.

      pattern ^whsec_[A-Za-z0-9+/]{43}=$

  • previous object or null required

DeliveriesResponse

no additional properties

  • id string required

  • deliveries array of object required

    no additional properties

    • delivery_id string required

      pattern ^obx_[0-9A-HJKMNP-TV-Z]{26}$

    • event_id string required

    • kind "accepted" or "redelivery" required

    • status "pending" or "delivered" or "failed" required

    • endpoint_id string required

    • next_attempt_at string or null required

    • deadline_at string required

    • created_at string required

    • finished_at string or null required

    • last_outcome "started" or "delivered" or "server_error" or "rate_limited" or "timeout" or "connection" or "dns" or "signing_unavailable" or "request_timeout" or "too_early" or "rejected" or "redirect" or "egress_refused" or "endpoint_unavailable" or "exhausted" or null required

      The job-level outcome: the last attempt’s, or exhausted when the attempt or time budget ran out, or endpoint_unavailable when its endpoint was replaced, disabled or its verification lapsed.

    • attempts array of object required

      Every started attempt. started with no finish time: the attempt was interrupted (e.g. a crash); the outcome at the endpoint is unknown and the job is retried.

      no additional properties

      • attempt integer required

        minimum 1

      • started_at string required

      • finished_at string or null required

      • outcome "started" or "delivered" or "server_error" or "rate_limited" or "timeout" or "connection" or "dns" or "signing_unavailable" or "request_timeout" or "too_early" or "rejected" or "redirect" or "egress_refused" or "endpoint_unavailable" or "exhausted" required

      • http_status integer or null required

WebhookDelivery

no additional properties

  • type "response.accepted" required

  • event_id string required

    Stable across retries and redeliveries: deduplicate on it.

  • session_id string required

  • sequence integer required

  • revision integer required

  • action_id string required

  • data object required

  • accepted_at string required

  • receipt string or null required

    The stored signed decision receipt (identical on every delivery).

WebhookVerification

no additional properties

  • type "sess.webhook.verification" required

  • challenge string required

PatchSessionRequest

no additional properties

  • interaction object required

    no additional properties

    • mode "interactive" required

    • title string required

      min length 1 · max length 200 · pattern \S

    • description string optional

      max length 4000

    • source object required

      no additional properties

      • kind "sess_surface" required

      • components array of object required

        min items 1 · max items 100

        • type string required

          min length 1 · max length 64

    • actions array of object required

      min items 1 · max items 5

      no additional properties

      • id string required

        pattern ^[a-z][a-z0-9_]{0,31}$

      • label string required

        min length 1 · max length 200 · pattern \S

      • intent "submit" or "continue" or "approve" or "reject" or "request_change" optional

    • response_policy "first" optional

      One accepted response per revision (the only P1 policy; the default).

SurfaceComponent

Type: object or object or object or object

HumanSubmissionForm

properties named ^data\.[a-z][a-z0-9_]{0,63}$: string · no additional properties

  • client_event_id string required

    pattern ^[A-Za-z0-9_-]{16,64}$

  • surface_revision string required

    pattern ^[1-9][0-9]{0,8}$

  • action_id string required

    pattern ^[a-z][a-z0-9_]{0,31}$

Error

no additional properties

  • error object required

    no additional properties

    • code "INVALID_SCHEMA" or "PAYLOAD_TOO_LARGE" or "UNAUTHORIZED" or "SESSION_NOT_FOUND" or "NOT_FOUND" or "INTERNAL" or "UNKNOWN_COMPONENT" or "SESSION_REVISION_CONFLICT" or "IDEMPOTENCY_CONFLICT" or "PRECONDITION_REQUIRED" or "SESSION_COMPLETED" or "ACTION_NOT_ALLOWED" or "ACTION_NOT_FOUND" or "VALIDATION_FAILED" or "RESPONSE_LIMIT_REACHED" or "SERVICE_UNAVAILABLE" or "RATE_LIMITED" or "TRIAL_UNAVAILABLE" or "SIGN_IN_UNAVAILABLE" or "WEBHOOK_INVALID_URL" or "WEBHOOK_VERIFICATION_FAILED" or "WEBHOOK_NOT_CONFIGURED" required

    • message string required

    • request_id string required

      min length 1

    • reason string optional

      A stable machine-readable refinement of some codes (P1 A4 webhook errors).

      pattern ^[a-z_]{1,40}$

HealthOk

no additional properties

  • status "ok" required

HealthUnavailable

no additional properties

  • status "unavailable" required

VersionResponse

no additional properties

  • git_sha string or null required

    The deployed commit, from SESS_GIT_SHA. null when SESS_GIT_SHA is missing, empty or not exactly 40 lower-case hex characters; readiness then answers 503. Never derived from a checkout or normalized.

  • build_id string or null required

    SESS_BUILD_ID, else the BUILD_ID file at the workspace root of the image. null when neither supplies a valid one; readiness then answers 503.

  • build_time string or null required

    ISO 8601 UTC build time, from SESS_BUILD_TIME, else the BUILD_TIME file at the workspace root of the image. Valid when it has real calendar components and is not more than 5 s after the current time, checked on every request. null when neither supplies a valid one, and readiness then answers 503; never the start time.

  • node_version string required

    The Node.js version (process.version).

TrialCreateSessionRequest

no additional properties

  • interaction object required

    no additional properties

    • mode "interactive" required

    • title string required

      min length 1 · max length 200 · pattern \S

    • description string optional

      max length 4000

    • source object required

      no additional properties

      • kind "sess_surface" required

      • components array of object required

        min items 1 · max items 100

        • type string required

          min length 1 · max length 64

    • actions array of object required

      min items 1 · max items 5

      no additional properties

      • id string required

        pattern ^[a-z][a-z0-9_]{0,31}$

      • label string required

        min length 1 · max length 200 · pattern \S

      • intent "submit" or "continue" or "approve" or "reject" or "request_change" optional

    • response_policy "first" optional

      One accepted response per revision (the only P1 policy; the default).

TrialCreateSessionResponse

no additional properties

  • id string required

    pattern ^ses_[0-9A-HJKMNP-TV-Z]{26}$

  • revision integer required

    minimum 1

  • human_url string required

    The human link (a capability): share it only with the responder.

  • workspace_id string required

    The trial workspace this Session belongs to.

  • management_credential string optional

    Returned once, only when this request created the trial (no Authorization header). It reads this trial’s results and creates further Sessions in it; it is never retrievable again. Keep it secret; never put it in a URL.

    pattern ^sess_mg_[A-Za-z0-9_-]{43}$

  • action_expires_at string required

    After this instant the human link accepts no response.

  • result_available_until string required

    Until this instant the result can be read with the management credential.

  • trial_expires_at string required

    After this instant the trial creates no further Session.

TrialSessionResponse

no additional properties

  • id string required

    pattern ^ses_[0-9A-HJKMNP-TV-Z]{26}$

  • status "active" or "responded" or "completed" required

  • revision integer required

    The current Surface revision.

    minimum 1

  • interaction object required

    no additional properties

    • mode "interactive" required

    • title string required

      min length 1 · max length 200 · pattern \S

    • description string optional

      max length 4000

    • source object required

      no additional properties

      • kind "sess_surface" required

      • components array of object or object or object or object required

    • actions array of object required

      no additional properties

      • id string required

        pattern ^[a-z][a-z0-9_]{0,31}$

      • label string required

        min length 1 · max length 200 · pattern \S

      • intent "submit" or "continue" or "approve" or "reject" or "request_change" optional

    • response_policy "first" required

  • response_schema object required

    The JSON Schema 2020-12 the current revision’s responses are validated against.

  • responses array of object required

    Every accepted response, in sequence order, each bound to its revision.

    no additional properties

    • event_id string required

      pattern ^evt_[0-9A-HJKMNP-TV-Z]{26}$

    • sequence integer required

      Monotonic per-Session Event sequence.

      minimum 1

    • revision integer required

      The Surface revision it was accepted on.

      minimum 1

    • action_id string required

      pattern ^[a-z][a-z0-9_]{0,31}$

    • data object required

      The normalized typed result, valid against that revision’s response_schema.

    • actor object required

      no additional properties

      • assurance "link_holder" required

    • accepted_at string required

      ISO 8601 UTC time of acceptance.

    • receipt string or null required

      The signed decision receipt: a compact JWS (EdDSA/Ed25519, typ sess-receipt+jwt, kid) over the RFC 8785 canonical claims, verifiable with GET /.well-known/sess-receipt-keys.json. Issued once in the acceptance transaction and never re-signed. Its exp is at least 720 hours after acceptance and, for an owner-key Session that is purged automatically, no earlier than the Session’s latest possible purge (its human link’s expiry plus its retention after it ends). null only for responses accepted before receipts existed.

  • trial object required

    no additional properties

    • workspace_id string required

    • action_expires_at string required

      After this instant the human link accepts no response.

    • result_available_until string required

      Until this instant this result remains readable.

EmailLinkRequest

no additional properties

  • email string required

    The address to send a sign-in link to. Trimmed and lower-cased.

    min length 3 · max length 254

EmailLinkAccepted

no additional properties

  • status "accepted" required

    The link was handed to the email provider. The same answer for every address: it never says whether an account exists.