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

# Create a client session

> Create a short-lived client session for one existing UPA, from your backend.

Call this from your backend with your app credentials, after your own auth has identified the user. Identify exactly one existing account by `accountId` or `externalUserId`. Both are strict lookups: this endpoint never creates or updates a UPA, so create the account through the Partner API first.

Grant only the `permissions` this browser or mobile flow needs; omitted permissions default to `account:read`. Each permission also requires the matching app module and issuing credential scope. The app secret stays on your backend. Pass the returned `clientSessionToken` to the client, which [exchanges it once](/api-reference/client-sessions/exchange-client-session) for a client bearer token.

See [Authentication](/authentication).


## OpenAPI

````yaml frontend-openapi.json POST /v2/client-sessions
openapi: 3.1.0
info:
  title: Stableyard Interfaces & SDK API
  version: 2.0.0-staging
  x-stableyard-api-version: '2026-09-09'
  x-stableyard-supported-api-versions:
    - '2026-09-09'
  summary: >-
    Advanced browser API used by Stableyard Checkout, Add Money, and
    account-bound interfaces.
  description: >

    These endpoints power Stableyard's official interface SDKs, hosted checkout,
    Add Money, and advanced custom browser integrations.


    Most partners should use `@stableyard/react` or `@stableyard/sdk` instead of
    calling these routes directly. A browser must never receive an app secret.
    Public checkout uses a Payment-scoped client secret, while account-bound
    experiences use a short-lived client bearer token created by the partner
    backend.
  x-stableyard-documentation-surface: frontend
servers:
  - url: https://prod-api.stableyard.fi
    description: Production
  - url: https://staging-api-v2.stableyard.fi
    description: Staging
  - url: http://localhost:3001
    description: Local
security: []
tags:
  - name: Authentication
    x-displayName: API authentication
    description: Verify your app ID and app secret before calling UPA APIs.
  - name: Client API
    description: >-
      Account-bound browser and mobile routes authenticated with a short-lived
      client bearer token. App secrets never enter client code.
  - name: Identity & KYC
    description: >-
      Verify the UPA email and run provider-neutral identity verification.
      Managed vaults and fiat payment rails use this same verified UPA identity.
  - name: Payments
    description: >-
      Create escrow-first payments, issue partner-authenticated send
      instructions or executions, power public checkout, and reconcile
      collection through final account settlement.
paths:
  /v2/client-sessions:
    post:
      tags:
        - Client API
      summary: Create client session
      description: >-
        Creates a short-lived Stableyard client session for exactly one existing
        account. Call this from your backend after your existing app auth has
        identified the user. Both accountId and externalUserId are strict
        lookups: this endpoint never creates or updates a UPA. Create the
        account through the Partner API first. Explicitly grant only the client
        permissions this browser or mobile flow needs; omitted permissions
        default to account:read. The app secret stays backend-only; the returned
        clientSessionToken can be passed to the client and exchanged once for a
        client bearer token.
      operationId: createClientSession
      parameters:
        - name: Stableyard-Version
          in: header
          required: false
          schema:
            type: string
            enum:
              - '2026-09-09'
          description: >-
            Optional contract-version assertion. Omit it to use the app
            environment's pinned version. A different supported version is
            accepted only after that environment is explicitly migrated.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateClientSessionRequest'
            examples:
              byAccountId:
                summary: Existing account
                value:
                  accountId: acct_123
                  expiresInSeconds: 600
                  permissions:
                    - account:read
                    - payments:read
                    - payments:write
              byExternalUserId:
                summary: Partner user id
                value:
                  externalUserId: user_123
                  expiresInSeconds: 600
                  permissions:
                    - account:read
                    - deposits:read
                    - deposits:write
      responses:
        '200':
          description: Client session token
          headers:
            Stableyard-Version:
              description: >-
                Effective date-based Stableyard API contract version for this
                response.
              schema:
                type: string
                enum:
                  - '2026-09-09'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClientSessionResponse'
              examples:
                example:
                  summary: Create client session 200 response
                  value:
                    clientSessionId: session_123
                    clientSessionToken: client_session_token_opaque_value_1234567890
                    apiVersion: '2026-09-09'
                    permissions:
                      - account:read
                    expiresAt: '2026-08-28T10:00:00.000Z'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '424':
          $ref: '#/components/responses/FailedDependency'
        '429':
          $ref: '#/components/responses/TooManyRequests'
      security:
        - partnerBasicAuth: []
components:
  schemas:
    CreateClientSessionRequest:
      title: Create client session request
      description: Bind the client session to exactly one UPA using either identifier.
      type: object
      additionalProperties: false
      properties:
        accountId:
          type: string
          example: acct_123
          description: Stableyard account id for the authenticated app user.
        externalUserId:
          type: string
          maxLength: 128
          example: user_123
          description: Partner-owned external user id.
        expiresInSeconds:
          type: integer
          minimum: 60
          maximum: 3600
          default: 600
        permissions:
          type: array
          minItems: 1
          maxItems: 6
          uniqueItems: true
          default:
            - account:read
          description: >-
            Least-privilege operations embedded in this account-bound client
            token. Each permission also requires the matching app module and
            issuing credential scope.
          items:
            $ref: '#/components/schemas/ClientPermission'
      oneOf:
        - title: Stableyard account ID
          required:
            - accountId
        - title: External user ID
          required:
            - externalUserId
    ClientSessionResponse:
      type: object
      additionalProperties: false
      required:
        - clientSessionId
        - clientSessionToken
        - apiVersion
        - permissions
        - expiresAt
      properties:
        clientSessionId:
          type: string
          example: session_123
        clientSessionToken:
          type: string
          minLength: 32
          maxLength: 4096
          example: client_session_token_opaque_value_1234567890
        apiVersion:
          $ref: '#/components/schemas/StableyardApiVersion'
        permissions:
          type: array
          items:
            $ref: '#/components/schemas/ClientPermission'
        expiresAt:
          type: string
          format: date-time
    ClientPermission:
      type: string
      enum:
        - account:read
        - payments:read
        - payments:write
        - deposits:read
        - deposits:write
        - vault_payments:write
      description: >-
        Account-bound browser/mobile authority granted by the partner backend.
        This is narrower than the issuing app credential and cannot enable a
        disabled app product.
    StableyardApiVersion:
      type: string
      enum:
        - '2026-08-28'
        - '2026-09-09'
      example: '2026-09-09'
      description: >-
        Immutable date-based contract recorded on the resource. Historical
        values may appear on existing records; only versions advertised in
        x-stableyard-supported-api-versions are accepted for new requests.
    ErrorResponse:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - message
          properties:
            code:
              type: string
              minLength: 1
              maxLength: 128
              example: bad_request
            message:
              type: string
              minLength: 1
              maxLength: 1000
              example: The request is invalid
            details: {}
  responses:
    BadRequest:
      description: Bad request
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: BadRequest response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    Unauthorized:
      description: Unauthorized
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: Unauthorized response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    Forbidden:
      description: The app secret does not include the required scope
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: Forbidden response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    NotFound:
      description: Not found
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: NotFound response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    Conflict:
      description: Conflict
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: Conflict response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    FailedDependency:
      description: Required chain, network, or provider configuration is missing
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: FailedDependency response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    TooManyRequests:
      description: >-
        Rate limit, payment-option limit, selection cooldown, or temporary abuse
        block
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
        Retry-After:
          description: Seconds until the caller should retry.
          schema:
            type: integer
            minimum: 1
        RateLimit-Limit:
          description: Quota for the most constrained policy.
          schema:
            type: integer
            minimum: 1
        RateLimit-Remaining:
          description: Requests remaining in that policy window.
          schema:
            type: integer
            minimum: 0
        RateLimit-Reset:
          description: Seconds until that policy window resets.
          schema:
            type: integer
            minimum: 0
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: TooManyRequests response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
  securitySchemes:
    partnerBasicAuth:
      type: http
      scheme: basic
      description: >-
        HTTP Basic auth. Username is the Stableyard app ID. Password is the app
        secret. The optional Stableyard-Version request header must match the
        environment pin.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.