openapi: 3.1.0
info:
  title: DarhimLabs API
  description: |
    DarhimLabs REST API v2 - AI Business OS for conversations, leads, agents and compliance.

    ## Authentication
    All endpoints require `Authorization: Bearer dl_live_...` or OAuth 2.0.

    ## Environments
    - Production: `https://api.darhimlabs.pl/api/v2`
    - Sandbox: `https://api.darhimlabs.pl/api/v2-sandbox`

    ## Versioning
    URL versioning. Full SLA coverage for `v2` for 24 months after `v3` is published.
  version: 2.4.0
  termsOfService: https://app.darhimlabs.pl/regulamin
  contact:
    name: Developer Support
    email: developers@darhimlabs.pl
    url: https://app.darhimlabs.pl/docs
  license:
    name: Proprietary
    url: https://app.darhimlabs.pl/regulamin

servers:
  - url: https://api.darhimlabs.pl/api/v2
    description: Production
  - url: https://api.darhimlabs.pl/api/v2-sandbox
    description: Sandbox

security:
  - BearerAuth: []
  - OAuth2: [read, write]

x-darhimlabs-code-samples: &defaultCodeSamples
  - lang: cURL
    source: |
      curl https://api.darhimlabs.pl/api/v2/{path} \
        -H "Authorization: Bearer $DARHIMLABS_API_KEY"
  - lang: Node.js
    source: |
      import { DarhimLabs } from "@darhimlabs/node";
      const client = new DarhimLabs(process.env.DARHIMLABS_API_KEY);
      // See the SDK docs for a typed helper for this operation.
  - lang: Python
    source: |
      from darhimlabs import DarhimLabs
      client = DarhimLabs(api_key=os.environ["DARHIMLABS_API_KEY"])
  - lang: PHP
    source: |
      $client = new DarhimLabs\Client(["api_key" => $_ENV["DARHIMLABS_API_KEY"]]);
  - lang: Ruby
    source: |
      client = DarhimLabs::Client.new(api_key: ENV["DARHIMLABS_API_KEY"])

tags:
  - name: Inbox
    description: Conversations, messages, AI Draft and escalations.
  - name: Bots
    description: Create and manage bots.
  - name: Agents
    description: AI Agents Studio - dry-run, approvals, runs.
  - name: Leads
    description: Lead management and CRM sync.
  - name: Knowledge
    description: Knowledge bases, documents, crawling and RAG search.
  - name: Voice
    description: Voice calls, numbers, recordings and transcripts.
  - name: Webhooks
    description: Webhook endpoints v2, retry, replay and playground.
  - name: Workspaces
    description: Workspace, team management and usage.
  - name: Compliance
    description: DSAR, audit log, evidence, retention and PII.

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
    OAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://app.darhimlabs.pl/oauth/authorize
          tokenUrl: https://api.darhimlabs.pl/oauth/token
          scopes:
            read: Read workspace data
            write: Modify workspace data
            admin: Manage workspace and members
  parameters:
    Id:
      name: id
      in: path
      required: true
      schema: { type: string }
    RunId:
      name: run_id
      in: path
      required: true
      schema: { type: string }
    MemberId:
      name: member_id
      in: path
      required: true
      schema: { type: string }
    PlaygroundToken:
      name: token
      in: path
      required: true
      schema: { type: string, minLength: 12, maxLength: 80 }
      description: Inbox token generated at /webhooks/playground.
    Cursor:
      name: cursor
      in: query
      schema: { type: string }
    Limit:
      name: limit
      in: query
      schema: { type: integer, minimum: 1, maximum: 100, default: 50 }
    WorkspaceIdHeader:
      name: X-Workspace-Id
      in: header
      schema: { type: string }
      description: Override workspace context. Default = workspace assigned to API key.
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      schema: { type: string, maxLength: 255 }
      description: Idempotency key for POST/PATCH requests.
  schemas:
    Error:
      type: object
      required: [error, message, request_id]
      properties:
        error: { type: string, example: rate_limited }
        message: { type: string, example: Too many requests. Retry after 60 seconds. }
        code: { type: string, example: RATE_LIMIT_EXCEEDED }
        request_id: { type: string, example: req_01HKQWERTY }
        documentation_url: { type: string, example: https://app.darhimlabs.pl/docs/errors#rate_limit }
    Pagination:
      type: object
      properties:
        next_cursor: { type: string, nullable: true }
        has_more: { type: boolean }
    Conversation:
      type: object
      required: [id, channel, status, created_at]
      properties:
        id: { type: string, example: conv_01HKQWERTY }
        channel: { type: string, enum: [whatsapp, messenger, email, voice, web, sms, instagram] }
        status: { type: string, enum: [open, pending, resolved, archived] }
        lead_score: { type: object, additionalProperties: true }
        created_at: { type: string, format: date-time }
        updated_at: { type: string, format: date-time }
    Message:
      type: object
      properties:
        id: { type: string }
        conversation_id: { type: string }
        direction: { type: string, enum: [inbound, outbound] }
        content: { type: string }
        created_at: { type: string, format: date-time }
    Bot:
      type: object
      properties:
        id: { type: string }
        name: { type: string }
        status: { type: string, enum: [draft, published, archived] }
    Agent:
      type: object
      properties:
        id: { type: string }
        name: { type: string }
        status: { type: string, enum: [draft, active, paused] }
    Lead:
      type: object
      properties:
        id: { type: string }
        email: { type: string, nullable: true }
        phone: { type: string, nullable: true }
        score: { type: integer }
    KnowledgeBase:
      type: object
      properties:
        id: { type: string }
        name: { type: string }
        freshness_status: { type: string }
    KnowledgeDocument:
      type: object
      properties:
        id: { type: string }
        title: { type: string }
        status: { type: string }
    VoiceCall:
      type: object
      properties:
        id: { type: string }
        status: { type: string }
        from: { type: string }
        to: { type: string }
    WebhookEndpoint:
      type: object
      properties:
        id: { type: string }
        url: { type: string }
        events: { type: array, items: { type: string } }
    Workspace:
      type: object
      properties:
        id: { type: string }
        name: { type: string }
        plan: { type: string }
    Member:
      type: object
      properties:
        id: { type: string }
        email: { type: string }
        role: { type: string }
    AuditEvent:
      type: object
      properties:
        id: { type: string }
        actor: { type: string }
        action: { type: string }
        created_at: { type: string, format: date-time }
    DSARRequest:
      type: object
      properties:
        id: { type: string }
        status: { type: string }
        subject_email: { type: string }
  responses:
    Ok:
      description: Successful response
      content:
        application/json:
          schema: { type: object, additionalProperties: true }
    Created:
      description: Resource created
      content:
        application/json:
          schema: { type: object, additionalProperties: true }
    Deleted:
      description: Resource deleted
      content:
        application/json:
          schema: { type: object, additionalProperties: true }
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema: { $ref: "#/components/schemas/Error" }
    RateLimited:
      description: Rate limit exceeded
      headers:
        X-RateLimit-Limit: { schema: { type: integer } }
        X-RateLimit-Remaining: { schema: { type: integer } }
        X-RateLimit-Reset: { schema: { type: integer } }
        Retry-After: { schema: { type: integer } }
      content:
        application/json:
          schema: { $ref: "#/components/schemas/Error" }

paths:
  /:
    get:
      operationId: getApiRoot
      tags: [Workspaces]
      summary: API root
      description: Returns the API v2 resource catalog and a preview event catalog.
      responses: { "200": { $ref: "#/components/responses/Ok" } }
      x-codeSamples: *defaultCodeSamples

  /inbox/conversations:
    get:
      operationId: listConversations
      tags: [Inbox]
      summary: List conversations
      description: Retrieves workspace conversations with optional filters and cursor pagination.
      parameters:
        - $ref: "#/components/parameters/Cursor"
        - $ref: "#/components/parameters/Limit"
        - name: channel
          in: query
          schema: { type: string, enum: [whatsapp, messenger, email, voice, web] }
        - name: status
          in: query
          schema: { type: string, enum: [open, pending, resolved] }
      responses: { "200": { $ref: "#/components/responses/Ok" }, "401": { $ref: "#/components/responses/Unauthorized" }, "429": { $ref: "#/components/responses/RateLimited" } }
      x-codeSamples:
        - lang: cURL
          source: |
            curl https://api.darhimlabs.pl/api/v2/inbox/conversations \
              -H "Authorization: Bearer $DARHIMLABS_API_KEY"
        - lang: Node.js
          source: |
            import { DarhimLabs } from "@darhimlabs/node";
            const client = new DarhimLabs(process.env.DARHIMLABS_API_KEY);
            const { data } = await client.inbox.conversations.list({ status: "open" });
        - lang: Python
          source: |
            from darhimlabs import DarhimLabs
            client = DarhimLabs(api_key=os.environ["DARHIMLABS_API_KEY"])
            page = client.inbox.conversations.list(status="open")
        - lang: PHP
          source: |
            $client = new DarhimLabs\Client(["api_key" => $_ENV["DARHIMLABS_API_KEY"]]);
            $page = $client->inbox->conversations->list(["status" => "open"]);
        - lang: Ruby
          source: |
            client = DarhimLabs::Client.new(api_key: ENV["DARHIMLABS_API_KEY"])
            client.inbox.conversations.list(status: "open")
    post:
      operationId: createConversation
      tags: [Inbox]
      summary: Create conversation
      parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }]
      responses: { "201": { $ref: "#/components/responses/Created" }, "401": { $ref: "#/components/responses/Unauthorized" } }
      x-codeSamples: *defaultCodeSamples
  /inbox/conversations/{id}:
    get:
      operationId: getConversation
      tags: [Inbox]
      summary: Get conversation details
      parameters: [{ $ref: "#/components/parameters/Id" }]
      responses: { "200": { $ref: "#/components/responses/Ok" }, "401": { $ref: "#/components/responses/Unauthorized" } }
      x-codeSamples: *defaultCodeSamples
    patch:
      operationId: updateConversation
      tags: [Inbox]
      summary: Update conversation
      parameters: [{ $ref: "#/components/parameters/Id" }, { $ref: "#/components/parameters/IdempotencyKey" }]
      responses: { "200": { $ref: "#/components/responses/Ok" } }
      x-codeSamples: *defaultCodeSamples
  /inbox/conversations/{id}/messages:
    get:
      operationId: listMessages
      tags: [Inbox]
      summary: List messages
      parameters: [{ $ref: "#/components/parameters/Id" }, { $ref: "#/components/parameters/Cursor" }, { $ref: "#/components/parameters/Limit" }]
      responses: { "200": { $ref: "#/components/responses/Ok" } }
      x-codeSamples: *defaultCodeSamples
    post:
      operationId: sendMessage
      tags: [Inbox]
      summary: Send message
      parameters: [{ $ref: "#/components/parameters/Id" }, { $ref: "#/components/parameters/IdempotencyKey" }]
      responses: { "200": { $ref: "#/components/responses/Ok" }, "429": { $ref: "#/components/responses/RateLimited" } }
      x-codeSamples: *defaultCodeSamples
  /inbox/conversations/{id}/ai-draft:
    post: { operationId: createAiDraft, tags: [Inbox], summary: Generate AI Draft, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /inbox/conversations/{id}/assign:
    post: { operationId: assignConversation, tags: [Inbox], summary: Assign conversation, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /inbox/conversations/{id}/resolve:
    post: { operationId: resolveConversation, tags: [Inbox], summary: Resolve conversation, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /inbox/templates:
    get: { operationId: listReplyTemplates, tags: [Inbox], summary: List reply templates, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: createReplyTemplate, tags: [Inbox], summary: Create reply template, responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /inbox/tags:
    get: { operationId: listInboxTags, tags: [Inbox], summary: List inbox tags, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: createInboxTag, tags: [Inbox], summary: Create inbox tag, responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /conversations:
    get: { operationId: listPublicConversations, tags: [Inbox], summary: List conversations public API v2, parameters: [{ $ref: "#/components/parameters/Cursor" }, { $ref: "#/components/parameters/Limit" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }

  /bots:
    get: { operationId: listBots, tags: [Bots], summary: List bots, parameters: [{ $ref: "#/components/parameters/Cursor" }, { $ref: "#/components/parameters/Limit" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: createBot, tags: [Bots], summary: Create bot, responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /bots/{id}:
    get: { operationId: getBot, tags: [Bots], summary: Get bot details, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    patch: { operationId: updateBot, tags: [Bots], summary: Update bot, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    delete: { operationId: deleteBot, tags: [Bots], summary: Delete bot, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Deleted" } }, x-codeSamples: *defaultCodeSamples }
  /bots/{id}/publish:
    post: { operationId: publishBot, tags: [Bots], summary: Publish bot, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /bots/{id}/versions:
    get: { operationId: listBotVersions, tags: [Bots], summary: List bot versions, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: createBotVersion, tags: [Bots], summary: Create bot version, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /bots/{id}/versions/{run_id}/rollback:
    post: { operationId: rollbackBotVersion, tags: [Bots], summary: Rollback bot version, parameters: [{ $ref: "#/components/parameters/Id" }, { $ref: "#/components/parameters/RunId" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /bots/{id}/clone:
    post: { operationId: cloneBot, tags: [Bots], summary: Clone bot, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /bots/{id}/tools:
    get: { operationId: listBotTools, tags: [Bots], summary: List bot tools, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: attachBotTool, tags: [Bots], summary: Attach bot tool, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /bots/{id}/guardrails:
    get: { operationId: getBotGuardrails, tags: [Bots], summary: Get bot guardrails, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    patch: { operationId: updateBotGuardrails, tags: [Bots], summary: Update bot guardrails, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /bots/{id}/messages:
    post: { operationId: sendBotMessage, tags: [Bots], summary: Send message to bot, parameters: [{ $ref: "#/components/parameters/Id" }, { $ref: "#/components/parameters/IdempotencyKey" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }

  /agents:
    get: { operationId: listAgents, tags: [Agents], summary: List agents, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: createAgent, tags: [Agents], summary: Create agent, responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /agents/{id}:
    get: { operationId: getAgent, tags: [Agents], summary: Get agent details, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    patch: { operationId: updateAgent, tags: [Agents], summary: Update agent, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /agents/{id}/runs:
    get:
      operationId: listAgentRuns
      tags: [Agents]
      summary: List agent runs
      description: |
        Retrieves agent runs. The `include=postmortem` parameter is deprecated as of v2.4.0.
        Use `GET /agents/{id}/runs/{run_id}` to retrieve run details with the postmortem.
      deprecated: true
      parameters:
        - { $ref: "#/components/parameters/Id" }
        - name: include
          in: query
          schema: { type: string, enum: [postmortem] }
          deprecated: true
          description: Deprecated. Use GET /agents/{id}/runs/{run_id}.
      responses: { "200": { $ref: "#/components/responses/Ok" } }
      x-darhimlabs-deprecation:
        since: "2.4.0"
        removeIn: "3.0.0"
        removeAt: "2026-12-31"
        sunset: "Wed, 31 Dec 2026 23:59:59 GMT"
        alternative: "GET /agents/{id}/runs/{run_id}"
        migrationGuide: "/docs/migration/v2-to-v3#runs-postmortem"
      x-codeSamples: *defaultCodeSamples
    post: { operationId: createAgentRun, tags: [Agents], summary: Create agent run, parameters: [{ $ref: "#/components/parameters/Id" }, { $ref: "#/components/parameters/IdempotencyKey" }], responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /agents/{id}/runs/{run_id}:
    get: { operationId: getAgentRun, tags: [Agents], summary: Get agent run details, parameters: [{ $ref: "#/components/parameters/Id" }, { $ref: "#/components/parameters/RunId" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /agents/{id}/runs/{run_id}/approve:
    post: { operationId: approveAgentRun, tags: [Agents], summary: Approve agent run, parameters: [{ $ref: "#/components/parameters/Id" }, { $ref: "#/components/parameters/RunId" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /agents/{id}/runs/{run_id}/cancel:
    post: { operationId: cancelAgentRun, tags: [Agents], summary: Cancel agent run, parameters: [{ $ref: "#/components/parameters/Id" }, { $ref: "#/components/parameters/RunId" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /agents/{id}/dry-run:
    post: { operationId: dryRunAgent, tags: [Agents], summary: Agent dry-run, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /agents/{id}/dry-run/stream:
    post: { operationId: streamAgentDryRun, tags: [Agents], summary: Stream agent dry-run, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /agents/{id}/approvals:
    get: { operationId: listAgentApprovals, tags: [Agents], summary: List agent approvals, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }

  /leads:
    get: { operationId: listLeads, tags: [Leads], summary: List leads, parameters: [{ $ref: "#/components/parameters/Cursor" }, { $ref: "#/components/parameters/Limit" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: createLead, tags: [Leads], summary: Create lead, parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }], responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /leads/{id}:
    get: { operationId: getLead, tags: [Leads], summary: Get lead details, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    patch: { operationId: updateLead, tags: [Leads], summary: Update lead, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    delete: { operationId: deleteLead, tags: [Leads], summary: Delete lead, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Deleted" } }, x-codeSamples: *defaultCodeSamples }
  /leads/{id}/qualify:
    post: { operationId: qualifyLead, tags: [Leads], summary: Qualify lead, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /leads/{id}/sync:
    post: { operationId: syncLeadToCrm, tags: [Leads], summary: Sync lead to CRM, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /leads/{id}/activities:
    get: { operationId: listLeadActivities, tags: [Leads], summary: List lead activities, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: createLeadActivity, tags: [Leads], summary: Create lead activity, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /leads/{id}/status:
    post: { operationId: updateLeadStatus, tags: [Leads], summary: Update lead status, parameters: [{ $ref: "#/components/parameters/Id" }, { $ref: "#/components/parameters/IdempotencyKey" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }

  /knowledge/bases:
    get: { operationId: listKnowledgeBases, tags: [Knowledge], summary: List knowledge bases, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: createKnowledgeBase, tags: [Knowledge], summary: Create knowledge base, responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /knowledge/bases/{id}:
    get: { operationId: getKnowledgeBase, tags: [Knowledge], summary: Get knowledge base details, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    patch: { operationId: updateKnowledgeBase, tags: [Knowledge], summary: Update knowledge base, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    delete: { operationId: deleteKnowledgeBase, tags: [Knowledge], summary: Delete knowledge base, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Deleted" } }, x-codeSamples: *defaultCodeSamples }
  /knowledge/bases/{id}/documents:
    get: { operationId: listKnowledgeDocuments, tags: [Knowledge], summary: List documents, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: uploadKnowledgeDocument, tags: [Knowledge], summary: Upload document, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /knowledge/documents/{id}:
    get: { operationId: getKnowledgeDocument, tags: [Knowledge], summary: Get document details, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    delete: { operationId: deleteKnowledgeDocument, tags: [Knowledge], summary: Delete document, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Deleted" } }, x-codeSamples: *defaultCodeSamples }
  /knowledge/search:
    post: { operationId: searchKnowledge, tags: [Knowledge], summary: RAG search, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /knowledge/crawl:
    post: { operationId: crawlKnowledgeSource, tags: [Knowledge], summary: Start website crawl, responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /knowledge/gaps:
    get: { operationId: listKnowledgeGaps, tags: [Knowledge], summary: List knowledge gaps, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }

  /voice/numbers:
    get: { operationId: listVoiceNumbers, tags: [Voice], summary: List voice numbers, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: provisionVoiceNumber, tags: [Voice], summary: Provision voice number, responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /voice/calls:
    get: { operationId: listVoiceCalls, tags: [Voice], summary: List voice calls, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: createVoiceCall, tags: [Voice], summary: Start voice call, responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /voice/calls/{id}:
    get: { operationId: getVoiceCall, tags: [Voice], summary: Get voice call details, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /voice/calls/{id}/transfer:
    post: { operationId: transferVoiceCall, tags: [Voice], summary: Transfer voice call to human, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /voice/calls/{id}/recording:
    get: { operationId: getVoiceRecording, tags: [Voice], summary: Get recording, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /voice/calls/{id}/transcript:
    get: { operationId: getVoiceTranscript, tags: [Voice], summary: Get transcript, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /voice/token:
    post: { operationId: createVoiceToken, tags: [Voice], summary: Create voice client token, responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }

  /webhooks/endpoints:
    get: { operationId: listWebhookEndpoints, tags: [Webhooks], summary: List webhook endpoints, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: createWebhookEndpoint, tags: [Webhooks], summary: Create webhook endpoint, responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /webhooks/endpoints/{id}:
    get: { operationId: getWebhookEndpoint, tags: [Webhooks], summary: Get webhook endpoint details, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    patch: { operationId: updateWebhookEndpoint, tags: [Webhooks], summary: Update webhook endpoint, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    delete: { operationId: deleteWebhookEndpoint, tags: [Webhooks], summary: Delete webhook endpoint, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Deleted" } }, x-codeSamples: *defaultCodeSamples }
  /webhooks/endpoints/{id}/test:
    post: { operationId: testWebhookEndpoint, tags: [Webhooks], summary: Send test webhook, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /webhooks/endpoints/{id}/rotate-secret:
    post: { operationId: rotateWebhookSecret, tags: [Webhooks], summary: Rotate webhook secret, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /webhooks/deliveries:
    get: { operationId: listWebhookDeliveries, tags: [Webhooks], summary: List webhook deliveries, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /webhooks/deliveries/{id}:
    get: { operationId: getWebhookDelivery, tags: [Webhooks], summary: Get webhook delivery details, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /webhooks/deliveries/{id}/replay:
    post: { operationId: replayWebhookDelivery, tags: [Webhooks], summary: Replay webhook delivery, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /webhooks/events:
    get: { operationId: listWebhookEvents, tags: [Webhooks], summary: Event catalog, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /webhooks/playground/{token}:
    get: { operationId: captureWebhookPlaygroundGet, tags: [Webhooks], summary: Capture GET in Webhook Playground, security: [], parameters: [{ $ref: "#/components/parameters/PlaygroundToken" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: captureWebhookPlaygroundPost, tags: [Webhooks], summary: Capture POST in Webhook Playground, security: [], parameters: [{ $ref: "#/components/parameters/PlaygroundToken" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    put: { operationId: captureWebhookPlaygroundPut, tags: [Webhooks], summary: Capture PUT in Webhook Playground, security: [], parameters: [{ $ref: "#/components/parameters/PlaygroundToken" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    patch: { operationId: captureWebhookPlaygroundPatch, tags: [Webhooks], summary: Capture PATCH in Webhook Playground, security: [], parameters: [{ $ref: "#/components/parameters/PlaygroundToken" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    delete: { operationId: captureWebhookPlaygroundDelete, tags: [Webhooks], summary: Capture DELETE in Webhook Playground, security: [], parameters: [{ $ref: "#/components/parameters/PlaygroundToken" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /events:
    get: { operationId: listEventCatalog, tags: [Webhooks], summary: Public event catalog, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /webhook-endpoints:
    get: { operationId: listPublicWebhookEndpoints, tags: [Webhooks], summary: List webhook endpoints public API v2, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: createPublicWebhookEndpoint, tags: [Webhooks], summary: Create webhook endpoint public API v2, responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /webhook-endpoints/{id}:
    get: { operationId: getPublicWebhookEndpoint, tags: [Webhooks], summary: Get webhook endpoint details public API v2, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    patch: { operationId: updatePublicWebhookEndpoint, tags: [Webhooks], summary: Update webhook endpoint public API v2, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    delete: { operationId: deletePublicWebhookEndpoint, tags: [Webhooks], summary: Delete webhook endpoint public API v2, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Deleted" } }, x-codeSamples: *defaultCodeSamples }

  /workspaces/current:
    get: { operationId: getCurrentWorkspace, tags: [Workspaces], summary: Get current workspace, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /workspaces/{id}:
    get: { operationId: getWorkspace, tags: [Workspaces], summary: Get workspace details, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    patch: { operationId: updateWorkspace, tags: [Workspaces], summary: Update workspace, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /workspaces/{id}/members:
    get: { operationId: listWorkspaceMembers, tags: [Workspaces], summary: List workspace members, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: inviteWorkspaceMember, tags: [Workspaces], summary: Invite workspace member, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /workspaces/{id}/members/{member_id}:
    patch: { operationId: updateWorkspaceMember, tags: [Workspaces], summary: Update member role, parameters: [{ $ref: "#/components/parameters/Id" }, { $ref: "#/components/parameters/MemberId" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    delete: { operationId: removeWorkspaceMember, tags: [Workspaces], summary: Remove workspace member, parameters: [{ $ref: "#/components/parameters/Id" }, { $ref: "#/components/parameters/MemberId" }], responses: { "200": { $ref: "#/components/responses/Deleted" } }, x-codeSamples: *defaultCodeSamples }
  /workspaces/{id}/usage:
    get: { operationId: getWorkspaceUsage, tags: [Workspaces], summary: Usage workspace, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /usage:
    get: { operationId: getPublicApiUsage, tags: [Workspaces], summary: Usage public API v2, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /api-logs:
    get: { operationId: listApiLogs, tags: [Workspaces], summary: Live API logs, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /oauth/apps:
    get: { operationId: listOAuthApps, tags: [Workspaces], summary: List OAuth apps, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: createOAuthApp, tags: [Workspaces], summary: Create OAuth app, responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
    patch: { operationId: updateOAuthApp, tags: [Workspaces], summary: Update OAuth app, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /openapi-snapshots:
    get: { operationId: listOpenApiSnapshots, tags: [Workspaces], summary: List OpenAPI snapshots, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: createOpenApiSnapshot, tags: [Workspaces], summary: Create OpenAPI snapshot, responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /sandbox-workspaces:
    get: { operationId: listSandboxWorkspaces, tags: [Workspaces], summary: List sandbox workspaces, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: createSandboxWorkspace, tags: [Workspaces], summary: Create sandbox workspace, responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /sdk-generations:
    get: { operationId: listSdkGenerations, tags: [Workspaces], summary: List SDK generations, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: createSdkGeneration, tags: [Workspaces], summary: Start SDK generation, responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /terraform-resources:
    get: { operationId: listTerraformResources, tags: [Workspaces], summary: List Terraform resources, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }

  /compliance/audit-log:
    get: { operationId: listAuditLog, tags: [Compliance], summary: Audit log, parameters: [{ $ref: "#/components/parameters/Cursor" }, { $ref: "#/components/parameters/Limit" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /compliance/dsar:
    get: { operationId: listDsarRequests, tags: [Compliance], summary: List DSAR requests, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    post: { operationId: createDsarRequest, tags: [Compliance], summary: Create DSAR request, responses: { "201": { $ref: "#/components/responses/Created" } }, x-codeSamples: *defaultCodeSamples }
  /compliance/dsar/{id}:
    get: { operationId: getDsarRequest, tags: [Compliance], summary: Get DSAR request details, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /compliance/dsar/{id}/export:
    post: { operationId: exportDsarRequest, tags: [Compliance], summary: Export DSAR request, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /compliance/evidence:
    get: { operationId: listComplianceEvidence, tags: [Compliance], summary: List compliance evidence, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /compliance/evidence/{id}/download:
    get: { operationId: downloadComplianceEvidence, tags: [Compliance], summary: Download compliance evidence, parameters: [{ $ref: "#/components/parameters/Id" }], responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /compliance/pii-redaction:
    post: { operationId: redactPii, tags: [Compliance], summary: Redact PII, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
  /compliance/retention:
    get: { operationId: getRetentionPolicies, tags: [Compliance], summary: Retention policies, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }
    patch: { operationId: updateRetentionPolicies, tags: [Compliance], summary: Update retention policies, responses: { "200": { $ref: "#/components/responses/Ok" } }, x-codeSamples: *defaultCodeSamples }

  /health:
    get:
      operationId: getApiHealth
      tags: [Workspaces]
      summary: Health API
      description: Returns API v2 module status.
      security: []
      responses: { "200": { $ref: "#/components/responses/Ok" } }
      x-codeSamples: *defaultCodeSamples
