openapi: 3.1.0
info:
  title: API do Kobana Dunning
  version: 1.0.0
  description: API pública da Régua de Cobrança — a régua de cobrança da Kobana. Gerencie clientes, cobranças, réguas, acordos, disputas e webhooks programaticamente. Autentique com uma chave de API (Bearer) criada no dashboard em Configurações → Segurança; o acesso é limitado pelos escopos da chave (`dunning.dashboard.<recurso>.<ação>`).
  license:
    name: Proprietário — Kobana
    url: https://kobana.com.br
servers:
  - url: https://api.dunning.kobana.com.br
    description: Produção
  - url: https://api.dunning.sandbox.kobana.com.br
    description: Sandbox — ambiente de testes isolado, separado da produção.
components:
  schemas:
    Error:
      type: object
      properties:
        message:
          type: string
          description: Mensagem legível descrevendo o erro.
        code:
          type: string
          description: "Código estável do erro (ex.: VALIDATION_ERROR, NOT_FOUND)."
          example: VALIDATION_ERROR
        details:
          description: "Detalhes adicionais (ex.: erros de validação por campo)."
      required:
        - message
        - code
      description: "Envelope de erro da API: mensagem legível + código estável."
    PaginationMeta:
      type: object
      properties:
        total:
          type: integer
          description: Total de registros que casam com o filtro.
        page:
          type: integer
          description: Página atual.
        limit:
          type: integer
          description: Itens por página aplicados.
        totalPages:
          type: integer
          description: Total de páginas.
      required:
        - total
        - page
        - limit
        - totalPages
      description: Metadados de paginação das listagens.
    PersonAddress:
      type: object
      properties:
        street:
          type: string
          description: Logradouro.
        number:
          type: string
          description: Número.
        complement:
          type: string
          description: Complemento.
        neighborhood:
          type: string
          description: Bairro.
        city:
          type: string
          description: Cidade.
        state:
          type: string
          minLength: 2
          maxLength: 2
          description: UF (2 letras).
          example: SP
        zipCode:
          type: string
          description: CEP (8 dígitos).
          example: "01310100"
      required:
        - street
        - number
        - neighborhood
        - city
        - state
        - zipCode
    PersonPhone:
      type: object
      properties:
        kind:
          type: string
          enum:
            - mobile
            - landline
            - commercial
            - whatsapp
          description: Tipo (`mobile` | `landline` | `commercial` | `whatsapp`).
        countryCode:
          type: string
          description: DDI.
          example: "55"
        areaCode:
          type: string
          description: DDD.
          example: "11"
        number:
          type: string
          description: Número.
          example: "999998888"
      required:
        - kind
        - countryCode
        - areaCode
        - number
    PersonEmail:
      type: object
      properties:
        label:
          type: string
          enum:
            - personal
            - commercial
            - financial
          description: Rótulo (`personal` | `commercial` | `financial`).
        address:
          type: string
          format: email
          description: Endereço de e-mail.
      required:
        - label
        - address
    Person:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        organizationId:
          type: string
          format: uuid
          description: Organização dona do registro.
        workspaceId:
          type:
            - string
            - "null"
          format: uuid
          description: Workspace do registro (hierarquia multi-tenant).
        companyId:
          type:
            - string
            - "null"
          format: uuid
          description: Empresa (credora) associada ao cliente.
        classificationId:
          type:
            - string
            - "null"
          format: uuid
          description: Classificação do cliente (segmentação da régua).
        documentNumber:
          type:
            - string
            - "null"
          description: CPF/CNPJ (somente dígitos).
          example: "12345678901"
        documentType:
          type:
            - string
            - "null"
          enum:
            - cpf
            - cnpj
            - null
          description: Tipo do documento (`cpf` | `cnpj`).
        kind:
          type:
            - string
            - "null"
          enum:
            - natural
            - juridical
            - null
          description: Natureza (`natural` = pessoa física, `juridical` = jurídica).
        name:
          type: string
          description: Nome do cliente.
          example: Maria da Silva
        legalName:
          type:
            - string
            - "null"
          description: Razão social.
        nickname:
          type:
            - string
            - "null"
          description: Apelido/nome fantasia.
        birthday:
          type:
            - string
            - "null"
          description: Data de nascimento (ISO 8601).
        addresses:
          type: array
          items:
            $ref: "#/components/schemas/PersonAddress"
          description: Endereços.
        phones:
          type: array
          items:
            $ref: "#/components/schemas/PersonPhone"
          description: Telefones.
        emails:
          type: array
          items:
            $ref: "#/components/schemas/PersonEmail"
          description: E-mails.
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema (chave das integrações).
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        notes:
          type:
            - string
            - "null"
          description: Observações internas.
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        createdViaApi:
          type: boolean
          description: true quando o registro foi criado pela API.
        flaggedThirdPartyAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento em que a pessoa marcou "não sou eu" no portal (supressão total).
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados gravados pelo sistema.
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        updatedAt:
          type: string
          format: date-time
          description: Atualizado em (ISO 8601).
        deletedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Excluído em (soft delete; null quando ativo).
      required:
        - id
        - publicId
        - organizationId
        - workspaceId
        - companyId
        - classificationId
        - documentNumber
        - documentType
        - kind
        - name
        - legalName
        - nickname
        - birthday
        - addresses
        - phones
        - emails
        - externalId
        - tags
        - notes
        - customData
        - createdViaApi
        - flaggedThirdPartyAt
        - metadata
        - createdAt
        - updatedAt
        - deletedAt
      description: Cliente (pessoa física ou jurídica) da carteira de cobrança.
    PersonCreateRequest:
      type: object
      properties:
        classificationId:
          type:
            - string
            - "null"
          format: uuid
          description: Classificação do cliente (segmentação da régua).
        documentNumber:
          type:
            - string
            - "null"
          maxLength: 20
          description: CPF/CNPJ (somente dígitos).
        documentType:
          type:
            - string
            - "null"
          enum:
            - cpf
            - cnpj
            - null
          description: Tipo do documento (`cpf` | `cnpj`).
        kind:
          type:
            - string
            - "null"
          enum:
            - natural
            - juridical
            - null
          description: Natureza (`natural` = pessoa física, `juridical` = jurídica).
        name:
          type: string
          minLength: 1
          maxLength: 120
          description: Nome do cliente.
        legalName:
          type:
            - string
            - "null"
          description: Razão social.
        nickname:
          type:
            - string
            - "null"
          maxLength: 120
          description: Apelido/nome fantasia.
        birthday:
          type:
            - string
            - "null"
          format: date-time
          description: Data de nascimento (ISO 8601).
        addresses:
          type: array
          items:
            $ref: "#/components/schemas/PersonAddress"
          description: Endereços.
        phones:
          type: array
          items:
            $ref: "#/components/schemas/PersonPhone"
          description: Telefones.
        emails:
          type: array
          items:
            $ref: "#/components/schemas/PersonEmail"
          description: E-mails.
        externalId:
          type:
            - string
            - "null"
          maxLength: 60
          description: Identificador no SEU sistema (chave das integrações).
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        notes:
          type:
            - string
            - "null"
          description: Observações internas.
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
      required:
        - name
      description: Dados para criar um cliente.
    PersonUpdateRequest:
      type: object
      properties:
        classificationId:
          type:
            - string
            - "null"
          format: uuid
          description: Classificação do cliente (segmentação da régua).
        documentNumber:
          type:
            - string
            - "null"
          maxLength: 20
          description: CPF/CNPJ (somente dígitos).
        documentType:
          type:
            - string
            - "null"
          enum:
            - cpf
            - cnpj
            - null
          description: Tipo do documento (`cpf` | `cnpj`).
        kind:
          type:
            - string
            - "null"
          enum:
            - natural
            - juridical
            - null
          description: Natureza (`natural` = pessoa física, `juridical` = jurídica).
        name:
          type: string
          minLength: 1
          maxLength: 120
          description: Nome do cliente.
        legalName:
          type:
            - string
            - "null"
          description: Razão social.
        nickname:
          type:
            - string
            - "null"
          maxLength: 120
          description: Apelido/nome fantasia.
        birthday:
          type:
            - string
            - "null"
          format: date-time
          description: Data de nascimento (ISO 8601).
        addresses:
          type: array
          items:
            $ref: "#/components/schemas/PersonAddress"
          description: Endereços.
        phones:
          type: array
          items:
            $ref: "#/components/schemas/PersonPhone"
          description: Telefones.
        emails:
          type: array
          items:
            $ref: "#/components/schemas/PersonEmail"
          description: E-mails.
        externalId:
          type:
            - string
            - "null"
          maxLength: 60
          description: Identificador no SEU sistema (chave das integrações).
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        notes:
          type:
            - string
            - "null"
          description: Observações internas.
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
      description: Campos a atualizar (parcial — envie só o que muda).
    PersonListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Person"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    ChargePolicy:
      type: object
      properties:
        fine:
          anyOf:
            - type: object
              properties:
                disabled:
                  type: boolean
                  enum:
                    - true
              required:
                - disabled
            - type: object
              properties:
                mode:
                  type: string
                  enum:
                    - percent
                    - fixed
                value:
                  type: number
                  minimum: 0
                graceDays:
                  type: integer
                  minimum: 0
              required:
                - mode
                - value
          description: "Multa por atraso: incide UMA vez após `graceDays` do vencimento. `mode` = `percent` (sobre o valor original) ou `fixed` (valor absoluto); `value` ≥ 0."
        interest:
          anyOf:
            - type: object
              properties:
                disabled:
                  type: boolean
                  enum:
                    - true
              required:
                - disabled
            - type: object
              properties:
                mode:
                  type: string
                  enum:
                    - percent_month
                    - percent_day
                    - fixed_day
                value:
                  type: number
                  minimum: 0
                graceDays:
                  type: integer
                  minimum: 0
              required:
                - mode
                - value
          description: "Juros de mora: pró-rata die, acumulam por dia a partir do vencimento (respeitando `graceDays`). `mode` = `percent_month`, `percent_day` ou `fixed_day`; `value` ≥ 0."
        discount:
          anyOf:
            - type: object
              properties:
                disabled:
                  type: boolean
                  enum:
                    - true
              required:
                - disabled
            - type: array
              items:
                type: object
                properties:
                  mode:
                    type: string
                    enum:
                      - percent
                      - fixed
                  value:
                    type: number
                    minimum: 0
                  limitDate:
                    type: string
                required:
                  - mode
                  - value
          description: "Desconto por antecipação: lista de faixas `{ mode, value, limitDate? }` por data-limite (mais cedo = mais desconto). `mode` = `percent` ou `fixed`. `limitDate` (`YYYY-MM-DD`) ausente = válido enquanto não vencido."
        correction:
          type: object
          properties:
            index:
              type: string
              enum:
                - none
                - ipca
                - igpm
              description: Índice de correção monetária (`none` | `ipca` | `igpm`).
          required:
            - index
          description: Correção monetária aplicada ao valor.
      description: 'Política de encargos por título (motor). Sobrescreve, no nível da cobrança, a política herdada (organização → régua → cobrança), com merge campo-a-campo. Cada bloco aceita `{ "disabled": true }` para desligar aquele encargo. Ausente/nulo = herda tudo do pai.'
    ChargeEncargos:
      type: object
      properties:
        fineAmount:
          type: number
          description: Multa apurada.
          example: 30
        interestAmount:
          type: number
          description: Juros de mora apurados.
          example: 15
        correctionAmount:
          type: number
          description: Correção monetária apurada.
          example: 0
        discountAmount:
          type: number
          description: Desconto apurado.
          example: 0
        currentAmount:
          type: number
          description: Valor atual = original + multa + juros + correção − desconto.
          example: 1545
        daysOverdue:
          type: integer
          description: Dias em atraso calculados no fuso da organização (0 quando não vencida).
          example: 12
      required:
        - fineAmount
        - interestAmount
        - correctionAmount
        - discountAmount
        - currentAmount
        - daysOverdue
      description: Breakdown de encargos derivado pelo motor no fuso da organização (aditivo à cobrança). Valores em number (não string decimal).
    Charge:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        organizationId:
          type: string
          format: uuid
          description: Organização dona do registro.
        workspaceId:
          type:
            - string
            - "null"
          format: uuid
          description: Workspace do registro (hierarquia multi-tenant).
        companyId:
          type:
            - string
            - "null"
          format: uuid
          description: Empresa (credora) da cobrança.
        businessUnitId:
          type:
            - string
            - "null"
          format: uuid
          description: Unidade de negócio (BU) da cobrança.
        personId:
          type: string
          format: uuid
          description: Cliente (devedor) da cobrança.
        collectionRuleId:
          type:
            - string
            - "null"
          format: uuid
          description: Régua de cobrança que acompanha o título. Se omitido na criação, usa a régua padrão da organização.
        documentNumber:
          type:
            - string
            - "null"
          description: Número do documento de origem (nota fiscal, contrato etc.).
          example: NF-2026-0042
        description:
          type:
            - string
            - "null"
          description: Descrição livre da cobrança.
        originalAmount:
          type: string
          description: Valor original do título.
          example: "1500.00"
        interestAmount:
          type: string
          description: Juros acumulados (padrão 0).
          example: "15.00"
        fineAmount:
          type: string
          description: Multa (padrão 0).
          example: "30.00"
        discountAmount:
          type: string
          description: Desconto aplicado (padrão 0).
          example: "0.00"
        correctionAmount:
          type: string
          description: Correção monetária acumulada (índice IPCA/IGP-M, padrão 0). Serializada como string decimal.
          example: "0.00"
        paidAmount:
          type:
            - string
            - "null"
          description: Valor efetivamente pago.
          example: "1545.00"
        currentAmount:
          type:
            - string
            - "null"
          description: Valor atual (original + juros + multa − desconto). Recalculado automaticamente em criações e atualizações.
          example: "1545.00"
        issueDate:
          type: string
          format: date-time
          description: Data de emissão.
        dueDate:
          type: string
          format: date-time
          description: Data de vencimento.
        paidAt:
          type:
            - string
            - "null"
          format: date-time
          description: Data do pagamento.
        daysOverdue:
          type: integer
          description: Dias em atraso (0 quando não vencida). Recalculado na leitura.
          example: 12
        status:
          type: string
          enum:
            - pending
            - paid
            - overdue
            - cancelled
            - negotiated
            - protested
            - negatived
            - written_off
          description: Status (`pending` | `paid` | `overdue` | `cancelled` | `negotiated` | `protested` | `negatived` | `written_off`).
        paymentMethod:
          type:
            - string
            - "null"
          enum:
            - boleto
            - pix
            - credit_card
            - transfer
            - null
          description: Meio de pagamento (`boleto` | `pix` | `credit_card` | `transfer`).
        barcode:
          type:
            - string
            - "null"
          description: Linha digitável/código de barras do boleto.
        pixEmv:
          type:
            - string
            - "null"
          description: Código Pix copia-e-cola (EMV).
        paymentUrl:
          type:
            - string
            - "null"
          description: URL da página de pagamento.
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        currentStep:
          type:
            - integer
            - "null"
          description: Etapa atual da régua de cobrança (0 = nenhuma executada).
        lastNotificationAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da última notificação enviada.
        negativedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da negativação (SPC/Serasa).
        protestedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento do protesto em cartório.
        source:
          type: string
          enum:
            - kobana
            - erp
            - api
            - spreadsheet
            - manual
          description: Origem do título (`kobana` | `erp` | `api` | `spreadsheet` | `manual`).
        lastVerifiedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Última verificação de pagamento na origem.
        paymentClaimed:
          type: boolean
          description: true quando o devedor declarou "já paguei" no portal — a régua pausa e abre verificação.
        legalHold:
          type: boolean
          description: "Trava jurídica (prescrição, determinação judicial): suspende a cobrança."
        legalHoldReason:
          type:
            - string
            - "null"
          description: Motivo da trava jurídica.
        encargoSource:
          type: string
          enum:
            - computed
            - boleto
          description: "Fonte dos encargos: `computed` (calculados pelo motor a partir da política) ou `boleto` (espelhados de um boleto registrado, que é a fonte da verdade e não recalcula)."
          example: computed
        chargePolicy:
          allOf:
            - $ref: "#/components/schemas/ChargePolicy"
            - type:
                - object
                - "null"
        deletedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Excluído em (soft delete; null quando ativo).
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados gravados pelo sistema.
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        updatedAt:
          type: string
          format: date-time
          description: Atualizado em (ISO 8601).
        encargos:
          $ref: "#/components/schemas/ChargeEncargos"
      required:
        - id
        - publicId
        - organizationId
        - workspaceId
        - companyId
        - businessUnitId
        - personId
        - collectionRuleId
        - documentNumber
        - description
        - originalAmount
        - interestAmount
        - fineAmount
        - discountAmount
        - correctionAmount
        - paidAmount
        - currentAmount
        - issueDate
        - dueDate
        - paidAt
        - daysOverdue
        - status
        - paymentMethod
        - barcode
        - pixEmv
        - paymentUrl
        - externalId
        - customData
        - tags
        - currentStep
        - lastNotificationAt
        - negativedAt
        - protestedAt
        - source
        - lastVerifiedAt
        - paymentClaimed
        - legalHold
        - legalHoldReason
        - encargoSource
        - chargePolicy
        - deletedAt
        - metadata
        - createdAt
        - updatedAt
        - encargos
      description: 'Cobrança (título) vinculada a um cliente e acompanhada pela régua. Valores monetários são serializados como string decimal (ex.: "1500.00").'
    ChargeCreateRequest:
      type: object
      properties:
        personId:
          type: string
          format: uuid
          description: Cliente (devedor) da cobrança.
        collectionRuleId:
          type:
            - string
            - "null"
          format: uuid
          description: Régua de cobrança que acompanha o título. Se omitido na criação, usa a régua padrão da organização.
        documentNumber:
          type:
            - string
            - "null"
          maxLength: 50
          description: Número do documento de origem (nota fiscal, contrato etc.).
        description:
          type:
            - string
            - "null"
          maxLength: 500
          description: Descrição livre da cobrança.
        originalAmount:
          type: number
          exclusiveMinimum: 0
          description: Valor original do título.
          example: 1500
        interestAmount:
          type: number
          minimum: 0
          description: Juros acumulados (padrão 0).
        fineAmount:
          type: number
          minimum: 0
          description: Multa (padrão 0).
        discountAmount:
          type: number
          minimum: 0
          description: Desconto aplicado (padrão 0).
        issueDate:
          type: string
          description: Data de emissão.
          example: 2026-07-01
        dueDate:
          type: string
          description: Data de vencimento.
          example: 2026-08-01
        status:
          type: string
          enum:
            - pending
            - paid
            - overdue
            - cancelled
            - negotiated
            - protested
            - negatived
            - written_off
          description: Status (`pending` | `paid` | `overdue` | `cancelled` | `negotiated` | `protested` | `negatived` | `written_off`).
        paymentMethod:
          type:
            - string
            - "null"
          enum:
            - boleto
            - pix
            - credit_card
            - transfer
            - null
          description: Meio de pagamento (`boleto` | `pix` | `credit_card` | `transfer`).
        barcode:
          type:
            - string
            - "null"
          maxLength: 100
          description: Linha digitável/código de barras do boleto.
        pixEmv:
          type:
            - string
            - "null"
          maxLength: 500
          description: Código Pix copia-e-cola (EMV).
        paymentUrl:
          type:
            - string
            - "null"
          format: uri
          description: URL da página de pagamento.
        externalId:
          type:
            - string
            - "null"
          maxLength: 100
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        chargePolicy:
          allOf:
            - $ref: "#/components/schemas/ChargePolicy"
            - type:
                - object
                - "null"
      required:
        - personId
        - originalAmount
        - issueDate
        - dueDate
      description: Dados para criar uma cobrança. Valores monetários entram como number; datas aceitam `YYYY-MM-DD` ou datetime ISO 8601.
    ChargeUpdateRequest:
      type: object
      properties:
        personId:
          type: string
          format: uuid
          description: Cliente (devedor) da cobrança.
        collectionRuleId:
          type:
            - string
            - "null"
          format: uuid
          description: Régua de cobrança que acompanha o título. Se omitido na criação, usa a régua padrão da organização.
        documentNumber:
          type:
            - string
            - "null"
          maxLength: 50
          description: Número do documento de origem (nota fiscal, contrato etc.).
        description:
          type:
            - string
            - "null"
          maxLength: 500
          description: Descrição livre da cobrança.
        originalAmount:
          type: number
          exclusiveMinimum: 0
          description: Valor original do título.
          example: 1500
        interestAmount:
          type: number
          minimum: 0
          description: Juros acumulados (padrão 0).
        fineAmount:
          type: number
          minimum: 0
          description: Multa (padrão 0).
        discountAmount:
          type: number
          minimum: 0
          description: Desconto aplicado (padrão 0).
        issueDate:
          type: string
          description: Data de emissão.
          example: 2026-07-01
        dueDate:
          type: string
          description: Data de vencimento.
          example: 2026-08-01
        status:
          type: string
          enum:
            - pending
            - paid
            - overdue
            - cancelled
            - negotiated
            - protested
            - negatived
            - written_off
          description: Status (`pending` | `paid` | `overdue` | `cancelled` | `negotiated` | `protested` | `negatived` | `written_off`).
        paymentMethod:
          type:
            - string
            - "null"
          enum:
            - boleto
            - pix
            - credit_card
            - transfer
            - null
          description: Meio de pagamento (`boleto` | `pix` | `credit_card` | `transfer`).
        barcode:
          type:
            - string
            - "null"
          maxLength: 100
          description: Linha digitável/código de barras do boleto.
        pixEmv:
          type:
            - string
            - "null"
          maxLength: 500
          description: Código Pix copia-e-cola (EMV).
        paymentUrl:
          type:
            - string
            - "null"
          format: uri
          description: URL da página de pagamento.
        externalId:
          type:
            - string
            - "null"
          maxLength: 100
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        chargePolicy:
          allOf:
            - $ref: "#/components/schemas/ChargePolicy"
            - type:
                - object
                - "null"
        paidAmount:
          type:
            - number
            - "null"
          minimum: 0
          description: Valor efetivamente pago.
        paidAt:
          type:
            - string
            - "null"
          description: Data do pagamento.
          example: 2026-08-03
      description: Campos a atualizar (parcial — envie só o que muda). `currentAmount` e `daysOverdue` são recalculados automaticamente.
    ChargeListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Charge"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    ChargeDeleteResponse:
      type: object
      properties:
        message:
          type: string
          description: Mensagem de confirmação da exclusão.
      required:
        - message
    ChargeNotifyRequest:
      type: object
      properties:
        channel:
          type: string
          enum:
            - email
            - sms
            - whatsapp
            - voice
            - manual
          description: Canal (`email` | `sms` | `whatsapp` | `voice` | `manual`).
        recipient:
          type: string
          minLength: 1
          description: "Destinatário: e-mail para `email`, telefone para `sms`/`whatsapp`/`voice`; livre para `manual`."
          example: maria@exemplo.com.br
        subject:
          type: string
          maxLength: 200
          description: Assunto (usado em e-mail).
        body:
          type: string
          minLength: 1
          description: Corpo da mensagem.
        collectionRuleStepId:
          type: string
          format: uuid
          description: Etapa da régua de cobrança a associar (atualiza o `currentStep` da cobrança).
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados livres gravados na notificação.
      required:
        - channel
        - recipient
        - body
      description: Dados da notificação manual a enviar para o devedor.
    ChargeNotifyResponse:
      type: object
      properties:
        message:
          type: string
          description: Mensagem de confirmação do enfileiramento.
        notification:
          type: object
          additionalProperties: {}
          description: Notificação criada (status `queued`), incluindo cliente e cobrança relacionados.
      required:
        - message
        - notification
    AgreementInstallment:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        agreementId:
          type: string
          format: uuid
          description: Acordo dono da parcela.
        installmentNumber:
          type: integer
          description: Número da parcela (a partir de 1).
          example: 1
        dueDate:
          type: string
          format: date-time
          description: Vencimento da parcela.
        amount:
          type: string
          description: Valor da parcela.
          example: "200.00"
        paidAmount:
          type:
            - string
            - "null"
          description: Valor pago da parcela.
          example: "200.00"
        paidAt:
          type:
            - string
            - "null"
          format: date-time
          description: Data do pagamento da parcela.
        status:
          type: string
          enum:
            - pending
            - paid
            - overdue
            - cancelled
          description: Status (`pending` | `paid` | `overdue` | `cancelled`).
        deletedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Excluído em (soft delete; null quando ativo).
        customMetadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados gravados pelo sistema.
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema (chave das integrações).
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        updatedAt:
          type: string
          format: date-time
          description: Atualizado em (ISO 8601).
      required:
        - id
        - publicId
        - agreementId
        - installmentNumber
        - dueDate
        - amount
        - paidAmount
        - paidAt
        - status
        - deletedAt
        - customMetadata
        - metadata
        - externalId
        - createdAt
        - updatedAt
      description: Parcela de um acordo. Criada automaticamente no aceite, com vencimentos mensais a partir de `firstDueDate`.
    Agreement:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        organizationId:
          type: string
          format: uuid
          description: Organização dona do registro.
        workspaceId:
          type:
            - string
            - "null"
          format: uuid
          description: Workspace do registro (hierarquia multi-tenant).
        companyId:
          type:
            - string
            - "null"
          format: uuid
          description: Empresa (credora) do acordo.
        businessUnitId:
          type:
            - string
            - "null"
          format: uuid
          description: Unidade de negócio (BU) do acordo.
        personId:
          type: string
          format: uuid
          description: Cliente (devedor) do acordo.
        negotiationOfferId:
          type:
            - string
            - "null"
          format: uuid
          description: Oferta de negociação que originou o acordo.
        originalTotal:
          type: string
          description: Total original da dívida renegociada.
          example: "1500.00"
        discountAmount:
          type: string
          description: Desconto concedido (padrão 0).
          example: "300.00"
        finalTotal:
          type: string
          description: Total final (`originalTotal` − `discountAmount`). Calculado no servidor.
          example: "1200.00"
        numberOfInstallments:
          type: integer
          description: Número de parcelas (1 a 120).
          example: 6
        installmentValue:
          type: string
          description: Valor de cada parcela (`finalTotal` / `numberOfInstallments`). Calculado no servidor.
          example: "200.00"
        firstDueDate:
          type: string
          format: date-time
          description: Vencimento da primeira parcela (as demais vencem mensalmente).
        status:
          type: string
          enum:
            - proposed
            - accepted
            - active
            - completed
            - cancelled
            - defaulted
          description: Status (`proposed` | `accepted` | `active` | `completed` | `cancelled` | `defaulted`).
        acceptedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento do aceite.
        acceptedIp:
          type:
            - string
            - "null"
          description: IP registrado no aceite (trilha de auditoria).
        termsAccepted:
          type:
            - string
            - "null"
          description: Termos aceitos pelo devedor (texto/versão).
        cancelledAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento do cancelamento.
        cancellationReason:
          type:
            - string
            - "null"
          description: Motivo do cancelamento.
        completedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da conclusão (todas as parcelas pagas).
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados gravados pelo sistema.
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        updatedAt:
          type: string
          format: date-time
          description: Atualizado em (ISO 8601).
        deletedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Excluído em (soft delete; null quando ativo).
      required:
        - id
        - publicId
        - organizationId
        - workspaceId
        - companyId
        - businessUnitId
        - personId
        - negotiationOfferId
        - originalTotal
        - discountAmount
        - finalTotal
        - numberOfInstallments
        - installmentValue
        - firstDueDate
        - status
        - acceptedAt
        - acceptedIp
        - termsAccepted
        - cancelledAt
        - cancellationReason
        - completedAt
        - externalId
        - customData
        - tags
        - metadata
        - createdAt
        - updatedAt
        - deletedAt
      description: 'Acordo de renegociação parcelado firmado com um cliente. Valores monetários são serializados como string decimal (ex.: "1200.00"). Ciclo: `proposed` → `accepted` → `active` → `completed`; pode terminar em `cancelled` ou `defaulted`.'
    AgreementCreateRequest:
      type: object
      properties:
        personId:
          type: string
          format: uuid
          description: Cliente (devedor) do acordo.
        negotiationOfferId:
          type:
            - string
            - "null"
          format: uuid
          description: Oferta de negociação que originou o acordo.
        originalTotal:
          type: number
          exclusiveMinimum: 0
          description: Total original da dívida renegociada.
          example: 1500
        discountAmount:
          type: number
          minimum: 0
          description: Desconto concedido (padrão 0).
          example: 300
        numberOfInstallments:
          type: integer
          exclusiveMinimum: 0
          maximum: 120
          description: Número de parcelas (1 a 120).
          example: 6
        firstDueDate:
          type: string
          description: Vencimento da primeira parcela (as demais vencem mensalmente).
          example: 2026-08-01
        termsAccepted:
          type:
            - string
            - "null"
          description: Termos aceitos pelo devedor (texto/versão).
        externalId:
          type:
            - string
            - "null"
          maxLength: 60
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
      required:
        - personId
        - originalTotal
        - numberOfInstallments
        - firstDueDate
      description: Dados para criar um acordo (nasce como `proposed`). `finalTotal` e `installmentValue` são calculados no servidor. Valores monetários entram como number.
    AgreementUpdateRequest:
      type: object
      properties:
        originalTotal:
          type: number
          exclusiveMinimum: 0
          description: Total original da dívida renegociada.
        discountAmount:
          type: number
          minimum: 0
          description: Desconto concedido (padrão 0).
        numberOfInstallments:
          type: integer
          exclusiveMinimum: 0
          maximum: 120
          description: Número de parcelas (1 a 120).
        firstDueDate:
          type: string
          description: Vencimento da primeira parcela (as demais vencem mensalmente).
          example: 2026-08-01
        termsAccepted:
          type:
            - string
            - "null"
          description: Termos aceitos pelo devedor (texto/versão).
        externalId:
          type:
            - string
            - "null"
          maxLength: 60
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
      description: Campos a atualizar (parcial). Alterar valores ou número de parcelas recalcula `finalTotal` e `installmentValue`.
    AgreementListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Agreement"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    AgreementAcceptRequest:
      type: object
      properties:
        acceptedIp:
          type: string
          description: IP registrado no aceite (trilha de auditoria).
        termsAccepted:
          type: string
          description: Termos aceitos pelo devedor (texto/versão).
      description: Dados do aceite (corpo opcional). Sem `acceptedIp`, o IP é extraído dos headers da requisição.
    AgreementCancelRequest:
      type: object
      properties:
        reason:
          type: string
          minLength: 1
          description: Motivo do cancelamento (obrigatório; gravado em `cancellationReason`).
      required:
        - reason
      description: Dados do cancelamento.
    AgreementInstallmentSummary:
      type: object
      properties:
        total:
          type: integer
          description: Total de parcelas.
        pending:
          type: integer
          description: Parcelas pendentes.
        paid:
          type: integer
          description: Parcelas pagas.
        overdue:
          type: integer
          description: Parcelas vencidas.
        cancelled:
          type: integer
          description: Parcelas canceladas.
        totalAmount:
          type: number
          description: Soma dos valores das parcelas.
          example: 1200
        paidAmount:
          type: number
          description: Soma dos valores pagos.
          example: 400
      required:
        - total
        - pending
        - paid
        - overdue
        - cancelled
        - totalAmount
        - paidAmount
      description: Resumo agregado das parcelas do acordo. Diferente dos campos do recurso, os totais monetários aqui são number.
    AgreementInstallmentListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/AgreementInstallment"
          description: Parcelas do acordo, ordenadas por número.
        summary:
          $ref: "#/components/schemas/AgreementInstallmentSummary"
      required:
        - data
        - summary
    AgreementInstallmentUpdateRequest:
      type: object
      properties:
        installmentNumber:
          type: integer
          exclusiveMinimum: 0
          description: Número da parcela (a partir de 1).
          example: 1
        paidAmount:
          type: number
          exclusiveMinimum: 0
          description: Valor pago da parcela.
        paidAt:
          type: string
          description: Data do pagamento da parcela.
          example: 2026-08-03
        status:
          type: string
          enum:
            - pending
            - paid
            - overdue
            - cancelled
          description: Status (`pending` | `paid` | `overdue` | `cancelled`).
      required:
        - installmentNumber
      description: Baixa/atualização de uma parcela, identificada por `installmentNumber`. Marcar como `paid` sem `paidAt`/`paidAmount` preenche com a data atual e o valor da parcela.
    AgreementInstallmentUpdateResponse:
      type: object
      properties:
        installment:
          $ref: "#/components/schemas/AgreementInstallment"
        agreement:
          $ref: "#/components/schemas/Agreement"
      required:
        - installment
        - agreement
    DisputeChargeSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        documentNumber:
          type:
            - string
            - "null"
          description: Número do documento da cobrança.
        currentAmount:
          type:
            - string
            - "null"
          description: Valor atual da cobrança (string decimal).
          example: "150.00"
        status:
          type: string
          description: Status da cobrança.
      required:
        - id
        - documentNumber
        - currentAmount
        - status
      description: Resumo da cobrança disputada (na listagem).
    DisputePersonSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        name:
          type: string
          description: Nome do cliente.
        documentNumber:
          type:
            - string
            - "null"
          description: CPF/CNPJ do cliente (presente no detalhe).
      required:
        - id
        - name
      description: Resumo do cliente da disputa.
    DisputeAssigneeSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        name:
          type: string
          description: Nome do responsável.
        email:
          type: string
          format: email
          description: E-mail do responsável.
      required:
        - id
        - name
        - email
      description: Resumo do usuário responsável.
    Dispute:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        organizationId:
          type: string
          format: uuid
          description: Organização dona do registro.
        workspaceId:
          type:
            - string
            - "null"
          format: uuid
          description: Workspace do registro (hierarquia multi-tenant).
        companyId:
          type:
            - string
            - "null"
          format: uuid
          description: Empresa (credora) do registro.
        businessUnitId:
          type:
            - string
            - "null"
          format: uuid
          description: Unidade de negócio do registro.
        chargeId:
          type: string
          format: uuid
          description: Cobrança disputada.
        personId:
          type: string
          format: uuid
          description: Cliente (devedor) da cobrança disputada.
        type:
          type: string
          enum:
            - already_paid
            - not_recognized
            - wrong_amount
            - service_not_provided
            - incorrect_invoice
            - wrong_recipient
            - other
          description: Tipo da contestação (`already_paid` | `not_recognized` | `wrong_amount` | `service_not_provided` | `incorrect_invoice` | `wrong_recipient` | `other`).
        reason:
          type:
            - string
            - "null"
          description: Relato do devedor/operador.
        disputedAmount:
          type:
            - string
            - "null"
          description: Valor contestado, como string decimal; null quando a contestação é integral.
          example: "150.00"
        isFullDispute:
          type: boolean
          description: true quando a contestação cobre o valor integral da cobrança.
        documents:
          type:
            - array
            - "null"
          items:
            type: object
            additionalProperties: {}
          description: Anexos/referências de evidência.
        status:
          type: string
          enum:
            - open
            - under_review
            - resolved_valid
            - resolved_invalid
            - canceled
          description: Status (`open` | `under_review` | `resolved_valid` | `resolved_invalid` | `canceled`).
        assignedToId:
          type:
            - string
            - "null"
          format: uuid
          description: Usuário responsável pela análise (precisa pertencer à organização).
        slaDueAt:
          type:
            - string
            - "null"
          format: date-time
          description: Prazo (SLA) para resolução.
        resolution:
          type:
            - string
            - "null"
          description: Decisão fundamentada da resolução.
        resolutionEffect:
          type:
            - string
            - "null"
          enum:
            - resume_rule
            - adjust_amount
            - cancel_charge
            - write_off
            - null
          description: Efeito aplicado na resolução (`resume_rule` | `adjust_amount` | `cancel_charge` | `write_off`).
        resolvedById:
          type:
            - string
            - "null"
          format: uuid
          description: Usuário que resolveu a disputa.
        openedAt:
          type: string
          format: date-time
          description: Abertura da disputa (ISO 8601).
        resolvedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Resolução da disputa (ISO 8601; null enquanto aberta).
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema (chave das integrações).
        customMetadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados gravados pelo sistema.
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        updatedAt:
          type: string
          format: date-time
          description: Atualizado em (ISO 8601).
        deletedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Excluído em (soft delete; null quando ativo).
      required:
        - id
        - publicId
        - organizationId
        - workspaceId
        - companyId
        - businessUnitId
        - chargeId
        - personId
        - type
        - reason
        - disputedAmount
        - isFullDispute
        - documents
        - status
        - assignedToId
        - slaDueAt
        - resolution
        - resolutionEffect
        - resolvedById
        - openedAt
        - resolvedAt
        - externalId
        - customMetadata
        - metadata
        - createdAt
        - updatedAt
        - deletedAt
      description: Disputa (contestação) aberta pelo devedor ou operador sobre uma cobrança. Enquanto aberta, a régua de cobrança fica pausada.
    DisputeListItem:
      allOf:
        - $ref: "#/components/schemas/Dispute"
        - type: object
          properties:
            charge:
              $ref: "#/components/schemas/DisputeChargeSummary"
            person:
              $ref: "#/components/schemas/DisputePersonSummary"
          required:
            - charge
            - person
      description: "Item da listagem: disputa com resumos da cobrança e do cliente."
    DisputeDetail:
      allOf:
        - $ref: "#/components/schemas/Dispute"
        - type: object
          properties:
            charge:
              type: object
              additionalProperties: {}
              description: Cobrança completa associada à disputa.
            person:
              $ref: "#/components/schemas/DisputePersonSummary"
            assignedTo:
              allOf:
                - $ref: "#/components/schemas/DisputeAssigneeSummary"
                - type:
                    - object
                    - "null"
                  description: Responsável pela análise (null quando não atribuída).
          required:
            - charge
            - person
            - assignedTo
      description: "Detalhe da disputa: inclui a cobrança completa, o cliente e o responsável."
    DisputeCreateRequest:
      type: object
      properties:
        chargeId:
          type: string
          format: uuid
          description: Cobrança disputada.
        type:
          type: string
          enum:
            - already_paid
            - not_recognized
            - wrong_amount
            - service_not_provided
            - incorrect_invoice
            - wrong_recipient
            - other
          description: Tipo da contestação (`already_paid` | `not_recognized` | `wrong_amount` | `service_not_provided` | `incorrect_invoice` | `wrong_recipient` | `other`).
        reason:
          type: string
          maxLength: 2000
          description: Relato do devedor/operador.
        disputedAmount:
          type: number
          exclusiveMinimum: 0
          description: Valor contestado (número). Omita para contestar o valor integral.
          example: 150
        documents:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Anexos/referências de evidência.
        assignedToId:
          type: string
          format: uuid
          description: Usuário responsável pela análise (precisa pertencer à organização).
        slaDays:
          type: integer
          exclusiveMinimum: 0
          maximum: 60
          description: Dias de SLA para resolução (máx. 60; padrão do sistema quando omitido).
          example: 5
      required:
        - chargeId
        - type
      description: Dados para abrir uma disputa sobre uma cobrança.
    DisputeStartReviewRequest:
      type: object
      properties:
        action:
          type: string
          enum:
            - start_review
          description: "Ação: iniciar análise (`start_review`)."
        assignedToId:
          type: string
          format: uuid
          description: Usuário responsável pela análise (precisa pertencer à organização).
      required:
        - action
      description: Move a disputa de `open` para `under_review`, opcionalmente atribuindo um responsável.
    DisputeResolveRequest:
      type: object
      properties:
        action:
          type: string
          enum:
            - resolve
          description: "Ação: resolver a disputa (`resolve`)."
        decision:
          type: string
          enum:
            - valid
            - invalid
          description: "Decisão: `valid` (procedente) ou `invalid` (improcedente)."
        resolution:
          type: string
          minLength: 1
          maxLength: 2000
          description: Decisão fundamentada da resolução.
        effect:
          type: string
          enum:
            - resume_rule
            - adjust_amount
            - cancel_charge
            - write_off
          description: Efeito da resolução (`resume_rule` | `adjust_amount` | `cancel_charge` | `write_off`).
        adjustedAmount:
          type: number
          exclusiveMinimum: 0
          description: Novo valor da cobrança quando o efeito é `adjust_amount`.
          example: 120
      required:
        - action
        - decision
        - resolution
      description: Resolve a disputa com decisão fundamentada e efeito sobre a cobrança/régua.
    DisputeCancelRequest:
      type: object
      properties:
        action:
          type: string
          enum:
            - cancel
          description: "Ação: cancelar a disputa (`cancel`)."
        reason:
          type: string
          maxLength: 2000
          description: Motivo do cancelamento.
      required:
        - action
      description: "Cancela a disputa (ex.: aberta por engano); a régua da cobrança retoma."
    DisputeActionRequest:
      oneOf:
        - $ref: "#/components/schemas/DisputeStartReviewRequest"
        - $ref: "#/components/schemas/DisputeResolveRequest"
        - $ref: "#/components/schemas/DisputeCancelRequest"
      discriminator:
        propertyName: action
        mapping:
          start_review: "#/components/schemas/DisputeStartReviewRequest"
          resolve: "#/components/schemas/DisputeResolveRequest"
          cancel: "#/components/schemas/DisputeCancelRequest"
      description: Ação sobre a disputa, discriminada pelo campo `action` (`start_review` | `resolve` | `cancel`).
    DisputeResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/Dispute"
      required:
        - data
    DisputeDetailResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/DisputeDetail"
      required:
        - data
    DisputeListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/DisputeListItem"
        pagination:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - pagination
      description: "Envelope da listagem de disputas. Atenção: usa a chave `pagination` (mesmos campos de `meta`)."
    TaskPersonSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        name:
          type: string
          description: Nome do cliente.
        documentNumber:
          type:
            - string
            - "null"
          description: CPF/CNPJ do cliente.
      required:
        - id
        - name
        - documentNumber
      description: Resumo do cliente vinculado.
    TaskAssigneeSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        name:
          type: string
          description: Nome do responsável.
        email:
          type: string
          format: email
          description: E-mail do responsável.
        avatarUrl:
          type:
            - string
            - "null"
          description: URL do avatar do responsável.
      required:
        - id
        - name
        - email
        - avatarUrl
      description: Resumo do usuário responsável.
    TaskChargeSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        documentNumber:
          type:
            - string
            - "null"
          description: Número do documento da cobrança.
        originalAmount:
          type: string
          description: Valor original da cobrança (string decimal).
          example: "350.00"
        dueDate:
          type: string
          description: Vencimento da cobrança.
          example: 2026-08-01T00:00:00.000Z
        status:
          type: string
          description: Status da cobrança.
      required:
        - id
        - documentNumber
        - originalAmount
        - dueDate
        - status
      description: Resumo da cobrança vinculada.
    Task:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        organizationId:
          type: string
          format: uuid
          description: Organização dona do registro.
        workspaceId:
          type:
            - string
            - "null"
          format: uuid
          description: Workspace do registro (hierarquia multi-tenant).
        companyId:
          type:
            - string
            - "null"
          format: uuid
          description: Empresa (credora) do registro.
        businessUnitId:
          type:
            - string
            - "null"
          format: uuid
          description: Unidade de negócio do registro.
        personId:
          type:
            - string
            - "null"
          format: uuid
          description: Cliente vinculado à tarefa.
        chargeId:
          type:
            - string
            - "null"
          format: uuid
          description: Cobrança vinculada à tarefa.
        assignedToId:
          type:
            - string
            - "null"
          format: uuid
          description: Usuário responsável pela tarefa.
        title:
          type: string
          description: Título da tarefa.
          example: Ligar para negociar parcela
        description:
          type:
            - string
            - "null"
          description: Descrição detalhada.
        taskType:
          type: string
          enum:
            - call
            - email
            - visit
            - review
            - follow_up
          description: Tipo (`call` | `email` | `visit` | `review` | `follow_up`).
        priority:
          type: string
          enum:
            - low
            - medium
            - high
            - urgent
          description: Prioridade (`low` | `medium` | `high` | `urgent`).
        status:
          type: string
          enum:
            - pending
            - in_progress
            - completed
            - cancelled
          description: Status (`pending` | `in_progress` | `completed` | `cancelled`).
        dueAt:
          type:
            - string
            - "null"
          format: date-time
          description: Prazo da tarefa (ISO 8601).
        completedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Conclusão da tarefa (ISO 8601; null enquanto pendente).
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados gravados pelo sistema.
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        updatedAt:
          type: string
          format: date-time
          description: Atualizado em (ISO 8601).
        deletedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Excluído em (soft delete; null quando ativo).
        person:
          anyOf:
            - $ref: "#/components/schemas/TaskPersonSummary"
            - type: "null"
          description: Cliente vinculado (presente na criação/consulta ou com `include=person`).
        assignedTo:
          anyOf:
            - $ref: "#/components/schemas/TaskAssigneeSummary"
            - type: "null"
          description: Responsável (presente na criação/consulta ou com `include=assignedTo`).
        charge:
          anyOf:
            - $ref: "#/components/schemas/TaskChargeSummary"
            - type: "null"
          description: Cobrança vinculada (presente na criação/consulta ou com `include=charge`).
      required:
        - id
        - publicId
        - organizationId
        - workspaceId
        - companyId
        - businessUnitId
        - personId
        - chargeId
        - assignedToId
        - title
        - description
        - taskType
        - priority
        - status
        - dueAt
        - completedAt
        - externalId
        - customData
        - tags
        - metadata
        - createdAt
        - updatedAt
        - deletedAt
      description: Tarefa manual de cobrança (ligação, e-mail, visita, revisão, follow-up) atribuível a um operador. As respostas unitárias não usam envelope `{ data }`.
    TaskCreateRequest:
      type: object
      properties:
        personId:
          type:
            - string
            - "null"
          format: uuid
          description: Cliente vinculado à tarefa.
        chargeId:
          type:
            - string
            - "null"
          format: uuid
          description: Cobrança vinculada à tarefa.
        assignedToId:
          type:
            - string
            - "null"
          format: uuid
          description: Usuário responsável pela tarefa.
        title:
          type: string
          minLength: 1
          maxLength: 255
          description: Título da tarefa.
        description:
          type:
            - string
            - "null"
          description: Descrição detalhada.
        taskType:
          type: string
          enum:
            - call
            - email
            - visit
            - review
            - follow_up
          description: Tipo (`call` | `email` | `visit` | `review` | `follow_up`).
        priority:
          type: string
          enum:
            - low
            - medium
            - high
            - urgent
          default: medium
          description: Prioridade inicial (`low` | `medium` | `high` | `urgent`; padrão `medium`).
        status:
          type: string
          enum:
            - pending
            - in_progress
            - completed
            - cancelled
          default: pending
          description: Status inicial (padrão `pending`).
        dueAt:
          type:
            - string
            - "null"
          format: date-time
          description: Prazo da tarefa (ISO 8601).
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
      required:
        - title
        - taskType
      description: Dados para criar uma tarefa.
    TaskUpdateRequest:
      type: object
      properties:
        personId:
          type:
            - string
            - "null"
          format: uuid
          description: Cliente vinculado à tarefa.
        chargeId:
          type:
            - string
            - "null"
          format: uuid
          description: Cobrança vinculada à tarefa.
        assignedToId:
          type:
            - string
            - "null"
          format: uuid
          description: Usuário responsável pela tarefa.
        title:
          type: string
          minLength: 1
          maxLength: 255
          description: Título da tarefa.
        description:
          type:
            - string
            - "null"
          description: Descrição detalhada.
        taskType:
          type: string
          enum:
            - call
            - email
            - visit
            - review
            - follow_up
          description: Tipo (`call` | `email` | `visit` | `review` | `follow_up`).
        priority:
          type: string
          enum:
            - low
            - medium
            - high
            - urgent
          description: Prioridade (`low` | `medium` | `high` | `urgent`).
        status:
          type: string
          enum:
            - pending
            - in_progress
            - completed
            - cancelled
          description: Novo status; `completed` preenche `completedAt` automaticamente.
        dueAt:
          type:
            - string
            - "null"
          format: date-time
          description: Prazo da tarefa (ISO 8601).
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
      description: Campos a atualizar (parcial — envie só o que muda). Mudar o status para `completed` preenche `completedAt`; sair de `completed` limpa o campo.
    TaskListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Task"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    InteractionPersonSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        name:
          type: string
          description: Nome do cliente.
        documentNumber:
          type:
            - string
            - "null"
          description: CPF/CNPJ do cliente.
      required:
        - id
        - name
        - documentNumber
      description: Resumo do cliente da interação.
    InteractionUserSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        name:
          type: string
          description: Nome do usuário.
        email:
          type: string
          format: email
          description: E-mail do usuário.
        avatarUrl:
          type:
            - string
            - "null"
          description: URL do avatar do usuário.
      required:
        - id
        - name
        - email
        - avatarUrl
      description: Resumo do usuário autor.
    InteractionChargeSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        documentNumber:
          type:
            - string
            - "null"
          description: Número do documento da cobrança.
        originalAmount:
          type: string
          description: Valor original da cobrança (string decimal).
          example: "350.00"
        dueDate:
          type: string
          description: Vencimento da cobrança.
          example: 2026-08-01T00:00:00.000Z
        status:
          type: string
          description: Status da cobrança.
      required:
        - id
        - documentNumber
        - originalAmount
        - dueDate
        - status
      description: Resumo da cobrança relacionada.
    Interaction:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        organizationId:
          type: string
          format: uuid
          description: Organização dona do registro.
        workspaceId:
          type:
            - string
            - "null"
          format: uuid
          description: Workspace do registro (hierarquia multi-tenant).
        companyId:
          type:
            - string
            - "null"
          format: uuid
          description: Empresa (credora) do registro.
        businessUnitId:
          type:
            - string
            - "null"
          format: uuid
          description: Unidade de negócio do registro.
        personId:
          type: string
          format: uuid
          description: Cliente da interação.
        chargeId:
          type:
            - string
            - "null"
          format: uuid
          description: Cobrança relacionada à interação.
        userId:
          type:
            - string
            - "null"
          format: uuid
          description: Usuário que registrou a interação (inferido da sessão/token).
        interactionType:
          type: string
          enum:
            - call
            - email
            - whatsapp
            - meeting
            - note
          description: Tipo (`call` | `email` | `whatsapp` | `meeting` | `note`).
        direction:
          type: string
          enum:
            - inbound
            - outbound
          description: Direção (`inbound` = cliente contatou, `outbound` = fomos ao cliente).
        summary:
          type:
            - string
            - "null"
          description: Resumo/notas da interação.
        outcome:
          type:
            - string
            - "null"
          enum:
            - promise_to_pay
            - negotiation
            - dispute
            - no_contact
            - callback_requested
            - payment_confirmed
            - null
          description: Desfecho (`promise_to_pay` | `negotiation` | `dispute` | `no_contact` | `callback_requested` | `payment_confirmed`).
        promiseDate:
          type:
            - string
            - "null"
          description: Data prometida para pagamento.
          example: 2026-08-15T00:00:00.000Z
        promisedAmount:
          type:
            - string
            - "null"
          description: Valor prometido (string decimal).
          example: "200.00"
        contactedAt:
          type: string
          format: date-time
          description: Momento do contato (ISO 8601).
        durationSeconds:
          type:
            - integer
            - "null"
          description: Duração do contato em segundos.
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados livres da interação.
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        updatedAt:
          type: string
          format: date-time
          description: Atualizado em (ISO 8601).
        deletedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Excluído em (soft delete; null quando ativo).
        person:
          allOf:
            - $ref: "#/components/schemas/InteractionPersonSummary"
            - description: Cliente (presente na criação/consulta ou com `include=person`).
        user:
          anyOf:
            - $ref: "#/components/schemas/InteractionUserSummary"
            - type: "null"
          description: Usuário autor (presente na criação/consulta ou com `include=user`).
        charge:
          anyOf:
            - $ref: "#/components/schemas/InteractionChargeSummary"
            - type: "null"
          description: Cobrança relacionada (presente na criação/consulta ou com `include=charge`).
      required:
        - id
        - publicId
        - organizationId
        - workspaceId
        - companyId
        - businessUnitId
        - personId
        - chargeId
        - userId
        - interactionType
        - direction
        - summary
        - outcome
        - promiseDate
        - promisedAmount
        - contactedAt
        - durationSeconds
        - metadata
        - externalId
        - customData
        - tags
        - createdAt
        - updatedAt
        - deletedAt
      description: Interação com o cliente (ligação, e-mail, WhatsApp, reunião, nota) registrada na esteira de cobrança. As respostas unitárias não usam envelope `{ data }`.
    InteractionCreateRequest:
      type: object
      properties:
        personId:
          type: string
          format: uuid
          description: Cliente da interação.
        chargeId:
          type:
            - string
            - "null"
          format: uuid
          description: Cobrança relacionada à interação.
        interactionType:
          type: string
          enum:
            - call
            - email
            - whatsapp
            - meeting
            - note
          description: Tipo (`call` | `email` | `whatsapp` | `meeting` | `note`).
        direction:
          type: string
          enum:
            - inbound
            - outbound
          description: Direção (`inbound` = cliente contatou, `outbound` = fomos ao cliente).
        summary:
          type:
            - string
            - "null"
          description: Resumo/notas da interação.
        outcome:
          type:
            - string
            - "null"
          enum:
            - promise_to_pay
            - negotiation
            - dispute
            - no_contact
            - callback_requested
            - payment_confirmed
            - null
          description: Desfecho (`promise_to_pay` | `negotiation` | `dispute` | `no_contact` | `callback_requested` | `payment_confirmed`).
        promiseDate:
          type:
            - string
            - "null"
          format: date-time
          description: Data prometida para pagamento.
        promisedAmount:
          type:
            - number
            - "null"
          exclusiveMinimum: 0
          description: Valor prometido (número positivo).
          example: 200
        contactedAt:
          type: string
          format: date-time
          description: "Momento do contato (ISO 8601; padrão: agora)."
        durationSeconds:
          type:
            - integer
            - "null"
          minimum: 0
          description: Duração do contato em segundos.
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados livres da interação.
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
      required:
        - personId
        - interactionType
        - direction
      description: Dados para registrar uma interação. O usuário autor é inferido da sessão/token.
    InteractionUpdateRequest:
      type: object
      properties:
        summary:
          type:
            - string
            - "null"
          description: Resumo/notas da interação.
        notes:
          type:
            - string
            - "null"
          description: Alias de `summary` (gravado no mesmo campo; se ambos vierem, `notes` prevalece).
        outcome:
          type:
            - string
            - "null"
          enum:
            - promise_to_pay
            - negotiation
            - dispute
            - no_contact
            - callback_requested
            - payment_confirmed
            - null
          description: Desfecho (`promise_to_pay` | `negotiation` | `dispute` | `no_contact` | `callback_requested` | `payment_confirmed`).
        promiseDate:
          type:
            - string
            - "null"
          format: date-time
          description: Data prometida para pagamento.
        promisedAmount:
          type:
            - number
            - "null"
          exclusiveMinimum: 0
          description: Valor prometido (número positivo).
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados livres da interação.
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
      description: "Campos editáveis após o registro: resumo/notas, desfecho, promessa e metadados. Tipo, direção e vínculos não mudam."
    InteractionListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Interaction"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    Notification:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        organizationId:
          type: string
          format: uuid
          description: Organização dona do registro.
        personId:
          type: string
          format: uuid
          description: Cliente destinatário.
        chargeId:
          type:
            - string
            - "null"
          format: uuid
          description: Cobrança relacionada à notificação.
        collectionRuleStepId:
          type:
            - string
            - "null"
          format: uuid
          description: Passo da régua de cobrança que originou a notificação.
        channel:
          type: string
          enum:
            - email
            - sms
            - whatsapp
            - voice
            - manual
          description: Canal (`email` | `sms` | `whatsapp` | `voice` | `manual`).
        status:
          type: string
          enum:
            - pending
            - queued
            - sent
            - delivered
            - read
            - failed
            - bounced
          description: Status do ciclo de vida (`pending` | `queued` | `sent` | `delivered` | `read` | `failed` | `bounced`).
        recipient:
          type: string
          description: "Destinatário: e-mail para canal `email`, telefone para `sms`/`whatsapp`/`voice`."
          example: maria@example.com
        subject:
          type:
            - string
            - "null"
          description: "Assunto (canais que suportam, ex.: e-mail)."
        body:
          type: string
          description: Corpo da mensagem.
        idempotencyKey:
          type:
            - string
            - "null"
          description: Chave de idempotência do envio (gerada pelo motor da régua).
        stepExecutionId:
          type:
            - string
            - "null"
          format: uuid
          description: Execução do passo da régua que gerou a notificação.
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema ou no provedor de envio.
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        sentAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento do envio (ISO 8601).
        deliveredAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da entrega (ISO 8601).
        readAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da leitura (ISO 8601).
        clickedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento do clique (ISO 8601).
        failedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da falha (ISO 8601).
        failureReason:
          type:
            - string
            - "null"
          description: Motivo da falha reportado pelo provedor.
        cost:
          type:
            - string
            - "null"
          description: Custo do envio (string decimal).
          example: "0.0450"
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: "Metadados gravados pelo sistema (ex.: `resendOf` em reenvios)."
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        updatedAt:
          type: string
          format: date-time
          description: Atualizado em (ISO 8601).
        person:
          type: object
          additionalProperties: {}
          description: Cliente completo (com `include=person`).
        charge:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Cobrança completa (com `include=charge`).
        collectionRuleStep:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Passo da régua com o template de mensagem (com `include=step` ou `include=template`).
      required:
        - id
        - publicId
        - organizationId
        - personId
        - chargeId
        - collectionRuleStepId
        - channel
        - status
        - recipient
        - subject
        - body
        - idempotencyKey
        - stepExecutionId
        - externalId
        - customData
        - tags
        - sentAt
        - deliveredAt
        - readAt
        - clickedAt
        - failedAt
        - failureReason
        - cost
        - metadata
        - createdAt
        - updatedAt
      description: Notificação enviada (ou a enviar) a um cliente por e-mail, SMS, WhatsApp, voz ou canal manual — em geral disparada por um passo da régua de cobrança. As respostas unitárias não usam envelope `{ data }`.
    NotificationCreateRequest:
      type: object
      properties:
        personId:
          type: string
          format: uuid
          description: Cliente destinatário.
        chargeId:
          type:
            - string
            - "null"
          format: uuid
          description: Cobrança relacionada à notificação.
        collectionRuleStepId:
          type:
            - string
            - "null"
          format: uuid
          description: Passo da régua de cobrança que originou a notificação.
        channel:
          type: string
          enum:
            - email
            - sms
            - whatsapp
            - voice
            - manual
          description: Canal (`email` | `sms` | `whatsapp` | `voice` | `manual`).
        recipient:
          type: string
          minLength: 1
          description: Destinatário; validado conforme o canal (e-mail para `email`, telefone para `sms`/`whatsapp`/`voice`).
        subject:
          type:
            - string
            - "null"
          maxLength: 500
          description: "Assunto (canais que suportam, ex.: e-mail)."
        body:
          type: string
          minLength: 1
          description: Corpo da mensagem.
        externalId:
          type:
            - string
            - "null"
          maxLength: 100
          description: Identificador no SEU sistema ou no provedor de envio.
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: "Metadados gravados pelo sistema (ex.: `resendOf` em reenvios)."
      required:
        - personId
        - channel
        - recipient
        - body
      description: Dados para criar uma notificação manual (nasce com status `pending`).
    NotificationUpdateRequest:
      type: object
      properties:
        status:
          type: string
          enum:
            - pending
            - queued
            - sent
            - delivered
            - read
            - failed
            - bounced
          description: Novo status; preenche o timestamp correspondente (sentAt/deliveredAt/readAt/failedAt) quando não informado.
        sentAt:
          type:
            - string
            - "null"
          description: Timestamp ISO 8601 ou data `YYYY-MM-DD`; null limpa o campo.
        deliveredAt:
          type:
            - string
            - "null"
          description: Timestamp ISO 8601 ou data `YYYY-MM-DD`; null limpa o campo.
        readAt:
          type:
            - string
            - "null"
          description: Timestamp ISO 8601 ou data `YYYY-MM-DD`; null limpa o campo.
        failedAt:
          type:
            - string
            - "null"
          description: Timestamp ISO 8601 ou data `YYYY-MM-DD`; null limpa o campo.
        failureReason:
          type:
            - string
            - "null"
          maxLength: 500
          description: Motivo da falha reportado pelo provedor.
        externalId:
          type:
            - string
            - "null"
          maxLength: 100
          description: Identificador no SEU sistema ou no provedor de envio.
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: "Metadados gravados pelo sistema (ex.: `resendOf` em reenvios)."
        cost:
          type:
            - number
            - "null"
          minimum: 0
          description: Custo do envio (número, mínimo 0).
      description: Campos a atualizar (parcial). Mudar o status preenche automaticamente o timestamp correspondente quando ele não é informado.
    NotificationListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Notification"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    ClassificationCriteria:
      type: object
      properties:
        minOnTimePercentage:
          type: number
          minimum: 0
          maximum: 100
          description: Percentual mínimo de pagamentos em dia (0-100).
        maxOnTimePercentage:
          type: number
          minimum: 0
          maximum: 100
          description: Percentual máximo de pagamentos em dia (0-100).
        maxConsecutiveDelays:
          type: integer
          minimum: 0
          description: Máximo de atrasos consecutivos tolerado.
        maxCurrentOverdueDays:
          type: integer
          minimum: 0
          description: Máximo de dias de atraso atual.
        evaluationPeriodMonths:
          type: integer
          minimum: 1
          description: Janela de avaliação, em meses.
        minChargesCount:
          type: integer
          minimum: 0
          description: Mínimo de cobranças no período.
        maxChargesCount:
          type: integer
          minimum: 0
          description: Máximo de cobranças no período.
        hasNegativationHistory:
          type: boolean
          description: Exige (true) ou veta (false) histórico de negativação.
        hasProtestHistory:
          type: boolean
          description: Exige (true) ou veta (false) histórico de protesto.
      description: Critérios de atribuição automática (comportamento de pagamento).
    Classification:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        organizationId:
          type: string
          format: uuid
          description: Organização dona do registro.
        workspaceId:
          type:
            - string
            - "null"
          format: uuid
          description: Workspace do registro (hierarquia multi-tenant).
        companyId:
          type:
            - string
            - "null"
          format: uuid
          description: Empresa (credora) associada.
        businessUnitId:
          type:
            - string
            - "null"
          format: uuid
          description: Unidade de negócio do registro.
        name:
          type: string
          description: Nome da classificação.
          example: Bom pagador
        code:
          type: string
          description: Código estável (minúsculas, números e underscore; único na organização).
          example: good_payer
        description:
          type:
            - string
            - "null"
          description: Descrição da classificação.
        color:
          type:
            - string
            - "null"
          description: "Cor hexadecimal exibida na interface (ex.: `#22c55e`)."
          example: "#22c55e"
        priority:
          type: integer
          description: Prioridade de avaliação (menor avalia primeiro).
        isDefault:
          type: boolean
          description: true quando é a classificação padrão da organização (única).
        autoAssign:
          type: boolean
          description: true quando clientes são atribuídos automaticamente pelos critérios.
        criteria:
          allOf:
            - $ref: "#/components/schemas/ClassificationCriteria"
            - type:
                - object
                - "null"
        activatedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da ativação (null = inativa).
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados gravados pelo sistema.
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        updatedAt:
          type: string
          format: date-time
          description: Atualizado em (ISO 8601).
        deletedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Excluído em (soft delete; null quando ativo).
        _count:
          type: object
          properties:
            people:
              type: integer
              description: Clientes com esta classificação.
            collectionRules:
              type: integer
              description: Réguas de cobrança que usam esta classificação.
          required:
            - people
            - collectionRules
          description: Contadores relacionados (presente com `include=_count` e nas respostas de criação/atualização).
      required:
        - id
        - publicId
        - organizationId
        - workspaceId
        - companyId
        - businessUnitId
        - name
        - code
        - description
        - color
        - priority
        - isDefault
        - autoAssign
        - criteria
        - activatedAt
        - externalId
        - customData
        - tags
        - metadata
        - createdAt
        - updatedAt
        - deletedAt
      description: "Classificação de clientes: segmenta a carteira (ex.: bom pagador) e direciona a régua de cobrança aplicada."
    ClassificationCreateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Nome da classificação.
        code:
          type: string
          minLength: 1
          maxLength: 100
          pattern: ^[a-z0-9_]+$
          description: Código estável (minúsculas, números e underscore; único na organização).
          example: good_payer
        description:
          type:
            - string
            - "null"
          maxLength: 1000
          description: Descrição da classificação.
        color:
          type:
            - string
            - "null"
          pattern: ^#[0-9A-Fa-f]{6}$
          description: "Cor hexadecimal exibida na interface (ex.: `#22c55e`)."
          example: "#22c55e"
        priority:
          type: integer
          minimum: 0
          description: Prioridade de avaliação (menor avalia primeiro).
        isDefault:
          type: boolean
          description: true quando é a classificação padrão da organização (única).
        autoAssign:
          type: boolean
          description: true quando clientes são atribuídos automaticamente pelos critérios.
        criteria:
          type:
            - object
            - "null"
          properties:
            minOnTimePercentage:
              type: number
              minimum: 0
              maximum: 100
              description: Percentual mínimo de pagamentos em dia (0-100).
            maxOnTimePercentage:
              type: number
              minimum: 0
              maximum: 100
              description: Percentual máximo de pagamentos em dia (0-100).
            maxConsecutiveDelays:
              type: integer
              minimum: 0
              description: Máximo de atrasos consecutivos tolerado.
            maxCurrentOverdueDays:
              type: integer
              minimum: 0
              description: Máximo de dias de atraso atual.
            evaluationPeriodMonths:
              type: integer
              minimum: 1
              description: Janela de avaliação, em meses.
            minChargesCount:
              type: integer
              minimum: 0
              description: Mínimo de cobranças no período.
            maxChargesCount:
              type: integer
              minimum: 0
              description: Máximo de cobranças no período.
            hasNegativationHistory:
              type: boolean
              description: Exige (true) ou veta (false) histórico de negativação.
            hasProtestHistory:
              type: boolean
              description: Exige (true) ou veta (false) histórico de protesto.
          description: Critérios de atribuição automática (comportamento de pagamento).
        activatedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da ativação (null = inativa).
        externalId:
          type:
            - string
            - "null"
          maxLength: 60
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
      required:
        - name
        - code
      description: Dados para criar uma classificação. `code` é único na organização.
    ClassificationUpdateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Nome da classificação.
        code:
          type: string
          minLength: 1
          maxLength: 100
          pattern: ^[a-z0-9_]+$
          description: Código estável (minúsculas, números e underscore; único na organização).
          example: good_payer
        description:
          type:
            - string
            - "null"
          maxLength: 1000
          description: Descrição da classificação.
        color:
          type:
            - string
            - "null"
          pattern: ^#[0-9A-Fa-f]{6}$
          description: "Cor hexadecimal exibida na interface (ex.: `#22c55e`)."
          example: "#22c55e"
        priority:
          type: integer
          minimum: 0
          description: Prioridade de avaliação (menor avalia primeiro).
        isDefault:
          type: boolean
          description: true quando é a classificação padrão da organização (única).
        autoAssign:
          type: boolean
          description: true quando clientes são atribuídos automaticamente pelos critérios.
        criteria:
          type:
            - object
            - "null"
          properties:
            minOnTimePercentage:
              type: number
              minimum: 0
              maximum: 100
              description: Percentual mínimo de pagamentos em dia (0-100).
            maxOnTimePercentage:
              type: number
              minimum: 0
              maximum: 100
              description: Percentual máximo de pagamentos em dia (0-100).
            maxConsecutiveDelays:
              type: integer
              minimum: 0
              description: Máximo de atrasos consecutivos tolerado.
            maxCurrentOverdueDays:
              type: integer
              minimum: 0
              description: Máximo de dias de atraso atual.
            evaluationPeriodMonths:
              type: integer
              minimum: 1
              description: Janela de avaliação, em meses.
            minChargesCount:
              type: integer
              minimum: 0
              description: Mínimo de cobranças no período.
            maxChargesCount:
              type: integer
              minimum: 0
              description: Máximo de cobranças no período.
            hasNegativationHistory:
              type: boolean
              description: Exige (true) ou veta (false) histórico de negativação.
            hasProtestHistory:
              type: boolean
              description: Exige (true) ou veta (false) histórico de protesto.
          description: Critérios de atribuição automática (comportamento de pagamento).
        activatedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da ativação (null = inativa).
        externalId:
          type:
            - string
            - "null"
          maxLength: 60
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
      description: Campos a atualizar (parcial — envie só o que muda).
    ClassificationListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Classification"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    MessageTemplate:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        organizationId:
          type: string
          format: uuid
          description: Organização dona do registro.
        workspaceId:
          type:
            - string
            - "null"
          format: uuid
          description: Workspace do registro (hierarquia multi-tenant).
        companyId:
          type:
            - string
            - "null"
          format: uuid
          description: Empresa (credora) associada.
        businessUnitId:
          type:
            - string
            - "null"
          format: uuid
          description: Unidade de negócio do registro.
        name:
          type: string
          description: Nome do template (único na organização).
          example: Lembrete 3 dias antes
        channel:
          type: string
          enum:
            - email
            - sms
            - whatsapp
            - voice
            - manual
          description: Canal de envio (`email` | `sms` | `whatsapp` | `voice` | `manual`).
        category:
          type: string
          enum:
            - reminder
            - overdue
            - negotiation
            - negativation_warning
            - protest_warning
            - payment_confirmation
          description: Categoria (`reminder` | `overdue` | `negotiation` | `negativation_warning` | `protest_warning` | `payment_confirmation`).
        tone:
          type:
            - string
            - "null"
          enum:
            - friendly
            - neutral
            - firm
            - urgent
            - null
          description: Tom da mensagem (`friendly` | `neutral` | `firm` | `urgent`).
        subject:
          type:
            - string
            - "null"
          description: Assunto (usado em e-mail).
        body:
          type: string
          description: Corpo da mensagem, com variáveis no formato `{{variavel}}`.
        variables:
          type: array
          items:
            type: string
          description: Variáveis disponíveis no corpo/assunto.
          example:
            - customer_name
            - amount
            - due_date
        activatedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da ativação (null = inativo).
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema (chave das integrações; único na organização).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados gravados pelo sistema.
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        updatedAt:
          type: string
          format: date-time
          description: Atualizado em (ISO 8601).
        deletedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Excluído em (soft delete; null quando ativo).
      required:
        - id
        - publicId
        - organizationId
        - workspaceId
        - companyId
        - businessUnitId
        - name
        - channel
        - category
        - tone
        - subject
        - body
        - variables
        - activatedAt
        - externalId
        - customData
        - tags
        - metadata
        - createdAt
        - updatedAt
        - deletedAt
      description: Template de mensagem reutilizado pelas etapas da régua de cobrança.
    MessageTemplateCreateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Nome do template (único na organização).
        channel:
          type: string
          enum:
            - email
            - sms
            - whatsapp
            - voice
            - manual
          description: Canal de envio (`email` | `sms` | `whatsapp` | `voice` | `manual`).
        category:
          type: string
          enum:
            - reminder
            - overdue
            - negotiation
            - negativation_warning
            - protest_warning
            - payment_confirmation
          description: Categoria (`reminder` | `overdue` | `negotiation` | `negativation_warning` | `protest_warning` | `payment_confirmation`).
        tone:
          type:
            - string
            - "null"
          enum:
            - friendly
            - neutral
            - firm
            - urgent
            - null
          description: Tom da mensagem (`friendly` | `neutral` | `firm` | `urgent`).
        subject:
          type:
            - string
            - "null"
          maxLength: 255
          description: Assunto (usado em e-mail).
        body:
          type: string
          minLength: 1
          description: Corpo da mensagem, com variáveis no formato `{{variavel}}`.
        variables:
          type: array
          items:
            type: string
          description: Variáveis disponíveis no corpo/assunto.
        activatedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da ativação (null = inativo).
        externalId:
          type:
            - string
            - "null"
          maxLength: 60
          description: Identificador no SEU sistema (chave das integrações; único na organização).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
      required:
        - name
        - channel
        - category
        - body
      description: Dados para criar um template. `name` e `externalId` são únicos na organização.
    MessageTemplateUpdateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Nome do template (único na organização).
        channel:
          type: string
          enum:
            - email
            - sms
            - whatsapp
            - voice
            - manual
          description: Canal de envio (`email` | `sms` | `whatsapp` | `voice` | `manual`).
        category:
          type: string
          enum:
            - reminder
            - overdue
            - negotiation
            - negativation_warning
            - protest_warning
            - payment_confirmation
          description: Categoria (`reminder` | `overdue` | `negotiation` | `negativation_warning` | `protest_warning` | `payment_confirmation`).
        tone:
          type:
            - string
            - "null"
          enum:
            - friendly
            - neutral
            - firm
            - urgent
            - null
          description: Tom da mensagem (`friendly` | `neutral` | `firm` | `urgent`).
        subject:
          type:
            - string
            - "null"
          maxLength: 255
          description: Assunto (usado em e-mail).
        body:
          type: string
          minLength: 1
          description: Corpo da mensagem, com variáveis no formato `{{variavel}}`.
        variables:
          type: array
          items:
            type: string
          description: Variáveis disponíveis no corpo/assunto.
        activatedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da ativação (null = inativo).
        externalId:
          type:
            - string
            - "null"
          maxLength: 60
          description: Identificador no SEU sistema (chave das integrações; único na organização).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
      description: Campos a atualizar (parcial — envie só o que muda).
    MessageTemplateDuplicateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Nome do template (único na organização).
      required:
        - name
      description: Nome do novo template gerado pela duplicação (único na organização).
    MessageTemplateListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/MessageTemplate"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    CollectionRuleStep:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        collectionRuleId:
          type: string
          format: uuid
          description: Régua de cobrança dona da etapa.
        messageTemplateId:
          type:
            - string
            - "null"
          format: uuid
          description: Template de mensagem usado pela etapa (deve pertencer à organização).
        position:
          type: integer
          description: Posição da etapa na régua (a partir de 1).
          example: 1
        name:
          type: string
          description: Nome da etapa.
          example: Lembrete 3 dias antes
        triggerType:
          type: string
          enum:
            - before_due
            - on_due
            - after_due
            - after_issue
            - after_payment
          description: Gatilho (`before_due` | `on_due` | `after_due` | `after_issue` | `after_payment`).
        triggerDays:
          type: integer
          description: Dias relativos ao gatilho (0 = no dia).
          example: 3
        actionType:
          type: string
          enum:
            - notification
            - negativation
            - protest
            - manual_task
            - negotiation_offer
            - judicial
          description: Ação (`notification` | `negativation` | `protest` | `manual_task` | `negotiation_offer` | `judicial`).
        channels:
          type: array
          items:
            type: string
            enum:
              - email
              - sms
              - whatsapp
              - voice
              - manual
          description: Canais de envio (`email` | `sms` | `whatsapp` | `voice` | `manual`).
        tone:
          type:
            - string
            - "null"
          enum:
            - friendly
            - neutral
            - firm
            - urgent
            - null
          description: Tom da mensagem (`friendly` | `neutral` | `firm` | `urgent`).
        preferredTime:
          type:
            - string
            - "null"
          description: "Horário preferido de envio (ex.: `09:00`)."
          example: 09:00
        activatedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da ativação (null = inativa).
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados gravados pelo sistema.
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        updatedAt:
          type: string
          format: date-time
          description: Atualizado em (ISO 8601).
        deletedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Excluído em (soft delete; null quando ativo).
        messageTemplate:
          type:
            - object
            - "null"
          properties:
            id:
              type: string
              format: uuid
              description: Identificador (UUID) do recurso.
            publicId:
              type: string
              description: Identificador público estável (exposto na interface).
            organizationId:
              type: string
              format: uuid
              description: Organização dona do registro.
            workspaceId:
              type:
                - string
                - "null"
              format: uuid
              description: Workspace do registro (hierarquia multi-tenant).
            companyId:
              type:
                - string
                - "null"
              format: uuid
              description: Empresa (credora) associada.
            businessUnitId:
              type:
                - string
                - "null"
              format: uuid
              description: Unidade de negócio do registro.
            name:
              type: string
              description: Nome do template (único na organização).
              example: Lembrete 3 dias antes
            channel:
              type: string
              enum:
                - email
                - sms
                - whatsapp
                - voice
                - manual
              description: Canal de envio (`email` | `sms` | `whatsapp` | `voice` | `manual`).
            category:
              type: string
              enum:
                - reminder
                - overdue
                - negotiation
                - negativation_warning
                - protest_warning
                - payment_confirmation
              description: Categoria (`reminder` | `overdue` | `negotiation` | `negativation_warning` | `protest_warning` | `payment_confirmation`).
            tone:
              type:
                - string
                - "null"
              enum:
                - friendly
                - neutral
                - firm
                - urgent
                - null
              description: Tom da mensagem (`friendly` | `neutral` | `firm` | `urgent`).
            subject:
              type:
                - string
                - "null"
              description: Assunto (usado em e-mail).
            body:
              type: string
              description: Corpo da mensagem, com variáveis no formato `{{variavel}}`.
            variables:
              type: array
              items:
                type: string
              description: Variáveis disponíveis no corpo/assunto.
              example:
                - customer_name
                - amount
                - due_date
            activatedAt:
              type:
                - string
                - "null"
              format: date-time
              description: Momento da ativação (null = inativo).
            externalId:
              type:
                - string
                - "null"
              description: Identificador no SEU sistema (chave das integrações; único na organização).
            customData:
              type:
                - object
                - "null"
              additionalProperties: {}
              description: Metadados personalizáveis pelo cliente da API.
            tags:
              type: array
              items:
                type: string
              description: Tags livres.
            metadata:
              type: object
              additionalProperties: {}
              description: Metadados gravados pelo sistema.
            createdAt:
              type: string
              format: date-time
              description: Criado em (ISO 8601).
            updatedAt:
              type: string
              format: date-time
              description: Atualizado em (ISO 8601).
            deletedAt:
              type:
                - string
                - "null"
              format: date-time
              description: Excluído em (soft delete; null quando ativo).
          required:
            - id
            - publicId
            - organizationId
            - workspaceId
            - companyId
            - businessUnitId
            - name
            - channel
            - category
            - tone
            - subject
            - body
            - variables
            - activatedAt
            - externalId
            - customData
            - tags
            - metadata
            - createdAt
            - updatedAt
            - deletedAt
          description: Template de mensagem embutido (presente nos endpoints de etapas).
      required:
        - id
        - publicId
        - collectionRuleId
        - messageTemplateId
        - position
        - name
        - triggerType
        - triggerDays
        - actionType
        - channels
        - tone
        - preferredTime
        - activatedAt
        - externalId
        - customData
        - tags
        - metadata
        - createdAt
        - updatedAt
        - deletedAt
      description: "Etapa da régua: ação disparada em função do vencimento (notificação, negativação, protesto etc.)."
    CollectionRule:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        organizationId:
          type: string
          format: uuid
          description: Organização dona do registro.
        workspaceId:
          type:
            - string
            - "null"
          format: uuid
          description: Workspace do registro (hierarquia multi-tenant).
        companyId:
          type:
            - string
            - "null"
          format: uuid
          description: Empresa (credora) associada.
        businessUnitId:
          type:
            - string
            - "null"
          format: uuid
          description: Unidade de negócio do registro.
        classificationId:
          type:
            - string
            - "null"
          format: uuid
          description: Classificação de clientes atendida pela régua (segmentação).
        name:
          type: string
          description: Nome da régua.
          example: Régua padrão
        description:
          type:
            - string
            - "null"
          description: Descrição da régua.
        isDefault:
          type: boolean
          description: true quando é a régua padrão da organização (única).
        priority:
          type: integer
          description: Prioridade na seleção de régua (maior vence).
        activatedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da ativação (null = inativa).
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados gravados pelo sistema.
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        updatedAt:
          type: string
          format: date-time
          description: Atualizado em (ISO 8601).
        deletedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Excluído em (soft delete; null quando ativo).
        classification:
          allOf:
            - $ref: "#/components/schemas/Classification"
            - type:
                - object
                - "null"
              description: Classificação associada (objeto completo; null quando não segmentada).
        steps:
          type: array
          items:
            $ref: "#/components/schemas/CollectionRuleStep"
          description: Etapas da régua ordenadas por `position` (presente com `include=steps` e nas respostas de criação/atualização).
        _count:
          type: object
          properties:
            charges:
              type: integer
              description: Cobranças ativas na régua (status pending, overdue ou negotiated).
          required:
            - charges
          description: Contadores relacionados.
      required:
        - id
        - publicId
        - organizationId
        - workspaceId
        - companyId
        - businessUnitId
        - classificationId
        - name
        - description
        - isDefault
        - priority
        - activatedAt
        - externalId
        - customData
        - tags
        - metadata
        - createdAt
        - updatedAt
        - deletedAt
        - classification
      description: "Régua de cobrança: sequência de etapas automatizadas aplicada às cobranças da carteira."
    CollectionRuleStepInput:
      type: object
      properties:
        messageTemplateId:
          type:
            - string
            - "null"
          format: uuid
          description: Template de mensagem usado pela etapa (deve pertencer à organização).
        position:
          type: integer
          exclusiveMinimum: 0
          description: Posição da etapa na régua (a partir de 1).
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Nome da etapa.
        triggerType:
          type: string
          enum:
            - before_due
            - on_due
            - after_due
            - after_issue
            - after_payment
          description: Gatilho (`before_due` | `on_due` | `after_due` | `after_issue` | `after_payment`).
        triggerDays:
          type: integer
          minimum: 0
          description: Dias relativos ao gatilho (0 = no dia).
        actionType:
          type: string
          enum:
            - notification
            - negativation
            - protest
            - manual_task
            - negotiation_offer
            - judicial
          description: Ação (`notification` | `negativation` | `protest` | `manual_task` | `negotiation_offer` | `judicial`).
        channels:
          type: array
          items:
            type: string
            enum:
              - email
              - sms
              - whatsapp
              - voice
              - manual
          minItems: 1
          description: Canais de envio (`email` | `sms` | `whatsapp` | `voice` | `manual`).
        tone:
          type:
            - string
            - "null"
          enum:
            - friendly
            - neutral
            - firm
            - urgent
            - null
          description: Tom da mensagem (`friendly` | `neutral` | `firm` | `urgent`).
        preferredTime:
          type:
            - string
            - "null"
          maxLength: 10
          description: "Horário preferido de envio (ex.: `09:00`)."
        activatedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da ativação (null = inativa).
        externalId:
          type:
            - string
            - "null"
          maxLength: 60
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
      required:
        - name
        - triggerType
        - triggerDays
        - actionType
        - channels
      description: Etapa criada junto com a régua. Sem `position`, as etapas são numeradas na ordem do array.
    CollectionRuleStepUpsert:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Nome da etapa.
        position:
          type: integer
          minimum: 1
          description: Posição da etapa na régua (a partir de 1).
        triggerType:
          type: string
          enum:
            - before_due
            - on_due
            - after_due
            - after_issue
            - after_payment
          description: Gatilho (`before_due` | `on_due` | `after_due` | `after_issue` | `after_payment`).
        triggerDays:
          type: integer
          minimum: 0
          description: Dias relativos ao gatilho (0 = no dia).
        actionType:
          type: string
          enum:
            - notification
            - negativation
            - protest
            - manual_task
            - negotiation_offer
            - judicial
          description: Ação (`notification` | `negativation` | `protest` | `manual_task` | `negotiation_offer` | `judicial`).
        channels:
          type: array
          items:
            type: string
            enum:
              - email
              - sms
              - whatsapp
              - voice
              - manual
          description: Canais de envio (`email` | `sms` | `whatsapp` | `voice` | `manual`).
        messageTemplateId:
          type:
            - string
            - "null"
          format: uuid
          description: Template de mensagem usado pela etapa (deve pertencer à organização).
        tone:
          type:
            - string
            - "null"
          enum:
            - friendly
            - neutral
            - firm
            - urgent
            - null
          description: Tom da mensagem (`friendly` | `neutral` | `firm` | `urgent`).
        preferredTime:
          type:
            - string
            - "null"
          description: "Horário preferido de envio (ex.: `09:00`)."
      required:
        - name
        - position
        - triggerType
        - triggerDays
        - actionType
      description: "Etapa no PUT da régua: com `id` atualiza a existente; sem `id` cria; etapas ausentes do array são excluídas (soft delete)."
    CollectionRuleCreateRequest:
      type: object
      properties:
        classificationId:
          type:
            - string
            - "null"
          format: uuid
          description: Classificação de clientes atendida pela régua (segmentação).
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Nome da régua.
        description:
          type:
            - string
            - "null"
          maxLength: 1000
          description: Descrição da régua.
        isDefault:
          type: boolean
          description: true quando é a régua padrão da organização (única).
        priority:
          type: integer
          minimum: 0
          description: Prioridade na seleção de régua (maior vence).
        activatedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da ativação (null = inativa).
        externalId:
          type:
            - string
            - "null"
          maxLength: 60
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        steps:
          type: array
          items:
            $ref: "#/components/schemas/CollectionRuleStepInput"
          description: Etapas da régua ordenadas por `position` (presente com `include=steps` e nas respostas de criação/atualização).
      required:
        - name
      description: Dados para criar uma régua de cobrança, opcionalmente com etapas inline.
    CollectionRuleUpdateRequest:
      type: object
      properties:
        classificationId:
          type:
            - string
            - "null"
          format: uuid
          description: Classificação de clientes atendida pela régua (segmentação).
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Nome da régua.
        description:
          type:
            - string
            - "null"
          maxLength: 1000
          description: Descrição da régua.
        isDefault:
          type: boolean
          description: true quando é a régua padrão da organização (única).
        priority:
          type: integer
          minimum: 0
          description: Prioridade na seleção de régua (maior vence).
        activatedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da ativação (null = inativa).
        externalId:
          type:
            - string
            - "null"
          maxLength: 60
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        steps:
          type: array
          items:
            $ref: "#/components/schemas/CollectionRuleStepUpsert"
          description: "Conjunto completo de etapas (upsert): com `id` atualiza, sem `id` cria, ausentes são excluídas."
      description: Campos a atualizar (parcial). Se `steps` for enviado, o array substitui o conjunto de etapas (upsert).
    CollectionRuleStepCreateRequest:
      allOf:
        - $ref: "#/components/schemas/CollectionRuleStepInput"
        - type: object
          properties:
            triggerType:
              type: string
              enum:
                - before_due
                - on_due
                - after_due
              description: Gatilho (`before_due` | `on_due` | `after_due`). Os gatilhos `after_issue`/`after_payment` só podem ser definidos via régua.
      description: Dados para criar uma etapa. Este endpoint aceita apenas gatilhos relativos ao vencimento (`before_due` | `on_due` | `after_due`).
    CollectionRuleStepUpdateRequest:
      type: object
      properties:
        messageTemplateId:
          type:
            - string
            - "null"
          format: uuid
          description: Template de mensagem usado pela etapa (deve pertencer à organização).
        position:
          type: integer
          exclusiveMinimum: 0
          description: Posição da etapa na régua (a partir de 1).
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Nome da etapa.
        triggerType:
          type: string
          enum:
            - before_due
            - on_due
            - after_due
          description: Gatilho (`before_due` | `on_due` | `after_due`). Os gatilhos `after_issue`/`after_payment` só podem ser definidos via régua.
        triggerDays:
          type: integer
          minimum: 0
          description: Dias relativos ao gatilho (0 = no dia).
        actionType:
          type: string
          enum:
            - notification
            - negativation
            - protest
            - manual_task
            - negotiation_offer
            - judicial
          description: Ação (`notification` | `negativation` | `protest` | `manual_task` | `negotiation_offer` | `judicial`).
        channels:
          type: array
          items:
            type: string
            enum:
              - email
              - sms
              - whatsapp
              - voice
              - manual
          minItems: 1
          description: Canais de envio (`email` | `sms` | `whatsapp` | `voice` | `manual`).
        tone:
          type:
            - string
            - "null"
          enum:
            - friendly
            - neutral
            - firm
            - urgent
            - null
          description: Tom da mensagem (`friendly` | `neutral` | `firm` | `urgent`).
        preferredTime:
          type:
            - string
            - "null"
          maxLength: 10
          description: "Horário preferido de envio (ex.: `09:00`)."
        activatedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da ativação (null = inativa).
        externalId:
          type:
            - string
            - "null"
          maxLength: 60
          description: Identificador no SEU sistema (chave das integrações).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
      description: Campos da etapa a atualizar (parcial — envie só o que muda).
    CollectionRuleListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/CollectionRule"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    CollectionRuleShowResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/CollectionRule"
      required:
        - data
    CollectionRuleStepListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/CollectionRuleStep"
      required:
        - data
    NegotiationCampaign:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        name:
          type: string
          description: Nome da campanha.
          example: 30% à vista · 30-60 dias
        discountPercentage:
          type:
            - string
            - "null"
          description: Percentual de desconto (0-100). Devolvido como string decimal.
          example: "30"
        maxInstallments:
          type:
            - integer
            - "null"
          description: Máximo de parcelas permitido (1 = só à vista).
          example: 1
        minDaysOverdue:
          type:
            - integer
            - "null"
          description: Início da faixa de dias de atraso em que a campanha vale (null = sem mínimo).
          example: 30
        maxDaysOverdue:
          type:
            - integer
            - "null"
          description: Fim da faixa de dias de atraso em que a campanha vale (null = sem máximo).
          example: 60
        validUntil:
          type:
            - string
            - "null"
          format: date-time
          description: Data-limite de validade da campanha (null = sem prazo).
        terms:
          type:
            - string
            - "null"
          description: Condições exibidas ao devedor.
        activatedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Momento da ativação (null = campanha encerrada).
      required:
        - id
        - publicId
        - name
        - discountPercentage
        - maxInstallments
        - minDaysOverdue
        - maxDaysOverdue
        - validUntil
        - terms
        - activatedAt
      description: "Campanha de negociação: oferta de desconto reutilizável, válida para toda a organização e segmentada por faixa de dias de atraso. O portal do devedor oferece automaticamente a campanha ativa aplicável."
    NegotiationCampaignDetail:
      allOf:
        - $ref: "#/components/schemas/NegotiationCampaign"
        - type: object
          properties:
            organizationId:
              type: string
              format: uuid
              description: Organização dona do registro.
            workspaceId:
              type:
                - string
                - "null"
              format: uuid
              description: Workspace do registro (hierarquia multi-tenant).
            companyId:
              type:
                - string
                - "null"
              format: uuid
              description: Empresa (credora) associada.
            businessUnitId:
              type:
                - string
                - "null"
              format: uuid
              description: Unidade de negócio do registro.
            chargeId:
              type:
                - string
                - "null"
              format: uuid
              description: Cobrança vinculada. Sempre null em campanhas (a oferta é org-wide).
            offerType:
              type: string
              enum:
                - discount
                - installment
                - extension
              description: Tipo da oferta (`discount` | `installment` | `extension`). Campanhas criadas pela API usam `discount`.
            minimumEntryPercentage:
              type:
                - string
                - "null"
              description: Percentual mínimo de entrada (string decimal; null quando não se aplica).
            externalId:
              type:
                - string
                - "null"
              description: Identificador no SEU sistema (chave das integrações).
            customData:
              type:
                - object
                - "null"
              additionalProperties: {}
              description: Metadados personalizáveis pelo cliente da API.
            tags:
              type: array
              items:
                type: string
              description: Tags livres.
            metadata:
              type: object
              additionalProperties: {}
              description: Metadados gravados pelo sistema.
            createdAt:
              type: string
              format: date-time
              description: Criado em (ISO 8601).
            updatedAt:
              type: string
              format: date-time
              description: Atualizado em (ISO 8601).
            deletedAt:
              type:
                - string
                - "null"
              format: date-time
              description: Excluído em (soft delete; null quando ativo).
          required:
            - organizationId
            - workspaceId
            - companyId
            - businessUnitId
            - chargeId
            - offerType
            - minimumEntryPercentage
            - externalId
            - customData
            - tags
            - metadata
            - createdAt
            - updatedAt
            - deletedAt
      description: Registro completo da campanha devolvido na criação (modelo de oferta de negociação inteiro).
    NegotiationCampaignCreateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 120
          description: Nome da campanha.
        discountPercentage:
          type: number
          minimum: 0
          maximum: 100
          description: Percentual de desconto (0-100). Devolvido como string decimal.
          example: 30
        maxInstallments:
          type: integer
          minimum: 1
          maximum: 36
          description: Máximo de parcelas permitido (1 = só à vista).
          example: 1
        minDaysOverdue:
          type:
            - integer
            - "null"
          minimum: 0
          description: Início da faixa de dias de atraso em que a campanha vale (null = sem mínimo).
        maxDaysOverdue:
          type:
            - integer
            - "null"
          minimum: 0
          description: Fim da faixa de dias de atraso em que a campanha vale (null = sem máximo).
        validUntil:
          type:
            - string
            - "null"
          format: date
          description: Data-limite de validade da campanha (null = sem prazo).
          example: 2026-12-31
        terms:
          type:
            - string
            - "null"
          maxLength: 500
          description: Condições exibidas ao devedor.
      required:
        - name
        - discountPercentage
      description: Dados para criar a campanha. Ela já nasce ativa; `minDaysOverdue` não pode ser maior que `maxDaysOverdue`.
    NegotiationCampaignListResponse:
      type: object
      properties:
        campaigns:
          type: array
          items:
            $ref: "#/components/schemas/NegotiationCampaign"
      required:
        - campaigns
    NegotiationCampaignCreateResponse:
      type: object
      properties:
        campaign:
          $ref: "#/components/schemas/NegotiationCampaignDetail"
      required:
        - campaign
    NegativationPersonSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        name:
          type: string
          description: Nome do cliente.
        documentNumber:
          type:
            - string
            - "null"
          description: CPF/CNPJ do cliente (somente dígitos).
        documentType:
          type:
            - string
            - "null"
          enum:
            - cpf
            - cnpj
            - null
          description: Tipo do documento (`cpf` | `cnpj`).
      required:
        - id
        - name
        - documentNumber
        - documentType
      description: Resumo do cliente (presente com `include=person` e nas respostas de criação/consulta).
    NegativationChargeSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        documentNumber:
          type:
            - string
            - "null"
          description: Número do documento da cobrança.
        description:
          type:
            - string
            - "null"
          description: Descrição da cobrança.
        originalAmount:
          type: string
          description: Valor original da cobrança (decimal como string).
          example: "150.00"
        currentAmount:
          type:
            - string
            - "null"
          description: Valor atualizado da cobrança (decimal como string).
          example: "175.50"
        dueDate:
          type: string
          format: date-time
          description: Vencimento da cobrança (ISO 8601).
        status:
          type: string
          description: Status da cobrança.
          example: overdue
      required:
        - id
        - documentNumber
        - description
        - originalAmount
        - currentAmount
        - dueDate
        - status
      description: Resumo da cobrança (presente com `include=charge` e nas respostas de criação/consulta).
    Negativation:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        organizationId:
          type: string
          format: uuid
          description: Organização dona do registro.
        workspaceId:
          type:
            - string
            - "null"
          format: uuid
          description: Workspace do registro (hierarquia multi-tenant).
        companyId:
          type:
            - string
            - "null"
          format: uuid
          description: Empresa (credora) do registro.
        businessUnitId:
          type:
            - string
            - "null"
          format: uuid
          description: Unidade de negócio (BU) do registro.
        chargeId:
          type: string
          format: uuid
          description: Cobrança negativada (UUID).
        personId:
          type: string
          format: uuid
          description: Cliente negativado (UUID).
        bureau:
          type: string
          enum:
            - serasa
            - spc
            - boa_vista
          description: Birô de crédito (`serasa` | `spc` | `boa_vista`).
        status:
          type: string
          enum:
            - pending
            - active
            - removed
            - failed
          description: Status (`pending` = aguardando revisão humana obrigatória, `active` = efetivada no birô, `removed` = baixada, `failed` = falhou).
        amount:
          type: string
          description: Valor negativado (decimal serializado como string).
          example: "150.00"
        registeredAt:
          type:
            - string
            - "null"
          format: date-time
          description: Data em que a negativação foi efetivada no birô (ISO 8601).
        removedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Data da baixa no birô (ISO 8601).
        removalReason:
          type:
            - string
            - "null"
          description: Motivo da baixa da negativação.
        responseData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Resposta bruta do birô (payload da integração).
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema ou protocolo no birô.
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados gravados pelo sistema.
        person:
          $ref: "#/components/schemas/NegativationPersonSummary"
        charge:
          $ref: "#/components/schemas/NegativationChargeSummary"
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        updatedAt:
          type: string
          format: date-time
          description: Atualizado em (ISO 8601).
        deletedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Excluído em (soft delete; null quando ativo).
      required:
        - id
        - publicId
        - organizationId
        - workspaceId
        - companyId
        - businessUnitId
        - chargeId
        - personId
        - bureau
        - status
        - amount
        - registeredAt
        - removedAt
        - removalReason
        - responseData
        - externalId
        - customData
        - tags
        - metadata
        - createdAt
        - updatedAt
        - deletedAt
      description: "Registro de negativação de uma cobrança em birô de crédito (Serasa, SPC ou Boa Vista). Workflow jurídico: todo registro nasce `pending` e passa por revisão humana obrigatória antes de ser efetivado no birô (evento `negativation.review_required`)."
    NegativationCreateRequest:
      type: object
      properties:
        personId:
          type: string
          format: uuid
          description: Cliente negativado (UUID).
        chargeId:
          type: string
          format: uuid
          description: Cobrança negativada (UUID).
        bureau:
          type: string
          enum:
            - serasa
            - spc
            - boa_vista
          description: Birô de crédito (`serasa` | `spc` | `boa_vista`).
        amount:
          type: number
          exclusiveMinimum: 0
          description: Valor a negativar (número decimal positivo).
          example: 150
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema ou protocolo no birô.
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
      required:
        - personId
        - chargeId
        - bureau
        - amount
      description: Dados para registrar uma negativação. A cobrança deve pertencer ao cliente informado.
    NegativationUpdateRequest:
      type: object
      properties:
        status:
          type: string
          enum:
            - pending
            - active
            - removed
            - failed
          description: Status (`pending` = aguardando revisão humana obrigatória, `active` = efetivada no birô, `removed` = baixada, `failed` = falhou).
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema ou protocolo no birô.
        registeredAt:
          type:
            - string
            - "null"
          format: date-time
          description: Data em que a negativação foi efetivada no birô (ISO 8601).
        removedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Data da baixa no birô (ISO 8601).
        removalReason:
          type:
            - string
            - "null"
          description: Motivo da baixa da negativação.
        responseData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Resposta bruta do birô (payload da integração).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
      description: Campos a atualizar (parcial). Usado pela revisão humana para aprovar/efetivar o registro e pelas integrações para gravar a resposta do birô.
    NegativationRemoveRequest:
      type: object
      properties:
        removalReason:
          type: string
          description: Motivo da baixa da negativação.
      description: Corpo opcional com o motivo da baixa da negativação.
    NegativationListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Negativation"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    ProtestPersonSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        name:
          type: string
          description: Nome do cliente.
        documentNumber:
          type:
            - string
            - "null"
          description: CPF/CNPJ do cliente (somente dígitos).
        documentType:
          type:
            - string
            - "null"
          enum:
            - cpf
            - cnpj
            - null
          description: Tipo do documento (`cpf` | `cnpj`).
      required:
        - id
        - name
        - documentNumber
        - documentType
      description: Resumo do cliente (presente com `include=person` e nas respostas de criação/consulta).
    ProtestChargeSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        documentNumber:
          type:
            - string
            - "null"
          description: Número do documento da cobrança.
        description:
          type:
            - string
            - "null"
          description: Descrição da cobrança.
        originalAmount:
          type: string
          description: Valor original da cobrança (decimal como string).
          example: "150.00"
        currentAmount:
          type:
            - string
            - "null"
          description: Valor atualizado da cobrança (decimal como string).
          example: "175.50"
        dueDate:
          type: string
          format: date-time
          description: Vencimento da cobrança (ISO 8601).
        status:
          type: string
          description: Status da cobrança.
          example: overdue
      required:
        - id
        - documentNumber
        - description
        - originalAmount
        - currentAmount
        - dueDate
        - status
      description: Resumo da cobrança (presente com `include=charge` e nas respostas de criação/consulta).
    Protest:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        organizationId:
          type: string
          format: uuid
          description: Organização dona do registro.
        workspaceId:
          type:
            - string
            - "null"
          format: uuid
          description: Workspace do registro (hierarquia multi-tenant).
        companyId:
          type:
            - string
            - "null"
          format: uuid
          description: Empresa (credora) do registro.
        businessUnitId:
          type:
            - string
            - "null"
          format: uuid
          description: Unidade de negócio (BU) do registro.
        chargeId:
          type: string
          format: uuid
          description: Cobrança protestada (UUID).
        personId:
          type: string
          format: uuid
          description: Cliente protestado (UUID).
        notary:
          type:
            - string
            - "null"
          description: Nome do cartório de protesto.
        notaryCode:
          type:
            - string
            - "null"
          description: Código/identificador do cartório.
        status:
          type: string
          enum:
            - pending
            - sent
            - intimated
            - protested
            - paid
            - cancelled
          description: Status (`pending` = aguardando revisão humana obrigatória, `sent` = enviado ao cartório, `intimated` = devedor intimado, `protested` = protestado, `paid` = pago, `cancelled` = cancelado).
        amount:
          type: string
          description: Valor protestado (decimal serializado como string).
          example: "150.00"
        fees:
          type:
            - string
            - "null"
          description: Emolumentos/custas do cartório (decimal como string).
          example: "12.50"
        sentAt:
          type:
            - string
            - "null"
          format: date-time
          description: Data de envio ao cartório (ISO 8601).
        intimationDate:
          type:
            - string
            - "null"
          format: date-time
          description: Data de intimação do devedor (ISO 8601).
        protestDate:
          type:
            - string
            - "null"
          format: date-time
          description: Data de lavratura do protesto (ISO 8601).
        paymentDate:
          type:
            - string
            - "null"
          format: date-time
          description: Data de pagamento em cartório (ISO 8601).
        cancellationDate:
          type:
            - string
            - "null"
          format: date-time
          description: Data de cancelamento do protesto (ISO 8601).
        responseData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Resposta bruta do cartório (payload da integração).
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema ou protocolo no cartório.
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados gravados pelo sistema.
        person:
          $ref: "#/components/schemas/ProtestPersonSummary"
        charge:
          $ref: "#/components/schemas/ProtestChargeSummary"
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        updatedAt:
          type: string
          format: date-time
          description: Atualizado em (ISO 8601).
        deletedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Excluído em (soft delete; null quando ativo).
      required:
        - id
        - publicId
        - organizationId
        - workspaceId
        - companyId
        - businessUnitId
        - chargeId
        - personId
        - notary
        - notaryCode
        - status
        - amount
        - fees
        - sentAt
        - intimationDate
        - protestDate
        - paymentDate
        - cancellationDate
        - responseData
        - externalId
        - customData
        - tags
        - metadata
        - createdAt
        - updatedAt
        - deletedAt
      description: "Registro de protesto de uma cobrança em cartório. Workflow jurídico: todo registro nasce `pending` e passa por revisão humana obrigatória antes do envio ao cartório (evento `protest.review_required`)."
    ProtestCreateRequest:
      type: object
      properties:
        personId:
          type: string
          format: uuid
          description: Cliente protestado (UUID).
        chargeId:
          type: string
          format: uuid
          description: Cobrança protestada (UUID).
        amount:
          type: number
          exclusiveMinimum: 0
          description: Valor a protestar (número decimal positivo).
          example: 150
        notary:
          type:
            - string
            - "null"
          description: Nome do cartório de protesto.
        notaryCode:
          type:
            - string
            - "null"
          description: Código/identificador do cartório.
        fees:
          type:
            - number
            - "null"
          description: Emolumentos/custas do cartório (número decimal).
          example: 12.5
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema ou protocolo no cartório.
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
      required:
        - personId
        - chargeId
        - amount
      description: Dados para registrar um protesto. A cobrança deve pertencer ao cliente informado.
    ProtestUpdateRequest:
      type: object
      properties:
        status:
          type: string
          enum:
            - pending
            - sent
            - intimated
            - protested
            - paid
            - cancelled
          description: Status (`pending` = aguardando revisão humana obrigatória, `sent` = enviado ao cartório, `intimated` = devedor intimado, `protested` = protestado, `paid` = pago, `cancelled` = cancelado).
        notary:
          type:
            - string
            - "null"
          description: Nome do cartório de protesto.
        notaryCode:
          type:
            - string
            - "null"
          description: Código/identificador do cartório.
        fees:
          type:
            - number
            - "null"
          description: Emolumentos/custas do cartório (número decimal).
        externalId:
          type:
            - string
            - "null"
          description: Identificador no SEU sistema ou protocolo no cartório.
        sentAt:
          type:
            - string
            - "null"
          format: date-time
          description: Data de envio ao cartório (ISO 8601).
        intimationDate:
          type:
            - string
            - "null"
          format: date-time
          description: Data de intimação do devedor (ISO 8601).
        protestDate:
          type:
            - string
            - "null"
          format: date-time
          description: Data de lavratura do protesto (ISO 8601).
        paymentDate:
          type:
            - string
            - "null"
          format: date-time
          description: Data de pagamento em cartório (ISO 8601).
        cancellationDate:
          type:
            - string
            - "null"
          format: date-time
          description: Data de cancelamento do protesto (ISO 8601).
        responseData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Resposta bruta do cartório (payload da integração).
        customData:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados personalizáveis pelo cliente da API.
        tags:
          type: array
          items:
            type: string
          description: Tags livres.
      description: Campos a atualizar (parcial). Usado pela revisão humana para aprovar/avançar o registro e pelas integrações para gravar datas e resposta do cartório.
    ProtestCancelRequest:
      type: object
      properties:
        cancellationReason:
          type: string
          description: Motivo do cancelamento.
      description: Corpo opcional com o motivo do cancelamento (gravado em `responseData.cancellationReason`).
    ProtestListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Protest"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    ImportRowError:
      type: object
      properties:
        line:
          type: integer
          description: Número da linha no arquivo (a linha 1 é o cabeçalho; os dados começam na 2).
          example: 2
        error:
          type: string
          description: Motivo da rejeição da linha.
          example: Nome obrigatório
      required:
        - line
        - error
      description: Erro de uma linha rejeitada da planilha.
    ImportSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        resourceType:
          type: string
          enum:
            - people
            - charges
          description: Tipo de recurso importado (`people` = clientes | `charges` = cobranças).
        status:
          type: string
          enum:
            - pending
            - processing
            - completed
            - failed
          description: Status do processamento (`pending` | `processing` | `completed` | `failed`).
        fileName:
          type:
            - string
            - "null"
          description: Nome do arquivo enviado.
        totalRows:
          type:
            - integer
            - "null"
          description: Total de linhas de dados do arquivo (null até o início do processamento).
        processedRows:
          type: integer
          description: Linhas já processadas.
        createdCount:
          type: integer
          description: Registros criados.
        updatedCount:
          type: integer
          description: Registros atualizados (deduplicação por `external_id`/documento).
        errorCount:
          type: integer
          description: Linhas rejeitadas.
        errorMessage:
          type:
            - string
            - "null"
          description: Mensagem de erro quando o lote inteiro falha.
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        completedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Fim do processamento (ISO 8601).
      required:
        - id
        - publicId
        - resourceType
        - status
        - fileName
        - totalRows
        - processedRows
        - createdCount
        - updatedCount
        - errorCount
        - errorMessage
        - createdAt
        - completedAt
      description: Resumo de uma importação (a listagem não traz o conteúdo do arquivo nem os erros por linha).
    Import:
      allOf:
        - $ref: "#/components/schemas/ImportSummary"
        - type: object
          properties:
            errors:
              type: array
              items:
                $ref: "#/components/schemas/ImportRowError"
              description: Erros por linha rejeitada (`[{ line, error }]`).
            startedAt:
              type:
                - string
                - "null"
              format: date-time
              description: Início do processamento (ISO 8601).
          required:
            - errors
            - startedAt
      description: Importação de planilha CSV (clientes ou cobranças), incluindo os erros por linha rejeitada.
    ImportCreateRequest:
      type: object
      properties:
        resourceType:
          type: string
          enum:
            - people
            - charges
          description: Tipo de recurso importado (`people` = clientes | `charges` = cobranças).
        fileName:
          type: string
          maxLength: 200
          description: Nome do arquivo enviado.
          example: clientes.csv
        content:
          type: string
          minLength: 10
          description: Conteúdo do CSV como texto puro (UTF-8), incluindo a linha de cabeçalho. Máx. 2 MB.
          example: |-
            nome,documento,email
            Maria da Silva,12345678901,maria@example.com
      required:
        - resourceType
        - content
      description: "Upload em JSON: o conteúdo do CSV vai como TEXTO puro no campo `content` (não é multipart nem base64). Limite de 2 MB (~10-20 mil linhas); acima disso a API responde 413."
    ImportCreated:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        resourceType:
          type: string
          enum:
            - people
            - charges
          description: Tipo de recurso importado (`people` = clientes | `charges` = cobranças).
        status:
          type: string
          enum:
            - pending
            - processing
            - completed
            - failed
          description: Status do processamento (`pending` | `processing` | `completed` | `failed`).
        fileName:
          type:
            - string
            - "null"
          description: Nome do arquivo enviado.
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
      required:
        - id
        - publicId
        - resourceType
        - status
        - fileName
        - createdAt
      description: Importação recém-criada (enfileirada para processamento).
    ImportListResponse:
      type: object
      properties:
        imports:
          type: array
          items:
            $ref: "#/components/schemas/ImportSummary"
      required:
        - imports
      description: Envelope `{ imports }` com as importações mais recentes.
    ImportShowResponse:
      type: object
      properties:
        import:
          $ref: "#/components/schemas/Import"
      required:
        - import
      description: Envelope `{ import }` com o detalhe da importação.
    ImportCreatedResponse:
      type: object
      properties:
        import:
          $ref: "#/components/schemas/ImportCreated"
      required:
        - import
      description: Envelope `{ import }` com o job recém-criado.
    ExportJobFilters:
      type: object
      properties:
        status:
          type: string
          maxLength: 40
          description: Filtra as cobranças pelo status.
          example: overdue
        from:
          type: string
          format: date
          description: Vencimento a partir de (data ISO `YYYY-MM-DD`).
          example: 2026-01-01
        to:
          type: string
          format: date
          description: Vencimento até (data ISO `YYYY-MM-DD`).
          example: 2026-06-30
      description: Filtros aplicados à exportação (somente `charges`); ficam gravados no job para auditoria.
    ExportJob:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        resourceType:
          type: string
          enum:
            - people
            - charges
          description: Tipo de recurso exportado (`people` = clientes | `charges` = cobranças).
        status:
          type: string
          enum:
            - pending
            - processing
            - completed
            - failed
          description: Status do processamento (`pending` | `processing` | `completed` | `failed`).
        fileName:
          type:
            - string
            - "null"
          description: "Nome do arquivo gerado (padrão: `{resourceType}.csv`)."
        rowCount:
          type:
            - integer
            - "null"
          description: Total de linhas do CSV gerado (null até concluir).
        truncated:
          type: boolean
          description: true quando o CSV bateu o teto de segurança e saiu parcial.
        errorMessage:
          type:
            - string
            - "null"
          description: Mensagem de erro quando a geração falha.
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        completedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Fim da geração (ISO 8601).
        expiresAt:
          type:
            - string
            - "null"
          format: date-time
          description: Validade do download (ISO 8601); depois disso o conteúdo é limpo e a rota de download responde 410.
      required:
        - id
        - publicId
        - resourceType
        - status
        - fileName
        - rowCount
        - truncated
        - errorMessage
        - createdAt
        - completedAt
        - expiresAt
      description: Job de exportação CSV assíncrona (sem o teto de 10 mil linhas do modo síncrono). O CSV pronto sai em GET /exports/jobs/{id}/download até expirar.
    ExportJobCreateRequest:
      type: object
      properties:
        resourceType:
          type: string
          enum:
            - people
            - charges
          description: Tipo de recurso exportado (`people` = clientes | `charges` = cobranças).
        fileName:
          type: string
          maxLength: 200
          description: "Nome do arquivo gerado (padrão: `{resourceType}.csv`)."
          example: cobrancas-junho.csv
        filters:
          $ref: "#/components/schemas/ExportJobFilters"
      required:
        - resourceType
      description: Dados para agendar uma exportação assíncrona. `filters` só se aplica a `charges`.
    ExportJobCreated:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável (exposto na interface).
        resourceType:
          type: string
          enum:
            - people
            - charges
          description: Tipo de recurso exportado (`people` = clientes | `charges` = cobranças).
        status:
          type: string
          enum:
            - pending
            - processing
            - completed
            - failed
          description: Status do processamento (`pending` | `processing` | `completed` | `failed`).
        fileName:
          type:
            - string
            - "null"
          description: "Nome do arquivo gerado (padrão: `{resourceType}.csv`)."
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
      required:
        - id
        - publicId
        - resourceType
        - status
        - fileName
        - createdAt
      description: Exportação recém-agendada (enfileirada para processamento).
    ExportJobListResponse:
      type: object
      properties:
        exports:
          type: array
          items:
            $ref: "#/components/schemas/ExportJob"
      required:
        - exports
      description: Envelope `{ exports }` com as exportações mais recentes.
    ExportJobCreatedResponse:
      type: object
      properties:
        export:
          $ref: "#/components/schemas/ExportJobCreated"
      required:
        - export
      description: Envelope `{ export }` com o job recém-criado.
    WebhookEventType:
      type: string
      enum:
        - person.created
        - person.updated
        - person.deleted
        - person.classification_changed
        - charge.created
        - charge.updated
        - charge.deleted
        - charge.paid
        - charge.overdue
        - agreement.created
        - agreement.updated
        - agreement.deleted
        - agreement.accepted
        - agreement.cancelled
        - agreement.broken
        - agreement.completed
        - dispute.created
        - dispute.updated
        - dispute.resolved
        - dispute.cancelled
        - task.created
        - task.updated
        - task.completed
        - task.deleted
        - collection_rule.created
        - collection_rule.updated
        - collection_rule.deleted
        - template.created
        - template.updated
        - template.deleted
        - classification.created
        - classification.updated
        - classification.deleted
        - interaction.created
        - notification.sent
        - notification.delivered
        - notification.read
        - notification.failed
        - negativation.review_required
        - negativation.registered
        - negativation.removed
        - protest.review_required
        - protest.registered
        - protest.paid
        - protest.cancelled
      description: "Tipo de evento assinável do catálogo (ex.: `charge.paid`)."
      example: charge.paid
    WebhookDeliveryEventType:
      type: string
      enum:
        - person.created
        - person.updated
        - person.deleted
        - person.classification_changed
        - charge.created
        - charge.updated
        - charge.deleted
        - charge.paid
        - charge.overdue
        - agreement.created
        - agreement.updated
        - agreement.deleted
        - agreement.accepted
        - agreement.cancelled
        - agreement.broken
        - agreement.completed
        - dispute.created
        - dispute.updated
        - dispute.resolved
        - dispute.cancelled
        - task.created
        - task.updated
        - task.completed
        - task.deleted
        - collection_rule.created
        - collection_rule.updated
        - collection_rule.deleted
        - template.created
        - template.updated
        - template.deleted
        - classification.created
        - classification.updated
        - classification.deleted
        - interaction.created
        - notification.sent
        - notification.delivered
        - notification.read
        - notification.failed
        - negativation.review_required
        - negativation.registered
        - negativation.removed
        - protest.review_required
        - protest.registered
        - protest.paid
        - protest.cancelled
        - webhook.test
      description: "Tipo de evento de uma entrega: catálogo assinável + `webhook.test` (disparado sob demanda via `POST /webhook-endpoints/{id}/test`)."
      example: charge.paid
    WebhookDeliveryStats:
      type: object
      properties:
        total:
          type: integer
          description: Total de entregas.
        pending:
          type: integer
          description: Entregas aguardando processamento.
        success:
          type: integer
          description: Entregas confirmadas (2xx).
        failed:
          type: integer
          description: Entregas com falha (nova tentativa agendada).
        exhausted:
          type: integer
          description: Entregas com tentativas esgotadas (fila morta).
      required:
        - total
      description: Contadores de entregas do endpoint, por status.
    WebhookEndpoint:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável.
        url:
          type: string
          format: uri
          description: URL HTTPS de destino das entregas (validada contra endereços internos — SSRF).
          example: https://example.com/webhooks/kobana
        description:
          type:
            - string
            - "null"
          description: Descrição livre do endpoint.
        events:
          type: array
          items:
            $ref: "#/components/schemas/WebhookEventType"
          description: Tipos de evento assinados. Lista vazia = todos os eventos.
        isActive:
          type: boolean
          description: Endpoint ativo recebe entregas; inativo é ignorado pelo worker.
        authType:
          type: string
          enum:
            - none
            - basic
            - bearer
            - header
          description: Autenticação do request contra o seu endpoint (`none` | `basic` | `bearer` | `header`), além da assinatura HMAC (sempre enviada).
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        deliveries:
          $ref: "#/components/schemas/WebhookDeliveryStats"
      required:
        - id
        - publicId
        - url
        - description
        - events
        - isActive
        - authType
        - createdAt
        - deliveries
      description: 'Endpoint de webhook: recebe os eventos da organização via HTTP POST (JSON). Cada entrega envia os headers `X-Webhook-Event` (tipo do evento), `X-Webhook-Event-Id`, `X-Webhook-Delivery-Id`, `X-Webhook-Attempt`, `X-Webhook-Timestamp` (ISO 8601) e `X-Webhook-Signature` no formato `t=<unix>,v1=<hex>` — HMAC-SHA256 de `"{t}.{corpo}"` com o secret do endpoint; valide a assinatura e rejeite `t` fora de uma janela de 5 minutos (anti-replay) antes de processar. Além da assinatura (sempre enviada), o request pode se autenticar contra o seu endpoint conforme `authType`: `none`, `basic` (usuário/senha), `bearer` (token) ou `header` (header customizado); as credenciais ficam em `authConfig`, cifrado em repouso e nunca retornado. `events` vazio = assina todos os eventos. Entregas com falha são retentadas com backoff exponencial e cada tentativa fica registrada.'
    WebhookDeliverySummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        status:
          type: string
          enum:
            - pending
            - success
            - failed
            - exhausted
          description: "Status da entrega: `pending` | `success` | `failed` (nova tentativa agendada) | `exhausted` (tentativas esgotadas)."
        attempts:
          type: integer
          description: Número de tentativas já realizadas.
        responseStatus:
          type:
            - integer
            - "null"
          description: Status HTTP retornado pelo destino (null sem resposta).
          example: 200
        error:
          type:
            - string
            - "null"
          description: Mensagem do último erro (null em sucesso).
        eventType:
          $ref: "#/components/schemas/WebhookDeliveryEventType"
        eventAt:
          type: string
          format: date-time
          description: Quando o evento ocorreu (ISO 8601).
        deliveredAt:
          type:
            - string
            - "null"
          format: date-time
          description: Quando a entrega foi confirmada (2xx); null se ainda não entregue.
        lastAttemptAt:
          type:
            - string
            - "null"
          format: date-time
          description: Última tentativa (ISO 8601).
      required:
        - id
        - status
        - attempts
        - responseStatus
        - error
        - eventType
        - eventAt
        - deliveredAt
        - lastAttemptAt
      description: Resumo de uma entrega recente do endpoint.
    WebhookEndpointDetail:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável.
        url:
          type: string
          format: uri
          description: URL HTTPS de destino das entregas (validada contra endereços internos — SSRF).
          example: https://example.com/webhooks/kobana
        description:
          type:
            - string
            - "null"
          description: Descrição livre do endpoint.
        events:
          type: array
          items:
            $ref: "#/components/schemas/WebhookEventType"
          description: Tipos de evento assinados. Lista vazia = todos os eventos.
        isActive:
          type: boolean
          description: Endpoint ativo recebe entregas; inativo é ignorado pelo worker.
        authType:
          type: string
          enum:
            - none
            - basic
            - bearer
            - header
          description: Autenticação do request contra o seu endpoint (`none` | `basic` | `bearer` | `header`), além da assinatura HMAC (sempre enviada).
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        deliveries:
          type: array
          items:
            $ref: "#/components/schemas/WebhookDeliverySummary"
          description: Últimas 20 entregas do endpoint.
      required:
        - id
        - publicId
        - url
        - description
        - events
        - isActive
        - authType
        - createdAt
        - deliveries
      description: 'Endpoint de webhook: recebe os eventos da organização via HTTP POST (JSON). Cada entrega envia os headers `X-Webhook-Event` (tipo do evento), `X-Webhook-Event-Id`, `X-Webhook-Delivery-Id`, `X-Webhook-Attempt`, `X-Webhook-Timestamp` (ISO 8601) e `X-Webhook-Signature` no formato `t=<unix>,v1=<hex>` — HMAC-SHA256 de `"{t}.{corpo}"` com o secret do endpoint; valide a assinatura e rejeite `t` fora de uma janela de 5 minutos (anti-replay) antes de processar. Além da assinatura (sempre enviada), o request pode se autenticar contra o seu endpoint conforme `authType`: `none`, `basic` (usuário/senha), `bearer` (token) ou `header` (header customizado); as credenciais ficam em `authConfig`, cifrado em repouso e nunca retornado. `events` vazio = assina todos os eventos. Entregas com falha são retentadas com backoff exponencial e cada tentativa fica registrada.'
    WebhookDelivery:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        eventId:
          type: string
          format: uuid
          description: Evento entregue (UUID).
        eventType:
          $ref: "#/components/schemas/WebhookDeliveryEventType"
        status:
          type: string
          enum:
            - pending
            - success
            - failed
            - exhausted
          description: "Status da entrega: `pending` | `success` | `failed` (nova tentativa agendada) | `exhausted` (tentativas esgotadas)."
        responseStatus:
          type:
            - integer
            - "null"
          description: Status HTTP retornado pelo destino (null sem resposta).
          example: 200
        attempts:
          type: integer
          description: Número de tentativas já realizadas.
        error:
          type:
            - string
            - "null"
          description: Mensagem do último erro (null em sucesso).
        requestHeaders:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Headers enviados (assinatura e credenciais redigidas).
        requestBody:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Corpo JSON enviado ao destino.
        responseHeaders:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Headers da resposta (headers sensíveis redigidos).
        responseBody:
          type:
            - string
            - "null"
          description: Corpo da resposta (texto).
        deliveredAt:
          type:
            - string
            - "null"
          format: date-time
          description: Quando a entrega foi confirmada (2xx); null se ainda não entregue.
        lastAttemptAt:
          type:
            - string
            - "null"
          format: date-time
          description: Última tentativa (ISO 8601).
        nextRetryAt:
          type:
            - string
            - "null"
          format: date-time
          description: Próxima tentativa agendada (null quando não há).
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
      required:
        - id
        - eventId
        - eventType
        - status
        - responseStatus
        - attempts
        - error
        - requestHeaders
        - requestBody
        - responseHeaders
        - responseBody
        - deliveredAt
        - lastAttemptAt
        - nextRetryAt
        - createdAt
      description: "Entrega de webhook: uma tentativa de envio de um evento a um endpoint, com captura de request/response para inspeção. Headers de assinatura e credenciais são redigidos antes de persistir."
    WebhookEndpointCreateRequest:
      type: object
      properties:
        url:
          type: string
          format: uri
          description: URL HTTPS de destino das entregas (validada contra endereços internos — SSRF).
          example: https://example.com/webhooks/kobana
        description:
          type:
            - string
            - "null"
          maxLength: 300
          description: Descrição livre do endpoint.
        events:
          type: array
          items:
            $ref: "#/components/schemas/WebhookEventType"
          description: Tipos de evento assinados. Lista vazia = todos os eventos.
          example:
            - charge.paid
            - charge.overdue
        authType:
          type: string
          enum:
            - none
            - basic
            - bearer
            - header
          description: Autenticação do request contra o seu endpoint (`none` | `basic` | `bearer` | `header`), além da assinatura HMAC (sempre enviada).
        authConfig:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: 'Credenciais do `authType`: `basic` → `{"username","password"}`; `bearer` → `{"token"}`; `header` → `{"key","value"}`. Cifrado em repouso; nunca retornado nas consultas.'
          example:
            token: meu-token-secreto
      required:
        - url
      description: Dados para criar um endpoint de webhook.
    WebhookEndpointUpdateRequest:
      type: object
      properties:
        url:
          type: string
          format: uri
          description: URL HTTPS de destino das entregas (validada contra endereços internos — SSRF).
        description:
          type:
            - string
            - "null"
          maxLength: 300
          description: Descrição livre do endpoint.
        events:
          type: array
          items:
            $ref: "#/components/schemas/WebhookEventType"
          description: Tipos de evento assinados. Lista vazia = todos os eventos.
        isActive:
          type: boolean
          description: Endpoint ativo recebe entregas; inativo é ignorado pelo worker.
        authType:
          type: string
          enum:
            - none
            - basic
            - bearer
            - header
          description: Autenticação do request contra o seu endpoint (`none` | `basic` | `bearer` | `header`), além da assinatura HMAC (sempre enviada).
        authConfig:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: 'Credenciais do `authType`: `basic` → `{"username","password"}`; `bearer` → `{"token"}`; `header` → `{"key","value"}`. Cifrado em repouso; nunca retornado nas consultas.'
          example:
            token: meu-token-secreto
      description: Campos a atualizar (parcial — envie só o que muda).
    WebhookEndpointCreateResponse:
      type: object
      properties:
        endpoint:
          type: object
          properties:
            id:
              type: string
              format: uuid
              description: Identificador (UUID) do recurso.
            publicId:
              type: string
              description: Identificador público estável.
            url:
              type: string
              format: uri
              description: URL HTTPS de destino das entregas (validada contra endereços internos — SSRF).
            description:
              type:
                - string
                - "null"
              description: Descrição livre do endpoint.
            events:
              type: array
              items:
                $ref: "#/components/schemas/WebhookEventType"
              description: Tipos de evento assinados. Lista vazia = todos os eventos.
            isActive:
              type: boolean
              description: Endpoint ativo recebe entregas; inativo é ignorado pelo worker.
            secret:
              type: string
              description: Secret HMAC (`whsec_…`) usado na assinatura `X-Webhook-Signature`. Exibido apenas na criação e na rotação — guarde com segurança.
              example: whsec_6f2a…
          required:
            - id
            - publicId
            - url
            - description
            - events
            - isActive
            - secret
      required:
        - endpoint
    WebhookEndpointListResponse:
      type: object
      properties:
        endpoints:
          type: array
          items:
            $ref: "#/components/schemas/WebhookEndpoint"
      required:
        - endpoints
    WebhookEndpointShowResponse:
      type: object
      properties:
        endpoint:
          $ref: "#/components/schemas/WebhookEndpointDetail"
      required:
        - endpoint
    WebhookEndpointUpdateResponse:
      type: object
      properties:
        endpoint:
          type: object
          properties:
            id:
              type: string
              format: uuid
              description: Identificador (UUID) do recurso.
            url:
              type: string
              format: uri
              description: URL HTTPS de destino das entregas (validada contra endereços internos — SSRF).
            description:
              type:
                - string
                - "null"
              description: Descrição livre do endpoint.
            events:
              type: array
              items:
                $ref: "#/components/schemas/WebhookEventType"
              description: Tipos de evento assinados. Lista vazia = todos os eventos.
            isActive:
              type: boolean
              description: Endpoint ativo recebe entregas; inativo é ignorado pelo worker.
          required:
            - id
            - url
            - description
            - events
            - isActive
      required:
        - endpoint
    WebhookEndpointRotateSecretResponse:
      type: object
      properties:
        secret:
          type: string
          description: Secret HMAC (`whsec_…`) usado na assinatura `X-Webhook-Signature`. Exibido apenas na criação e na rotação — guarde com segurança.
          example: whsec_6f2a…
      required:
        - secret
    WebhookDeliveryListResponse:
      type: object
      properties:
        endpoint:
          type: object
          properties:
            id:
              type: string
              format: uuid
              description: Identificador (UUID) do recurso.
            url:
              type: string
              format: uri
              description: URL HTTPS de destino das entregas (validada contra endereços internos — SSRF).
          required:
            - id
            - url
          description: Endpoint dono das entregas.
        deliveries:
          type: array
          items:
            $ref: "#/components/schemas/WebhookDelivery"
        meta:
          type: object
          properties:
            page:
              type: integer
              description: Página atual.
            perPage:
              type: integer
              description: Itens por página aplicados.
            total:
              type: integer
              description: Total de registros que casam com o filtro.
            totalPages:
              type: integer
              description: Total de páginas.
          required:
            - page
            - perPage
            - total
            - totalPages
          description: Metadados de paginação das listagens.
      required:
        - endpoint
        - deliveries
        - meta
    WebhookDeliveryRetryResponse:
      type: object
      properties:
        deliveryId:
          type: string
          format: uuid
          description: Identificador (UUID) da entrega.
        status:
          type: string
          enum:
            - queued
          description: Sempre `queued` — a entrega foi re-enfileirada.
      required:
        - deliveryId
        - status
    WebhookEndpointTestResponse:
      type: object
      properties:
        eventId:
          type: string
          format: uuid
          description: Evento `webhook.test` criado (UUID).
        deliveryId:
          type: string
          format: uuid
          description: Identificador (UUID) da entrega.
        status:
          type: string
          enum:
            - queued
          description: Sempre `queued` — a entrega foi enfileirada.
      required:
        - eventId
        - deliveryId
        - status
    AuditLogActor:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        name:
          type:
            - string
            - "null"
          description: Nome do usuário.
        email:
          type: string
          format: email
          description: E-mail do usuário.
      required:
        - id
        - name
        - email
      description: Dados do usuário quando `actorType` = `user` (null caso contrário).
    AuditLog:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        action:
          type: string
          description: "Ação registrada (ex.: `webhook_endpoint.created`, `dispute.resolved`)."
          example: webhook_endpoint.created
        entityType:
          type: string
          description: "Tipo da entidade afetada (ex.: `WebhookEndpoint`)."
          example: WebhookEndpoint
        entityId:
          type:
            - string
            - "null"
          description: ID da entidade afetada (null quando não se aplica).
        actorType:
          type: string
          enum:
            - user
            - system
            - job
          description: "Quem executou: `user` (humano), `system` ou `job`."
        actorId:
          type:
            - string
            - "null"
          description: ID do usuário, nome do job ou do sistema.
        actor:
          allOf:
            - $ref: "#/components/schemas/AuditLogActor"
            - type:
                - object
                - "null"
        before:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Estado (parcial) antes da mudança.
        after:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Estado (parcial) depois da mudança.
        reason:
          type:
            - string
            - "null"
          description: Justificativa informada, quando houver.
        ip:
          type:
            - string
            - "null"
          description: IP de origem da requisição.
        userAgent:
          type:
            - string
            - "null"
          description: User-Agent da requisição.
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
      required:
        - id
        - action
        - entityType
        - entityId
        - actorType
        - actorId
        - actor
        - before
        - after
        - reason
        - ip
        - userAgent
        - createdAt
      description: "Registro imutável (append-only) da trilha de auditoria: quem fez o quê, em qual entidade, com o estado antes/depois. A escrita é exclusiva do sistema; a API expõe apenas leitura."
    AuditLogListResponse:
      type: object
      properties:
        logs:
          type: array
          items:
            $ref: "#/components/schemas/AuditLog"
        pagination:
          type: object
          properties:
            page:
              type: integer
              description: Página atual.
            perPage:
              type: integer
              description: Itens por página aplicados.
            total:
              type: integer
              description: Total de registros que casam com o filtro.
            totalPages:
              type: integer
              description: Total de páginas.
          required:
            - page
            - perPage
            - total
            - totalPages
          description: Metadados de paginação das listagens.
      required:
        - logs
        - pagination
    RecoveryMetrics:
      type: object
      properties:
        period:
          type: object
          properties:
            since:
              type: string
              description: Início do período (YYYY-MM-DD).
              example: 2026-01-01
            months:
              type: integer
              description: Meses considerados.
              example: 6
          required:
            - since
            - months
          description: Período considerado.
        totals:
          type: object
          properties:
            recoveredAmount:
              type: number
              description: Valor total recuperado no período.
              example: 15230.5
            recoveredCount:
              type: integer
              description: Quantidade de cobranças recuperadas.
              example: 42
            avgDaysOverdue:
              type:
                - integer
                - "null"
              description: Atraso médio (dias) no momento do pagamento.
              example: 12
            avgStepsToRecover:
              type:
                - number
                - "null"
              description: Média de etapas da régua executadas até o pagamento.
              example: 2.4
            recoveryRate:
              type:
                - number
                - "null"
              description: Recuperado ÷ (recuperado + em atraso hoje); null sem base de cálculo.
              example: 0.63
            overdueAmountNow:
              type: number
              description: Valor da carteira em atraso hoje.
              example: 8940
          required:
            - recoveredAmount
            - recoveredCount
            - avgDaysOverdue
            - avgStepsToRecover
            - recoveryRate
            - overdueAmountNow
          description: Totais do período.
        byMonth:
          type: array
          items:
            type: object
            properties:
              month:
                type: string
                description: Mês (YYYY-MM).
                example: 2026-03
              amount:
                type: number
                description: Valor recuperado no mês.
              count:
                type: integer
                description: Cobranças recuperadas no mês.
            required:
              - month
              - amount
              - count
          description: Série mensal de recuperação.
        byMethod:
          type: array
          items:
            type: object
            properties:
              method:
                type: string
                enum:
                  - rule
                  - agreement
                  - overdue_no_rule
                description: "Método: `rule` (em régua) | `agreement` (estava negociada) | `overdue_no_rule` (em atraso sem régua)."
              amount:
                type: number
                description: Valor recuperado no grupo.
              count:
                type: integer
                description: Quantidade de cobranças no grupo.
            required:
              - method
              - amount
              - count
          description: Atribuição por método de recuperação.
        byChannel:
          type: array
          items:
            type: object
            properties:
              channel:
                type: string
                description: "Canal (ex.: `email`, `sms`, `whatsapp`)."
                example: email
              amount:
                type: number
                description: Valor recuperado no grupo.
              count:
                type: integer
                description: Quantidade de cobranças no grupo.
            required:
              - channel
              - amount
              - count
          description: Atribuição pelo canal da última etapa enviada antes do pagamento.
      required:
        - period
        - totals
        - byMonth
        - byMethod
        - byChannel
      description: "Métricas de recuperação: o que a régua de cobrança recuperou no período — totais, série mensal, atribuição por método e por canal, e taxa de recuperação (recuperado ÷ (recuperado + carteira em atraso hoje))."
    EmailLayoutListItem:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável.
        name:
          type: string
          description: Nome do layout.
          example: Layout institucional
        htmlBody:
          type: string
          description: HTML completo do layout; deve conter o placeholder `{{content}}`.
        isDefault:
          type: boolean
          description: Layout padrão da organização (apenas um; definir um novo padrão desmarca o anterior).
        isActive:
          type: boolean
          description: Layout disponível para uso.
        companiesCount:
          type: integer
          description: Quantidade de empresas que usam este layout.
      required:
        - id
        - publicId
        - name
        - htmlBody
        - isDefault
        - isActive
        - companiesCount
      description: "Layout de e-mail: HTML que envolve o conteúdo das mensagens enviadas pela régua. Deve conter o placeholder `{{content}}`, substituído pelo corpo da notificação no envio."
    EmailLayout:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Identificador (UUID) do recurso.
        publicId:
          type: string
          description: Identificador público estável.
        organizationId:
          type: string
          format: uuid
          description: Organização dona do layout.
        name:
          type: string
          description: Nome do layout.
        htmlBody:
          type: string
          description: HTML completo do layout; deve conter o placeholder `{{content}}`.
        isDefault:
          type: boolean
          description: Layout padrão da organização (apenas um; definir um novo padrão desmarca o anterior).
        isActive:
          type: boolean
          description: Layout disponível para uso.
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados gravados pelo sistema.
        createdAt:
          type: string
          format: date-time
          description: Criado em (ISO 8601).
        updatedAt:
          type: string
          format: date-time
          description: Atualizado em (ISO 8601).
        deletedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Excluído em (soft delete; null quando ativo).
      required:
        - id
        - publicId
        - organizationId
        - name
        - htmlBody
        - isDefault
        - isActive
        - metadata
        - createdAt
        - updatedAt
        - deletedAt
      description: "Layout de e-mail: HTML que envolve o conteúdo das mensagens enviadas pela régua. Deve conter o placeholder `{{content}}`, substituído pelo corpo da notificação no envio."
    EmailLayoutCreateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 80
          description: Nome do layout.
          example: Layout institucional
        htmlBody:
          type: string
          minLength: 20
          description: HTML completo do layout; deve conter o placeholder `{{content}}`.
          example: <html><body><header>ACME</header>{{content}}</body></html>
        isDefault:
          type: boolean
          description: Layout padrão da organização (apenas um; definir um novo padrão desmarca o anterior).
      required:
        - name
        - htmlBody
      description: Dados para criar um layout de e-mail.
    EmailLayoutListResponse:
      type: object
      properties:
        layouts:
          type: array
          items:
            $ref: "#/components/schemas/EmailLayoutListItem"
        builtinLayout:
          type: string
          description: Layout embutido de referência (usado quando a organização não tem layout padrão).
      required:
        - layouts
        - builtinLayout
    EmailLayoutCreateResponse:
      type: object
      properties:
        layout:
          $ref: "#/components/schemas/EmailLayout"
      required:
        - layout
    NotificationPreference:
      type: object
      properties:
        type:
          type: string
          enum:
            - reminder
            - overdue
            - negotiation
            - negativation_warning
            - protest_warning
            - payment_confirmation
          description: "Tipo de mensagem: `reminder` (lembrete pré-vencimento) | `overdue` (cobrança pós-vencimento) | `negotiation` (proposta de negociação) | `negativation_warning` (aviso de negativação) | `protest_warning` (aviso de protesto) | `payment_confirmation` (confirmação de pagamento)."
          example: reminder
        label:
          type: string
          description: Rótulo legível do tipo (pt-BR).
          example: Lembrete pré-vencimento
        emailEnabled:
          type: boolean
          description: Canal e-mail habilitado para o tipo.
        smsEnabled:
          type: boolean
          description: Canal SMS habilitado para o tipo.
        whatsappEnabled:
          type: boolean
          description: Canal WhatsApp habilitado para o tipo.
      required:
        - type
        - label
        - emailEnabled
        - smsEnabled
        - whatsappEnabled
      description: "Preferência de notificação: liga/desliga canais (e-mail, SMS, WhatsApp) por tipo de mensagem da régua. Sem registro salvo, todos os canais ficam ligados."
    NotificationPreferenceListResponse:
      type: object
      properties:
        preferences:
          type: array
          items:
            $ref: "#/components/schemas/NotificationPreference"
      required:
        - preferences
    NotificationPreferenceUpdateRequest:
      type: object
      properties:
        preferences:
          type: array
          items:
            type: object
            properties:
              type:
                type: string
                enum:
                  - reminder
                  - overdue
                  - negotiation
                  - negativation_warning
                  - protest_warning
                  - payment_confirmation
                description: "Tipo de mensagem: `reminder` (lembrete pré-vencimento) | `overdue` (cobrança pós-vencimento) | `negotiation` (proposta de negociação) | `negativation_warning` (aviso de negativação) | `protest_warning` (aviso de protesto) | `payment_confirmation` (confirmação de pagamento)."
                example: reminder
              emailEnabled:
                type: boolean
                description: Canal e-mail habilitado para o tipo.
              smsEnabled:
                type: boolean
                description: Canal SMS habilitado para o tipo.
              whatsappEnabled:
                type: boolean
                description: Canal WhatsApp habilitado para o tipo.
            required:
              - type
              - emailEnabled
              - smsEnabled
              - whatsappEnabled
          minItems: 1
      required:
        - preferences
      description: Preferências a gravar (mínimo 1 tipo).
    NotificationPreferenceUpdateResponse:
      type: object
      properties:
        ok:
          type: boolean
          description: Sempre `true` em caso de sucesso.
          example: true
      required:
        - ok
  parameters: {}
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: "Chave de API no header `Authorization: Bearer <token>`. Crie e gerencie chaves no dashboard (Configurações → Segurança), com escopos opcionais e expiração. Chave sem escopos tem acesso total ao negócio; administração da conta (membros, roles, chaves) nunca é acessível via API."
paths:
  /api/v1/people:
    get:
      tags:
        - Clientes
      summary: Listar clientes
      description: Lista os clientes da organização com paginação e filtros.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            exclusiveMinimum: 0
            description: Página (a partir de 1).
            example: 1
          required: false
          description: Página (a partir de 1).
          name: page
          in: query
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            description: "Itens por página (máx. 100). Alias legado: `limit`."
            example: 20
          required: false
          description: "Itens por página (máx. 100). Alias legado: `limit`."
          name: per_page
          in: query
        - schema:
            type: string
            description: "Campo de ordenação. Alias legado: `sortField`."
            example: createdAt
          required: false
          description: "Campo de ordenação. Alias legado: `sortField`."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          required: false
          description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          name: sort_order
          in: query
        - schema:
            type: string
            description: Busca por nome, documento ou e-mail.
          required: false
          description: Busca por nome, documento ou e-mail.
          name: search
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pela classificação (UUID).
          required: false
          description: Filtra pela classificação (UUID).
          name: classification_id
          in: query
        - schema:
            type: string
            enum:
              - active
              - deleted
            description: Filtra por status do cadastro (`active` | `deleted`).
          required: false
          description: Filtra por status do cadastro (`active` | `deleted`).
          name: status
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Lista paginada de clientes.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PersonListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-people
    post:
      tags:
        - Clientes
      summary: Criar cliente
      description: Cria um cliente na carteira. `externalId` e `documentNumber` são usados para deduplicação em importações e integrações.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PersonCreateRequest"
      responses:
        "201":
          description: Cliente criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Person"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-people
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/people/{id}:
    get:
      tags:
        - Clientes
      summary: Consultar cliente
      description: Retorna um cliente pelo ID.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Cliente encontrado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Person"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-people-id
    put:
      tags:
        - Clientes
      summary: Atualizar cliente
      description: Atualiza os dados de um cliente (parcial).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PersonUpdateRequest"
      responses:
        "200":
          description: Cliente atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Person"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: put-people-id
    delete:
      tags:
        - Clientes
      summary: Excluir cliente
      description: Exclui (soft delete) um cliente. Cobranças e histórico permanecem para trilha de auditoria.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "204":
          description: Cliente excluído.
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-people-id
  /api/v1/people/{id}/statement-pdf:
    get:
      tags:
        - Clientes
      summary: Extrato do devedor (PDF)
      description: "Gera o extrato do devedor em PDF: todas as cobranças da pessoa (documento, vencimento, status, valor original e atual) com os totais em aberto, vencido e já pago. Escopado pela organização. Responde `application/pdf` como anexo binário."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: PDF do extrato do devedor (anexo binário `application/pdf`).
          content:
            application/pdf:
              schema:
                type: string
                format: binary
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-people-id-statement-pdf
  /api/v1/charges:
    get:
      tags:
        - Cobranças
      summary: Listar cobranças
      description: Lista as cobranças da organização com paginação e filtros. Cobranças pendentes vencidas são promovidas a `overdue` na leitura.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            exclusiveMinimum: 0
            description: Página (a partir de 1).
            example: 1
          required: false
          description: Página (a partir de 1).
          name: page
          in: query
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            description: "Itens por página (máx. 100). Alias legado: `limit`."
            example: 20
          required: false
          description: "Itens por página (máx. 100). Alias legado: `limit`."
          name: per_page
          in: query
        - schema:
            type: string
            description: "Campo de ordenação. Alias legado: `sortField`."
            example: createdAt
          required: false
          description: "Campo de ordenação. Alias legado: `sortField`."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          required: false
          description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          name: sort_order
          in: query
        - schema:
            type: string
            description: Busca por número do documento, descrição, `externalId`, nome ou documento do cliente.
          required: false
          description: Busca por número do documento, descrição, `externalId`, nome ou documento do cliente.
          name: search
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelas cobranças de um cliente (UUID).
          required: false
          description: Filtra pelas cobranças de um cliente (UUID).
          name: person_id
          in: query
        - schema:
            type: string
            description: Filtra por status. Aceita um valor ou lista separada por vírgula (`pending`, `paid`, `overdue`, `cancelled`, `negotiated`, `protested`, `negatived`, `written_off`).
            example: pending,overdue
          required: false
          description: Filtra por status. Aceita um valor ou lista separada por vírgula (`pending`, `paid`, `overdue`, `cancelled`, `negotiated`, `protested`, `negatived`, `written_off`).
          name: status
          in: query
        - schema:
            type: string
            description: Vencimento a partir de (inclusive, `YYYY-MM-DD` ou datetime ISO).
            example: 2026-01-01
          required: false
          description: Vencimento a partir de (inclusive, `YYYY-MM-DD` ou datetime ISO).
          name: due_date_from
          in: query
        - schema:
            type: string
            description: Vencimento até (inclusive, `YYYY-MM-DD` ou datetime ISO).
            example: 2026-12-31
          required: false
          description: Vencimento até (inclusive, `YYYY-MM-DD` ou datetime ISO).
          name: due_date_to
          in: query
        - schema:
            type: string
            description: Relações a incluir na resposta (`person`).
            example: person
          required: false
          description: Relações a incluir na resposta (`person`).
          name: include
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Lista paginada de cobranças.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChargeListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-charges
    post:
      tags:
        - Cobranças
      summary: Criar cobrança
      description: Cria uma cobrança para um cliente. Sem `collectionRuleId`, a régua padrão da organização é aplicada. `currentAmount` = original + juros + multa − desconto; cobrança já vencida entra como `overdue`.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ChargeCreateRequest"
      responses:
        "201":
          description: Cobrança criada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Charge"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-charges
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/charges/{id}:
    get:
      tags:
        - Cobranças
      summary: Consultar cobrança
      description: Retorna uma cobrança pelo ID. Use `include=engine` para receber a telemetria do motor (enrollment na régua e execuções de etapa).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - schema:
            type: string
            description: Relações a incluir na resposta (`person`, `engine` — telemetria da régua).
            example: person,engine
          required: false
          description: Relações a incluir na resposta (`person`, `engine` — telemetria da régua).
          name: include
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Cobrança encontrada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Charge"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-charges-id
    put:
      tags:
        - Cobranças
      summary: Atualizar cobrança
      description: Atualiza os dados de uma cobrança (parcial).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ChargeUpdateRequest"
      responses:
        "200":
          description: Cobrança atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Charge"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: put-charges-id
    delete:
      tags:
        - Cobranças
      summary: Excluir cobrança
      description: Exclui (soft delete) uma cobrança e as tarefas e ofertas relacionadas. Cobrança com notificações, interações, negativações ou protestos associados não pode ser excluída (409).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Cobrança excluída (retorna mensagem de confirmação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChargeDeleteResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-charges-id
  /api/v1/charges/{id}/settlement-pdf:
    get:
      tags:
        - Cobranças
      summary: Carta de quitação (PDF)
      description: Gera a carta de quitação da cobrança em PDF (documento jurídico), escopada pela organização. Só é permitida quando a cobrança está paga (status `paid`); caso contrário retorna 409 (`CHARGE_NOT_SETTLED`). Responde `application/pdf` como anexo binário.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: PDF da carta de quitação (anexo binário `application/pdf`).
          content:
            application/pdf:
              schema:
                type: string
                format: binary
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Cobrança não está quitada — a carta só pode ser gerada para status `paid` (código `CHARGE_NOT_SETTLED`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-charges-id-settlement-pdf
  /api/v1/charges/{id}/notify:
    post:
      tags:
        - Cobranças
      summary: Notificar cobrança
      description: Cria uma notificação manual para a cobrança e a envia para a fila de processamento. Atualiza `lastNotificationAt` e, quando `collectionRuleStepId` é informado, o `currentStep` da cobrança.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ChargeNotifyRequest"
      responses:
        "201":
          description: Notificação criada e enfileirada (status `queued`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChargeNotifyResponse"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-charges-id-notify
  /api/v1/agreements:
    get:
      tags:
        - Acordos
      summary: Listar acordos
      description: Lista os acordos da organização com paginação e filtros.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            exclusiveMinimum: 0
            description: Página (a partir de 1).
            example: 1
          required: false
          description: Página (a partir de 1).
          name: page
          in: query
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            description: "Itens por página (máx. 100). Alias legado: `limit`."
            example: 20
          required: false
          description: "Itens por página (máx. 100). Alias legado: `limit`."
          name: per_page
          in: query
        - schema:
            type: string
            description: "Campo de ordenação. Alias legado: `sortField`."
            example: createdAt
          required: false
          description: "Campo de ordenação. Alias legado: `sortField`."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          required: false
          description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - proposed
              - accepted
              - active
              - completed
              - cancelled
              - defaulted
            description: Filtra por status do acordo.
          required: false
          description: Filtra por status do acordo.
          name: status
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelos acordos de um cliente (UUID).
          required: false
          description: Filtra pelos acordos de um cliente (UUID).
          name: person_id
          in: query
        - schema:
            type: string
            description: Relações a incluir na resposta (`person`, `installments`, `negotiationOffer`).
            example: person,installments
          required: false
          description: Relações a incluir na resposta (`person`, `installments`, `negotiationOffer`).
          name: include
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Lista paginada de acordos.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgreementListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-agreements
    post:
      tags:
        - Acordos
      summary: Criar acordo
      description: Cria um acordo com status `proposed`. `finalTotal` = `originalTotal` − `discountAmount` (deve ser maior que zero) e `installmentValue` = `finalTotal` / `numberOfInstallments`.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AgreementCreateRequest"
      responses:
        "201":
          description: Acordo criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Agreement"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-agreements
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/agreements/{id}:
    get:
      tags:
        - Acordos
      summary: Consultar acordo
      description: Retorna um acordo pelo ID (sempre inclui dados resumidos do cliente).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - schema:
            type: string
            description: Relações a incluir na resposta (`installments`, `negotiationOffer`).
            example: installments,negotiationOffer
          required: false
          description: Relações a incluir na resposta (`installments`, `negotiationOffer`).
          name: include
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Acordo encontrado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Agreement"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-agreements-id
    put:
      tags:
        - Acordos
      summary: Atualizar acordo
      description: Atualiza um acordo (parcial). Permitido apenas com status `proposed` ou `accepted` (409 nos demais).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AgreementUpdateRequest"
      responses:
        "200":
          description: Acordo atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Agreement"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: put-agreements-id
    delete:
      tags:
        - Acordos
      summary: Excluir acordo
      description: Exclui (soft delete) um acordo, marcando-o como `cancelled`. Acordos `completed` não podem ser excluídos (409).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "204":
          description: Acordo excluído.
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-agreements-id
  /api/v1/agreements/{id}/accept:
    post:
      tags:
        - Acordos
      summary: Aceitar acordo
      description: "Aceita um acordo `proposed` (409 nos demais status): registra `acceptedAt`/`acceptedIp` e cria as parcelas com vencimentos mensais a partir de `firstDueDate`."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AgreementAcceptRequest"
      responses:
        "200":
          description: Acordo aceito (retorna o acordo com as parcelas criadas).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Agreement"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-agreements-id-accept
  /api/v1/agreements/{id}/cancel:
    post:
      tags:
        - Acordos
      summary: Cancelar acordo
      description: Cancela um acordo, registrando `cancelledAt` e o motivo, e cancela as parcelas pendentes/vencidas. Acordos `completed` ou já cancelados retornam 409.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AgreementCancelRequest"
      responses:
        "200":
          description: Acordo cancelado (retorna o acordo com as parcelas).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Agreement"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-agreements-id-cancel
  /api/v1/agreements/{id}/pdf:
    get:
      tags:
        - Acordos
      summary: Termo de acordo (PDF)
      description: Gera o termo de acordo em PDF (documento jurídico) com credor, devedor, totais e parcelas, escopado pela organização. Responde `application/pdf` como anexo binário.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: PDF do termo de acordo (anexo binário `application/pdf`).
          content:
            application/pdf:
              schema:
                type: string
                format: binary
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-agreements-id-pdf
  /api/v1/agreements/{id}/installments:
    get:
      tags:
        - Acordos
      summary: Listar parcelas do acordo
      description: Lista as parcelas de um acordo (ordenadas por número) com um resumo agregado.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Parcelas do acordo com resumo.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgreementInstallmentListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-agreements-id-installments
    put:
      tags:
        - Acordos
      summary: Atualizar parcela do acordo
      description: Atualiza uma parcela (pagamento/status). Permitido apenas em acordos `accepted` ou `active`; parcelas canceladas não podem ser alteradas (409). Primeiro pagamento ativa o acordo; com todas as parcelas pagas, o acordo é concluído (`completed`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AgreementInstallmentUpdateRequest"
      responses:
        "200":
          description: Parcela atualizada (retorna a parcela e o acordo atualizado).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgreementInstallmentUpdateResponse"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: put-agreements-id-installments
  /api/v1/disputes:
    get:
      tags:
        - Disputas
      summary: Listar disputas
      description: Lista as disputas da organização, ordenadas por abertura (mais recente primeiro). Não aceita ordenação customizada.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            exclusiveMinimum: 0
            description: Página (a partir de 1).
            example: 1
          required: false
          description: Página (a partir de 1).
          name: page
          in: query
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            description: "Itens por página (máx. 100). Alias legado: `limit`."
            example: 20
          required: false
          description: "Itens por página (máx. 100). Alias legado: `limit`."
          name: per_page
          in: query
        - schema:
            type: string
            enum:
              - open
              - under_review
              - resolved_valid
              - resolved_invalid
              - canceled
            description: Filtra por status (`open` | `under_review` | `resolved_valid` | `resolved_invalid` | `canceled`).
          required: false
          description: Filtra por status (`open` | `under_review` | `resolved_valid` | `resolved_invalid` | `canceled`).
          name: status
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pela cobrança (UUID).
          required: false
          description: Filtra pela cobrança (UUID).
          name: charge_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelo cliente (UUID).
          required: false
          description: Filtra pelo cliente (UUID).
          name: person_id
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Lista paginada de disputas.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DisputeListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-disputes
    post:
      tags:
        - Disputas
      summary: Abrir disputa
      description: Abre uma disputa sobre uma cobrança e pausa a régua imediatamente. Se já houver disputa aberta ou em análise para a cobrança, retorna a existente (não duplica). Suporta `Idempotency-Key`.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DisputeCreateRequest"
      responses:
        "201":
          description: Disputa aberta (ou disputa aberta existente da cobrança).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DisputeResponse"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-disputes
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/disputes/{id}:
    get:
      tags:
        - Disputas
      summary: Consultar disputa
      description: Retorna uma disputa pelo ID, com cobrança completa, cliente e responsável.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Disputa encontrada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DisputeDetailResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-disputes-id
    patch:
      tags:
        - Disputas
      summary: Executar ação na disputa
      description: "Executa uma ação de fluxo na disputa: `start_review`, `resolve` ou `cancel`. Transições inválidas (ex.: `start_review` quando o status não é `open`) retornam 409."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DisputeActionRequest"
      responses:
        "200":
          description: Disputa atualizada pela ação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DisputeResponse"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: patch-disputes-id
  /api/v1/tasks:
    get:
      tags:
        - Tarefas
      summary: Listar tarefas
      description: Lista as tarefas da organização com paginação e filtros. Ordenável via `sort_by` (`title` | `priority` | `status` | `dueAt` | `createdAt` | `updatedAt`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            exclusiveMinimum: 0
            description: Página (a partir de 1).
            example: 1
          required: false
          description: Página (a partir de 1).
          name: page
          in: query
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            description: "Itens por página (máx. 100). Alias legado: `limit`."
            example: 20
          required: false
          description: "Itens por página (máx. 100). Alias legado: `limit`."
          name: per_page
          in: query
        - schema:
            type: string
            description: "Campo de ordenação. Alias legado: `sortField`."
            example: createdAt
          required: false
          description: "Campo de ordenação. Alias legado: `sortField`."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          required: false
          description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - pending
              - in_progress
              - completed
              - cancelled
            description: Filtra por status (`pending` | `in_progress` | `completed` | `cancelled`).
          required: false
          description: Filtra por status (`pending` | `in_progress` | `completed` | `cancelled`).
          name: status
          in: query
        - schema:
            type: string
            enum:
              - low
              - medium
              - high
              - urgent
            description: Filtra por prioridade (`low` | `medium` | `high` | `urgent`).
          required: false
          description: Filtra por prioridade (`low` | `medium` | `high` | `urgent`).
          name: priority
          in: query
        - schema:
            type: string
            enum:
              - call
              - email
              - visit
              - review
              - follow_up
            description: Filtra pelo tipo (`call` | `email` | `visit` | `review` | `follow_up`).
          required: false
          description: Filtra pelo tipo (`call` | `email` | `visit` | `review` | `follow_up`).
          name: task_type
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelo responsável (UUID).
          required: false
          description: Filtra pelo responsável (UUID).
          name: assigned_to_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelo cliente (UUID).
          required: false
          description: Filtra pelo cliente (UUID).
          name: person_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pela cobrança (UUID).
          required: false
          description: Filtra pela cobrança (UUID).
          name: charge_id
          in: query
        - schema:
            type: string
            description: Relações a incluir, separadas por vírgula (`person`, `assignedTo`, `charge`).
            example: person,assignedTo,charge
          required: false
          description: Relações a incluir, separadas por vírgula (`person`, `assignedTo`, `charge`).
          name: include
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Lista paginada de tarefas.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TaskListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-tasks
    post:
      tags:
        - Tarefas
      summary: Criar tarefa
      description: Cria uma tarefa, opcionalmente vinculada a um cliente, uma cobrança e um responsável (todos da própria organização). Suporta `Idempotency-Key`.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TaskCreateRequest"
      responses:
        "201":
          description: Tarefa criada (inclui os resumos de cliente, responsável e cobrança).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Task"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-tasks
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/tasks/{id}:
    get:
      tags:
        - Tarefas
      summary: Consultar tarefa
      description: Retorna uma tarefa pelo ID, com resumos de cliente, responsável e cobrança.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Tarefa encontrada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Task"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-tasks-id
    put:
      tags:
        - Tarefas
      summary: Atualizar tarefa
      description: Atualiza os dados de uma tarefa (parcial).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TaskUpdateRequest"
      responses:
        "200":
          description: Tarefa atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Task"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: put-tasks-id
    delete:
      tags:
        - Tarefas
      summary: Excluir tarefa
      description: "Exclui logicamente uma tarefa: o status passa a `cancelled` (o registro permanece)."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "204":
          description: Tarefa cancelada.
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-tasks-id
  /api/v1/tasks/{id}/complete:
    post:
      tags:
        - Tarefas
      summary: Concluir tarefa
      description: Marca a tarefa como concluída e preenche `completedAt`. Retorna 409 se a tarefa já estiver concluída ou cancelada.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Tarefa concluída.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Task"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-tasks-id-complete
  /api/v1/interactions:
    get:
      tags:
        - Interações
      summary: Listar interações
      description: Lista as interações da organização com paginação e filtros. Ordenável via `sort_by` (`contactedAt` | `interactionType` | `createdAt` | `updatedAt`; padrão `contactedAt` desc).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            exclusiveMinimum: 0
            description: Página (a partir de 1).
            example: 1
          required: false
          description: Página (a partir de 1).
          name: page
          in: query
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            description: "Itens por página (máx. 100). Alias legado: `limit`."
            example: 20
          required: false
          description: "Itens por página (máx. 100). Alias legado: `limit`."
          name: per_page
          in: query
        - schema:
            type: string
            description: "Campo de ordenação. Alias legado: `sortField`."
            example: createdAt
          required: false
          description: "Campo de ordenação. Alias legado: `sortField`."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          required: false
          description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - call
              - email
              - whatsapp
              - meeting
              - note
            description: Filtra pelo tipo (`call` | `email` | `whatsapp` | `meeting` | `note`).
          required: false
          description: Filtra pelo tipo (`call` | `email` | `whatsapp` | `meeting` | `note`).
          name: interaction_type
          in: query
        - schema:
            type: string
            enum:
              - inbound
              - outbound
            description: Filtra pela direção (`inbound` | `outbound`).
          required: false
          description: Filtra pela direção (`inbound` | `outbound`).
          name: direction
          in: query
        - schema:
            type: string
            enum:
              - promise_to_pay
              - negotiation
              - dispute
              - no_contact
              - callback_requested
              - payment_confirmed
            description: Filtra pelo desfecho (`promise_to_pay` | `negotiation` | `dispute` | `no_contact` | `callback_requested` | `payment_confirmed`).
          required: false
          description: Filtra pelo desfecho (`promise_to_pay` | `negotiation` | `dispute` | `no_contact` | `callback_requested` | `payment_confirmed`).
          name: outcome
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelo cliente (UUID).
          required: false
          description: Filtra pelo cliente (UUID).
          name: person_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pela cobrança (UUID).
          required: false
          description: Filtra pela cobrança (UUID).
          name: charge_id
          in: query
        - schema:
            type: string
            description: Relações a incluir, separadas por vírgula (`person`, `user`, `charge`).
            example: person,user,charge
          required: false
          description: Relações a incluir, separadas por vírgula (`person`, `user`, `charge`).
          name: include
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Lista paginada de interações.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InteractionListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-interactions
    post:
      tags:
        - Interações
      summary: Registrar interação
      description: Registra uma interação com um cliente, opcionalmente vinculada a uma cobrança. Suporta `Idempotency-Key`.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/InteractionCreateRequest"
      responses:
        "201":
          description: Interação registrada (inclui os resumos de cliente, usuário e cobrança).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Interaction"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-interactions
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/interactions/{id}:
    get:
      tags:
        - Interações
      summary: Consultar interação
      description: Retorna uma interação pelo ID, com resumos de cliente, usuário e cobrança.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Interação encontrada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Interaction"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-interactions-id
    put:
      tags:
        - Interações
      summary: Atualizar interação
      description: Atualiza os campos editáveis de uma interação (parcial).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/InteractionUpdateRequest"
      responses:
        "200":
          description: Interação atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Interaction"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: put-interactions-id
    delete:
      tags:
        - Interações
      summary: Excluir interação
      description: Exclui (soft delete) uma interação; o registro permanece para trilha de auditoria.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "204":
          description: Interação excluída.
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-interactions-id
  /api/v1/notifications:
    get:
      tags:
        - Notificações
      summary: Listar notificações
      description: Lista as notificações da organização com paginação e filtros. Ordenável via `sort_by` (`createdAt` | `updatedAt` | `sentAt` | `deliveredAt` | `channel` | `status`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            exclusiveMinimum: 0
            description: Página (a partir de 1).
            example: 1
          required: false
          description: Página (a partir de 1).
          name: page
          in: query
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            description: "Itens por página (máx. 100). Alias legado: `limit`."
            example: 20
          required: false
          description: "Itens por página (máx. 100). Alias legado: `limit`."
          name: per_page
          in: query
        - schema:
            type: string
            description: "Campo de ordenação. Alias legado: `sortField`."
            example: createdAt
          required: false
          description: "Campo de ordenação. Alias legado: `sortField`."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          required: false
          description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          name: sort_order
          in: query
        - schema:
            type: string
            description: Filtra por canal; aceita valor único ou lista separada por vírgula (`email` | `sms` | `whatsapp` | `voice` | `manual`).
            example: email,whatsapp
          required: false
          description: Filtra por canal; aceita valor único ou lista separada por vírgula (`email` | `sms` | `whatsapp` | `voice` | `manual`).
          name: channel
          in: query
        - schema:
            type: string
            description: Filtra por status; aceita valor único ou lista separada por vírgula (`pending` | `queued` | `sent` | `delivered` | `read` | `failed` | `bounced`).
            example: failed,bounced
          required: false
          description: Filtra por status; aceita valor único ou lista separada por vírgula (`pending` | `queued` | `sent` | `delivered` | `read` | `failed` | `bounced`).
          name: status
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelo cliente (UUID).
          required: false
          description: Filtra pelo cliente (UUID).
          name: person_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pela cobrança (UUID).
          required: false
          description: Filtra pela cobrança (UUID).
          name: charge_id
          in: query
        - schema:
            type: string
            description: Relações a incluir, separadas por vírgula (`person`, `charge`, `step`; `template` equivale a `step`).
            example: person,charge,step
          required: false
          description: Relações a incluir, separadas por vírgula (`person`, `charge`, `step`; `template` equivale a `step`).
          name: include
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Lista paginada de notificações.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NotificationListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-notifications
    post:
      tags:
        - Notificações
      summary: Criar notificação
      description: Cria uma notificação manual para um cliente, opcionalmente vinculada a uma cobrança e a um passo da régua. O destinatário é validado conforme o canal.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NotificationCreateRequest"
      responses:
        "201":
          description: Notificação criada com status `pending`.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Notification"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-notifications
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/notifications/{id}:
    get:
      tags:
        - Notificações
      summary: Consultar notificação
      description: Retorna uma notificação pelo ID; use `include` para anexar relações.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - schema:
            type: string
            description: Relações a incluir, separadas por vírgula (`person`, `charge`, `step`; `template` equivale a `step`).
            example: person,charge,step
          required: false
          description: Relações a incluir, separadas por vírgula (`person`, `charge`, `step`; `template` equivale a `step`).
          name: include
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Notificação encontrada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Notification"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-notifications-id
    put:
      tags:
        - Notificações
      summary: Atualizar notificação
      description: Atualiza status, timestamps de entrega e metadados de uma notificação (parcial). Útil para integrações que confirmam envio/entrega.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NotificationUpdateRequest"
      responses:
        "200":
          description: Notificação atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Notification"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: put-notifications-id
    delete:
      tags:
        - Notificações
      summary: Excluir notificação
      description: Exclui uma notificação DEFINITIVAMENTE (hard delete — o modelo não tem soft delete).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "204":
          description: Notificação excluída.
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-notifications-id
  /api/v1/notifications/{id}/resend:
    post:
      tags:
        - Notificações
      summary: Reenviar notificação
      description: Cria uma NOVA notificação `pending` copiando a original (o `metadata` da nova referencia a original em `resendOf`). Só é permitido quando a original está `failed` ou `bounced`; caso contrário retorna 400. Suporta `Idempotency-Key`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      responses:
        "201":
          description: Nova notificação criada a partir da original.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Notification"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-notifications-id-resend
  /api/v1/collection-rules:
    get:
      tags:
        - Réguas de cobrança
      summary: Listar réguas
      description: Lista as réguas de cobrança da organização, ordenadas por prioridade. `_count.charges` traz o total de cobranças ativas na régua.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            exclusiveMinimum: 0
            description: Página (a partir de 1).
            example: 1
          required: false
          description: Página (a partir de 1).
          name: page
          in: query
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            description: "Itens por página (máx. 100). Alias legado: `limit`."
            example: 20
          required: false
          description: "Itens por página (máx. 100). Alias legado: `limit`."
          name: per_page
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pela classificação associada (UUID).
          required: false
          description: Filtra pela classificação associada (UUID).
          name: classification_id
          in: query
        - schema:
            type: string
            enum:
              - "true"
              - "false"
            description: Filtra pela régua padrão (`true` | `false`).
          required: false
          description: Filtra pela régua padrão (`true` | `false`).
          name: is_default
          in: query
        - schema:
            type: string
            enum:
              - "true"
              - "false"
            description: "Filtra por ativação: `true` = ativas, `false` = inativas."
          required: false
          description: "Filtra por ativação: `true` = ativas, `false` = inativas."
          name: activated_at
          in: query
        - schema:
            type: string
            description: "Relações a embutir, separadas por vírgula. Suportado: `steps`."
            example: steps
          required: false
          description: "Relações a embutir, separadas por vírgula. Suportado: `steps`."
          name: include
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Lista paginada de réguas.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CollectionRuleListResponse"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-collection-rules
    post:
      tags:
        - Réguas de cobrança
      summary: Criar régua
      description: Cria uma régua de cobrança, opcionalmente já com etapas. Marcar `isDefault` desmarca a régua padrão anterior.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CollectionRuleCreateRequest"
      responses:
        "201":
          description: Régua criada (com classificação e etapas).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CollectionRule"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-collection-rules
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/collection-rules/{id}:
    get:
      tags:
        - Réguas de cobrança
      summary: Consultar régua
      description: Retorna uma régua pelo ID. Use `include=steps` para incluir as etapas.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - schema:
            type: string
            description: "Relações a embutir, separadas por vírgula. Suportado: `steps`."
            example: steps
          required: false
          description: "Relações a embutir, separadas por vírgula. Suportado: `steps`."
          name: include
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Régua encontrada (envelope `data`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CollectionRuleShowResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-collection-rules-id
    put:
      tags:
        - Réguas de cobrança
      summary: Atualizar régua
      description: Atualiza os dados da régua (parcial). O array `steps`, quando enviado, faz upsert e exclui as etapas ausentes.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CollectionRuleUpdateRequest"
      responses:
        "200":
          description: Régua atualizada (envelope `data`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CollectionRuleShowResponse"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: put-collection-rules-id
    delete:
      tags:
        - Réguas de cobrança
      summary: Excluir régua
      description: Exclui (soft delete) a régua e suas etapas. Falha com 409 se houver cobranças usando a régua.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "204":
          description: Régua excluída.
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-collection-rules-id
  /api/v1/collection-rules/{id}/steps:
    get:
      tags:
        - Réguas de cobrança
      summary: Listar etapas da régua
      description: Lista as etapas da régua ordenadas por `position`, com o template de mensagem embutido.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Etapas da régua (envelope `data`, sem paginação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CollectionRuleStepListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-collection-rules-id-steps
    post:
      tags:
        - Réguas de cobrança
      summary: Criar etapa
      description: Cria uma etapa na régua. Sem `position`, entra no fim; com `position`, desloca as etapas seguintes.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CollectionRuleStepCreateRequest"
      responses:
        "201":
          description: Etapa criada (com template de mensagem).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CollectionRuleStep"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-collection-rules-id-steps
  /api/v1/collection-rules/{id}/steps/{stepId}:
    put:
      tags:
        - Réguas de cobrança
      summary: Atualizar etapa
      description: Atualiza uma etapa (parcial). Mudar `position` reordena as demais etapas automaticamente.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) da etapa.
          required: true
          description: Identificador (UUID) da etapa.
          name: stepId
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CollectionRuleStepUpdateRequest"
      responses:
        "200":
          description: Etapa atualizada (com template de mensagem).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CollectionRuleStep"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: put-collection-rules-id-steps-stepid
    delete:
      tags:
        - Réguas de cobrança
      summary: Excluir etapa
      description: Exclui (soft delete) uma etapa e reordena as restantes. Falha com 409 se a etapa tiver notificações associadas.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) da etapa.
          required: true
          description: Identificador (UUID) da etapa.
          name: stepId
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "204":
          description: Etapa excluída.
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-collection-rules-id-steps-stepid
  /api/v1/templates:
    get:
      tags:
        - Templates de mensagem
      summary: Listar templates
      description: Lista os templates de mensagem da organização com paginação, busca e filtros.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            exclusiveMinimum: 0
            description: Página (a partir de 1).
            example: 1
          required: false
          description: Página (a partir de 1).
          name: page
          in: query
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            description: "Itens por página (máx. 100). Alias legado: `limit`."
            example: 20
          required: false
          description: "Itens por página (máx. 100). Alias legado: `limit`."
          name: per_page
          in: query
        - schema:
            type: string
            description: Busca por nome, assunto ou corpo.
          required: false
          description: Busca por nome, assunto ou corpo.
          name: search
          in: query
        - schema:
            type: string
            enum:
              - email
              - sms
              - whatsapp
              - voice
              - manual
            description: Filtra pelo canal.
          required: false
          description: Filtra pelo canal.
          name: channel
          in: query
        - schema:
            type: string
            enum:
              - reminder
              - overdue
              - negotiation
              - negativation_warning
              - protest_warning
              - payment_confirmation
            description: Filtra pela categoria.
          required: false
          description: Filtra pela categoria.
          name: category
          in: query
        - schema:
            type: string
            enum:
              - friendly
              - neutral
              - firm
              - urgent
            description: Filtra pelo tom.
          required: false
          description: Filtra pelo tom.
          name: tone
          in: query
        - schema:
            type: string
            enum:
              - "true"
              - "false"
            description: "Filtra por ativação: `true` = ativos, `false` = inativos."
          required: false
          description: "Filtra por ativação: `true` = ativos, `false` = inativos."
          name: is_active
          in: query
        - schema:
            type: string
            enum:
              - name
              - channel
              - category
              - createdAt
              - updatedAt
            description: "Campo de ordenação. Alias legado: `sortField`."
            example: createdAt
          required: false
          description: "Campo de ordenação. Alias legado: `sortField`."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          required: false
          description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          name: sort_order
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Lista paginada de templates.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessageTemplateListResponse"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-templates
    post:
      tags:
        - Templates de mensagem
      summary: Criar template
      description: Cria um template de mensagem. Falha com 409 se já existir template com o mesmo `name` ou `externalId`.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MessageTemplateCreateRequest"
      responses:
        "201":
          description: Template criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessageTemplate"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-templates
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/templates/{id}:
    get:
      tags:
        - Templates de mensagem
      summary: Consultar template
      description: Retorna um template pelo ID.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Template encontrado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessageTemplate"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-templates-id
    put:
      tags:
        - Templates de mensagem
      summary: Atualizar template
      description: Atualiza um template (parcial). Falha com 409 se o novo `name` ou `externalId` já estiver em uso.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MessageTemplateUpdateRequest"
      responses:
        "200":
          description: Template atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessageTemplate"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: put-templates-id
    delete:
      tags:
        - Templates de mensagem
      summary: Excluir template
      description: Exclui (soft delete) um template. Falha com 409 se ele estiver em uso por etapas de régua.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "204":
          description: Template excluído.
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-templates-id
  /api/v1/templates/{id}/duplicate:
    post:
      tags:
        - Templates de mensagem
      summary: Duplicar template
      description: Cria uma cópia do template com o nome informado. A cópia nasce inativa (`activatedAt` null) e sem `externalId`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MessageTemplateDuplicateRequest"
      responses:
        "201":
          description: Template duplicado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessageTemplate"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-templates-id-duplicate
  /api/v1/classifications:
    get:
      tags:
        - Classificações
      summary: Listar classificações
      description: Lista as classificações da organização, por padrão ordenadas por `priority` e `name`. Use `include=_count` para os contadores.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            exclusiveMinimum: 0
            description: Página (a partir de 1).
            example: 1
          required: false
          description: Página (a partir de 1).
          name: page
          in: query
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            description: "Itens por página (máx. 100). Alias legado: `limit`."
            example: 20
          required: false
          description: "Itens por página (máx. 100). Alias legado: `limit`."
          name: per_page
          in: query
        - schema:
            type: string
            enum:
              - "true"
              - "false"
            description: Filtra pela classificação padrão (`true` | `false`).
          required: false
          description: Filtra pela classificação padrão (`true` | `false`).
          name: is_default
          in: query
        - schema:
            type: string
            enum:
              - "true"
              - "false"
            description: Filtra por atribuição automática (`true` | `false`).
          required: false
          description: Filtra por atribuição automática (`true` | `false`).
          name: auto_assign
          in: query
        - schema:
            type: string
            enum:
              - "true"
              - "false"
              - "null"
            description: "Filtra por ativação: `true` = ativas, `false` ou `null` = inativas."
          required: false
          description: "Filtra por ativação: `true` = ativas, `false` ou `null` = inativas."
          name: activated_at
          in: query
        - schema:
            type: string
            description: "Relações a embutir. Suportado: `_count` (clientes e réguas)."
            example: _count
          required: false
          description: "Relações a embutir. Suportado: `_count` (clientes e réguas)."
          name: include
          in: query
        - schema:
            type: string
            enum:
              - name
              - code
              - priority
              - createdAt
              - updatedAt
            description: Campo de ordenação (`name` | `code` | `priority` | `createdAt` | `updatedAt`).
          required: false
          description: Campo de ordenação (`name` | `code` | `priority` | `createdAt` | `updatedAt`).
          name: sort
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: Direção da ordenação (`asc` | `desc`).
          required: false
          description: Direção da ordenação (`asc` | `desc`).
          name: order
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Lista paginada de classificações.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ClassificationListResponse"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-classifications
    post:
      tags:
        - Classificações
      summary: Criar classificação
      description: Cria uma classificação. Marcar `isDefault` desmarca a padrão anterior; `code` duplicado falha com 409.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ClassificationCreateRequest"
      responses:
        "201":
          description: Classificação criada (com contadores).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Classification"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-classifications
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/classifications/{id}:
    get:
      tags:
        - Classificações
      summary: Consultar classificação
      description: Retorna uma classificação pelo ID. Use `include=_count` para os contadores.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - schema:
            type: string
            description: "Relações a embutir. Suportado: `_count` (clientes e réguas)."
            example: _count
          required: false
          description: "Relações a embutir. Suportado: `_count` (clientes e réguas)."
          name: include
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Classificação encontrada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Classification"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-classifications-id
    put:
      tags:
        - Classificações
      summary: Atualizar classificação
      description: Atualiza uma classificação (parcial). `code` duplicado falha com 409.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ClassificationUpdateRequest"
      responses:
        "200":
          description: Classificação atualizada (com contadores).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Classification"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: put-classifications-id
    delete:
      tags:
        - Classificações
      summary: Excluir classificação
      description: Exclui (soft delete) uma classificação. Falha com 409 se houver clientes ou réguas associados. O `code` continua reservado.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "204":
          description: Classificação excluída.
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-classifications-id
  /api/v1/negotiation-campaigns:
    get:
      tags:
        - Campanhas de negociação
      summary: Listar campanhas
      description: Lista as campanhas de negociação da organização (ativas e encerradas), da mais recente para a mais antiga. Sem paginação.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Campanhas da organização (envelope `campaigns`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NegotiationCampaignListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-negotiation-campaigns
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
    post:
      tags:
        - Campanhas de negociação
      summary: Criar campanha
      description: Cria e ativa uma campanha de desconto. O portal do devedor passa a oferecê-la às cobranças na faixa de atraso configurada.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NegotiationCampaignCreateRequest"
      responses:
        "201":
          description: Campanha criada e ativada (envelope `campaign`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NegotiationCampaignCreateResponse"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-negotiation-campaigns
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/negotiation-campaigns/{id}:
    delete:
      tags:
        - Campanhas de negociação
      summary: Encerrar campanha
      description: Encerra a campanha (desativa; `activatedAt` vira null). O registro é mantido e o portal deixa de oferecê-la.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "204":
          description: Campanha encerrada.
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-negotiation-campaigns-id
  /api/v1/negativations:
    get:
      tags:
        - Negativações
      summary: Listar negativações
      description: Lista as negativações da organização com paginação e filtros. Use `include=person,charge` para embutir os resumos de cliente e cobrança.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            exclusiveMinimum: 0
            description: Página (a partir de 1).
            example: 1
          required: false
          description: Página (a partir de 1).
          name: page
          in: query
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            description: "Itens por página (máx. 100). Alias legado: `limit`."
            example: 20
          required: false
          description: "Itens por página (máx. 100). Alias legado: `limit`."
          name: per_page
          in: query
        - schema:
            type: string
            enum:
              - createdAt
              - updatedAt
              - amount
              - registeredAt
            description: "Campo de ordenação (`createdAt` | `updatedAt` | `amount` | `registeredAt`). Alias legado: `sortField`."
            example: createdAt
          required: false
          description: "Campo de ordenação (`createdAt` | `updatedAt` | `amount` | `registeredAt`). Alias legado: `sortField`."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          required: false
          description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - pending
              - active
              - removed
              - failed
            description: Filtra por status (`pending` | `active` | `removed` | `failed`).
          required: false
          description: Filtra por status (`pending` | `active` | `removed` | `failed`).
          name: status
          in: query
        - schema:
            type: string
            enum:
              - serasa
              - spc
              - boa_vista
            description: Filtra pelo birô de crédito (`serasa` | `spc` | `boa_vista`).
          required: false
          description: Filtra pelo birô de crédito (`serasa` | `spc` | `boa_vista`).
          name: bureau
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelo cliente (UUID).
          required: false
          description: Filtra pelo cliente (UUID).
          name: person_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pela cobrança (UUID).
          required: false
          description: Filtra pela cobrança (UUID).
          name: charge_id
          in: query
        - schema:
            type: string
            description: Relações a embutir, separadas por vírgula (`person`, `charge`).
            example: person,charge
          required: false
          description: Relações a embutir, separadas por vírgula (`person`, `charge`).
          name: include
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Lista paginada de negativações.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NegativationListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-negativations
    post:
      tags:
        - Negativações
      summary: Criar negativação
      description: Registra uma negativação para uma cobrança. O registro nasce `pending` e SÓ é enviado ao birô após revisão e aprovação humana (workflow jurídico; evento `negativation.review_required`). Retorna 409 se já existir negativação `pending`/`active` para a mesma cobrança no mesmo birô.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NegativationCreateRequest"
      responses:
        "201":
          description: Negativação criada (aguardando revisão humana).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Negativation"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-negativations
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/negativations/{id}:
    get:
      tags:
        - Negativações
      summary: Consultar negativação
      description: Retorna uma negativação pelo ID, com os resumos de cliente e cobrança.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Negativação encontrada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Negativation"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-negativations-id
    put:
      tags:
        - Negativações
      summary: Atualizar negativação
      description: "Atualiza uma negativação (parcial). É a etapa de aprovação do workflow jurídico: exige permissão de revisão (`approve`) e é onde o status sai de `pending` para `active` após a revisão humana."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NegativationUpdateRequest"
      responses:
        "200":
          description: Negativação atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Negativation"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: put-negativations-id
    delete:
      tags:
        - Negativações
      summary: Excluir negativação
      description: "Baixa lógica: marca a negativação como `removed` e grava `removedAt`. O registro permanece para trilha de auditoria."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "204":
          description: Negativação removida.
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-negativations-id
  /api/v1/negativations/{id}/remove:
    post:
      tags:
        - Negativações
      summary: Solicitar baixa da negativação
      description: Solicita a baixa de uma negativação no birô. Só é permitido para registros `active`; o status vira `removed` e o motivo (se enviado) fica em `removalReason`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NegativationRemoveRequest"
      responses:
        "200":
          description: Baixa registrada; negativação atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Negativation"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-negativations-id-remove
  /api/v1/protests:
    get:
      tags:
        - Protestos
      summary: Listar protestos
      description: Lista os protestos da organização com paginação e filtros. Use `include=person,charge` para embutir os resumos de cliente e cobrança.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            exclusiveMinimum: 0
            description: Página (a partir de 1).
            example: 1
          required: false
          description: Página (a partir de 1).
          name: page
          in: query
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            description: "Itens por página (máx. 100). Alias legado: `limit`."
            example: 20
          required: false
          description: "Itens por página (máx. 100). Alias legado: `limit`."
          name: per_page
          in: query
        - schema:
            type: string
            enum:
              - createdAt
              - updatedAt
              - amount
              - protestDate
              - sentAt
            description: "Campo de ordenação (`createdAt` | `updatedAt` | `amount` | `protestDate` | `sentAt`). Alias legado: `sortField`."
            example: createdAt
          required: false
          description: "Campo de ordenação (`createdAt` | `updatedAt` | `amount` | `protestDate` | `sentAt`). Alias legado: `sortField`."
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          required: false
          description: "Direção da ordenação (`asc` | `desc`). Alias legado: `sortDirection`."
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - pending
              - sent
              - intimated
              - protested
              - paid
              - cancelled
            description: Filtra por status (`pending` | `sent` | `intimated` | `protested` | `paid` | `cancelled`).
          required: false
          description: Filtra por status (`pending` | `sent` | `intimated` | `protested` | `paid` | `cancelled`).
          name: status
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelo cliente (UUID).
          required: false
          description: Filtra pelo cliente (UUID).
          name: person_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pela cobrança (UUID).
          required: false
          description: Filtra pela cobrança (UUID).
          name: charge_id
          in: query
        - schema:
            type: string
            description: Relações a embutir, separadas por vírgula (`person`, `charge`).
            example: person,charge
          required: false
          description: Relações a embutir, separadas por vírgula (`person`, `charge`).
          name: include
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Lista paginada de protestos.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProtestListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-protests
    post:
      tags:
        - Protestos
      summary: Criar protesto
      description: Registra um protesto para uma cobrança. O registro nasce `pending` e SÓ é enviado ao cartório após revisão e aprovação humana (workflow jurídico; evento `protest.review_required`). Retorna 409 se já existir protesto ativo (`pending`/`sent`/`intimated`/`protested`) para a mesma cobrança.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProtestCreateRequest"
      responses:
        "201":
          description: Protesto criado (aguardando revisão humana).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Protest"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-protests
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/protests/{id}:
    get:
      tags:
        - Protestos
      summary: Consultar protesto
      description: Retorna um protesto pelo ID, com os resumos de cliente e cobrança.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Protesto encontrado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Protest"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-protests-id
    put:
      tags:
        - Protestos
      summary: Atualizar protesto
      description: "Atualiza um protesto (parcial). É a etapa de aprovação do workflow jurídico: exige permissão de revisão (`approve`) e é onde o status avança de `pending` para `sent`/`intimated`/`protested` após a revisão humana."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProtestUpdateRequest"
      responses:
        "200":
          description: Protesto atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Protest"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: put-protests-id
    delete:
      tags:
        - Protestos
      summary: Excluir protesto
      description: "Baixa lógica: marca o protesto como `cancelled` e grava `cancellationDate`. O registro permanece para trilha de auditoria."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "204":
          description: Protesto cancelado.
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-protests-id
  /api/v1/protests/{id}/cancel:
    post:
      tags:
        - Protestos
      summary: Solicitar cancelamento do protesto
      description: Solicita o cancelamento de um protesto. Não é permitido para protestos já `cancelled` nem `paid`; o status vira `cancelled` e o motivo (se enviado) fica em `responseData.cancellationReason`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProtestCancelRequest"
      responses:
        "200":
          description: Cancelamento registrado; protesto atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Protest"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-protests-id-cancel
  /api/v1/imports:
    get:
      tags:
        - Importações
      summary: Listar importações
      description: Histórico das 50 importações mais recentes da organização (sem paginação). O conteúdo do arquivo e os erros por linha ficam de fora; consulte GET /imports/{id} para o detalhe.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Lista das importações mais recentes.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ImportListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-imports
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
    post:
      tags:
        - Importações
      summary: Criar importação
      description: "Sobe uma planilha CSV de clientes ou cobranças e agenda o processamento assíncrono (fila). O corpo é JSON com o CSV em texto puro no campo `content` (máx. 2 MB). Linhas inválidas não derrubam o lote: são registradas em `errors` (`[{ line, error }]`) e o restante é processado. Acompanhe pelo GET /imports/{id}. Responde 202."
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ImportCreateRequest"
      responses:
        "202":
          description: Importação aceita e enfileirada para processamento.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ImportCreatedResponse"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "413":
          description: Arquivo acima de 2 MB — divida a planilha em partes menores.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-imports
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/imports/{id}:
    get:
      tags:
        - Importações
      summary: Consultar importação
      description: "Retorna o status de uma importação com contadores de progresso e os erros por linha rejeitada (`errors: [{ line, error }]`; a linha 1 é o cabeçalho, os dados começam na linha 2)."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Importação encontrada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ImportShowResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-imports-id
  /api/v1/exports/people:
    get:
      tags:
        - Exportações
      summary: Exportar clientes (CSV síncrono)
      description: "Gera e responde na hora o CSV de clientes (`text/csv; charset=utf-8` com BOM, `Content-Disposition: attachment`). Colunas: nome, documento, tipo_documento, email, telefone, classificacao, external_id, tags, criado_em. Teto de 10 mil linhas; acima disso use a exportação assíncrona (POST /exports/jobs)."
      security:
        - bearerAuth: []
      responses:
        "200":
          description: "Arquivo CSV (`text/csv; charset=utf-8` com BOM para o Excel abrir acentos corretamente; `Content-Disposition: attachment`)."
          content:
            text/csv:
              schema:
                type: string
                description: Conteúdo do arquivo CSV.
                example: |-
                  nome,documento,email
                  Maria da Silva,12345678901,maria@example.com
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-exports-people
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
  /api/v1/exports/charges:
    get:
      tags:
        - Exportações
      summary: Exportar cobranças (CSV síncrono)
      description: "Gera e responde na hora o CSV de cobranças (`text/csv; charset=utf-8` com BOM, `Content-Disposition: attachment`), com filtros opcionais de status e período de vencimento. Colunas: cliente, documento_cliente, numero_documento, descricao, valor_original, valor_atual, vencimento, dias_atraso, status, origem, external_id. Teto de 10 mil linhas; acima disso use a exportação assíncrona (POST /exports/jobs)."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            description: "Filtra as cobranças pelo status (ex.: `pending`, `overdue`, `paid`)."
            example: overdue
          required: false
          description: "Filtra as cobranças pelo status (ex.: `pending`, `overdue`, `paid`)."
          name: status
          in: query
        - schema:
            type: string
            format: date
            description: Vencimento a partir de (data ISO `YYYY-MM-DD`).
            example: 2026-01-01
          required: false
          description: Vencimento a partir de (data ISO `YYYY-MM-DD`).
          name: from
          in: query
        - schema:
            type: string
            format: date
            description: Vencimento até (data ISO `YYYY-MM-DD`).
            example: 2026-06-30
          required: false
          description: Vencimento até (data ISO `YYYY-MM-DD`).
          name: to
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: "Arquivo CSV (`text/csv; charset=utf-8` com BOM para o Excel abrir acentos corretamente; `Content-Disposition: attachment`)."
          content:
            text/csv:
              schema:
                type: string
                description: Conteúdo do arquivo CSV.
                example: |-
                  nome,documento,email
                  Maria da Silva,12345678901,maria@example.com
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-exports-charges
  /api/v1/exports/jobs:
    get:
      tags:
        - Exportações
      summary: Listar exportações assíncronas
      description: Histórico das 50 exportações assíncronas mais recentes da organização (sem paginação). Use esta rota para acompanhar o status dos jobs; o CSV em si não vem na listagem.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Lista das exportações mais recentes.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExportJobListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-exports-jobs
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
    post:
      tags:
        - Exportações
      summary: Criar exportação assíncrona
      description: Agenda a geração do CSV num worker, sem o teto de 10 mil linhas do modo síncrono e sem travar a request. Acompanhe o status em GET /exports/jobs e baixe o arquivo em GET /exports/jobs/{id}/download antes de `expiresAt`. Responde 202.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ExportJobCreateRequest"
      responses:
        "202":
          description: Exportação aceita e enfileirada para processamento.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExportJobCreatedResponse"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-exports-jobs
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/exports/jobs/{id}/download:
    get:
      tags:
        - Exportações
      summary: Baixar CSV da exportação
      description: Serve o CSV já gerado de uma exportação assíncrona (`text/csv; charset=utf-8` com BOM). Só entrega se o job estiver `completed` e dentro da validade (`expiresAt`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: "Arquivo CSV (`text/csv; charset=utf-8` com BOM para o Excel abrir acentos corretamente; `Content-Disposition: attachment`)."
          content:
            text/csv:
              schema:
                type: string
                description: Conteúdo do arquivo CSV.
                example: |-
                  nome,documento,email
                  Maria da Silva,12345678901,maria@example.com
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Exportação ainda não concluída (código `NOT_READY`; o campo `status` informa o estado atual).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "410":
          description: Exportação expirada — gere uma nova (código `EXPIRED`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-exports-jobs-id-download
  /api/v1/webhook-endpoints:
    get:
      tags:
        - Webhooks
      summary: Listar endpoints de webhook
      description: Lista os endpoints de webhook da organização com contadores de entrega por status. `secret` e `authConfig` nunca aparecem na listagem.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Lista de endpoints.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookEndpointListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-webhook-endpoints
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
    post:
      tags:
        - Webhooks
      summary: Criar endpoint de webhook
      description: Cria um endpoint de webhook. A URL exige HTTPS e é validada contra endereços internos (SSRF). O `secret` é retornado apenas nesta resposta — guarde com segurança.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WebhookEndpointCreateRequest"
      responses:
        "201":
          description: Endpoint criado (inclui `secret` — única exibição).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookEndpointCreateResponse"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-webhook-endpoints
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/webhook-endpoints/{id}:
    get:
      tags:
        - Webhooks
      summary: Consultar endpoint de webhook
      description: Retorna o endpoint com as últimas 20 entregas. O `secret` nunca é retornado.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Endpoint com entregas recentes.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookEndpointShowResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-webhook-endpoints-id
    patch:
      tags:
        - Webhooks
      summary: Atualizar endpoint de webhook
      description: Atualiza o endpoint (parcial). A URL, se enviada, é revalidada (HTTPS + SSRF); `authConfig` é cifrado e nunca retornado.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WebhookEndpointUpdateRequest"
      responses:
        "200":
          description: Endpoint atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookEndpointUpdateResponse"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: patch-webhook-endpoints-id
    delete:
      tags:
        - Webhooks
      summary: Excluir endpoint de webhook
      description: Exclui (soft delete) o endpoint; entregas pendentes deixam de ser processadas.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "204":
          description: Endpoint excluído.
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: delete-webhook-endpoints-id
  /api/v1/webhook-endpoints/{id}/rotate-secret:
    post:
      tags:
        - Webhooks
      summary: Rotacionar secret
      description: Gera um novo secret HMAC; o anterior deixa de validar imediatamente. O novo secret é retornado apenas nesta resposta — guarde com segurança.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Novo secret (única exibição).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookEndpointRotateSecretResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-webhook-endpoints-id-rotate-secret
  /api/v1/webhook-endpoints/{id}/test:
    post:
      tags:
        - Webhooks
      summary: Disparar evento de teste
      description: Entrega um evento `webhook.test` REAL ao endpoint, pelo mesmo pipeline dos eventos de negócio (fila, assinatura HMAC, captura de request/response, retry) — valide seu consumidor fim a fim sem esperar um evento real. Entregue somente ao endpoint alvo, independente da lista de eventos assinados. Falha com 409 se o endpoint estiver inativo.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      responses:
        "202":
          description: Evento de teste enfileirado para entrega.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookEndpointTestResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-webhook-endpoints-id-test
  /api/v1/webhook-endpoints/{id}/deliveries:
    get:
      tags:
        - Webhooks
      summary: Listar entregas do endpoint
      description: Lista as entregas do endpoint (paginado, mais recentes primeiro) com a captura de request/response para inspeção e debug.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - schema:
            type: integer
            exclusiveMinimum: 0
            description: Página (a partir de 1).
            example: 1
          required: false
          description: Página (a partir de 1).
          name: page
          in: query
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            description: "Itens por página (máx. 100). Alias legado: `limit`."
            example: 20
          required: false
          description: "Itens por página (máx. 100). Alias legado: `limit`."
          name: per_page
          in: query
        - schema:
            type: string
            enum:
              - pending
              - success
              - failed
              - exhausted
            description: Filtra pelo status da entrega.
          required: false
          description: Filtra pelo status da entrega.
          name: status
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Lista paginada de entregas.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookDeliveryListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-webhook-endpoints-id-deliveries
  /api/v1/webhook-endpoints/{id}/deliveries/{deliveryId}/retry:
    post:
      tags:
        - Webhooks
      summary: Reenviar entrega
      description: Re-enfileira uma entrega para nova tentativa imediata (status volta a `pending`). Falha com 409 se o endpoint estiver inativo ou removido.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) do recurso.
          required: true
          description: Identificador (UUID) do recurso.
          name: id
          in: path
        - schema:
            type: string
            format: uuid
            description: Identificador (UUID) da entrega.
          required: true
          description: Identificador (UUID) da entrega.
          name: deliveryId
          in: path
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Entrega re-enfileirada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookDeliveryRetryResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "409":
          description: Conflito com o estado atual do recurso (ou chave de idempotência reusada).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-webhook-endpoints-id-deliveries-deliveryid-retry
  /api/v1/audit-logs:
    get:
      tags:
        - Trilha de auditoria
      summary: Consultar trilha de auditoria
      description: Lista os registros da trilha de auditoria da organização (mais recentes primeiro), com filtros por ação, entidade, ator e período.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            exclusiveMinimum: 0
            description: Página (a partir de 1).
            example: 1
          required: false
          description: Página (a partir de 1).
          name: page
          in: query
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            description: "Itens por página (máx. 100). Alias legado: `limit`."
            example: 20
          required: false
          description: "Itens por página (máx. 100). Alias legado: `limit`."
          name: per_page
          in: query
        - schema:
            type: string
            description: Filtra por ação (busca parcial, `contains`).
          required: false
          description: Filtra por ação (busca parcial, `contains`).
          name: action
          in: query
        - schema:
            type: string
            description: Filtra pelo tipo de entidade.
          required: false
          description: Filtra pelo tipo de entidade.
          name: entity_type
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pela entidade (UUID).
          required: false
          description: Filtra pela entidade (UUID).
          name: entity_id
          in: query
        - schema:
            type: string
            enum:
              - user
              - system
              - job
            description: Filtra pelo tipo de ator (`user` | `system` | `job`).
          required: false
          description: Filtra pelo tipo de ator (`user` | `system` | `job`).
          name: actor_type
          in: query
        - schema:
            type: string
            description: Filtra pelo ator (ID do usuário, nome do job ou do sistema).
          required: false
          description: Filtra pelo ator (ID do usuário, nome do job ou do sistema).
          name: actor_id
          in: query
        - schema:
            type: string
            format: date-time
            description: Início do período (ISO 8601, inclusive).
          required: false
          description: Início do período (ISO 8601, inclusive).
          name: from
          in: query
        - schema:
            type: string
            format: date-time
            description: Fim do período (ISO 8601, inclusive).
          required: false
          description: Fim do período (ISO 8601, inclusive).
          name: to
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Lista paginada de registros de auditoria.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuditLogListResponse"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-audit-logs
  /api/v1/metrics/recovery:
    get:
      tags:
        - Métricas
      summary: Métricas de recuperação
      description: "Retorna as métricas de recuperação do período (padrão: últimos 6 meses, contados a partir do primeiro dia do mês inicial)."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            maximum: 24
            description: Janela em meses (1–24; padrão 6).
            example: 6
          required: false
          description: Janela em meses (1–24; padrão 6).
          name: months
          in: query
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
      responses:
        "200":
          description: Métricas calculadas.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RecoveryMetrics"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-metrics-recovery
  /api/v1/email-layouts:
    get:
      tags:
        - Layouts de e-mail
      summary: Listar layouts de e-mail
      description: Lista os layouts de e-mail da organização (padrão primeiro) e o layout embutido de referência.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Lista de layouts.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EmailLayoutListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-email-layouts
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
    post:
      tags:
        - Layouts de e-mail
      summary: Criar layout de e-mail
      description: "Cria um layout de e-mail. O `htmlBody` deve conter o placeholder `{{content}}` (senão, 400 `MISSING_CONTENT_PLACEHOLDER`). `isDefault: true` desmarca o padrão anterior."
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EmailLayoutCreateRequest"
      responses:
        "201":
          description: Layout criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EmailLayoutCreateResponse"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: post-email-layouts
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
  /api/v1/notification-preferences:
    get:
      tags:
        - Preferências de notificação
      summary: Consultar preferências de notificação
      description: Retorna o gate efetivo por tipo de mensagem — tipos sem registro salvo aparecem com todos os canais ligados.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Preferências efetivas por tipo.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NotificationPreferenceListResponse"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: get-notification-preferences
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
    put:
      tags:
        - Preferências de notificação
      summary: Atualizar preferências de notificação
      description: "Faz upsert das preferências enviadas (parcial: só os tipos incluídos são alterados)."
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NotificationPreferenceUpdateRequest"
      responses:
        "200":
          description: Preferências gravadas.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NotificationPreferenceUpdateResponse"
        "400":
          description: Requisição inválida (erro de validação).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Chave de API ausente, inválida, expirada ou revogada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: A chave não tem o escopo exigido pela operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          description: Recurso inexistente ou fora da sua organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Limite de requisições excedido. Aguarde e tente novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "500":
          description: Erro interno. Tente novamente; persistindo, contate o suporte.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      operationId: put-notification-preferences
      parameters:
        - name: User-Agent
          in: header
          required: true
          description: "Identificação do integrador. Inclua nome e e-mail de contato — ex.: `Kevin Mitnick <kmitnick@kobana.com.br>`. Usado para suporte e auditoria."
          schema:
            type: string
            example: Kevin Mitnick <kmitnick@kobana.com.br>
          example: Kevin Mitnick <kmitnick@kobana.com.br>
        - name: X-Idempotency-Key
          in: header
          required: false
          description: "Chave única (UUID v4 recomendado) para reexecutar a mesma requisição sem efeitos colaterais. Requisições com a mesma chave em 24h retornam o resultado original (header `X-Idempotent-Replay: true`)."
          schema:
            type: string
            format: uuid
webhooks: {}
