> ## 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.

# Delete all of a tenant's widget sessions

> The erasure endpoint. Every session for a tenant, across all widgets, and every conversation they created.

Built for GDPR erasure requests. One call deletes every session belonging to a tenant across all widgets in the workspace, along with the conversations those sessions created. The response reports both counts.

<CodeGroup>
  ```typescript TypeScript theme={null}
  const result = await client.widgetSessions.deleteTenant({
    workspaceId,
    tenantId: 'external_id:acme-corp',
  });

  console.log(result.sessionsDeleted, result.objectivesDeleted);
  // 14  212
  ```

  ```go Go theme={null}
  result, err := client.WidgetSessions.DeleteTenant(ctx,
  	cadenya.WidgetSessionDeleteTenantParams{
  		WorkspaceID: cadenya.String(workspaceID),
  		TenantID:    cadenya.String("external_id:acme-corp"),
  	})
  if err != nil {
  	panic(err.Error())
  }
  fmt.Println(result.SessionsDeleted, result.ObjectivesDeleted)
  // 14  212
  ```

  ```ruby Ruby theme={null}
  result = cadenya.widget_sessions.delete_tenant(
    workspace_id: workspace_id,
    tenant_id: "external_id:acme-corp"
  )

  puts [result.sessions_deleted, result.objectives_deleted].join("  ")
  # 14  212
  ```

  ```bash cURL theme={null}
  curl -X DELETE "https://api.cadenya.com/v1/workspaces/${WORKSPACE_ID}/widget_sessions?tenantId=external_id:acme-corp" \
    -H "Authorization: Bearer ${CADENYA_API_KEY}"
  ```
</CodeGroup>

## `tenantId` is required, and that is the safety

An empty or missing `tenantId` is rejected rather than matching everything. There is no "delete all sessions in the workspace" spelling of this endpoint, so a bug in your parameter plumbing turns into a `400`, not a workspace-wide purge.

The tenant accepts the canonical `tenant_…` form or `external_id:<value>`, which is usually the natural one here: the erasure request arrives with your identifier for the customer, not Cadenya's.

## This deletes conversations. The single delete does not.

The [single-session delete](/docs/api-reference/widgetsessionservice/delete-a-widget-session) disassociates conversations and leaves them. This endpoint deletes them, because "erase this customer" means the content too. `objectivesDeleted` is your receipt for the erasure record.

The tenant record itself survives, empty. To remove that too, finish with [erase a tenant](/docs/api-reference/tenantservice/erase-a-tenant).

## Related

<CardGroup cols={2}>
  <Card title="Erase a tenant" icon="eraser" href="/docs/api-reference/tenantservice/erase-a-tenant">
    Remove the tenant record after its data.
  </Card>

  <Card title="List widget sessions" icon="list" href="/docs/api-reference/widgetsessionservice/list-widget-sessions">
    `?tenantId=` shows what this call takes with it.
  </Card>

  <Card title="Delete a widget session" icon="trash" href="/docs/api-reference/widgetsessionservice/delete-a-widget-session">
    One row, conversations kept.
  </Card>

  <Card title="List tenants" icon="building" href="/docs/api-reference/tenantservice/list-tenants">
    Resolve your customer identifier to a tenant.
  </Card>
</CardGroup>


## OpenAPI

````yaml delete /v1/workspaces/{workspaceId}/widget_sessions
openapi: 3.1.0
info:
  title: Cadenya API
  description: API for the Cadenya Agent Runtime platform.
  version: '1.0'
servers:
  - url: https://api.cadenya.com
    description: Production server
security:
  - bearerAuth: []
tags:
  - name: AIProviderKeyService
  - name: APIKeyService
    description: |-
      Issue, rotate, disable, and revoke a workspace's API keys. Every key
       belongs to exactly one workspace; the system-managed global account key is
       managed via GlobalAPIKeyService instead.
  - name: AccountService
    description: >-
      Manage the authenticated account. Accounts are the top-level
      organizational
       unit and contain one or more workspaces.
  - name: AgentScheduleService
    description: >-
      Manage recurring schedules attached to agents. Schedules trigger
      objectives
       on a cadence defined by AgentScheduleSpec.Schedule.
  - name: AgentService
    description: >-
      Manage AI agents within a workspace. Agents define AI behavior and tool
      access.
  - name: AgentVariationService
    description: >-
      Manage variations of an agent and their tool, sub-agent, and memory layer
      assignments.
  - name: GlobalAPIKeyService
    description: |-
      Manage the account's system-provisioned global API key. The global key is
       the only key that spans every workspace; it is created by the system and
       cannot be deleted, so the surface is retrieve, rotate, and the
       disable/enable kill switch.
  - name: MemoryService
    description: >-
      Manage memory layers and their entries. Layers are named containers that
      can
       be composed into an objective's memory cascade; entries are the keyed values
       within a layer. System-managed layers (e.g., episodic layers created by the
       runtime) cannot be mutated through this API.
  - name: ModelService
    description: |-
      Manage LLM models available to a workspace. Models represent provider and
       family pairs (e.g., "anthropic/claude-sonnet-4.6"). Workspaces are seeded
       with the supported models and you can enable or disable each one.
  - name: ObjectiveEventStreamsService
  - name: ObjectiveService
  - name: ProfilesService
    description: |-
      Operations on profiles, the account-level principals (users, API keys,
       system) that authenticate against the API.
  - name: SearchService
  - name: TenantService
    description: >-
      Read and erase tenants and the subjects under them. Tenants and subjects
      are
       created by assertion — on objective creation or widget session mint — never
       directly, so this service has no create or update: it exists to enumerate what
       assertions have produced, and to destroy it on request.
  - name: ToolService
    description: >-
      Manage tool sets and the tools they contain. Tool sets group related
      tools,
       and tools define specific capabilities available to agents.

       When a tool set is managed, only API key actors can modify its tools; human
       (profile) actors cannot.
  - name: UploadService
    description: |-
      Issue short-lived presigned URLs for direct client-to-object-storage
       uploads. Created uploads can be referenced by id when creating or updating
       resources that accept binary content (e.g., MemoryEntry).
  - name: WidgetService
    description: |-
      Manage embeddable chat widgets. A widget binds an agent to a globally
       unique hostname with a per-widget origin allowlist; browsers reach it with
       session tokens minted via WidgetSessionService.
  - name: WidgetSessionService
    description: >-
      Mint and manage widget sessions. Session creation is server-to-server
      only:
       the customer's backend authenticates its visitor, asserts tenant/subject
       context, attaches any per-visitor secrets, and receives a short-lived
       bearer token the browser uses against the widget host.
  - name: WorkspaceAdminService
    description: >-
      Administer workspaces across the account: create and archive workspaces
      and
       manage their membership. These operations are account-scoped and require the
       admin role (a token whose profile holds the WorkOS admin role); they live
       under /v1/account/workspaces rather than the workspace-scoped /v1/workspaces
       tree so an admin can manage any workspace in the account, including ones they
       are not themselves a member of.
  - name: WorkspaceSecretService
  - name: WorkspaceService
    description: |-
      Manage workspaces within an account. Workspaces provide organizational
       grouping and isolation for resources such as agents, tools, and API keys.

       This is the workspace-scoped, end-user surface. Administrative operations
       (create / archive workspaces, manage members) live in WorkspaceAdminService
       under /v1/account/workspaces and require the admin role.
paths:
  /v1/workspaces/{workspaceId}/widget_sessions:
    delete:
      tags:
        - WidgetSessionService
        - Widget Sessions
      summary: Delete all of a tenant's widget sessions
      description: >-
        Deletes every session belonging to a tenant across all widgets in the
        workspace, along with the conversations those sessions created — built
        for GDPR erasure requests. The tenant is required; an empty value is
        rejected rather than matching everything.
      operationId: WidgetSessionService_DeleteTenantWidgetSessions
      parameters:
        - name: workspaceId
          in: path
          description: Workspace ID.
          required: true
          schema:
            type: string
            example: workspace_01HXKD2E5NQM3T9AYWCF133E3Q
        - name: tenantId
          in: query
          description: >-
            Tenant whose sessions to delete. Required — an empty value is
            rejected
             rather than matching everything. Accepts the canonical `tenant_…` form or
             the `external_id:<value>` form.
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeleteTenantWidgetSessionsResponse'
        default:
          description: Default error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Status'
      x-codeSamples:
        - lang: JavaScript
          source: |-
            import Cadenya from '@cadenya/cadenya';

            const client = new Cadenya({
              apiKey: process.env['CADENYA_API_KEY'], // This is the default and can be omitted
            });

            const response = await client.widgetSessions.deleteTenant({
              workspaceId: 'workspace_01HXKD2E5NQM3T9AYWCF133E3Q',
            });

            console.log(response.objectivesDeleted);
        - lang: Python
          source: |-
            import os
            from cadenya import Cadenya

            client = Cadenya(
                api_key=os.environ.get("CADENYA_API_KEY"),  # This is the default and can be omitted
            )
            response = client.widget_sessions.delete_tenant(
                workspace_id="workspace_01HXKD2E5NQM3T9AYWCF133E3Q",
            )
            print(response.objectives_deleted)
        - lang: Go
          source: "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"go.cadenya.com/cadenya-go\"\n\t\"go.cadenya.com/cadenya-go/option\"\n)\n\nfunc main() {\n\tclient := cadenya.NewClient(\n\t\toption.WithAPIKey(\"My API Key\"),\n\t)\n\tresponse, err := client.WidgetSessions.DeleteTenant(context.TODO(), cadenya.WidgetSessionDeleteTenantParams{\n\t\tWorkspaceID: cadenya.String(\"workspace_01HXKD2E5NQM3T9AYWCF133E3Q\"),\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", response.ObjectivesDeleted)\n}\n"
        - lang: Ruby
          source: >-
            require "cadenya"


            cadenya = Cadenya::Client.new(api_key: "My API Key")


            response = cadenya.widget_sessions.delete_tenant(workspace_id:
            "workspace_01HXKD2E5NQM3T9AYWCF133E3Q")


            puts(response)
        - lang: CLI
          source: |-
            cadenya widget-sessions delete-tenant \
              --api-key 'My API Key' \
              --workspace-id workspace_01HXKD2E5NQM3T9AYWCF133E3Q
components:
  schemas:
    DeleteTenantWidgetSessionsResponse:
      type: object
      properties:
        sessionsDeleted:
          readOnly: true
          type: integer
          description: Number of sessions deleted.
          format: int32
        objectivesDeleted:
          readOnly: true
          type: integer
          description: >-
            Number of conversations (objectives) deleted along with the
            sessions.
          format: int32
      description: Delete tenant widget sessions response.
    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:
            $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).
    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.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````