# Gerado por scripts/generate-openapi-user-docs.ts a partir de public/openapi.json.
# Não edite à mão: rode `npm run docs:generate`.
openapi: 3.1.0
info:
  title: API do Kadu
  version: 1.0.0
  description: |-
    API multi-tenant para orquestração de agentes.

    ## Autenticação

    Toda rota exige `Authorization: Bearer <token>`, onde o token é um access token RS256 emitido pelo Authorization Server da Kobana (Conta Kobana) para o recurso `kadu`. O Kadu só verifica o token, com as chaves públicas que o AS publica; não emite token. A organização é a claim `org`.

    ## Escopos

    Os escopos são exigidos em toda rota, exceto `GET /v1/me`. Cada requisição exige um único nível de acesso, e um nível nunca substitui outro:

    | Nível | Concede |
    | --- | --- |
    | `read` | leitura (`GET`) |
    | `write` | criação e alteração (`POST`, `PATCH`, `PUT`) — e leitura |
    | `delete` | remoção (`DELETE`) |
    | `import` | importação em massa (nenhum endpoint hoje) |
    | `export` | exportação em massa (nenhum endpoint hoje) |
    | `all` | todos os níveis acima |

    Um token com escopos `kadu/{recurso}` (ex.: `kadu/tasks`) fica restrito a esses recursos, e o nível vale só dentro deles; `kadu/all` alcança todos os recursos. O recurso de uma rota é o primeiro segmento depois de `/v1` (`/executions/{id}/logs` → `executions`). Recursos: `activities`, `environments`, `executions`, `files`, `memberships`, `memories`, `organizations`, `repository`, `roles`, `schedules`, `secrets`, `system_events`, `tasks`, `todos`, `usage`, `users`, `webhook_deliveries`, `webhooks`, `workspaces`.

    ## Permissões do usuário

    Além dos escopos, um token emitido para uma pessoa (com `email`) fica limitado ao papel dela na organização (`Role.permissions`): cada rota exige `agent.<recurso>.<ação>` (`list`, `read`, `create`, `update`, `delete`, e as ações `executions.run`, `webhook_deliveries.replay` e `repository.sync`), com curingas `*`, `agent.*` e `agent.<recurso>.*`. Papel que não concede responde `403 USER_PERMISSION_DENIED` (`details.required`); pessoa sem vínculo com a organização, `403 NOT_A_MEMBER`. Token de integração, sem pessoa, vale só pelos escopos. `GET /v1/me` não confere papel.

    ## Permissões da organização

    As rotas de disparo, logs, webhooks, entregas, ambientes, secrets, agendamentos, endpoint da Task, repositório e uso respeitam também as liberações que a Kobana dá à organização para as telas do console. Operação não liberada responde `403 FEATURE_NOT_ENABLED`, com `details.permission`.

    Token sem escopo que o Kadu reconheça não alcança nada além do `/me`. Escopo insuficiente responde `403 INSUFFICIENT_SCOPE`, com `details.required` (os níveis que bastariam).

    ## Contrato

    - Wire em `snake_case`; mapas livres (`custom_metadata`, `payload`, `parameters`…) são opacos.
    - Valores monetários e de custo são `number` (USD em `*_usd`, reais em `*_brl`).
    - Sucesso: `{ data }` ou `{ data, meta }`; erro: `{ error: { code, message, details? } }` com `code` em UPPER_SNAKE.
    - Listagens por cursor: `cursor` + `limit` (máx. 100), ordenação por `sort_by` + `sort_order`; `meta: { next_cursor, limit }`.
    - `X-Idempotency-Key` em todo `POST`/`PUT`/`PATCH` (24h por organização).
    - Corpo de `POST`/`PUT`/`PATCH` até 1 MiB; acima disso, `413 PAYLOAD_TOO_LARGE`.
servers:
  - url: https://api.kadu.ia.br
    description: Produção
  - url: https://api.staging.kadu.ia.br
    description: Staging
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: "Access token RS256 (`typ: at+jwt`) emitido pelo Authorization Server da Kobana (`iss` = `https://account.kobana.com.br`), com `aud` contendo `https://api.kadu.ia.br` (staging: `https://api.staging.kadu.ia.br`) e `exp` obrigatório. A organização é a claim `org` (`organizations.public_id`); `sub` é a pessoa. O cabeçalho precisa ter `typ: at+jwt` (RFC 9068): outro JWT do mesmo emissor, como um ID token, é recusado. Os escopos são exigidos em toda rota — ver a descrição da API."
  schemas:
    PaginationMeta:
      type: object
      properties:
        next_cursor:
          type:
            - string
            - "null"
        limit:
          type: number
      required:
        - next_cursor
        - limit
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: "UPPER_SNAKE estável: VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, INSUFFICIENT_SCOPE, NOT_FOUND, CONFLICT, IDEMPOTENCY_KEY_REUSED, IDEMPOTENCY_REQUEST_IN_PROGRESS, RATE_LIMITED, INTERNAL_ERROR, além dos códigos específicos de cada rota."
              example: VALIDATION_ERROR
            message:
              type: string
            details: {}
          required:
            - code
            - message
      required:
        - error
    Organization:
      type: object
      properties:
        id:
          type: string
          format: uuid
        external_id:
          type:
            - string
            - "null"
        public_id:
          type:
            - string
            - "null"
          format: uuid
        label:
          type: string
        monthly_cost_limit:
          type:
            - number
            - "null"
          description: Teto mensal de custo em USD, definido pela Kobana. null = sem limite.
        monthly_cost_accumulated_usd:
          type: number
        timezone:
          type: string
        custom_metadata:
          type: object
          additionalProperties: {}
        created_at:
          type: string
        updated_at:
          type: string
      required:
        - id
        - external_id
        - public_id
        - label
        - monthly_cost_limit
        - monthly_cost_accumulated_usd
        - timezone
        - custom_metadata
        - created_at
        - updated_at
    Workspace:
      type: object
      properties:
        id:
          type: string
          format: uuid
        label:
          type: string
        organization_id:
          type: string
          format: uuid
        created_at:
          type: string
      required:
        - id
        - label
        - organization_id
        - created_at
    Activity:
      type: object
      properties:
        id:
          type: string
          format: uuid
        label:
          type: string
        organization_id:
          type: string
          format: uuid
        workspace_id:
          type: string
          format: uuid
        created_at:
          type: string
      required:
        - id
        - label
        - organization_id
        - workspace_id
        - created_at
    Task:
      type: object
      properties:
        id:
          type: string
          format: uuid
        label:
          type: string
        skill_slug:
          type: string
        organization_id:
          type: string
          format: uuid
        workspace_id:
          type: string
          format: uuid
        activity_id:
          type: string
          format: uuid
        parameters_schema: {}
        parameters_sensitive:
          type: boolean
        conversational:
          type: boolean
          description: "Aceita continuar a conversa: `POST /executions/{id}/continue`."
      required:
        - id
        - label
        - skill_slug
        - organization_id
        - workspace_id
        - activity_id
        - parameters_sensitive
        - conversational
    Execution:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type: string
          format: uuid
        workspace_id:
          type: string
          format: uuid
        activity_id:
          type: string
          format: uuid
        task_id:
          type: string
          format: uuid
        status:
          type: string
          enum:
            - pending
            - queued
            - running
            - success
            - failed
            - cancelled
        source:
          type: string
        reference_date:
          type:
            - string
            - "null"
        started_at:
          type: string
        finished_at:
          type:
            - string
            - "null"
        cost_usd:
          type:
            - number
            - "null"
        parent_execution_id:
          type:
            - string
            - "null"
          format: uuid
          description: Rodada anterior da conversa (Task conversacional); null na primeira.
        root_execution_id:
          type:
            - string
            - "null"
          format: uuid
          description: Primeira rodada da conversa; null nela mesma.
      required:
        - id
        - organization_id
        - workspace_id
        - activity_id
        - task_id
        - status
        - source
        - reference_date
        - started_at
        - finished_at
        - cost_usd
        - parent_execution_id
        - root_execution_id
    Memory:
      type: object
      properties:
        id:
          type: string
          format: uuid
        external_id:
          type:
            - string
            - "null"
        organization_id:
          type: string
          format: uuid
        workspace_id:
          type:
            - string
            - "null"
          format: uuid
        activity_id:
          type:
            - string
            - "null"
          format: uuid
        entity_type:
          type:
            - string
            - "null"
        entity_value:
          type:
            - string
            - "null"
        key:
          type:
            - string
            - "null"
        content:
          type: string
        summary:
          type:
            - string
            - "null"
        status:
          type:
            - string
            - "null"
        custom_metadata:
          type: object
          additionalProperties: {}
        system_metadata:
          type: object
          additionalProperties: {}
        created_at:
          type: string
        updated_at:
          type: string
        deleted_at:
          type:
            - string
            - "null"
      required:
        - id
        - external_id
        - organization_id
        - workspace_id
        - activity_id
        - entity_type
        - entity_value
        - key
        - content
        - summary
        - status
        - custom_metadata
        - system_metadata
        - created_at
        - updated_at
        - deleted_at
    Environment:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type: string
          format: uuid
        label:
          type: string
        color:
          type: string
          example: "#16a34a"
        branch:
          type: string
          description: Branch do Playbook usada no disparo.
        repo_managed:
          type: boolean
          description: "Declarado no `kadu.yaml` do repositório da organização: o sync recria o ambiente e reaplica cor e branch declaradas. Não pode ser apagado pela API."
        created_at:
          type: string
        updated_at:
          type: string
        deleted_at:
          type:
            - string
            - "null"
      required:
        - id
        - organization_id
        - label
        - color
        - branch
        - repo_managed
        - created_at
        - updated_at
        - deleted_at
    Secret:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type: string
          format: uuid
        environment_id:
          type: string
          format: uuid
        workspace_id:
          type:
            - string
            - "null"
          format: uuid
          description: null = vale para todos os workspaces da organização.
        key:
          type: string
        notes:
          type:
            - string
            - "null"
        created_at:
          type: string
        updated_at:
          type: string
        deleted_at:
          type:
            - string
            - "null"
      required:
        - id
        - organization_id
        - environment_id
        - workspace_id
        - key
        - notes
        - created_at
        - updated_at
        - deleted_at
      description: "O valor é write-only: nenhuma rota o devolve."
    Schedule:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type: string
          format: uuid
        task_id:
          type: string
          format: uuid
        environment_id:
          type: string
          format: uuid
        cron:
          type: string
          example: 0 9 * * 1-5
        timezone:
          type: string
          example: America/Sao_Paulo
        paused:
          type: boolean
        paused_at:
          type:
            - string
            - "null"
        repo_managed:
          type: boolean
          description: "Declarado no `schedules` do frontmatter da skill: o sync reaplica cron, fuso e pausa declarados. Não pode ser apagado pela API."
        created_at:
          type: string
        updated_at:
          type: string
        deleted_at:
          type:
            - string
            - "null"
      required:
        - id
        - organization_id
        - task_id
        - environment_id
        - cron
        - timezone
        - paused
        - paused_at
        - repo_managed
        - created_at
        - updated_at
        - deleted_at
    TaskEndpoint:
      type: object
      properties:
        task_id:
          type: string
          format: uuid
        endpoint:
          type:
            - object
            - "null"
          properties:
            enabled:
              type: boolean
            auth:
              type: string
              enum:
                - basic
                - bearer
                - header
                - params
            auth_basic_user:
              type:
                - string
                - "null"
            auth_header_key:
              type:
                - string
                - "null"
            auth_param_key:
              type:
                - string
                - "null"
            auth_basic_password_set:
              type: boolean
            auth_bearer_token_set:
              type: boolean
            auth_header_value_set:
              type: boolean
            auth_param_value_set:
              type: boolean
          required:
            - enabled
            - auth
            - auth_basic_user
            - auth_header_key
            - auth_param_key
            - auth_basic_password_set
            - auth_bearer_token_set
            - auth_header_value_set
            - auth_param_value_set
          description: null = a Task nunca teve endpoint configurado.
      required:
        - task_id
        - endpoint
    File:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type: string
          format: uuid
        task_id:
          type:
            - string
            - "null"
          format: uuid
        execution_id:
          type:
            - string
            - "null"
          format: uuid
        kind:
          type: string
          enum:
            - input
            - output
        status:
          type: string
          enum:
            - pending
            - uploaded
        filename:
          type: string
        content_type:
          type: string
        size_bytes:
          type: number
        custom_metadata:
          type: object
          additionalProperties: {}
        created_at:
          type: string
        updated_at:
          type: string
        deleted_at:
          type:
            - string
            - "null"
      required:
        - id
        - organization_id
        - task_id
        - execution_id
        - kind
        - status
        - filename
        - content_type
        - size_bytes
        - custom_metadata
        - created_at
        - updated_at
        - deleted_at
    SlackInstallation:
      type: object
      properties:
        id:
          type: string
          format: uuid
        team_id:
          type:
            - string
            - "null"
        team_name:
          type:
            - string
            - "null"
        enterprise_id:
          type:
            - string
            - "null"
        is_enterprise_install:
          type: boolean
        settings:
          type: object
          properties:
            allowed_channel_types:
              type: array
              items:
                type: string
                enum:
                  - im
                  - private_channel
                  - public_channel
                  - mpim
                  - shared_channel
            files_mode:
              type: string
              enum:
                - link
                - upload
            max_upload_bytes:
              type: integer
            log_detail:
              type: string
              enum:
                - milestones
                - verbose
          required:
            - allowed_channel_types
            - files_mode
            - max_upload_bytes
            - log_detail
        connected_users:
          type: integer
        created_at:
          type: string
      required:
        - id
        - team_id
        - team_name
        - enterprise_id
        - is_enterprise_install
        - settings
        - connected_users
        - created_at
    Todo:
      type: object
      properties:
        id:
          type: number
        execution_id:
          type: string
          format: uuid
        title:
          type: string
        description:
          type:
            - string
            - "null"
        status:
          type: string
          enum:
            - todo
            - resolved
        payload: {}
        resolved_at:
          type:
            - string
            - "null"
        created_at:
          type: string
        updated_at:
          type: string
      required:
        - id
        - execution_id
        - title
        - description
        - status
        - resolved_at
        - created_at
        - updated_at
    Webhook:
      type: object
      properties:
        id:
          type: string
          format: uuid
        external_id:
          type:
            - string
            - "null"
        label:
          type: string
        organization_id:
          type: string
          format: uuid
        workspace_id:
          type:
            - string
            - "null"
          format: uuid
        status:
          type: string
          enum:
            - active
            - inactive
        auth:
          type: string
          enum:
            - basic
            - bearer
            - header
        auth_basic_user:
          type:
            - string
            - "null"
        auth_header_key:
          type:
            - string
            - "null"
        auth_configured:
          type: boolean
        url:
          type: string
        subscribed_events:
          type: array
          items:
            type: string
        previous_signing_secret_expires_at:
          type:
            - string
            - "null"
        consecutive_failures:
          type: number
        emails:
          type: array
          items:
            type: object
            properties:
              address:
                type: string
            required:
              - address
        repo_managed:
          type: boolean
          description: "Declarado no `kadu.yaml`: o sync reaplica URL, eventos, status, e-mails e metadata; as credenciais e o segredo de assinatura continuam sendo definidos pela API. Não pode ser apagado pela API."
        custom_metadata:
          type: object
          additionalProperties: {}
        created_at:
          type: string
        updated_at:
          type: string
        deleted_at:
          type:
            - string
            - "null"
      required:
        - id
        - external_id
        - label
        - organization_id
        - workspace_id
        - status
        - auth
        - auth_basic_user
        - auth_header_key
        - auth_configured
        - url
        - subscribed_events
        - previous_signing_secret_expires_at
        - consecutive_failures
        - emails
        - repo_managed
        - custom_metadata
        - created_at
        - updated_at
        - deleted_at
      description: Segredos e credenciais nunca são devolvidos.
    WebhookDelivery:
      type: object
      properties:
        id:
          type: string
          format: uuid
        webhook_id:
          type: string
          format: uuid
        system_event_id:
          type: string
          format: uuid
        attempt:
          type: number
        status:
          type: string
          enum:
            - pending
            - success
            - failed
        request_headers:
          type: object
          additionalProperties:
            type: string
          description: Cabeçalhos de autenticação aparecem como `[redacted]`.
        request_body: {}
        response_status:
          type:
            - number
            - "null"
        response_headers:
          type:
            - object
            - "null"
          additionalProperties:
            type: string
        response_body:
          type:
            - string
            - "null"
        error:
          type:
            - string
            - "null"
        duration_ms:
          type:
            - number
            - "null"
        delivered_at:
          type:
            - string
            - "null"
        next_retry_at:
          type:
            - string
            - "null"
        created_at:
          type: string
        updated_at:
          type: string
      required:
        - id
        - webhook_id
        - system_event_id
        - attempt
        - status
        - request_headers
        - response_status
        - response_headers
        - response_body
        - error
        - duration_ms
        - delivered_at
        - next_retry_at
        - created_at
        - updated_at
    OperationApproval:
      type: object
      properties:
        id:
          type: string
          format: uuid
        status:
          type: string
          enum:
            - pending
            - approved
            - executed
            - declined
            - failed
            - expired
          description: "`pending` (esperando a decisão, dentro do prazo), `approved` (confirmada, em processamento), `executed`, `declined` (cancelada), `failed` (confirmada, mas a execução falhou), `expired` (o link venceu sem decisão — inclui pendente vencida)."
        resource:
          type: string
          description: "Recurso da API afetado, ex.: `tasks`."
          example: tasks
        operation:
          type: string
          description: "Operação no recurso, ex.: `run`."
          example: run
        action:
          type: string
          description: Tool do MCP que pediu.
          example: kadu_tasks_run
        requester:
          type: object
          properties:
            client_id:
              type:
                - string
                - "null"
              description: Cliente OAuth do token que pediu (verificado). null = token pessoal.
            client_name:
              type:
                - string
                - "null"
              description: Nome que o cliente MCP declarou sobre si (não verificado).
          required:
            - client_id
            - client_name
        created_at:
          type: string
        expires_at:
          type: string
        decided_at:
          type:
            - string
            - "null"
        executed_at:
          type:
            - string
            - "null"
      required:
        - id
        - status
        - resource
        - operation
        - action
        - requester
        - created_at
        - expires_at
        - decided_at
        - executed_at
    OperationApprovalDetail:
      allOf:
        - $ref: "#/components/schemas/OperationApproval"
        - type: object
          properties:
            organization_name:
              type:
                - string
                - "null"
            card:
              type: object
              additionalProperties: {}
              description: "O que a tela de aprovação mostra: registros afetados (`sections`), argumentos com rótulo (`args`) e sem rótulo (`other`). Depois da decisão, o retrato do que foi decidido."
            args:
              type: object
              additionalProperties: {}
              description: Argumentos da chamada.
            result:
              description: "Retorno da operação, ou `{ error: { code, message } }`. Segredos mascarados."
          required:
            - organization_name
            - card
            - args
    Role:
      type: object
      properties:
        id:
          type: string
          format: uuid
        external_id:
          type:
            - string
            - "null"
        label:
          type: string
        organization_id:
          type: string
          format: uuid
        permissions:
          type: array
          items:
            type: string
        custom_metadata:
          type: object
          additionalProperties: {}
        created_at:
          type: string
        updated_at:
          type: string
      required:
        - id
        - external_id
        - label
        - organization_id
        - permissions
        - custom_metadata
        - created_at
        - updated_at
    User:
      type: object
      properties:
        id:
          type: string
          format: uuid
        external_id:
          type:
            - string
            - "null"
        name:
          type:
            - string
            - "null"
        email:
          type:
            - string
            - "null"
        role_id:
          type: string
          format: uuid
        last_sign_in_at:
          type:
            - string
            - "null"
        created_at:
          type: string
      required:
        - id
        - external_id
        - name
        - email
        - role_id
        - last_sign_in_at
        - created_at
    Membership:
      type: object
      properties:
        id:
          type: string
          format: uuid
        external_id:
          type:
            - string
            - "null"
        organization_id:
          type: string
          format: uuid
        user_id:
          type: string
          format: uuid
        role_id:
          type: string
          format: uuid
        custom_metadata:
          type: object
          additionalProperties: {}
        created_at:
          type: string
        updated_at:
          type: string
      required:
        - id
        - external_id
        - organization_id
        - user_id
        - role_id
        - custom_metadata
        - created_at
        - updated_at
    SystemEvent:
      type: object
      properties:
        id:
          type: string
          format: uuid
        slug:
          type: string
          example: execution.created
        organization_id:
          type: string
          format: uuid
        workspace_id:
          type:
            - string
            - "null"
          format: uuid
        activity_id:
          type:
            - string
            - "null"
          format: uuid
        task_id:
          type:
            - string
            - "null"
          format: uuid
        execution_id:
          type:
            - string
            - "null"
          format: uuid
        actor_user_id:
          type:
            - string
            - "null"
          format: uuid
        payload: {}
        created_at:
          type: string
      required:
        - id
        - slug
        - organization_id
        - workspace_id
        - activity_id
        - task_id
        - execution_id
        - actor_user_id
        - created_at
  parameters: {}
paths:
  /v1/me:
    get:
      tags:
        - Identidade
      summary: Identidade por trás do token
      description: "Devolve a pessoa, a organização e o token (tipo, escopos, nível de acesso, expiração) da credencial Bearer. Serve para testar se o token configurado é válido: é a única rota isenta da checagem de escopo, então qualquer token válido responde. `user` é a pessoa do `sub` quando o token traz e-mail, e null num token de máquina. Nunca devolve o token."
      security:
        - bearerAuth: []
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      user:
                        type:
                          - object
                          - "null"
                        properties:
                          id:
                            type: string
                          name:
                            type:
                              - string
                              - "null"
                          email:
                            type: string
                        required:
                          - id
                          - name
                          - email
                      organization:
                        type: object
                        properties:
                          id:
                            type: string
                            format: uuid
                          name:
                            type: string
                          external_id:
                            type:
                              - string
                              - "null"
                        required:
                          - id
                          - name
                          - external_id
                      token:
                        type: object
                        properties:
                          type:
                            type: string
                            enum:
                              - oauth
                          scopes:
                            type: array
                            items:
                              type: string
                          access_level:
                            type: string
                            enum:
                              - read
                              - write
                              - all
                          expires_at:
                            type:
                              - string
                              - "null"
                        required:
                          - type
                          - scopes
                          - access_level
                          - expires_at
                    required:
                      - user
                      - organization
                      - token
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-me
  /v1/organizations:
    get:
      tags:
        - Organizações
      summary: Lista organizações
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: number
            minimum: 1
            maximum: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          required: false
          description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Padrão: desc."
          required: false
          description: "Padrão: desc."
          name: sort_order
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Organization"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-organizations
  /v1/organizations/{id}:
    get:
      tags:
        - Organizações
      summary: Detalha a organização
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Organization"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-organizations-id
    patch:
      tags:
        - Organizações
      summary: Atualiza a organização do token
      description: "`monthly_cost_limit` e `bypass_subscription` são definidos pela Kobana e recusados (403). Outra organização: 403."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                label:
                  type: string
                  minLength: 1
                  maxLength: 255
                timezone:
                  type: string
                  example: America/Sao_Paulo
                custom_metadata:
                  type: object
                  additionalProperties: {}
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Organization"
                required:
                  - data
        "400":
          description: VALIDATION_ERROR
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: FORBIDDEN
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: patch-organizations-id
  /v1/workspaces:
    get:
      tags:
        - Workspaces
      summary: Lista workspaces
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: number
            minimum: 1
            maximum: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          required: false
          description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Padrão: desc."
          required: false
          description: "Padrão: desc."
          name: sort_order
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Workspace"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-workspaces
    post:
      tags:
        - Workspaces
      summary: Cria workspace
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                label:
                  type: string
                  minLength: 1
                external_id:
                  type: string
                  minLength: 1
                  maxLength: 255
                  description: Id do registro no sistema de origem (texto livre).
                custom_metadata:
                  type: object
                  additionalProperties: {}
              required:
                - label
      responses:
        "201":
          description: created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Workspace"
                required:
                  - data
        "400":
          description: VALIDATION_ERROR
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: CONFLICT — registro duplicado / IDEMPOTENCY_KEY_REUSED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-workspaces
  /v1/workspaces/{id}:
    get:
      tags:
        - Workspaces
      summary: Detalha o workspace
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Workspace"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-workspaces-id
    patch:
      tags:
        - Workspaces
      summary: Atualiza workspace
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                label:
                  type: string
                  minLength: 1
                custom_metadata:
                  type: object
                  additionalProperties: {}
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Workspace"
                required:
                  - data
        "400":
          description: VALIDATION_ERROR
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: patch-workspaces-id
    delete:
      tags:
        - Workspaces
      summary: Remove workspaces (soft delete)
      description: "Exige o nível `delete` (ou `all`): `write` não apaga. Cascata: activities, tasks, execuções, webhooks, memórias e secrets do workspace; cancela agendamentos e desliga o endpoint das tasks."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Workspace"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-workspaces-id
  /v1/activities:
    get:
      tags:
        - Atividades
      summary: Lista atividades
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: number
            minimum: 1
            maximum: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          required: false
          description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Padrão: desc."
          required: false
          description: "Padrão: desc."
          name: sort_order
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Activity"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-activities
    post:
      tags:
        - Atividades
      summary: Cria activity
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                label:
                  type: string
                  minLength: 1
                workspace_id:
                  type: string
                  format: uuid
                external_id:
                  type: string
                  minLength: 1
                  maxLength: 255
                  description: Id do registro no sistema de origem (texto livre).
                custom_metadata:
                  type: object
                  additionalProperties: {}
              required:
                - label
                - workspace_id
      responses:
        "201":
          description: created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Activity"
                required:
                  - data
        "400":
          description: VALIDATION_ERROR
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          description: VALIDATION_ERROR — workspace fora da organização
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-activities
  /v1/activities/{id}:
    get:
      tags:
        - Atividades
      summary: Detalha a atividade
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Activity"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-activities-id
    patch:
      tags:
        - Atividades
      summary: Atualiza activity
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                label:
                  type: string
                  minLength: 1
                custom_metadata:
                  type: object
                  additionalProperties: {}
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Activity"
                required:
                  - data
        "400":
          description: VALIDATION_ERROR
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: patch-activities-id
    delete:
      tags:
        - Atividades
      summary: Remove activities (soft delete)
      description: "Exige o nível `delete` (ou `all`): `write` não apaga. Cascata: tasks, execuções e memórias da activity; cancela agendamentos e desliga o endpoint das tasks."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Activity"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-activities-id
  /v1/tasks:
    get:
      tags:
        - Tarefas
      summary: Lista tarefas
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: number
            minimum: 1
            maximum: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          required: false
          description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Padrão: desc."
          required: false
          description: "Padrão: desc."
          name: sort_order
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Task"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-tasks
    post:
      tags:
        - Tarefas
      summary: Cria task
      description: A task nasce no tier de preço padrão; tier e modelo de IA são definidos pela Kobana (`model` no corpo é recusado).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                label:
                  type: string
                  minLength: 1
                workspace_id:
                  type: string
                  format: uuid
                activity_id:
                  type: string
                  format: uuid
                skill_slug:
                  type: string
                  description: "`<plugin>:<skill>` do repositório da organização: plugin do workspace (quando ele tem um), skill presente no catálogo sincronizado (quando há catálogo), nunca `kadu:*`."
                  example: finance:task-baixar-pagamentos-via-boleto-pix
                parameters_schema:
                  type:
                    - object
                    - "null"
                  additionalProperties: {}
                parameters_sensitive:
                  type: boolean
                external_id:
                  type: string
                  minLength: 1
                  maxLength: 255
                  description: Id do registro no sistema de origem (texto livre).
                custom_metadata:
                  type: object
                  additionalProperties: {}
              required:
                - label
                - workspace_id
                - activity_id
                - skill_slug
      responses:
        "201":
          description: created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Task"
                required:
                  - data
        "400":
          description: VALIDATION_ERROR
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          description: VALIDATION_ERROR — workspace/activity fora da organização ou `skill_slug` não permitido
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-tasks
  /v1/tasks/{id}:
    get:
      tags:
        - Tarefas
      summary: Detalha a tarefa
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Task"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-tasks-id
    patch:
      tags:
        - Tarefas
      summary: Atualiza task
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                label:
                  type: string
                  minLength: 1
                skill_slug:
                  type: string
                  description: "`<plugin>:<skill>` do repositório da organização: plugin do workspace (quando ele tem um), skill presente no catálogo sincronizado (quando há catálogo), nunca `kadu:*`."
                  example: finance:task-baixar-pagamentos-via-boleto-pix
                parameters_schema:
                  type:
                    - object
                    - "null"
                  additionalProperties: {}
                parameters_sensitive:
                  type: boolean
                custom_metadata:
                  type: object
                  additionalProperties: {}
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Task"
                required:
                  - data
        "400":
          description: VALIDATION_ERROR
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: FORBIDDEN — `model` é definido pelo tier (Kobana)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          description: VALIDATION_ERROR — `skill_slug` não permitido
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: patch-tasks-id
    delete:
      tags:
        - Tarefas
      summary: Remove tasks (soft delete)
      description: "Exige o nível `delete` (ou `all`): `write` não apaga. Cascata: execuções e arquivos da task; cancela agendamentos e desliga o endpoint."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Task"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-tasks-id
  /v1/tasks/{id}/run:
    post:
      tags:
        - Tarefas
      summary: Dispara execução
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                reference_date:
                  type: string
                  pattern: ^\d{4}-\d{2}-\d{2}$
                parameters:
                  type: object
                  additionalProperties: {}
                  default: {}
                environment_id:
                  type: string
                  format: uuid
                locale:
                  type: string
                  pattern: ^[a-z]{2}(-[A-Z]{2})?$
                additional_instructions:
                  type: string
                  maxLength: 8000
                input_file_ids:
                  type: array
                  items:
                    type: string
                    format: uuid
                  maxItems: 50
                  description: Arquivos enviados por `POST /files` (confirmados e ainda não usados).
                mode:
                  type: string
                  enum:
                    - default
                    - resolve_pendencies
                  default: default
                  description: '`resolve_pendencies` só resolve as pendências das execuções anteriores da Task (console: "Resolver pendências"); `parameters` é ignorado.'
              required:
                - reference_date
                - environment_id
      responses:
        "201":
          description: created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      execution_id:
                        type: string
                        format: uuid
                      status:
                        type: string
                        enum:
                          - queued
                    required:
                      - execution_id
                      - status
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: 'INSUFFICIENT_SCOPE — exige `write` (ou `all`). ENTITLEMENT_REQUIRED — a organização não tem plano contratado do Kadu (nem cortesia vigente). details: { reason: "no_plan" | "missing_product", required_product: string | null }. Conferido antes do teto mensal de custo.'
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          description: COST_LIMIT_REACHED / INVALID_PARAMETERS / ENVIRONMENT_REQUIRED / MISSING_SECRETS (details.keys) / INVALID_INPUT_FILES
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-tasks-id-run
  /v1/executions:
    get:
      tags:
        - Execuções
      summary: Lista execuções
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: number
            minimum: 1
            maximum: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          required: false
          description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Padrão: desc."
          required: false
          description: "Padrão: desc."
          name: sort_order
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Execution"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-executions
  /v1/executions/{id}:
    get:
      tags:
        - Execuções
      summary: Detalha a execução
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Execution"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-executions-id
  /v1/executions/{id}/cancel:
    post:
      tags:
        - Execuções
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      responses:
        "200":
          description: cancelled (ou o status terminal atual, se já terminou)
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                      status:
                        type: string
                    required:
                      - id
                      - status
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-executions-id-cancel
      summary: Cancela a execução
  /v1/executions/{id}/continue:
    post:
      tags:
        - Execuções
      summary: Continua a conversa (próxima rodada)
      description: "Só para Task conversacional (`conversational`): cria uma execução filha desta que retoma a sessão do agente (contexto, arquivos de saída e estado) e atende ao pedido em `message`. Usa os parâmetros, a data de referência e o ambiente desta execução, que precisa estar terminada (`success` ou `failed`). Continuar uma rodada antiga abre um ramo. A nova execução traz `parentExecutionId` (esta) e `rootExecutionId` (a primeira rodada)."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                message:
                  type: string
                  minLength: 1
                  maxLength: 8000
                locale:
                  type: string
                  pattern: ^[a-z]{2}(-[A-Z]{2})?$
                input_file_ids:
                  type: array
                  items:
                    type: string
                    format: uuid
                  maxItems: 50
                  description: Arquivos novos para esta rodada (`POST /files`, ainda não usados).
              required:
                - message
      responses:
        "201":
          description: rodada criada (na fila da Task)
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      execution_id:
                        type: string
                        format: uuid
                      parent_execution_id:
                        type: string
                        format: uuid
                      status:
                        type: string
                        enum:
                          - queued
                    required:
                      - execution_id
                      - parent_execution_id
                      - status
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: NOT_CONVERSATIONAL / EXECUTOR_NOT_SUPPORTED / EXECUTOR_CHANGED / NOT_FINISHED / SESSION_UNAVAILABLE
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          description: ENVIRONMENT_REQUIRED / MISSING_SECRETS (details.keys) / INVALID_PARAMETERS / INVALID_INPUT_FILES / COST_LIMIT_REACHED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-executions-id-continue
  /v1/memories:
    get:
      tags:
        - Memórias
      summary: Lista memórias
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: number
            minimum: 1
            maximum: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          required: false
          description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Padrão: desc."
          required: false
          description: "Padrão: desc."
          name: sort_order
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Memory"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-memories
    post:
      tags:
        - Memórias
      summary: Cria memória
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                content:
                  type: string
                  minLength: 1
                workspace_id:
                  type:
                    - string
                    - "null"
                  format: uuid
                activity_id:
                  type:
                    - string
                    - "null"
                  format: uuid
                entity_type:
                  type:
                    - string
                    - "null"
                  minLength: 1
                entity_value:
                  type:
                    - string
                    - "null"
                  minLength: 1
                key:
                  type:
                    - string
                    - "null"
                  minLength: 1
                summary:
                  type:
                    - string
                    - "null"
                status:
                  type:
                    - string
                    - "null"
                external_id:
                  type:
                    - string
                    - "null"
                  minLength: 1
                  maxLength: 255
                custom_metadata:
                  type: object
                  additionalProperties: {}
              required:
                - content
      responses:
        "201":
          description: created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Memory"
                required:
                  - data
        "400":
          description: VALIDATION_ERROR
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: CONFLICT (external_id duplicado na organização) / IDEMPOTENCY_KEY_REUSED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          description: VALIDATION_ERROR — workspace/activity fora da organização
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-memories
  /v1/memories/{id}:
    get:
      tags:
        - Memórias
      summary: Detalha a memória
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Memory"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-memories-id
    patch:
      tags:
        - Memórias
      summary: Atualiza memória
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                content:
                  type: string
                  minLength: 1
                workspace_id:
                  type:
                    - string
                    - "null"
                  format: uuid
                activity_id:
                  type:
                    - string
                    - "null"
                  format: uuid
                entity_type:
                  type:
                    - string
                    - "null"
                  minLength: 1
                entity_value:
                  type:
                    - string
                    - "null"
                  minLength: 1
                key:
                  type:
                    - string
                    - "null"
                  minLength: 1
                summary:
                  type:
                    - string
                    - "null"
                status:
                  type:
                    - string
                    - "null"
                custom_metadata:
                  type: object
                  additionalProperties: {}
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Memory"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          description: VALIDATION_ERROR — workspace/activity fora da organização
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: patch-memories-id
    delete:
      tags:
        - Memórias
      summary: Remove memória (soft delete)
      description: "Exige o nível `delete` (ou `all`): `write` não apaga."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Memory"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-memories-id
  /v1/environments:
    get:
      tags:
        - Ambientes
      summary: Lista ambientes
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: number
            minimum: 1
            maximum: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          required: false
          description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Padrão: desc."
          required: false
          description: "Padrão: desc."
          name: sort_order
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Environment"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-environments
    post:
      tags:
        - Ambientes
      summary: Cria ambiente
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                label:
                  type: string
                  minLength: 1
                color:
                  type: string
                  pattern: ^#[0-9a-fA-F]{6}$
                branch:
                  type: string
                  minLength: 1
                  default: main
              required:
                - label
                - color
      responses:
        "201":
          description: created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Environment"
                required:
                  - data
        "400":
          description: VALIDATION_ERROR
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE (ver acima) ou FEATURE_NOT_ENABLED — a operação não está liberada para a organização (a mesma permissão que libera a tela no console); `details: { permission }`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: CONFLICT — já existe ambiente vivo com este label / IDEMPOTENCY_KEY_REUSED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-environments
  /v1/environments/{id}:
    get:
      tags:
        - Ambientes
      summary: Detalha o ambiente
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Environment"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-environments-id
    patch:
      tags:
        - Ambientes
      summary: Atualiza ambiente
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                label:
                  type: string
                  minLength: 1
                color:
                  type: string
                  pattern: ^#[0-9a-fA-F]{6}$
                branch:
                  type: string
                  minLength: 1
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Environment"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE (ver acima) ou FEATURE_NOT_ENABLED — a operação não está liberada para a organização (a mesma permissão que libera a tela no console); `details: { permission }`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: CONFLICT — label já usado / IDEMPOTENCY_KEY_REUSED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: patch-environments-id
    delete:
      tags:
        - Ambientes
      summary: Remove ambiente (soft delete)
      description: Recusado enquanto o ambiente tiver secrets ou agendamentos.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Environment"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE (ver acima) ou FEATURE_NOT_ENABLED — a operação não está liberada para a organização (a mesma permissão que libera a tela no console); `details: { permission }`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: "ENVIRONMENT_IN_USE — `details: { secrets, schedules }` / REPO_MANAGED — declarado no `kadu.yaml`: remova-o de lá"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-environments-id
  /v1/secrets:
    get:
      tags:
        - Secrets
      summary: Lista secrets
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: number
            minimum: 1
            maximum: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          required: false
          description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Padrão: desc."
          required: false
          description: "Padrão: desc."
          name: sort_order
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Secret"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-secrets
    post:
      tags:
        - Secrets
      summary: Cria secret
      description: O valor é gravado encriptado e nunca devolvido.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                environment_id:
                  type: string
                  format: uuid
                workspace_id:
                  type:
                    - string
                    - "null"
                  format: uuid
                key:
                  type: string
                  minLength: 1
                value:
                  type: string
                notes:
                  type:
                    - string
                    - "null"
              required:
                - environment_id
                - key
                - value
      responses:
        "201":
          description: created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Secret"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE (ver acima) ou FEATURE_NOT_ENABLED — a operação não está liberada para a organização (a mesma permissão que libera a tela no console); `details: { permission }`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          description: VALIDATION_ERROR — ambiente ou workspace fora da organização
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-secrets
  /v1/secrets/{id}:
    get:
      tags:
        - Secrets
      summary: Detalha o secret
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Secret"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-secrets-id
    patch:
      tags:
        - Secrets
      summary: Atualiza secret
      description: "`value` ausente ou vazio mantém o valor gravado."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                environment_id:
                  type: string
                  format: uuid
                workspace_id:
                  type:
                    - string
                    - "null"
                  format: uuid
                key:
                  type: string
                  minLength: 1
                value:
                  type: string
                notes:
                  type:
                    - string
                    - "null"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Secret"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE (ver acima) ou FEATURE_NOT_ENABLED — a operação não está liberada para a organização (a mesma permissão que libera a tela no console); `details: { permission }`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          description: VALIDATION_ERROR — ambiente ou workspace fora da organização
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: patch-secrets-id
    delete:
      tags:
        - Secrets
      summary: Remove secret (soft delete)
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Secret"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE (ver acima) ou FEATURE_NOT_ENABLED — a operação não está liberada para a organização (a mesma permissão que libera a tela no console); `details: { permission }`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-secrets-id
  /v1/schedules:
    get:
      tags:
        - Agendamentos
      summary: Lista agendamentos
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: number
            minimum: 1
            maximum: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          required: false
          description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Padrão: desc."
          required: false
          description: "Padrão: desc."
          name: sort_order
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Schedule"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-schedules
    post:
      tags:
        - Agendamentos
      summary: Agenda uma Task num ambiente
      description: "Um agendamento por Task e ambiente. Agendamento não empilha: o disparo é pulado se a Task já tem execução ativa ou na fila."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                task_id:
                  type: string
                  format: uuid
                environment_id:
                  type: string
                  format: uuid
                cron:
                  type: string
                  minLength: 1
                timezone:
                  type: string
                  default: UTC
                paused:
                  type: boolean
                  default: false
              required:
                - task_id
                - environment_id
                - cron
      responses:
        "201":
          description: created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Schedule"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE (ver acima) ou FEATURE_NOT_ENABLED — a operação não está liberada para a organização (a mesma permissão que libera a tela no console); `details: { permission }`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: CONFLICT — a Task já tem agendamento no ambiente (`details.schedule_id`) / IDEMPOTENCY_KEY_REUSED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          description: INVALID_CRON / VALIDATION_ERROR — Task ou ambiente fora da organização
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-schedules
  /v1/schedules/{id}:
    get:
      tags:
        - Agendamentos
      summary: Detalha o agendamento
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Schedule"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-schedules-id
    patch:
      tags:
        - Agendamentos
      summary: Altera, pausa ou retoma agendamento
      description: "`paused: true` mantém o cron e faz o dispatcher pular o agendamento."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                cron:
                  type: string
                  minLength: 1
                timezone:
                  type: string
                paused:
                  type: boolean
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Schedule"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE (ver acima) ou FEATURE_NOT_ENABLED — a operação não está liberada para a organização (a mesma permissão que libera a tela no console); `details: { permission }`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          description: INVALID_CRON
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: patch-schedules-id
    delete:
      tags:
        - Agendamentos
      summary: Cancela agendamento (soft delete)
      description: Um novo POST para a mesma Task e ambiente reativa o agendamento.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Schedule"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE (ver acima) ou FEATURE_NOT_ENABLED — a operação não está liberada para a organização (a mesma permissão que libera a tela no console); `details: { permission }`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: "REPO_MANAGED — declarado no `schedules` do frontmatter da skill: remova-o de lá"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-schedules-id
  /v1/tasks/{id}/endpoint:
    get:
      tags:
        - Tarefas
      summary: Endpoint HTTP de disparo da Task
      description: "Configuração do endpoint público `POST /api/run-task/{task_id}`. Credenciais nunca são devolvidas: só as flags `*_set`."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/TaskEndpoint"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE (ver acima) ou FEATURE_NOT_ENABLED — a operação não está liberada para a organização (a mesma permissão que libera a tela no console); `details: { permission }`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-tasks-id-endpoint
    put:
      tags:
        - Tarefas
      summary: Configura o endpoint HTTP da Task
      description: "Cria ou atualiza. Credencial omitida mantém a gravada enquanto o tipo de auth não muda. Evite `auth: params`: o segredo vai na URL e fica nos logs de acesso de proxies e CDNs; prefira `bearer` ou `header`."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                enabled:
                  type: boolean
                auth:
                  type: string
                  enum:
                    - basic
                    - bearer
                    - header
                    - params
                auth_basic_user:
                  type: string
                auth_basic_password:
                  type: string
                auth_bearer_token:
                  type: string
                auth_header_key:
                  type: string
                auth_header_value:
                  type: string
                auth_param_key:
                  type: string
                auth_param_value:
                  type: string
              required:
                - enabled
                - auth
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/TaskEndpoint"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE (ver acima) ou FEATURE_NOT_ENABLED — a operação não está liberada para a organização (a mesma permissão que libera a tela no console); `details: { permission }`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          description: INCOMPLETE_AUTH — falta credencial para o tipo de auth escolhido
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: put-tasks-id-endpoint
    delete:
      tags:
        - Tarefas
      summary: Desabilita o endpoint HTTP da Task
      description: "Mantém a configuração; um PUT com `enabled: true` reativa."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/TaskEndpoint"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE (ver acima) ou FEATURE_NOT_ENABLED — a operação não está liberada para a organização (a mesma permissão que libera a tela no console); `details: { permission }`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-tasks-id-endpoint
  /v1/tasks/{id}/readiness:
    get:
      tags:
        - Tarefas
      summary: Pré-checagem do disparo
      description: "Se a Task pode rodar no ambiente: ambiente válido e valor para todas as secrets exigidas (no workspace da Task ou globais). Traz também a fila da Task. O disparo revalida tudo."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            format: uuid
          required: false
          name: environment_id
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      ready:
                        type: boolean
                      environment:
                        type:
                          - object
                          - "null"
                        properties:
                          id:
                            type: string
                            format: uuid
                          label:
                            type: string
                          color:
                            type: string
                        required:
                          - id
                          - label
                          - color
                      required_secrets:
                        type: array
                        items:
                          type: string
                      missing_secrets:
                        type: array
                        items:
                          type: string
                      queue:
                        type: object
                        properties:
                          active:
                            type:
                              - object
                              - "null"
                            properties:
                              id:
                                type: string
                                format: uuid
                              status:
                                type: string
                            required:
                              - id
                              - status
                          queued:
                            type: number
                        required:
                          - active
                          - queued
                    required:
                      - ready
                      - environment
                      - required_secrets
                      - missing_secrets
                      - queue
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-tasks-id-readiness
  /v1/files:
    get:
      tags:
        - Arquivos
      summary: Lista arquivos
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: number
            minimum: 1
            maximum: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          required: false
          description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Padrão: desc."
          required: false
          description: "Padrão: desc."
          name: sort_order
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/File"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-files
    post:
      tags:
        - Arquivos
      summary: Inicia upload de arquivo de entrada
      description: "Fluxo em três passos: (1) este POST cria o arquivo `pending` e devolve `upload_url`; (2) `PUT` dos bytes em `upload_url` com o mesmo `Content-Type`; (3) `POST /files/{id}/confirm`. O id vai em `input_file_ids` do `POST /tasks/{id}/run` (a Task precisa aceitar arquivos de entrada). Tamanho máximo: 100 MB."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                task_id:
                  type: string
                  format: uuid
                filename:
                  type: string
                  minLength: 1
                  maxLength: 255
                content_type:
                  type: string
                  default: application/octet-stream
                size_bytes:
                  type: integer
                  minimum: 0
              required:
                - task_id
                - filename
                - size_bytes
      responses:
        "201":
          description: created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                      filename:
                        type: string
                      content_type:
                        type: string
                      status:
                        type: string
                        enum:
                          - pending
                      upload_url:
                        type: string
                      expires_in:
                        type: number
                        description: Validade de `upload_url`, em segundos.
                    required:
                      - id
                      - filename
                      - content_type
                      - status
                      - upload_url
                      - expires_in
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          description: TASK_DOES_NOT_ACCEPT_FILES / VALIDATION_ERROR — Task fora da organização
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-files
  /v1/files/{id}:
    get:
      tags:
        - Arquivos
      summary: Detalha o arquivo
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/File"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-files-id
  /v1/files/{id}/confirm:
    post:
      tags:
        - Arquivos
      summary: Confirma o upload (pending → uploaded)
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/File"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: CONFLICT — não é um arquivo de entrada pendente / IDEMPOTENCY_KEY_REUSED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-files-id-confirm
  /v1/files/{id}/download:
    get:
      tags:
        - Arquivos
      summary: URL temporária de download
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                      url:
                        type: string
                      expires_in:
                        type: number
                    required:
                      - id
                      - url
                      - expires_in
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: FILE_NOT_UPLOADED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-files-id-download
  /v1/executions/search:
    get:
      tags:
        - Execuções
      summary: Busca textual nas execuções
      description: "Procura em eventos, todos, logs, resultado e erro. Até 30 execuções, mais recentes primeiro, cada uma com até 3 trechos. Só entram as fontes que o chamador poderia ler direto: logs exigem a liberação `executions_logs.view` da organização, e num token de pessoa o papel precisa de `agent.logs.list`, `agent.events.list` e `agent.todos.list` para logs, eventos e todos."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            minLength: 2
          required: true
          name: q
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          format: uuid
                        skill:
                          type: string
                        status:
                          type: string
                        started_at:
                          type: string
                        finished_at:
                          type:
                            - string
                            - "null"
                        workspace_label:
                          type:
                            - string
                            - "null"
                        activity_label:
                          type:
                            - string
                            - "null"
                        task_label:
                          type:
                            - string
                            - "null"
                        matches:
                          type: array
                          items:
                            type: object
                            properties:
                              source:
                                type: string
                                enum:
                                  - event
                                  - result
                                  - logs
                                  - error
                                  - todo
                              snippet:
                                type: string
                            required:
                              - source
                              - snippet
                      required:
                        - id
                        - skill
                        - status
                        - started_at
                        - finished_at
                        - workspace_label
                        - activity_label
                        - task_label
                        - matches
                required:
                  - data
        "400":
          description: VALIDATION_ERROR — `q` com menos de 2 caracteres
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: "RATE_LIMITED — limite próprio da busca: 30 por minuto por token"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-executions-search
  /v1/executions/{id}/logs:
    get:
      tags:
        - Execuções
      summary: Logs da execução
      description: Em ordem de chegada, até 1000 por chamada. Para acompanhar uma execução em andamento, passe em `after_id` o último `id` recebido e repita.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type:
              - integer
              - "null"
          required: false
          name: after_id
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: number
                        execution_id:
                          type: string
                          format: uuid
                        occurred_at:
                          type: string
                        level:
                          type: string
                        text:
                          type: string
                      required:
                        - id
                        - execution_id
                        - occurred_at
                        - level
                        - text
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-executions-id-logs
  /v1/executions/{id}/events:
    get:
      tags:
        - Execuções
      summary: Eventos da execução
      description: Por `sequence`, até 500 por chamada. Para acompanhar, passe em `after_sequence` o último `sequence` recebido e repita.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type:
              - integer
              - "null"
          required: false
          name: after_sequence
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: number
                        execution_id:
                          type: string
                          format: uuid
                        sequence:
                          type: number
                        occurred_at:
                          type: string
                        type:
                          type: string
                        level:
                          type: string
                        step:
                          type:
                            - string
                            - "null"
                        message:
                          type: string
                        payload: {}
                      required:
                        - id
                        - execution_id
                        - sequence
                        - occurred_at
                        - type
                        - level
                        - step
                        - message
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-executions-id-events
  /v1/repository:
    get:
      tags:
        - Repositório
      summary: Kadu Playbook da organização
      description: Conectar o repositório é a instalação do GitHub App, feita no console (fluxo OAuth no navegador).
      security:
        - bearerAuth: []
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      url:
                        type:
                          - string
                          - "null"
                      connection:
                        type:
                          - string
                          - "null"
                        enum:
                          - github_app
                          - deploy_key
                          - null
                      skills_count:
                        type: number
                      synced_at:
                        type:
                          - string
                          - "null"
                      sync_error:
                        type:
                          - string
                          - "null"
                    required:
                      - url
                      - connection
                      - skills_count
                      - synced_at
                      - sync_error
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE (ver acima) ou FEATURE_NOT_ENABLED — a operação não está liberada para a organização (a mesma permissão que libera a tela no console); `details: { permission }`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-repository
  /v1/repository/sync:
    post:
      tags:
        - Repositório
      summary: Sincroniza o Kadu Playbook
      description: Enfileira a sincronização (o worker clona o repositório e atualiza o catálogo de Tasks). Acompanhe `synced_at` e `sync_error` em `GET /repository`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      responses:
        "202":
          description: accepted
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      enqueued:
                        type: boolean
                        enum:
                          - true
                    required:
                      - enqueued
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE (ver acima) ou FEATURE_NOT_ENABLED — a operação não está liberada para a organização (a mesma permissão que libera a tela no console); `details: { permission }`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          description: NO_PLUGIN_REPO / NO_DEPLOY_KEY
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: QUEUE_UNAVAILABLE / AS_UNAVAILABLE
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-repository-sync
  /v1/usage:
    get:
      tags:
        - Uso
      summary: Uso e custo das execuções e das conversas
      description: "Agregado por dia (no fuso da organização) × grupo, somando execuções e turnos de conversa do bot do Slack (origem `slack_chat`, sem workspace/atividade/Task). Padrão: últimos 30 dias; período máximo de 366 dias. `group` é o id (tier, workspace, activity, task) ou a origem; null = sem valor."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            pattern: ^\d{4}-\d{2}-\d{2}$
          required: false
          name: from
          in: query
        - schema:
            type: string
            pattern: ^\d{4}-\d{2}-\d{2}$
          required: false
          name: to
          in: query
        - schema:
            type: string
            enum:
              - tier
              - workspace
              - activity
              - task
              - source
          required: false
          name: group_by
          in: query
        - schema:
            type: string
            format: uuid
          required: false
          name: workspace_id
          in: query
        - schema:
            type: string
            format: uuid
          required: false
          name: activity_id
          in: query
        - schema:
            type: string
            format: uuid
          required: false
          name: task_id
          in: query
        - schema:
            type: string
          required: false
          name: source
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      from:
                        type: string
                      to:
                        type: string
                      time_zone:
                        type: string
                      group_by:
                        type: string
                      totals:
                        type: object
                        properties:
                          executions:
                            type: number
                          conversation_turns:
                            type: number
                            description: Turnos de conversa do bot do Slack (origem `slack_chat`).
                          input_tokens:
                            type: number
                          output_tokens:
                            type: number
                          cache_read_tokens:
                            type: number
                          cache_write_tokens:
                            type: number
                          cost_brl:
                            type: number
                            description: Preço em R$ (tokens × preço do tier). Só com Analytics › Custo liberado.
                        required:
                          - executions
                          - conversation_turns
                          - input_tokens
                          - output_tokens
                          - cache_read_tokens
                          - cache_write_tokens
                      buckets:
                        type: array
                        items:
                          type: object
                          properties:
                            executions:
                              type: number
                            conversation_turns:
                              type: number
                              description: Turnos de conversa do bot do Slack (origem `slack_chat`).
                            input_tokens:
                              type: number
                            output_tokens:
                              type: number
                            cache_read_tokens:
                              type: number
                            cache_write_tokens:
                              type: number
                            cost_brl:
                              type: number
                              description: Preço em R$ (tokens × preço do tier). Só com Analytics › Custo liberado.
                            date:
                              type: string
                            group:
                              type:
                                - string
                                - "null"
                          required:
                            - executions
                            - conversation_turns
                            - input_tokens
                            - output_tokens
                            - cache_read_tokens
                            - cache_write_tokens
                            - date
                            - group
                    required:
                      - from
                      - to
                      - time_zone
                      - group_by
                      - totals
                      - buckets
                required:
                  - data
        "400":
          description: VALIDATION_ERROR
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE (ver acima) ou FEATURE_NOT_ENABLED — a operação não está liberada para a organização (a mesma permissão que libera a tela no console); `details: { permission }`."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-usage
  /v1/organizations/{id}/slack_installations:
    get:
      tags:
        - Organizações
      summary: Instalações do bot do Slack da organização
      description: "Workspaces do Slack ligados à organização do token. Outra organização: 403."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/SlackInstallation"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-organizations-id-slack-installations
  /v1/organizations/{id}/slack_installations/{installationId}:
    patch:
      tags:
        - Organizações
      summary: Configura uma instalação do Slack
      description: Onde o bot responde (`allowed_channel_types`), arquivos de saída como link ou anexo (`files_mode`, `max_upload_bytes` até 100 MB) e detalhe na thread (`log_detail`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            format: uuid
          required: true
          name: installationId
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                allowed_channel_types:
                  type: array
                  items:
                    type: string
                    enum:
                      - im
                      - private_channel
                      - public_channel
                      - mpim
                      - shared_channel
                  minItems: 1
                files_mode:
                  type: string
                  enum:
                    - link
                    - upload
                max_upload_bytes:
                  type: integer
                  exclusiveMinimum: 0
                  maximum: 104857600
                log_detail:
                  type: string
                  enum:
                    - milestones
                    - verbose
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/SlackInstallation"
                required:
                  - data
        "400":
          description: VALIDATION_ERROR
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: patch-organizations-id-slack-installations-installationid
    delete:
      tags:
        - Organizações
      summary: Remove uma instalação do Slack
      description: Exige o nível `delete` (ou `all`). Revoga o token do bot no Slack e desfaz as conexões de conta.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            format: uuid
          required: true
          name: installationId
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                      deleted:
                        type: boolean
                    required:
                      - id
                      - deleted
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-organizations-id-slack-installations-installationid
  /v1/executions/{id}/todos:
    get:
      tags:
        - Execuções
      summary: Pendências (todos) da execução
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Todo"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-executions-id-todos
  /v1/todos/{id}:
    patch:
      tags:
        - Pendências
      summary: Resolve pendência
      description: "A única transição pela API: `status: resolved`."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            pattern: ^\d+$
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                status:
                  type: string
                  enum:
                    - resolved
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Todo"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: patch-todos-id
  /v1/webhooks:
    get:
      tags:
        - Webhooks
      summary: Lista webhooks
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: number
            minimum: 1
            maximum: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          required: false
          description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Padrão: desc."
          required: false
          description: "Padrão: desc."
          name: sort_order
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Webhook"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-webhooks
    post:
      tags:
        - Webhooks
      summary: Cria webhook
      description: A URL é conferida contra rede interna. `signing_secret` é devolvido só nesta resposta (o replay de idempotência devolve `null`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                label:
                  type: string
                  minLength: 1
                workspace_id:
                  type:
                    - string
                    - "null"
                  format: uuid
                url:
                  type: string
                  format: uri
                auth:
                  type: string
                  enum:
                    - basic
                    - bearer
                    - header
                auth_basic_user:
                  type: string
                auth_basic_password:
                  type: string
                auth_bearer_token:
                  type: string
                auth_header_key:
                  type: string
                auth_header_value:
                  type: string
                subscribed_events:
                  type: array
                  items:
                    type: string
                  default: []
                emails:
                  type: array
                  items:
                    type: object
                    properties:
                      address:
                        type: string
                        format: email
                    required:
                      - address
                  default: []
              required:
                - label
                - url
                - auth
      responses:
        "201":
          description: created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    allOf:
                      - $ref: "#/components/schemas/Webhook"
                      - type: object
                        properties:
                          signing_secret:
                            type:
                              - string
                              - "null"
                        required:
                          - signing_secret
                    description: Segredos e credenciais nunca são devolvidos.
                required:
                  - data
        "400":
          description: VALIDATION_ERROR
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: FEATURE_NOT_ENABLED — exige a liberação `webhooks.create` da organização
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "422":
          description: VALIDATION_ERROR — workspace fora da organização
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-webhooks
  /v1/webhooks/{id}:
    get:
      tags:
        - Webhooks
      summary: Detalha o webhook
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Webhook"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-webhooks-id
    patch:
      tags:
        - Webhooks
      summary: Atualiza webhook
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                label:
                  type: string
                  minLength: 1
                url:
                  type: string
                  format: uri
                subscribed_events:
                  type: array
                  items:
                    type: string
                status:
                  type: string
                  enum:
                    - active
                    - inactive
                emails:
                  type: array
                  items:
                    type: object
                    properties:
                      address:
                        type: string
                        format: email
                    required:
                      - address
                auth_basic_user:
                  type: string
                auth_basic_password:
                  type: string
                auth_bearer_token:
                  type: string
                auth_header_key:
                  type: string
                auth_header_value:
                  type: string
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Webhook"
                required:
                  - data
        "400":
          description: VALIDATION_ERROR
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: FEATURE_NOT_ENABLED — exige a liberação `webhooks.update` da organização
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: patch-webhooks-id
    delete:
      tags:
        - Webhooks
      summary: Remove webhooks (soft delete)
      description: "Exige o nível `delete` (ou `all`): `write` não apaga. Exige a liberação `webhooks.delete`. Webhook declarado no `kadu.yaml` (`repo_managed`) responde 409 REPO_MANAGED: remova-o de lá."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Webhook"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-webhooks-id
  /v1/webhooks/{id}/rotate-secret:
    post:
      tags:
        - Webhooks
      summary: Gira o segredo de assinatura
      description: "Devolve o segredo novo só nesta resposta; o anterior continua assinando por 24h (o replay de idempotência devolve `signing_secret: null`)."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                      signing_secret:
                        type:
                          - string
                          - "null"
                      previous_signing_secret_expires_at:
                        type: string
                    required:
                      - id
                      - signing_secret
                      - previous_signing_secret_expires_at
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-webhooks-id-rotate-secret
  /v1/webhook_deliveries:
    get:
      tags:
        - Entregas de webhook
      summary: Entregas de webhook (50 mais recentes)
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: false
          name: webhook_id
          in: query
        - schema:
            type: string
            enum:
              - pending
              - success
              - failed
          required: false
          name: status
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/WebhookDelivery"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "400":
          description: BAD_REQUEST — `status` ou `webhook_id` inválido
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-webhook-deliveries
  /v1/webhook_deliveries/{id}:
    get:
      tags:
        - Entregas de webhook
      summary: Detalha a entrega de webhook
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/WebhookDelivery"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-webhook-deliveries-id
  /v1/webhook_deliveries/{id}/replay:
    post:
      tags:
        - Entregas de webhook
      summary: Reenfileira a entrega
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      responses:
        "202":
          description: accepted
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      webhook_delivery_id:
                        type: string
                        format: uuid
                      webhook_id:
                        type: string
                        format: uuid
                      system_event_id:
                        type: string
                        format: uuid
                      enqueued:
                        type: boolean
                        enum:
                          - true
                    required:
                      - webhook_delivery_id
                      - webhook_id
                      - system_event_id
                      - enqueued
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: REPLAY_IN_FLIGHT — já há reenvio pendente deste evento / IDEMPOTENCY_KEY_REUSED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-webhook-deliveries-id-replay
  /v1/operation_approvals:
    get:
      tags:
        - Aprovações
      summary: Aprovações por link da pessoa do token
      description: "Operações que um assistente pediu pelo MCP e que só rodam depois que a pessoa confirma pelo link no console. Lista só as aprovações da pessoa do token, na organização do token, mais recentes primeiro. Só leitura: Continuar e Cancelar acontecem no console. Escopo: `kadu/system_events`."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            enum:
              - pending
              - approved
              - executed
              - declined
              - failed
              - expired
          required: false
          name: status
          in: query
        - schema:
            type: string
            example: tasks
          required: false
          name: resource
          in: query
        - schema:
            type: string
            description: ISO 8601 (data ou data e hora).
          required: false
          description: ISO 8601 (data ou data e hora).
          name: created_at[gte]
          in: query
        - schema:
            type: string
            description: ISO 8601 (data ou data e hora).
          required: false
          description: ISO 8601 (data ou data e hora).
          name: created_at[lte]
          in: query
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: number
            minimum: 1
            maximum: 100
          required: false
          name: limit
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/OperationApproval"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "400":
          description: VALIDATION_ERROR — filtro ou cursor inválido
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: PERSON_REQUIRED — o token não é de uma pessoa da organização / INSUFFICIENT_SCOPE
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-operation-approvals
  /v1/operation_approvals/{id}:
    get:
      tags:
        - Aprovações
      summary: Detalha uma aprovação por link
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
          required: true
          name: id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/OperationApprovalDetail"
                required:
                  - data
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: PERSON_REQUIRED — o token não é de uma pessoa da organização / INSUFFICIENT_SCOPE
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-operation-approvals-id
  /v1/roles:
    get:
      tags:
        - Papéis
      summary: Lista papéis
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: number
            minimum: 1
            maximum: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          required: false
          description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Padrão: desc."
          required: false
          description: "Padrão: desc."
          name: sort_order
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Role"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-roles
    post:
      tags:
        - Papéis
      summary: Cria papel
      description: Permissões no formato `*`, `agent.*`, `agent.<recurso>.*` ou `agent.<recurso>.<ação>`. Num token de pessoa, nenhuma pode ir além do papel de quem cria.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          required: false
          description: "Chave opaca (até 255 caracteres), válida por 24h na organização. Mesma chave + mesma requisição devolve a resposta original com `X-Idempotent-Replay: true`; mesma chave com corpo diferente → 409 IDEMPOTENCY_KEY_REUSED. Segredo de uso único (`signing_secret` na criação e na rotação de webhook) não é guardado: no replay ele volta `null`."
          name: X-Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                label:
                  type: string
                  minLength: 1
                  maxLength: 255
                permissions:
                  type: array
                  items:
                    type: string
                  maxItems: 200
                  default: []
              required:
                - label
      responses:
        "201":
          description: created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: "#/components/schemas/Role"
                required:
                  - data
        "400":
          description: VALIDATION_ERROR
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: PERMISSION_ESCALATION — `details.permissions` lista o que excede o seu papel
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: IDEMPOTENCY_KEY_REUSED / IDEMPOTENCY_REQUEST_IN_PROGRESS (ou CONFLICT da rota)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-roles
  /v1/users:
    get:
      tags:
        - Usuários
      summary: Membros da organização (até 100)
      security:
        - bearerAuth: []
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/User"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-users
  /v1/memberships:
    get:
      tags:
        - Vínculos
      summary: Lista vínculos
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: number
            minimum: 1
            maximum: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          required: false
          description: "Campo em snake_case: created_at (padrão), updated_at ou um campo filtrável."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Padrão: desc."
          required: false
          description: "Padrão: desc."
          name: sort_order
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Membership"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-memberships
  /v1/system_events:
    get:
      tags:
        - Eventos de sistema
      summary: Eventos de sistema (100 mais recentes)
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
          required: false
          name: slug
          in: query
        - schema:
            type: string
            format: uuid
          required: false
          name: workspace_id
          in: query
        - schema:
            type: string
            format: uuid
          required: false
          name: task_id
          in: query
        - schema:
            type: string
            format: uuid
          required: false
          name: execution_id
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/SystemEvent"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
                required:
                  - data
                  - meta
        "400":
          description: VALIDATION_ERROR — filtro inválido
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: INVALID_TOKEN / INVALID_AUDIENCE / INVALID_ISSUER / TOKEN_EXPIRED / TOKEN_REVOKED / MTLS_REQUIRED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: "INSUFFICIENT_SCOPE — o token não tem o nível de acesso (ou o recurso `kadu/…`) que a operação exige; `details: { required, granted }`. USER_PERMISSION_DENIED — o papel da pessoa dona do token não concede a operação; `details: { required }`. NOT_A_MEMBER — a pessoa não é membro da organização. FEATURE_NOT_ENABLED — a operação não está liberada para a organização; `details: { permission }`. UNKNOWN_ORGANIZATION — o `org` do token não é uma organização do Kadu."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: AS_UNAVAILABLE — a verificação do token está indisponível (Authorization Server fora do ar ou configuração ausente). Tente de novo (`Retry-After`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-system-events
webhooks: {}
tags:
  - name: Identidade
    description: Quem está por trás do token.
  - name: Organizações
    description: "A organização do token: nome, fuso, teto mensal de custo e `custom_metadata`."
  - name: Workspaces
    description: Domínios de negócio da organização. Cada workspace é um plugin do Kadu Playbook.
  - name: Atividades
    description: Agrupadores de tarefas dentro de um workspace.
  - name: Tarefas
    description: "As skills executáveis da organização: cadastro, disparo, pré-checagem e o endpoint HTTP de disparo."
  - name: Execuções
    description: Cada disparo de uma tarefa, com logs, eventos, pendências e busca textual.
  - name: Pendências
    description: Pendências criadas pelas execuções.
  - name: Arquivos
    description: Arquivos de entrada (anexados ao disparo) e de saída (publicados pela execução).
  - name: Ambientes
    description: Ambientes de execução (Produção, Sandbox…). Cada secret e agendamento pertence a um.
  - name: Secrets
    description: Credenciais entregues às execuções. O valor é gravado cifrado e nunca é devolvido.
  - name: Agendamentos
    description: Execuções recorrentes de uma tarefa num ambiente, por expressão cron.
  - name: Memórias
    description: "Memória da organização: registros por entidade (`entity_type` + `entity_value`), no escopo da organização, de um workspace ou de uma atividade."
  - name: Webhooks
    description: Notificações HTTP assinadas enviadas quando eventos acontecem.
  - name: Entregas de webhook
    description: Histórico e reenvio das entregas de webhook.
  - name: Aprovações
    description: Operações pedidas por um assistente pelo MCP que esperam a confirmação da pessoa pelo link (só leitura).
  - name: Repositório
    description: O Kadu Playbook da organização e a sincronização dele.
  - name: Uso
    description: Tokens, custo e preço das execuções.
  - name: Usuários
    description: Membros da organização.
  - name: Vínculos
    description: Vínculos de pessoas com a organização.
  - name: Papéis
    description: Papéis e as permissões `agent.*` que concedem.
  - name: Eventos de sistema
    description: Eventos da organização (os mesmos que alimentam os webhooks).
