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

# Renew a widget session token

> Requires a valid widget bearer token with 60 seconds of clock-skew tolerance: serverNow must be strictly before exp + 60 seconds. Hard session expiry has no tolerance. A token beyond the drift window fails with TOKEN_EXPIRED and requires newer credentials or explicit app reauthentication; never recursively renew or automatically replace the session. Resolves the token's existing session, rechecks current session and authorization policy, and returns fresh credentials for that same session. The required workspace ID must match the authenticated session; no session ID or management credential is supplied. Preserves identity, scope, secrets, pinned parameters, counters, and hard session expiry. Other unexpired tokens remain valid. Returns tokenExpiresAt and sessionExpiresAt with Cache-Control: no-store. Revoked, expired, and exhausted sessions cannot renew.



## OpenAPI

````yaml /widgets-api-spec.yml post /v1/workspaces/{workspaceId}/session:renew
openapi: 3.1.0
info:
  title: Cadenya Widgets API
  description: >-
    Browser-facing API for the embeddable Cadenya chat widget. The customer's
    backend authenticates the visitor and creates the initial session. The
    browser renews that same session through RenewWidgetSession using its
    existing bearer token and required workspace ID, with no session ID in the
    request. Both return tokenExpiresAt and sessionExpiresAt; renewal never
    extends the session deadline. Renewal requires a valid token with 60 seconds
    of clock-skew tolerance; hard session expiry has no tolerance. Management
    credentials remain server-side. Terminal session errors never create a
    replacement. The only unauthenticated route is the widget config.
  version: '1.0'
servers:
  - url: https://{widgetHost}
    description: The Widget host returned in a Widget Session's info.host
    variables:
      widgetHost:
        default: adbtaawrmh4h.widgets.cadenya.com
security:
  - bearerAuth: []
tags:
  - name: WidgetConfigService
    description: |-
      Serves the widget's presentation config. The only unauthenticated surface:
       the widget is identified by the hostname and the edge enforces the origin
       allowlist; no session or token is required.
  - name: WidgetConversationEventStreamsService
    description: |-
      Server-streaming events over SSE. A separate service so deployments can
       route it around the JSON transcoder to a dedicated stream server — the
       transcoder cannot produce text/event-stream.
  - name: WidgetConversationService
    description: |-
      Conversations between the session's visitor and the widget's agent. All
       routes are token-implicit: scope comes entirely from the bearer's claims,
       and a conversation outside that scope 404s indistinguishably from one that
       does not exist.
  - name: WidgetSessionService
    description: |-
      Renews the caller's existing session token. Session identity comes only
       from the verified bearer token; no caller-supplied ID selects a session.
paths:
  /v1/workspaces/{workspaceId}/session:renew:
    post:
      tags:
        - WidgetSessionService
        - Session
      summary: Renew a widget session token
      description: >-
        Requires a valid widget bearer token with 60 seconds of clock-skew
        tolerance: serverNow must be strictly before exp + 60 seconds. Hard
        session expiry has no tolerance. A token beyond the drift window fails
        with TOKEN_EXPIRED and requires newer credentials or explicit app
        reauthentication; never recursively renew or automatically replace the
        session. Resolves the token's existing session, rechecks current session
        and authorization policy, and returns fresh credentials for that same
        session. The required workspace ID must match the authenticated session;
        no session ID or management credential is supplied. Preserves identity,
        scope, secrets, pinned parameters, counters, and hard session expiry.
        Other unexpired tokens remain valid. Returns tokenExpiresAt and
        sessionExpiresAt with Cache-Control: no-store. Revoked, expired, and
        exhausted sessions cannot renew.
      operationId: WidgetSessionService_RenewWidgetSession
      parameters:
        - name: workspaceId
          in: path
          description: >-
            Required workspace containing the authenticated session. Must match
            the
             session resolved from the bearer token; never authorizes access by itself.
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RenewWidgetSessionRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WidgetSessionCredentials'
          headers:
            Cache-Control:
              description: Credential responses must not be cached.
              schema:
                type: string
                enum:
                  - no-store
        '401':
          description: >-
            Unauthenticated. TOKEN_EXPIRED identifies verified access-token
            expiry at or beyond exp + 60 seconds before execution. That token
            cannot renew; use already-installed newer credentials or require
            explicit app reauthentication. Never retry renewal recursively.
            Missing, malformed, or invalid tokens do not authorize renewal.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Status'
        '403':
          description: >-
            Permission denied. SESSION_REVOKED or SESSION_EXPIRED is terminal.
            Management authorization failures never trigger visitor-token
            renewal.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Status'
        '429':
          description: >-
            Resource exhausted. SESSION_EXHAUSTED is terminal; rate limiting
            uses a distinct reason and may include Retry-After.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Status'
        default:
          description: Default error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Status'
      x-codeSamples:
        - lang: typescript
          label: TypeScript
          source: >-
            import CadenyaWidgets from '@cadenya/widgets';


            const client = new CadenyaWidgets();

            const result = await client.session.renewWidget({ workspaceId:
            "sample" });
        - lang: go
          label: Go
          source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\n\tcadenyawidgets \"go.cadenya.com/cadenya-widgets-go\"\n)\n\nfunc main() {\n\tclient, err := cadenyawidgets.NewClient()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tctx := context.Background()\n\tparams := &cadenyawidgets.SessionRenewWidgetParams{\n\t\tWorkspaceID: \"sample\",\n\t}\n\tresult, err := client.Session().RenewWidget(ctx, params)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Printf(\"%+v\\n\", result)\n}"
        - lang: python
          label: Python
          source: |-
            from cadenya_widgets import CadenyaWidgets

            with CadenyaWidgets() as client:
                result = client.session.renew_widget(workspace_id="sample")
                print(result)
        - lang: ruby
          label: Ruby
          source: |-
            require "cadenya-widgets"

            client = CadenyaWidgets::Client.new
            result = client.session.renew_widget(workspace_id: "sample")
            puts result.inspect
        - lang: bash
          label: CLI
          source: |-
            cadenya-widgets session renew-widget \
              --workspace-id sample
        - lang: shell
          label: curl
          source: |-
            curl --request POST \
              --url '/v1/workspaces/workspace_123/session:renew' \
              --header "Authorization: Bearer ${CADENYAWIDGETS_API_KEY}"
components:
  schemas:
    RenewWidgetSessionRequest:
      type: object
      properties:
        workspaceId:
          readOnly: true
          type: string
          description: >-
            Required workspace containing the authenticated session. Must match
            the
             session resolved from the bearer token; never authorizes access by itself.
      description: |-
        RenewWidgetSessionRequest has no session ID or credential in its body.
         The verified bearer token identifies the existing session. The server
         rechecks current session and authorization policy before issuing a token.
         Token validation allows 60 seconds of clock skew: now must be strictly
         before exp + 60 seconds. Hard session expiry has no tolerance. A token
         beyond this window cannot renew even while the session remains active.
    WidgetSessionCredentials:
      required:
        - sessionId
        - host
        - token
        - tokenExpiresAt
        - sessionExpiresAt
      type: object
      properties:
        sessionId:
          readOnly: true
          type: string
          description: >-
            Canonical wsess_ identifier. Ordinary renewal cannot change the
            session.
        host:
          readOnly: true
          type: string
          description: >-
            Authoritative hostname, without a scheme or path. Use HTTPS with
            this
             host; never construct it or accept a host change during renewal.
        token:
          readOnly: true
          type: string
          description: Short-lived bearer credential for the widget host only.
        tokenExpiresAt:
          readOnly: true
          type: string
          description: >-
            Exact token expiry, at most 15 minutes after issuance and never
            later
             than session_expires_at. Equals JWT exp without the 60-second validation
             tolerance added. Renew proactively before this timestamp.
          format: date-time
        sessionExpiresAt:
          readOnly: true
          type: string
          description: Immutable hard session expiry. Issuance never extends this deadline.
          format: date-time
      description: |-
        WidgetSessionCredentials is the browser-safe projection of creation
         credentials. Renewal returns the same fields, including exact token expiry
         and immutable session expiry, without importing the management API module.
         Responses containing credentials use Cache-Control: no-store.
    Status:
      type: object
      properties:
        code:
          type: integer
          description: >-
            The status code, which should be an enum value of
            [google.rpc.Code][google.rpc.Code].
          format: int32
        message:
          type: string
          description: >-
            A developer-facing error message, which should be in English. Any
            user-facing error message should be localized and sent in the
            [google.rpc.Status.details][google.rpc.Status.details] field, or
            localized by the client.
        details:
          type: array
          items:
            anyOf:
              - $ref: '#/components/schemas/WidgetSessionErrorInfo'
              - $ref: '#/components/schemas/GoogleProtobufAny'
          description: >-
            A list of messages that carry the error details.  There is a common
            set of message types for APIs to use.
      description: >-
        The `Status` type defines a logical error model that is suitable for
        different programming environments, including REST APIs and RPC APIs. It
        is used by [gRPC](https://github.com/grpc). Each `Status` message
        contains three pieces of data: error code, error message, and error
        details. You can find out more about this error model and how to work
        with it in the [API Design
        Guide](https://cloud.google.com/apis/design/errors).
    WidgetSessionErrorInfo:
      type: object
      description: >-
        google.rpc.ErrorInfo detail for widget lifecycle failures. Match both
        domain and reason; ignore unknown reasons rather than renewing
        automatically.
      required:
        - '@type'
        - domain
        - reason
      properties:
        '@type':
          type: string
          enum:
            - type.googleapis.com/google.rpc.ErrorInfo
        domain:
          type: string
          enum:
            - api.cadenya.com
        reason:
          $ref: '#/components/schemas/WidgetSessionErrorReason'
        metadata:
          type: object
          additionalProperties:
            type: string
          description: Optional non-sensitive context. Never contains tokens or secrets.
    GoogleProtobufAny:
      type: object
      properties:
        '@type':
          type: string
          description: The type of the serialized message.
      additionalProperties: true
      description: >-
        Contains an arbitrary serialized message along with a @type that
        describes the type of the serialized message.
    WidgetSessionErrorReason:
      type: string
      description: >-
        TOKEN_EXPIRED identifies access-token expiry beyond the 60-second
        clock-skew tolerance. That token cannot renew; use already-installed
        newer credentials or require explicit app reauthentication. SESSION_*
        reasons are terminal. Never infer renewability from HTTP status alone.
      enum:
        - TOKEN_EXPIRED
        - SESSION_REVOKED
        - SESSION_EXPIRED
        - SESSION_EXHAUSTED
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````

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