openapi: 3.1.0
info:
  title: API do Faturamento Automático
  version: 1.0.0
  description: |-
    Você que é dev, divirta-se! ✨

    > **Índice da documentação** — acesse o índice completo em [https://docs.billing.kobana.com.br/llms.txt](https://docs.billing.kobana.com.br/llms.txt). Use este arquivo para descobrir todas as páginas disponíveis antes de explorar.

    > **Atenção às versões da API** — você está na documentação da **v1.0** da API do Faturamento Automático, que cobre os endpoints de **Assinaturas** (criação, alteração de plano, pausa, cancelamento, faturamento manual, sincronização de itens) e recursos correlatos. Recursos como **Pagamentos, Transferências, Extrato e Recebimento por Pix** seguem disponíveis em outras APIs da Kobana — use o seletor de produto no menu superior para acessá-las.

    ## Formato

    A API aceita apenas o formato `JSON`. Todas as requisições devem usar `Content-Type: application/json`. Todas as respostas usam `snake_case`.

    | Tipo de Campo | Formato |
    | :--- | :--- |
    | **DateTime** | Formato [ISO8601](https://pt.wikipedia.org/wiki/ISO_8601). Exemplos — Data: `2026-01-24`. Data e Hora: `2026-01-24T10:07Z` |
    | **Money (`_cents`)** | Inteiro em centavos (÷100). Ex.: `10000` = R$ 100,00 |
    | **Money (`_subcents`)** | Inteiro em subcentavos (÷10000), usado em precificação. Ex.: `1000000` = R$ 100,00 |
    | **UUID** | Identificadores de recursos no formato UUID v4 |

    ## Convenções

    Convenções usadas nesta documentação:

    | Convenção | Descrição |
    | :--- | :--- |
    | **`:variable`** | Nome de variável que precisa ser substituída em uma URL. |
    | **`#{variable}`** | Nome de variável que precisa ser substituída por valores da sua conta. |
    | **`...`** | Conteúdo da resposta truncado para facilitar a leitura. |
    | **`$KOBANA_TOKEN`** | Token de acesso. Para testes em linha de comando, exporte-o: `export KOBANA_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxx` e cole os comandos da documentação no terminal. |

    ## Códigos de Retorno

    A API retorna códigos HTTP padrão:

    | | Código | Descrição |
    | :--- | :--- | :--- |
    | ✅ | **200 OK** | Requisição bem-sucedida com corpo de resposta. |
    | ✅ | **201 Created** | Recurso criado com sucesso. |
    | ✅ | **204 No Content** | Requisição bem-sucedida, sem corpo de resposta. |
    | ❌ | **400 Bad Request** | Requisição inválida, em geral conteúdo mal formado. |
    | ❌ | **401 Unauthorized** | Token de acesso ausente ou inválido. |
    | ❌ | **403 Forbidden** | Acesso à API bloqueado ou usuário sem permissão. |
    | ❌ | **404 Not Found** | Endereço acessado não existe. |
    | ❌ | **422 Unprocessable Entity** | Requisição válida, mas os dados enviados não são. |
    | ❌ | **429 Too Many Requests** | Limite de requisições atingido. |
    | ❌ | **500 Internal Server Error** | Erro interno no processamento. Consulte o [status dos servidores](https://status.kobana.com.br). |

    ## ID das Requisições (Request ID)

    Cada requisição possui um identificador associado, disponível no cabeçalho `Request-Id` da resposta. Esse valor ajuda na depuração e auditoria — as requisições e seus IDs podem ser consultadas no painel do sistema. O log de requisições fica disponível por **30 dias**. Ao abrir um chamado de suporte sobre uma requisição específica, informe o `Request-Id` para acelerar a investigação.

    ## Segurança

    A API da Kobana usa certificados **SSL 2048 bits**. Toda requisição deve ser feita via **HTTPS** — chamadas na porta 80 são redirecionadas para 443.

    Os clientes devem suportar `TLSv1.2` ou `TLSv1.3` com uma das cifras: `TLS_AES_128_GCM_SHA256`, `TLS_AES_256_GCM_SHA384`, `TLS_CHACHA20_POLY1305_SHA256`, `ECDHE-RSA-AES128-GCM-SHA256`, `ECDHE-RSA-AES128-SHA256`, `ECDHE-RSA-AES256-GCM-SHA384`, `ECDHE-RSA-CHACHA20-POLY1305`, `ECDHE-RSA-AES256-SHA384`. `TLSv1` e `TLSv1.1` não são suportados.

    ## Cache HTTP

    Use os cabeçalhos HTTP de cache para reduzir carga e ganhar velocidade. A maioria das respostas inclui `ETag` e/ou `Last-Modified` — armazene esses valores e reenvie nas próximas requisições via `If-None-Match` e `If-Modified-Since`. Se o recurso não mudou, a resposta será `304 Not Modified`, sem corpo e sem reprocessamento. Mais informações: [HTTP Cache Docs](http://www.mnot.net/cache_docs/).

    ## Tratamento de Erros

    Erros 5xx indicam falhas no servidor: **500 Internal Server Error** (aplicação indisponível), **502 Bad Gateway**, **503 Service Unavailable** e **504 Gateway Timeout** (falhas pontuais de infraestrutura). Sua aplicação deve identificar esses códigos e reagendar a requisição após alguns minutos com backoff. Status dos servidores: [https://status.kobana.com.br](https://status.kobana.com.br).

    ## Valores monetários

    Valores monetários seguem duas convenções: campos com sufixo `_cents` (÷100) e campos de precificação com sufixo `_subcents` (÷10000). Use estas convenções para converter para reais (BRL) antes de exibir ao usuário final.
  license:
    name: Proprietário — Kobana
    url: https://kobana.com.br
servers:
  - url: https://api.billing.kobana.com.br
    description: Produção. Substituído em tempo de execução quando `API_V1_PUBLIC_URL` é definido.
  - url: https://api.billing.sandbox.kobana.com.br
    description: Sandbox — ambiente de testes isolado da produção.
components:
  schemas:
    ApiV1Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: Código de erro estável. Use este campo para tratar o erro programaticamente — nunca faça parse da `message`.
              example: invalid_token
            message:
              type: string
              description: Mensagem legível para humanos. Nunca inclui dados do usuário verbatim.
              example: Cabeçalho Authorization ausente.
            details:
              description: "Payload opcional específico do erro (ex.: `{ required, granted }` em `insufficient_scope`)."
          required:
            - code
            - message
          description: Envelope de erro. Presente em toda resposta 4xx e 5xx.
      required:
        - error
    PaginationMeta:
      type: object
      properties:
        total:
          type: integer
          description: Total de itens em todas as páginas.
        page:
          type: integer
          description: Página atual (começa em 1).
        per_page:
          type: integer
          description: Itens por página.
        total_pages:
          type: integer
          description: Total de páginas.
      required:
        - total
        - page
        - per_page
        - total_pages
    DeletedResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            deleted:
              type: boolean
              example: true
          required:
            - deleted
      required:
        - data
    SubscriptionV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        billing_account_id:
          type: string
          format: uuid
        company_id:
          type:
            - string
            - "null"
          format: uuid
        plan_id:
          type:
            - string
            - "null"
          format: uuid
        product_group_id:
          type:
            - string
            - "null"
          format: uuid
        status:
          type: string
          enum:
            - draft
            - confirmed
            - trialing
            - active
            - past_due
            - canceled
            - paused
          description: "Estado da assinatura. Ciclo: `draft` → `confirmed` → `trialing` → `active` ↔ `past_due` → `canceled`. Também aceita `paused`."
        billing_cycle:
          type: string
          enum:
            - monthly
            - quarterly
            - semiannual
            - annual
          description: "Periodicidade de cobrança: mensal, trimestral, semestral ou anual."
        billing_cycle_anchor:
          type: string
          format: date-time
          description: Data âncora usada no cálculo dos períodos de cobrança.
        current_period_start:
          type: string
          format: date-time
          description: Início do período de cobrança atual.
        current_period_end:
          type: string
          format: date-time
          description: Fim do período de cobrança atual.
        trial_start:
          type:
            - string
            - "null"
          format: date-time
        trial_end:
          type:
            - string
            - "null"
          format: date-time
        activated_at:
          type:
            - string
            - "null"
          format: date-time
        confirmed_at:
          type:
            - string
            - "null"
          format: date-time
        cancel_at_period_end:
          type: boolean
          description: Quando `true`, a assinatura será cancelada ao fim do período atual em vez de imediatamente.
        canceled_at:
          type:
            - string
            - "null"
          format: date-time
        cancellation_reason:
          type:
            - string
            - "null"
        pause_collection:
          description: Quando pausada, contém `{ behavior, resumes_at }`. `null` quando ativa.
        paused_at:
          type:
            - string
            - "null"
          format: date-time
        resumes_at:
          type:
            - string
            - "null"
          format: date-time
        resumed_at:
          type:
            - string
            - "null"
          format: date-time
        discount_code_id:
          type:
            - string
            - "null"
          format: uuid
        discount_percent:
          type:
            - string
            - "null"
          description: 'Decimal como string (ex.: `"10.00"` = 10%). Faixa: 0–100.'
        recurring_amount_cents:
          type:
            - integer
            - "null"
          description: Valor recorrente em centavos (÷100 → BRL).
          example: 9990
        proration_behavior:
          type: string
          enum:
            - create_prorations
            - none
            - always_invoice
          description: "Comportamento de proração ao trocar de plano. `create_prorations` (padrão): gera ajuste; `none`: ignora; `always_invoice`: emite fatura imediata."
        collection_method:
          type: string
          enum:
            - charge_automatically
            - manual_charge
            - manual_invoice
          description: "`charge_automatically`: fatura e cobrança automáticas. `manual_charge`: fatura automática, cobrança manual. `manual_invoice`: ambos manuais."
        nfe_issuance_policy:
          type:
            - string
            - "null"
          enum:
            - disabled
            - on_finalization
            - on_full_payment
            - per_installment
          description: "Política de emissão de NF-e: `disabled`, `on_finalization`, `on_full_payment` ou `per_installment`."
        renewal_settings:
          description: '`{ type: "auto_renew" | "cancel" | "downgrade_to_flexible", ... }`.'
        commitment: {}
        allow_pause:
          type: boolean
        allow_cancel:
          type: boolean
        proposal_id:
          type:
            - string
            - "null"
          format: uuid
        notes:
          type:
            - string
            - "null"
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - billing_account_id
        - company_id
        - plan_id
        - product_group_id
        - status
        - billing_cycle
        - billing_cycle_anchor
        - current_period_start
        - current_period_end
        - trial_start
        - trial_end
        - activated_at
        - confirmed_at
        - cancel_at_period_end
        - canceled_at
        - cancellation_reason
        - discount_code_id
        - discount_percent
        - recurring_amount_cents
        - proration_behavior
        - collection_method
        - nfe_issuance_policy
        - allow_pause
        - allow_cancel
        - proposal_id
        - notes
        - custom_metadata
        - created_at
        - updated_at
    SubscriptionListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/SubscriptionV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    SubscriptionResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/SubscriptionV1"
      required:
        - data
    SubscriptionCreateRequest:
      type: object
      properties:
        billing_account_id:
          type: string
          format: uuid
          description: UUID da conta de cobrança que receberá esta assinatura.
        company_id:
          type: string
          format: uuid
        plan_id:
          type: string
          format: uuid
          description: UUID do plano. Obrigatório quando `items` não é enviado.
        product_group_id:
          type: string
          format: uuid
        billing_cycle:
          type: string
          enum:
            - monthly
            - quarterly
            - semiannual
            - annual
        collection_method:
          type: string
          enum:
            - charge_automatically
            - manual_charge
            - manual_invoice
        trial_end:
          type: string
          format: date-time
          description: Data de término do trial (ISO 8601).
        trial_period_days:
          type: integer
          minimum: 0
          description: Alternativa a `trial_end`. Dias de trial a partir da criação.
        discount_code_id:
          type: string
          format: uuid
        proration_behavior:
          type: string
          enum:
            - create_prorations
            - none
            - always_invoice
        nfe_issuance_policy:
          type: string
          enum:
            - disabled
            - on_finalization
            - on_full_payment
            - per_installment
        items:
          type: array
          items:
            type: object
            properties:
              product_id:
                type: string
                format: uuid
              price_id:
                type: string
                format: uuid
              quantity:
                type: integer
                minimum: 1
                default: 1
              unit_amount_subcents:
                type: integer
                minimum: 0
                description: Precisão de 4 decimais (÷10000 → BRL). Sobrescreve o valor do preço.
            required:
              - product_id
              - price_id
        notes:
          type:
            - string
            - "null"
        custom_metadata:
          type: object
          additionalProperties: {}
      required:
        - billing_account_id
    SubscriptionUpdateRequest:
      type: object
      properties:
        plan_id:
          type:
            - string
            - "null"
          format: uuid
        billing_cycle:
          type: string
          enum:
            - monthly
            - quarterly
            - semiannual
            - annual
        collection_method:
          type: string
          enum:
            - charge_automatically
            - manual_charge
            - manual_invoice
        cancel_at_period_end:
          type: boolean
        discount_code_id:
          type:
            - string
            - "null"
          format: uuid
        discount_percent:
          type:
            - number
            - "null"
          minimum: 0
          maximum: 100
        proration_behavior:
          type: string
          enum:
            - create_prorations
            - none
            - always_invoice
        nfe_issuance_policy:
          type:
            - string
            - "null"
          enum:
            - disabled
            - on_finalization
            - on_full_payment
            - per_installment
        allow_pause:
          type: boolean
        allow_cancel:
          type: boolean
        notes:
          type:
            - string
            - "null"
        custom_metadata:
          type: object
          additionalProperties: {}
    SubscriptionPauseRequest:
      type: object
      properties:
        behavior:
          type: string
          enum:
            - mark_uncollectible
            - keep_as_draft
            - void
          description: "Como tratar faturas geradas durante a pausa. Padrão: `mark_uncollectible`."
        resumes_at:
          type: string
          format: date-time
          description: Data para retomada automática. Omita para retomada manual.
    SubscriptionChangePlanRequest:
      type: object
      properties:
        plan_id:
          type: string
          format: uuid
          description: UUID do novo plano.
        timing:
          type: string
          enum:
            - immediate
            - end_of_period
          description: "Quando a troca de plano entra em vigor. Padrão: `immediate`."
        reason:
          type: string
          description: Motivo da troca (opcional, registrado no audit log).
      required:
        - plan_id
    SubscriptionCancelRequest:
      type: object
      properties:
        cancel_at_period_end:
          type: boolean
          description: "Quando `true`, agenda o cancelamento para o fim do período atual. Padrão: `false` (cancela imediatamente)."
        reason:
          type: string
    BillingAccountCustomerV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        external_id:
          type:
            - string
            - "null"
        name:
          type: string
        nickname:
          type:
            - string
            - "null"
        legal_name:
          type:
            - string
            - "null"
        document_type:
          type:
            - string
            - "null"
          enum:
            - cpf
            - cnpj
        document_number:
          type:
            - string
            - "null"
        kind:
          type:
            - string
            - "null"
          enum:
            - individual
            - company
        birthday:
          type:
            - string
            - "null"
        notes:
          type:
            - string
            - "null"
        addresses: {}
        phones: {}
        emails: {}
        websites: {}
        tags:
          type:
            - array
            - "null"
          items:
            type: string
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - name
    BillingAccountV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        external_id:
          type:
            - string
            - "null"
          description: Identificador externo da conta no sistema do cliente.
        currency:
          type: string
          description: "Moeda ISO 4217 (ex.: `BRL`)."
          example: BRL
        billing_email:
          type:
            - string
            - "null"
          format: email
          description: E-mail para o qual faturas e avisos são enviados.
        payment_terms_days:
          type: integer
          description: "Prazo de pagamento em dias (padrão: 10)."
          example: 10
        auto_collection:
          type: boolean
          description: Quando `true`, cobranças são realizadas automaticamente.
        balance_cents:
          type: integer
          description: Saldo da conta em centavos (÷100 → BRL).
          example: 0
        status:
          type: string
          enum:
            - active
            - suspended
            - closed
          description: "Status da conta: `active`, `suspended` ou `closed`."
        suspended_at:
          type:
            - string
            - "null"
          format: date-time
        suspension_reason:
          type:
            - string
            - "null"
        tax_exempt:
          type: boolean
          description: Indica se a conta é isenta de impostos.
        tax_exemption_certificate:
          type:
            - string
            - "null"
          description: Número do certificado de isenção tributária.
        customer_tax_type:
          type:
            - string
            - "null"
          enum:
            - individual
            - business
            - exempt
          description: "Tipo tributário do cliente: pessoa física, jurídica ou isento."
        withhold_iss:
          type: boolean
          description: Reter ISS.
        withhold_irrf:
          type: boolean
          description: Reter IRRF.
        withhold_csrf:
          type: boolean
          description: Reter CSRF (PIS/COFINS/CSLL).
        withhold_inss:
          type: boolean
          description: Reter INSS.
        municipal_registration:
          type:
            - string
            - "null"
          description: Inscrição municipal do cliente.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        customer:
          allOf:
            - $ref: "#/components/schemas/BillingAccountCustomerV1"
            - description: Customer associado, presente quando a relação é carregada.
      required:
        - id
        - external_id
        - currency
        - billing_email
        - payment_terms_days
        - auto_collection
        - balance_cents
        - status
        - suspended_at
        - suspension_reason
        - tax_exempt
        - tax_exemption_certificate
        - customer_tax_type
        - withhold_iss
        - withhold_irrf
        - withhold_csrf
        - withhold_inss
        - municipal_registration
        - created_at
        - updated_at
    BillingAccountListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/BillingAccountV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    BillingAccountResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/BillingAccountV1"
      required:
        - data
    BillingAccountCustomerInput:
      type: object
      properties:
        id:
          type: string
          description: UUID ou external_code do customer existente.
        external_id:
          type: string
          description: External code para localizar/criar o customer.
        document_number:
          type: string
          description: CPF ou CNPJ para localizar/criar o customer.
        name:
          type: string
          description: Obrigatório ao criar um novo customer.
        nickname:
          type: string
        legal_name:
          type: string
        kind:
          type: string
          enum:
            - individual
            - company
        birthday:
          type: string
        email:
          type: string
          format: email
        phone:
          type: string
        notes:
          type: string
        addresses: {}
        phones: {}
        emails: {}
        websites: {}
        tags:
          type: array
          items:
            type: string
        custom_metadata:
          type: object
          additionalProperties: {}
    BillingAccountCreateRequest:
      type: object
      properties:
        customer:
          allOf:
            - $ref: "#/components/schemas/BillingAccountCustomerInput"
            - description: Customer a associar — existente ou novo.
        external_id:
          type: string
          description: Identificador externo da conta no sistema do cliente.
        billing_email:
          type: string
          format: email
          description: "E-mail de cobrança. Padrão: `customer.email`."
        payment_terms_days:
          type: integer
          minimum: 1
          maximum: 90
          description: "Prazo de pagamento em dias (1–90). Padrão: 10."
        auto_collection:
          type: boolean
          description: "Habilita cobrança automática. Padrão: `true`."
      required:
        - customer
    BillingAccountUpdateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
        email:
          type: string
          format: email
        phone:
          type: string
        address:
          type: object
          additionalProperties: {}
        billing_email:
          type: string
          format: email
        payment_terms_days:
          type: integer
          minimum: 1
          maximum: 90
        auto_collection:
          type: boolean
        custom_metadata:
          type: object
          additionalProperties: {}
    BillingAccountReasonRequest:
      type: object
      properties:
        reason:
          type: string
          description: Motivo da operação (registrado no audit log).
    CustomerV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        external_id:
          type:
            - string
            - "null"
          description: Identificador externo do cliente (apelido `external_code` interno).
        name:
          type: string
        nickname:
          type:
            - string
            - "null"
        legal_name:
          type:
            - string
            - "null"
          description: Razão social (para pessoa jurídica).
        document_type:
          type:
            - string
            - "null"
          enum:
            - cpf
            - cnpj
          description: Tipo do documento principal. Inferido pelo comprimento de `document_number`.
        document_number:
          type:
            - string
            - "null"
          description: CPF (11 dígitos) ou CNPJ (14 dígitos). Pode conter máscara.
        kind:
          type:
            - string
            - "null"
          enum:
            - natural
            - juridical
          description: "`natural` para pessoa física; `juridical` para pessoa jurídica."
        birthday:
          type:
            - string
            - "null"
          description: Data de nascimento (ISO 8601).
        notes:
          type:
            - string
            - "null"
        addresses:
          type:
            - array
            - "null"
          items:
            type: object
            properties:
              kind:
                type: string
                description: "Tipo do endereço (ex.: `billing`, `shipping`)."
              street:
                type: string
              number:
                type: string
              complement:
                type:
                  - string
                  - "null"
              neighborhood:
                type: string
              city:
                type: string
              state:
                type: string
              postal_code:
                type: string
              country:
                type: string
                description: "Código ISO do país (ex.: `BR`)."
        phones:
          type:
            - array
            - "null"
          items:
            type: object
            properties:
              kind:
                type: string
              value:
                type: string
            required:
              - value
        emails:
          type:
            - array
            - "null"
          items:
            type: object
            properties:
              kind:
                type: string
              value:
                type: string
            required:
              - value
        websites:
          type:
            - array
            - "null"
          items:
            type: object
            properties:
              kind:
                type: string
              value:
                type: string
            required:
              - value
        tags:
          type:
            - array
            - "null"
          items:
            type: string
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados customizados definidos pela organização.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        billing_accounts:
          type: array
          items:
            $ref: "#/components/schemas/BillingAccountV1"
          description: Incluído apenas quando o cliente é carregado com contas de cobrança.
      required:
        - id
        - external_id
        - name
        - nickname
        - legal_name
        - document_type
        - document_number
        - kind
        - birthday
        - notes
        - addresses
        - phones
        - emails
        - websites
        - tags
        - custom_metadata
        - created_at
        - updated_at
    CustomerListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/CustomerV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    CustomerResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/CustomerV1"
      required:
        - data
    CustomerCreateResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            customer:
              $ref: "#/components/schemas/CustomerV1"
            billing_account:
              allOf:
                - $ref: "#/components/schemas/BillingAccountV1"
                - type:
                    - object
                    - "null"
          required:
            - customer
            - billing_account
      required:
        - data
    CustomerCreateRequest:
      type: object
      properties:
        name:
          type: string
          description: Nome do cliente (obrigatório).
        external_id:
          type: string
          description: Identificador externo do cliente no sistema de origem.
        nickname:
          type: string
        legal_name:
          type: string
          description: Razão social (para pessoa jurídica).
        document_number:
          type: string
          description: CPF ou CNPJ. O `document_type` é inferido pelo comprimento (≤11 → cpf, senão cnpj).
        kind:
          type: string
          enum:
            - natural
            - juridical
        birthday:
          type: string
          description: Data de nascimento (ISO 8601).
        email:
          type: string
          description: E-mail principal de contato.
        phone:
          type: string
        notes:
          type: string
        addresses:
          type: array
          items:
            type: object
            properties:
              kind:
                type: string
                description: "Tipo do endereço (ex.: `billing`, `shipping`)."
              street:
                type: string
              number:
                type: string
              complement:
                type:
                  - string
                  - "null"
              neighborhood:
                type: string
              city:
                type: string
              state:
                type: string
              postal_code:
                type: string
              country:
                type: string
                description: "Código ISO do país (ex.: `BR`)."
        phones:
          type: array
          items:
            type: object
            properties:
              kind:
                type: string
              value:
                type: string
            required:
              - value
        emails:
          type: array
          items:
            type: object
            properties:
              kind:
                type: string
              value:
                type: string
            required:
              - value
        websites:
          type: array
          items:
            type: object
            properties:
              kind:
                type: string
              value:
                type: string
            required:
              - value
        tags:
          type: array
          items:
            type: string
        custom_metadata:
          type: object
          additionalProperties: {}
        create_billing_account:
          type: boolean
          description: "Quando `false`, não cria conta de cobrança automaticamente. Padrão: `true`."
        billing_email:
          type: string
          description: "E-mail para envio de faturas. Padrão: usa `email` quando omitido."
        payment_terms_days:
          type: integer
          minimum: 0
          description: "Prazo de pagamento em dias. Padrão: `10`."
        auto_collection:
          type: boolean
          description: "Cobrança automática na conta criada. Padrão: `true`."
      required:
        - name
    CustomerUpdateRequest:
      type: object
      properties:
        name:
          type: string
        external_id:
          type: string
        nickname:
          type: string
        legal_name:
          type: string
        document_number:
          type: string
        kind:
          type: string
          enum:
            - natural
            - juridical
        birthday:
          type: string
        email:
          type: string
        phone:
          type: string
        notes:
          type: string
        addresses:
          type: array
          items:
            type: object
            properties:
              kind:
                type: string
                description: "Tipo do endereço (ex.: `billing`, `shipping`)."
              street:
                type: string
              number:
                type: string
              complement:
                type:
                  - string
                  - "null"
              neighborhood:
                type: string
              city:
                type: string
              state:
                type: string
              postal_code:
                type: string
              country:
                type: string
                description: "Código ISO do país (ex.: `BR`)."
        phones:
          type: array
          items:
            type: object
            properties:
              kind:
                type: string
              value:
                type: string
            required:
              - value
        emails:
          type: array
          items:
            type: object
            properties:
              kind:
                type: string
              value:
                type: string
            required:
              - value
        websites:
          type: array
          items:
            type: object
            properties:
              kind:
                type: string
              value:
                type: string
            required:
              - value
        tags:
          type: array
          items:
            type: string
        custom_metadata:
          type: object
          additionalProperties: {}
    CustomerStatementItem:
      type: object
      properties:
        id:
          type: string
          format: uuid
        billing_account_id:
          type: string
          format: uuid
        kind:
          type: string
          description: "Tipo do lançamento (ex.: `invoice`, `payment`, `credit_application`)."
        occurred_at:
          type: string
          format: date-time
        description:
          type:
            - string
            - "null"
        amount_cents:
          type: integer
          description: Valor do lançamento em centavos (÷100 → BRL). Pode ser negativo.
        parent_id:
          type:
            - string
            - "null"
        parent_type:
          type:
            - string
            - "null"
        created_at:
          type: string
          format: date-time
      required:
        - id
        - billing_account_id
        - kind
        - occurred_at
        - description
        - amount_cents
        - parent_id
        - parent_type
        - created_at
    CustomerStatementListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/CustomerStatementItem"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    CustomerStatementSyncResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            customer_id:
              type: string
              format: uuid
            billing_account_id:
              type: string
              format: uuid
            invoices_created:
              type: integer
            payments_created:
              type: integer
            credit_applications_created:
              type: integer
            total_created:
              type: integer
          required:
            - customer_id
            - billing_account_id
            - invoices_created
            - payments_created
            - credit_applications_created
            - total_created
      required:
        - data
    CustomerStatementSyncRequest:
      type: object
      properties:
        billing_account_id:
          type: string
          format: uuid
          description: Necessário quando o cliente possui múltiplas contas de cobrança.
    CustomerRecalculateMrrResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            customer_id:
              type: string
              format: uuid
            total_mrr_cents:
              type: integer
              description: MRR consolidado de todas as contas, em centavos (÷100 → BRL).
            billing_accounts:
              type: array
              items:
                type: object
                properties:
                  billing_account_id:
                    type: string
                    format: uuid
                  mrr_amount_cents:
                    type: integer
                required:
                  - billing_account_id
                  - mrr_amount_cents
          required:
            - customer_id
            - total_mrr_cents
            - billing_accounts
      required:
        - data
    CustomerPortalUserV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        email:
          type: string
        status:
          type: string
          enum:
            - active
            - pending_verification
            - pending_invitation
            - suspended
            - locked
        sso_only:
          type: boolean
        external_id:
          type:
            - string
            - "null"
        email_verified_at:
          type:
            - string
            - "null"
          format: date-time
        last_login_at:
          type:
            - string
            - "null"
          format: date-time
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        name:
          type:
            - string
            - "null"
          description: Nome do `Person` vinculado, quando carregado.
      required:
        - id
        - email
        - status
        - sso_only
        - external_id
        - email_verified_at
        - last_login_at
        - custom_metadata
        - created_at
        - updated_at
    CustomerPortalUserListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/CustomerPortalUserV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    CustomerPortalUserResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/CustomerPortalUserV1"
      required:
        - data
    CustomerPortalUserInviteRequest:
      type: object
      properties:
        email:
          type: string
          description: E-mail do convidado (obrigatório).
      required:
        - email
    CustomerPortalUserUpdateRequest:
      type: object
      properties:
        email:
          type: string
        external_id:
          type:
            - string
            - "null"
        sso_only:
          type: boolean
        status:
          type: string
          enum:
            - active
            - suspended
          description: "Transições permitidas: `active` ↔ `suspended`."
    CustomerPortalUserEmailPreviewResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            type:
              type: string
              enum:
                - invitation
                - verification
            from:
              type: string
            to:
              type: string
            subject:
              type: string
            message:
              type: string
          required:
            - type
            - from
            - to
            - subject
            - message
      required:
        - data
    CustomerPortalUserResendResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            resent:
              type: boolean
            type:
              type: string
              enum:
                - invitation
                - verification
          required:
            - resent
            - type
      required:
        - data
    PlanItemV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        plan_id:
          type: string
          format: uuid
        product_id:
          type: string
          format: uuid
        price_id:
          type: string
          format: uuid
        quantity:
          type: integer
          description: Quantidade do produto incluída no plano.
          example: 1
        included:
          type: boolean
          description: Quando `true`, o item está incluído no preço do plano. Quando `false`, é um add-on cobrado à parte.
        created_at:
          type: string
          format: date-time
      required:
        - id
        - plan_id
        - product_id
        - price_id
        - quantity
        - included
        - created_at
    PlanV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type:
            - string
            - "null"
          format: uuid
        company_id:
          type:
            - string
            - "null"
          format: uuid
        plan_group_id:
          type:
            - string
            - "null"
          format: uuid
        billing_account_id:
          type:
            - string
            - "null"
          format: uuid
          description: Quando preenchido, o plano é específico para uma conta de cobrança (plano custom).
        name:
          type: string
        slug:
          type: string
          description: Identificador único por organização. Apenas `[a-z0-9-]`.
        description:
          type:
            - string
            - "null"
        status:
          type: string
          enum:
            - draft
            - active
            - archived
          description: "Estado do plano: `draft`, `active` ou `archived`."
        plan_type:
          type: string
          enum:
            - standard
            - custom
            - promotional
          description: "`standard`: plano público padrão. `custom`: plano específico de cliente. `promotional`: plano promocional temporário."
        visibility:
          type: string
          enum:
            - public
            - private
          description: "`public`: visível no catálogo. `private`: oculto."
        features:
          type: array
          items:
            type: string
          description: Lista de features do plano (strings livres).
        limits:
          type: object
          properties:
            users:
              type: integer
            subaccounts:
              type: integer
            operationsPerMonth:
              type: integer
            apiRequestsPerDay:
              type: integer
          description: Limites do plano (usuários, subcontas, operações, etc.).
        trial_period_days:
          type:
            - integer
            - "null"
          description: Dias de trial concedidos ao criar uma assinatura deste plano.
        default_billing_cycle:
          type: string
          enum:
            - monthly
            - quarterly
            - semiannual
            - annual
          description: Periodicidade de cobrança padrão.
        available_billing_cycles:
          type: array
          items:
            type: string
            enum:
              - monthly
              - quarterly
              - semiannual
              - annual
          description: Periodicidades de cobrança permitidas para este plano.
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        items:
          type: array
          items:
            $ref: "#/components/schemas/PlanItemV1"
          description: Itens do plano. Presente quando incluído via relations.
      required:
        - id
        - organization_id
        - company_id
        - plan_group_id
        - billing_account_id
        - name
        - slug
        - description
        - status
        - plan_type
        - visibility
        - features
        - limits
        - trial_period_days
        - default_billing_cycle
        - available_billing_cycles
        - custom_metadata
        - created_at
        - updated_at
    PlanListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/PlanV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    PlanResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/PlanV1"
      required:
        - data
    PlanItemListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/PlanItemV1"
      required:
        - data
    PlanItemInput:
      type: object
      properties:
        product_id:
          type: string
          format: uuid
        price_id:
          type: string
          format: uuid
        quantity:
          type: integer
          minimum: 1
          default: 1
        included:
          type: boolean
          default: true
      required:
        - product_id
        - price_id
    PlanCreateRequest:
      type: object
      properties:
        company_id:
          type: string
          format: uuid
        plan_group_id:
          type:
            - string
            - "null"
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 255
        slug:
          type: string
          minLength: 1
          maxLength: 100
          pattern: ^[a-z0-9-]+$
          description: Apenas letras minúsculas, dígitos e hífens.
        description:
          type:
            - string
            - "null"
        status:
          type: string
          enum:
            - draft
            - active
            - archived
        plan_type:
          type: string
          enum:
            - standard
            - custom
            - promotional
          description: "Padrão: `standard`."
        billing_account_id:
          type:
            - string
            - "null"
          format: uuid
        visibility:
          type: string
          enum:
            - public
            - private
          description: "Padrão: `public`."
        features:
          type: array
          items:
            type: string
        limits:
          type: object
          properties:
            users:
              type: integer
            subaccounts:
              type: integer
            operationsPerMonth:
              type: integer
            apiRequestsPerDay:
              type: integer
        trial_period_days:
          type: integer
          minimum: 0
          maximum: 90
        default_billing_cycle:
          type: string
          enum:
            - monthly
            - quarterly
            - semiannual
            - annual
        available_billing_cycles:
          type: array
          items:
            type: string
            enum:
              - monthly
              - quarterly
              - semiannual
              - annual
        items:
          type: array
          items:
            $ref: "#/components/schemas/PlanItemInput"
        custom_metadata:
          type: object
          additionalProperties: {}
      required:
        - name
        - slug
    PlanUpdateRequest:
      type: object
      properties:
        company_id:
          type:
            - string
            - "null"
          format: uuid
        plan_group_id:
          type:
            - string
            - "null"
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 255
        slug:
          type: string
          minLength: 1
          maxLength: 100
          pattern: ^[a-z0-9-]+$
          description: Apenas letras minúsculas, dígitos e hífens.
        description:
          type:
            - string
            - "null"
        status:
          type: string
          enum:
            - draft
            - active
            - archived
        plan_type:
          type: string
          enum:
            - standard
            - custom
            - promotional
          description: "Padrão: `standard`."
        billing_account_id:
          type:
            - string
            - "null"
          format: uuid
        visibility:
          type: string
          enum:
            - public
            - private
          description: "Padrão: `public`."
        features:
          type: array
          items:
            type: string
        limits:
          type: object
          properties:
            users:
              type: integer
            subaccounts:
              type: integer
            operationsPerMonth:
              type: integer
            apiRequestsPerDay:
              type: integer
        trial_period_days:
          type: integer
          minimum: 0
          maximum: 90
        default_billing_cycle:
          type: string
          enum:
            - monthly
            - quarterly
            - semiannual
            - annual
        available_billing_cycles:
          type: array
          items:
            type: string
            enum:
              - monthly
              - quarterly
              - semiannual
              - annual
        items:
          type: array
          items:
            $ref: "#/components/schemas/PlanItemInput"
        custom_metadata:
          type: object
          additionalProperties: {}
    PlanItemsReplaceRequest:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/PlanItemInput"
      required:
        - items
    PlanItemsReplaceResponse:
      type: array
      items:
        $ref: "#/components/schemas/PlanItemV1"
    PlanBulkIdsRequest:
      type: object
      properties:
        ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
          description: Lista de UUIDs de planos. Mínimo 1.
      required:
        - ids
    PlanBulkMoveGroupRequest:
      type: object
      properties:
        ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
        plan_group_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do grupo destino. Use `null` para remover o agrupamento.
      required:
        - ids
        - plan_group_id
    PlanBulkArchiveResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            archived_count:
              type: integer
            skipped_count:
              type: integer
            skipped_ids:
              type: array
              items:
                type: string
                format: uuid
          required:
            - archived_count
            - skipped_count
            - skipped_ids
      required:
        - data
    PlanBulkDeleteResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            deleted_count:
              type: integer
            skipped_count:
              type: integer
            skipped_ids:
              type: array
              items:
                type: string
                format: uuid
          required:
            - deleted_count
            - skipped_count
            - skipped_ids
      required:
        - data
    PlanBulkMoveGroupResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            moved_count:
              type: integer
          required:
            - moved_count
      required:
        - data
    PlanGroupV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type: string
          format: uuid
        company_id:
          type:
            - string
            - "null"
          format: uuid
        name:
          type: string
          description: Nome do grupo de planos.
        slug:
          type:
            - string
            - "null"
          description: Identificador legível usado em URLs públicas.
        display_order:
          type: integer
          description: Posição de exibição (menor valor aparece primeiro).
        archived_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data de arquivamento. `null` quando ativo.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - organization_id
        - company_id
        - name
        - slug
        - display_order
        - archived_at
        - created_at
        - updated_at
    PlanGroupListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/PlanGroupV1"
      required:
        - data
    PlanGroupResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/PlanGroupV1"
      required:
        - data
    PlanGroupCreateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Nome do grupo de planos.
        slug:
          type: string
          minLength: 1
          maxLength: 100
          description: Identificador legível (opcional). Gerado automaticamente se omitido.
      required:
        - name
    PlanGroupUpdateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
        slug:
          type: string
          minLength: 1
          maxLength: 100
    PlanGroupReorderRequest:
      type: object
      properties:
        group_ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
          description: Lista de UUIDs dos grupos na nova ordem de exibição. Todos devem pertencer à organização atual.
      required:
        - group_ids
    PlanGroupReorderResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            success:
              type: boolean
              example: true
          required:
            - success
      required:
        - data
    ProductV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type:
            - string
            - "null"
          format: uuid
        company_id:
          type:
            - string
            - "null"
          format: uuid
        parent_product_id:
          type:
            - string
            - "null"
          format: uuid
        product_group_id:
          type:
            - string
            - "null"
          format: uuid
        service_item_id:
          type:
            - string
            - "null"
          format: uuid
        name:
          type: string
          description: Nome de exibição do produto.
        slug:
          type: string
          description: Identificador legível único dentro do grupo de produto. Aceita apenas `[a-z0-9_-]+`.
        description:
          type:
            - string
            - "null"
        status:
          type: string
          enum:
            - draft
            - active
            - archived
          description: "Estado do produto: `draft`, `active` ou `archived`."
        visibility:
          type: string
          enum:
            - public
            - private
          description: "Visibilidade no portal do cliente. `public`: visível para clientes; `private`: apenas operadores."
        product_type:
          type: string
          enum:
            - base
            - addon_quantity
            - addon_fixed
            - metered
            - one_time_fixed
            - one_time_quantity
          description: "Tipo do produto. `base`: plano principal; `addon_quantity`/`addon_fixed`: complementos; `metered`: cobrança por uso; `one_time_fixed`/`one_time_quantity`: cobrança única."
        unit_label:
          type:
            - string
            - "null"
          description: 'Rótulo da unidade (ex.: "usuário", "GB"). Usado em faturas e portal.'
        increment:
          type: integer
          description: Incremento mínimo de quantidade ao alterar o item.
        website_url:
          type:
            - string
            - "null"
        display_order:
          type: integer
          description: Ordem de exibição (menor primeiro).
        is_required:
          type: boolean
          description: Quando `true`, o produto é obrigatório no plano onde é incluído.
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - organization_id
        - company_id
        - parent_product_id
        - product_group_id
        - service_item_id
        - name
        - slug
        - description
        - status
        - visibility
        - product_type
        - unit_label
        - increment
        - website_url
        - display_order
        - is_required
        - custom_metadata
        - created_at
        - updated_at
    ProductListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/ProductV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    ProductResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/ProductV1"
      required:
        - data
    ProductCreateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Nome do produto.
        slug:
          type: string
          minLength: 1
          maxLength: 100
          pattern: ^[a-z0-9_-]+$
          description: Slug único dentro do grupo. Aceita apenas `[a-z0-9_-]+`.
        description:
          type: string
        productType:
          type: string
          enum:
            - base
            - addon_quantity
            - addon_fixed
            - metered
            - one_time_fixed
            - one_time_quantity
          description: "Tipo do produto. Padrão: `base`."
        visibility:
          type: string
          enum:
            - public
            - private
          description: "Visibilidade no portal. Padrão: `public`."
        unitLabel:
          type: string
        increment:
          type: integer
          exclusiveMinimum: 0
          description: "Incremento mínimo. Padrão: `1`."
        websiteUrl:
          type: string
          format: uri
        isRequired:
          type: boolean
        parentProductId:
          type: string
          format: uuid
        productGroupId:
          type: string
          format: uuid
        companyId:
          type: string
          format: uuid
        customMetadata:
          type: object
          additionalProperties: {}
      required:
        - name
        - slug
    ProductUpdateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
        slug:
          type: string
          minLength: 1
          maxLength: 100
          pattern: ^[a-z0-9_-]+$
        description:
          type: string
        status:
          type: string
          enum:
            - draft
            - active
            - archived
        productType:
          type: string
          enum:
            - base
            - addon_quantity
            - addon_fixed
            - metered
            - one_time_fixed
            - one_time_quantity
        visibility:
          type: string
          enum:
            - public
            - private
        unitLabel:
          type: string
        increment:
          type: integer
          exclusiveMinimum: 0
        websiteUrl:
          type: string
          format: uri
        isRequired:
          type: boolean
        parentProductId:
          type:
            - string
            - "null"
          format: uuid
        productGroupId:
          type:
            - string
            - "null"
          format: uuid
        companyId:
          type:
            - string
            - "null"
          format: uuid
        customMetadata:
          type: object
          additionalProperties: {}
    ProductReorderRequest:
      type: object
      properties:
        product_ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
          description: IDs de produtos na nova ordem desejada. Índice 0 vira o primeiro da lista.
      required:
        - product_ids
    ProductBulkArchiveRequest:
      type: object
      properties:
        ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
          description: IDs de produtos a arquivar.
      required:
        - ids
    ProductBulkDeleteRequest:
      type: object
      properties:
        ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
          description: IDs de produtos a excluir permanentemente.
      required:
        - ids
    ProductBulkVisibilityRequest:
      type: object
      properties:
        ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
        visibility:
          type: string
          enum:
            - public
            - private
          description: Nova visibilidade a aplicar em todos os produtos.
      required:
        - ids
        - visibility
    ProductBulkMoveGroupRequest:
      type: object
      properties:
        ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
        product_group_id:
          type:
            - string
            - "null"
          format: uuid
          description: Grupo de destino. Use `null` para remover do grupo atual.
      required:
        - ids
        - product_group_id
    ProductBulkChangeCompanyRequest:
      type: object
      properties:
        ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
        company_id:
          type:
            - string
            - "null"
          format: uuid
          description: Empresa de destino. Use `null` para limpar o vínculo.
      required:
        - ids
        - company_id
    ProductBulkResultResponse:
      type: object
      properties:
        data: {}
    ProductGroupV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type: string
          format: uuid
        company_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da empresa emissora associada ao grupo (opcional).
        proposal_template_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do template de proposta padrão do grupo (opcional).
        service_item_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do item de serviço fiscal padrão do grupo (opcional).
        name:
          type: string
          description: Nome do grupo de produtos.
        slug:
          type: string
          description: Identificador legível usado em URLs públicas. Único por organização.
        display_order:
          type: integer
          description: Ordem de exibição do grupo (menor primeiro).
        archived_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data de arquivamento. `null` quando ativo.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - organization_id
        - company_id
        - proposal_template_id
        - service_item_id
        - name
        - slug
        - display_order
        - archived_at
        - created_at
        - updated_at
    ProductGroupListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/ProductGroupV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    ProductGroupResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/ProductGroupV1"
      required:
        - data
    ProductGroupCreateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Nome do grupo.
        slug:
          type: string
          description: Slug do grupo. Gerado a partir do nome quando omitido.
        company_id:
          type:
            - string
            - "null"
          format: uuid
        proposal_template_id:
          type:
            - string
            - "null"
          format: uuid
        service_item_id:
          type:
            - string
            - "null"
          format: uuid
      required:
        - name
    ProductGroupUpdateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
        slug:
          type: string
        company_id:
          type:
            - string
            - "null"
          format: uuid
        proposal_template_id:
          type:
            - string
            - "null"
          format: uuid
        service_item_id:
          type:
            - string
            - "null"
          format: uuid
    ProductGroupReorderRequest:
      type: object
      properties:
        group_ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
          description: Lista de UUIDs na nova ordem desejada. Todos os IDs devem pertencer à organização.
      required:
        - group_ids
    ProductGroupReorderResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            success:
              type: boolean
              example: true
          required:
            - success
      required:
        - data
    ProductGroupDeletedResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            deleted:
              type: boolean
              example: true
          required:
            - deleted
      required:
        - data
    OrganizationPersonV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        external_code:
          type:
            - string
            - "null"
        name:
          type: string
          description: Razão social ou nome de exibição.
        nickname:
          type:
            - string
            - "null"
        legal_name:
          type:
            - string
            - "null"
        document_type:
          type:
            - string
            - "null"
          enum:
            - cpf
            - cnpj
          description: "Tipo de documento: `cpf` ou `cnpj`."
        document_number:
          type:
            - string
            - "null"
          description: Número do documento (apenas dígitos).
        kind:
          type:
            - string
            - "null"
          enum:
            - individual
            - company
        birthday:
          type:
            - string
            - "null"
        notes:
          type:
            - string
            - "null"
        addresses:
          description: Lista de endereços.
        phones:
          description: Lista de telefones de contato.
        emails:
          description: Lista de e-mails de contato.
        websites: {}
        tags:
          type:
            - array
            - "null"
          items:
            type: string
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
        type:
          type: string
        parent_id:
          type:
            - string
            - "null"
          format: uuid
        external_id:
          type:
            - string
            - "null"
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - name
    OrganizationV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        external_id:
          type:
            - string
            - "null"
          description: Identificador externo da organização no sistema da Kobana.
        status:
          type: string
          description: "Status da organização (ex.: `active`)."
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados arbitrários. Chaves internas (`apiKeys`, `encryptionKey`, `secrets`) são removidas antes da resposta.
        person:
          allOf:
            - $ref: "#/components/schemas/OrganizationPersonV1"
            - description: Dados cadastrais da organização (nome, documento, contatos, endereços). Sempre incluído.
      required:
        - id
        - external_id
        - status
        - created_at
        - updated_at
        - person
    OrganizationResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/OrganizationV1"
      required:
        - data
    OrganizationUpdateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Nome de exibição da organização.
        email:
          type: string
          format: email
          description: E-mail de contato principal da organização.
        phone:
          type: string
          description: Telefone de contato principal da organização.
        addresses:
          type: array
          items: {}
          description: Lista de endereços da organização.
    CompanyPersonV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        external_code:
          type:
            - string
            - "null"
          description: Código externo do registro `Person` no sistema do cliente.
        name:
          type: string
        nickname:
          type:
            - string
            - "null"
        legal_name:
          type:
            - string
            - "null"
          description: Razão social.
        document_type:
          type:
            - string
            - "null"
          enum:
            - cpf
            - cnpj
          description: "Tipo de documento: `cpf` ou `cnpj`."
        document_number:
          type:
            - string
            - "null"
          description: Número do documento (CPF ou CNPJ), armazenado apenas com dígitos.
        kind:
          type:
            - string
            - "null"
        birthday:
          type:
            - string
            - "null"
        notes:
          type:
            - string
            - "null"
        addresses: {}
        phones: {}
        emails: {}
        websites: {}
        tags:
          type:
            - array
            - "null"
          items:
            type: string
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
        type:
          type: string
        parent_id:
          type:
            - string
            - "null"
        external_id:
          type:
            - string
            - "null"
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - name
    CompanyV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        public_id:
          type:
            - string
            - "null"
          description: Identificador público curto da empresa (estável e seguro para exibição).
        organization_id:
          type: string
          format: uuid
          description: UUID da organização (tenant) dona da empresa.
        person_id:
          type: string
          format: uuid
          description: UUID do registro `Person` (identidade jurídica) associado à empresa.
        parent_company_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da matriz quando a empresa é uma filial; `null` para matrizes.
        is_default:
          type: boolean
          description: Indica se esta é a empresa padrão da organização. Apenas matrizes podem ser padrão.
        status:
          type: string
          enum:
            - active
            - inactive
          description: "Status da empresa: `active` ou `inactive`."
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados internos da empresa (chave/valor livre).
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados customizados definidos pelo cliente (chave/valor livre).
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        person:
          allOf:
            - $ref: "#/components/schemas/CompanyPersonV1"
            - description: Identidade jurídica da empresa (nome, razão social, documento, contatos).
      required:
        - id
        - public_id
        - organization_id
        - person_id
        - parent_company_id
        - is_default
        - status
        - metadata
        - custom_metadata
        - created_at
        - updated_at
    CompanyListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/CompanyV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    CompanyResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/CompanyV1"
      required:
        - data
    CompanyMatrizListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/CompanyV1"
      required:
        - data
    CompanyDeleteResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            deleted:
              type: boolean
              example: true
          required:
            - deleted
      required:
        - data
    CompanyCreateRequest:
      type: object
      properties:
        parent_company_id:
          type: string
          format: uuid
          description: UUID da matriz ao criar uma filial. Omita para criar uma matriz.
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Nome fantasia da empresa.
        legal_name:
          type: string
          maxLength: 255
          description: Razão social.
        document_type:
          type: string
          enum:
            - cpf
            - cnpj
          description: "Tipo de documento: `cpf` ou `cnpj`. Apenas `cnpj` pode ter filiais."
        document_number:
          type: string
          minLength: 11
          maxLength: 18
          description: CPF ou CNPJ (com ou sem máscara — será normalizado para apenas dígitos).
        email:
          type: string
          format: email
          description: E-mail principal da empresa.
        phone:
          type: string
          description: Telefone principal da empresa. Quando informado, é adicionado ao array `phones`.
        addresses:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Lista de endereços da empresa.
        emails:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Lista de e-mails adicionais. Se omitida, o `email` principal é usado.
        phones:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Lista de telefones da empresa.
        websites:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Lista de sites da empresa.
        is_default:
          type: boolean
          description: Quando `true`, marca esta empresa como padrão da organização. Apenas matrizes podem ser padrão.
        custom_metadata:
          type: object
          additionalProperties: {}
          description: Metadados customizados (chave/valor livre).
      required:
        - name
        - document_type
        - document_number
        - email
    CompanyUpdateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Novo nome fantasia.
        legal_name:
          type: string
          maxLength: 255
          description: Nova razão social.
        email:
          type: string
          format: email
          description: Novo e-mail principal. Atualiza o primeiro e-mail do array `emails`.
        phone:
          type: string
          description: Novo telefone principal. Atualiza o primeiro telefone do array `phones`.
        addresses:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Substitui a lista de endereços.
        emails:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Substitui a lista de e-mails.
        phones:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Substitui a lista de telefones.
        websites:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: Substitui a lista de sites.
        is_default:
          type: boolean
          description: Quando `true`, marca esta empresa como padrão. Use o endpoint `set-default` para a operação dedicada.
        custom_metadata:
          type: object
          additionalProperties: {}
          description: Substitui os metadados customizados.
    CompanyFiscalProfileUpsertRequest:
      type: object
      properties:
        taxation_regime:
          type: string
          enum:
            - simple_national
            - presumed_profit
            - real_profit
            - mei
          description: "Regime tributário: `simple_national`, `presumed_profit`, `real_profit` ou `mei`."
        simples_annex:
          type:
            - string
            - "null"
          enum:
            - annex_iii
            - annex_iv
            - annex_v
          description: "Anexo do Simples Nacional: `annex_iii`, `annex_iv` ou `annex_v`."
        rbt12_cents:
          type:
            - integer
            - "null"
          minimum: 0
          description: Receita bruta acumulada nos últimos 12 meses, em centavos (÷100 → BRL).
        factor_r:
          type:
            - number
            - "null"
          description: Fator R (folha de pagamento ÷ receita), usado no enquadramento do Simples Nacional.
        cpp_inside_das:
          type: boolean
          description: Indica se a CPP (contribuição previdenciária patronal) está embutida no DAS.
        presumption_rate:
          type:
            - number
            - "null"
          description: "Alíquota de presunção (lucro presumido), em decimal (ex.: 0.32)."
        iss_municipality:
          type:
            - string
            - "null"
          description: Município de incidência do ISS.
        iss_rate:
          type:
            - number
            - "null"
          description: Alíquota do ISS, em decimal.
        pis_rate:
          type:
            - number
            - "null"
          description: Alíquota do PIS, em decimal.
        cofins_rate:
          type:
            - number
            - "null"
          description: Alíquota da COFINS, em decimal.
        csll_rate:
          type:
            - number
            - "null"
          description: Alíquota da CSLL, em decimal.
        irpj_rate:
          type:
            - number
            - "null"
          description: Alíquota do IRPJ, em decimal.
        cbs_ibs_enabled:
          type: boolean
          description: Habilita os campos CBS/IBS (Reforma Tributária).
        cbs_rate:
          type:
            - number
            - "null"
          description: Alíquota da CBS, em decimal.
        ibs_rate:
          type:
            - number
            - "null"
          description: Alíquota do IBS, em decimal.
        cbs_ibs_mode:
          type: string
          enum:
            - informative
            - compositive
          description: "Modo de cálculo CBS/IBS: `informative` (apenas demonstrativo) ou `compositive` (compõe o preço)."
      required:
        - taxation_regime
    CompanyFiscalProfileResponse:
      type: object
      properties:
        data: {}
    CertificatePersonV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: UUID do person.
        name:
          type: string
          description: Nome do person.
        document_number:
          type:
            - string
            - "null"
          description: CPF ou CNPJ do person.
      required:
        - id
        - name
        - document_number
    CertificateV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        person_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do `person` associado (quando o documento bate com um cadastro existente).
        name:
          type: string
          description: Nome amigável do certificado.
        status:
          type: string
          enum:
            - active
            - expired
            - revoked
          description: "Status do certificado: `active`, `expired` ou `revoked`."
        format:
          type: string
          enum:
            - pfx
            - pem
          description: "Formato do certificado armazenado: `pfx` ou `pem`."
        document:
          type:
            - string
            - "null"
          description: CPF ou CNPJ extraído do certificado (apenas dígitos).
        common_name:
          type:
            - string
            - "null"
          description: Nome comum (`CN`) do subject do certificado.
        organization_name:
          type:
            - string
            - "null"
          description: Nome da organização (`O`) do subject.
        organizational_unit:
          type:
            - string
            - "null"
          description: Unidade organizacional (`OU`) do subject.
        issuer_common_name:
          type:
            - string
            - "null"
          description: Nome comum (`CN`) do emissor (AC).
        issuer_organization:
          type:
            - string
            - "null"
          description: Organização (`O`) do emissor (AC).
        serial_number:
          type:
            - string
            - "null"
          description: Número de série do certificado.
        thumbprint:
          type:
            - string
            - "null"
          description: Thumbprint SHA-1 do certificado (hex maiúsculo). Único por certificado.
        not_before:
          type:
            - string
            - "null"
          format: date-time
          description: Início da validade do certificado (UTC).
        not_after:
          type:
            - string
            - "null"
          format: date-time
          description: Fim da validade do certificado (UTC).
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados internos do certificado.
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados arbitrários definidos pelo cliente.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        person:
          allOf:
            - $ref: "#/components/schemas/CertificatePersonV1"
            - type:
                - object
                - "null"
              description: Resumo do `person` associado (id, name, document_number), quando carregado.
      required:
        - id
        - person_id
        - name
        - status
        - format
        - document
        - common_name
        - organization_name
        - organizational_unit
        - issuer_common_name
        - issuer_organization
        - serial_number
        - thumbprint
        - not_before
        - not_after
        - created_at
        - updated_at
    CertificateListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/CertificateV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    CertificateResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/CertificateV1"
      required:
        - data
    CertificateUploadRequest:
      type: object
      properties:
        type:
          type: string
          enum:
            - pfx
            - cert_key
            - combined_pem
            - cert_key_password
          description: "Formato do envio: `pfx`, `cert_key`, `combined_pem` ou `cert_key_password`."
        name:
          type: string
          description: Nome amigável do certificado. Quando omitido, é derivado do `common_name` ou do documento.
        file:
          type: string
          description: Arquivo binário (PFX/P12) quando `type=pfx`, ou PEM combinado quando `type=combined_pem`.
          format: binary
        cert_file:
          type: string
          description: Arquivo PEM do certificado (somente para `type=cert_key` ou `type=cert_key_password`).
          format: binary
        key_file:
          type: string
          description: Arquivo PEM da chave privada (somente para `type=cert_key` ou `type=cert_key_password`).
          format: binary
        password:
          type: string
          description: Senha do PFX (`type=pfx`) ou da chave privada (`type=cert_key_password`). Armazenada criptografada e nunca retornada.
      required:
        - type
    CouponTargetV1:
      type: object
      properties:
        planIds:
          type: array
          items:
            type: string
            format: uuid
          description: Lista de UUIDs de planos.
        productIds:
          type: array
          items:
            type: string
            format: uuid
          description: Lista de UUIDs de produtos.
    CouponV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        code:
          type: string
          description: Código público do cupom — usado pelos clientes ao aplicar o desconto. Único por organização.
        name:
          type: string
          description: Nome interno do cupom (exibido no dashboard).
        description:
          type:
            - string
            - "null"
          description: Descrição opcional do cupom.
        discount_type:
          type: string
          enum:
            - percentage
            - fixed_amount
          description: "Tipo de desconto: `percentage` (em pontos percentuais) ou `fixed_amount` (em centavos, ÷100 → BRL)."
        discount_value:
          type: integer
          description: Valor do desconto. Quando `discount_type=percentage`, é um inteiro entre `0` e `100`. Quando `discount_type=fixed_amount`, é o valor em centavos (÷100 → BRL).
          example: 10
        currency:
          type: string
          description: "Moeda ISO 4217. Padrão: `BRL`."
          example: BRL
        min_purchase_cents:
          type:
            - integer
            - "null"
          description: Valor mínimo da fatura (em centavos, ÷100 → BRL) para o cupom poder ser aplicado.
        max_discount_cents:
          type:
            - integer
            - "null"
          description: Teto absoluto do desconto (em centavos, ÷100 → BRL). Aplica-se principalmente a cupons percentuais.
        usage_limit:
          type:
            - integer
            - "null"
          description: Número total de vezes que o cupom pode ser resgatado em toda a organização. `null` = ilimitado.
        usage_limit_per_user:
          type:
            - integer
            - "null"
          description: Número máximo de resgates por conta de cobrança. `null` = ilimitado.
        usage_count:
          type: integer
          description: Quantidade de resgates já registrados para o cupom.
          example: 0
        valid_from:
          type:
            - string
            - "null"
          format: date-time
          description: Início do período de validade (ISO 8601). `null` = sem início definido.
        valid_until:
          type:
            - string
            - "null"
          format: date-time
          description: Fim do período de validade (ISO 8601). `null` = sem expiração.
        applies_to:
          allOf:
            - $ref: "#/components/schemas/CouponTargetV1"
            - type:
                - object
                - "null"
              description: Restringe o cupom a planos e/ou produtos específicos. Quando `null`, vale para qualquer item.
        excludes:
          allOf:
            - $ref: "#/components/schemas/CouponTargetV1"
            - type:
                - object
                - "null"
              description: Lista de planos e/ou produtos onde o cupom **não** pode ser aplicado.
        is_active:
          type: boolean
          description: Quando `false`, o cupom não aceita novos resgates.
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados arbitrários definidos pelo cliente (chave/valor).
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - code
        - name
        - description
        - discount_type
        - discount_value
        - currency
        - min_purchase_cents
        - max_discount_cents
        - usage_limit
        - usage_limit_per_user
        - usage_count
        - valid_from
        - valid_until
        - applies_to
        - excludes
        - is_active
        - custom_metadata
        - created_at
        - updated_at
    CouponListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/CouponV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    CouponResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/CouponV1"
      required:
        - data
    CouponCreateRequest:
      type: object
      properties:
        code:
          type: string
          minLength: 1
          description: Código público do cupom — único por organização.
        name:
          type: string
          minLength: 1
          description: Nome interno do cupom.
        description:
          type: string
          description: Descrição opcional.
        discount_type:
          type: string
          enum:
            - percentage
            - fixed_amount
          description: "Tipo de desconto: `percentage` ou `fixed_amount`."
        discount_value:
          type: integer
          minimum: 0
          description: Valor do desconto. Para `percentage`, inteiro entre `0` e `100`. Para `fixed_amount`, valor em centavos (÷100 → BRL).
        currency:
          type: string
          description: "Moeda ISO 4217. Padrão: `BRL`."
        min_purchase_cents:
          type: integer
          minimum: 0
          description: Valor mínimo da fatura, em centavos (÷100 → BRL), para o cupom poder ser aplicado.
        max_discount_cents:
          type: integer
          minimum: 0
          description: Teto absoluto do desconto, em centavos (÷100 → BRL).
        usage_limit:
          type: integer
          exclusiveMinimum: 0
          description: Total máximo de resgates na organização. Omita para ilimitado.
        usage_limit_per_user:
          type: integer
          exclusiveMinimum: 0
          description: Máximo de resgates por conta de cobrança. Omita para ilimitado.
        valid_from:
          type: string
          description: Início do período de validade (ISO 8601 — data ou data/hora).
        valid_until:
          type: string
          description: Fim do período de validade (ISO 8601 — data ou data/hora).
        applies_to:
          allOf:
            - $ref: "#/components/schemas/CouponTargetV1"
            - description: Restringe o cupom a planos e/ou produtos.
        excludes:
          allOf:
            - $ref: "#/components/schemas/CouponTargetV1"
            - description: Lista de planos e/ou produtos onde o cupom não pode ser aplicado.
        custom_metadata:
          type: object
          additionalProperties: {}
          description: Metadados arbitrários definidos pelo cliente (chave/valor).
      required:
        - code
        - name
        - discount_type
        - discount_value
    CouponUpdateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          description: Novo nome interno do cupom.
        description:
          type:
            - string
            - "null"
          description: Nova descrição. Envie `null` para limpar.
        usage_limit:
          type:
            - integer
            - "null"
          exclusiveMinimum: 0
          description: Novo limite total de resgates. `null` = ilimitado.
        usage_limit_per_user:
          type:
            - integer
            - "null"
          exclusiveMinimum: 0
          description: Novo limite por conta de cobrança. `null` = ilimitado.
        valid_from:
          type:
            - string
            - "null"
          description: Novo início de validade (ISO 8601). `null` = remove a restrição.
        valid_until:
          type:
            - string
            - "null"
          description: Novo fim de validade (ISO 8601). `null` = remove a expiração.
        applies_to:
          allOf:
            - $ref: "#/components/schemas/CouponTargetV1"
            - type:
                - object
                - "null"
              description: Nova restrição de planos/produtos. `null` = remove a restrição.
        excludes:
          allOf:
            - $ref: "#/components/schemas/CouponTargetV1"
            - type:
                - object
                - "null"
              description: Nova lista de exclusões. `null` = remove as exclusões.
        custom_metadata:
          type: object
          additionalProperties: {}
          description: Metadados arbitrários definidos pelo cliente (chave/valor).
    CouponRedemptionV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        coupon_id:
          type: string
          format: uuid
          description: UUID do cupom resgatado.
        billing_account_id:
          type: string
          format: uuid
          description: UUID da conta de cobrança que aplicou o cupom.
        invoice_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da fatura onde o desconto foi aplicado, quando aplicável.
        discount_cents:
          type: integer
          description: Valor efetivamente descontado neste resgate, em centavos (÷100 → BRL).
        created_at:
          type: string
          format: date-time
      required:
        - id
        - coupon_id
        - billing_account_id
        - invoice_id
        - discount_cents
        - created_at
    CouponRedemptionListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/CouponRedemptionV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    CreditV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        billing_account_id:
          type: string
          format: uuid
          description: UUID da conta de cobrança dona do crédito.
        organization_id:
          type: string
          format: uuid
          description: UUID da organização (tenant).
        company_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID opcional da `company` vinculada. Quando preenchido, o crédito só pode ser aplicado a faturas da mesma `company`.
        type:
          type: string
          enum:
            - promotional
            - adjustment
            - refund
            - manual
          description: "Tipo do crédito: `promotional`, `adjustment`, `refund` ou `manual`."
        amount_cents:
          type: integer
          description: Valor original do crédito em centavos (÷100 → BRL).
          example: 10000
        amount_remaining_cents:
          type: integer
          description: Saldo remanescente do crédito em centavos (÷100 → BRL).
          example: 10000
        currency:
          type: string
          description: "Moeda ISO 4217 (ex.: `BRL`)."
          example: BRL
        description:
          type:
            - string
            - "null"
          description: Descrição livre — exibida no extrato e no audit log.
        expires_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data e hora de expiração (ISO8601). `null` quando o crédito não expira.
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados internos do crédito.
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados customizados validados contra o schema da organização.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        applications:
          type: array
          items: {}
          description: Aplicações deste crédito em faturas, quando a relação é carregada.
      required:
        - id
        - billing_account_id
        - organization_id
        - company_id
        - type
        - amount_cents
        - amount_remaining_cents
        - currency
        - description
        - expires_at
        - metadata
        - custom_metadata
        - created_at
        - updated_at
    CreditListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/CreditV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    CreditResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/CreditV1"
      required:
        - data
    CreditCreateRequest:
      type: object
      properties:
        billing_account_id:
          type: string
          format: uuid
          description: UUID da conta de cobrança que receberá o crédito.
        company_id:
          type: string
          format: uuid
          description: UUID opcional da `company` à qual o crédito está vinculado. Quando informado, restringe a aplicação do crédito a faturas da mesma `company`.
        type:
          type: string
          enum:
            - promotional
            - adjustment
            - refund
            - manual
          description: "Tipo do crédito: `promotional`, `adjustment`, `refund` ou `manual`."
        amount_cents:
          type: integer
          exclusiveMinimum: 0
          description: Valor do crédito em centavos (÷100 → BRL). Deve ser inteiro positivo.
          example: 10000
        description:
          type: string
          maxLength: 500
          description: Descrição livre (até 500 caracteres) — exibida no extrato e no audit log.
        expires_at:
          type: string
          format: date-time
          description: Data e hora de expiração (ISO8601). Após essa data o saldo remanescente é descartado.
        custom_metadata:
          type: object
          additionalProperties: {}
          description: Metadados customizados validados contra o schema da organização.
      required:
        - billing_account_id
        - type
        - amount_cents
    CreditUpdateRequest:
      type: object
      properties:
        type:
          type: string
          enum:
            - promotional
            - adjustment
            - refund
            - manual
          description: "Novo tipo do crédito: `promotional`, `adjustment`, `refund` ou `manual`."
        amount_cents:
          type: integer
          exclusiveMinimum: 0
          description: Novo valor em centavos (÷100 → BRL). Inteiro positivo. Só pode mudar se o crédito ainda não foi consumido.
        description:
          type:
            - string
            - "null"
          maxLength: 500
          description: Nova descrição. Envie `null` para limpar.
        expires_at:
          type:
            - string
            - "null"
          format: date-time
          description: Nova data de expiração (ISO8601). Envie `null` para remover a expiração.
        custom_metadata:
          type: object
          additionalProperties: {}
          description: Metadados customizados validados contra o schema da organização.
    CreditDeleteResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            deleted:
              type: boolean
              example: true
          required:
            - deleted
      required:
        - data
    InvoiceLineItemV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        invoice_id:
          type: string
          format: uuid
        subscription_item_id:
          type:
            - string
            - "null"
          format: uuid
        product_id:
          type:
            - string
            - "null"
          format: uuid
        price_id:
          type:
            - string
            - "null"
          format: uuid
        service_item_id:
          type:
            - string
            - "null"
          format: uuid
        type:
          type:
            - string
            - "null"
        description:
          type:
            - string
            - "null"
          description: Descrição do item.
        quantity:
          type: number
          description: Quantidade.
        unit_amount_subcents:
          type: integer
          description: Valor unitário em subcentavos (÷10000 → BRL).
        amount_cents:
          type: integer
          description: Subtotal do item em centavos (÷100 → BRL).
        discount_cents:
          type:
            - integer
            - "null"
        tax_cents:
          type:
            - integer
            - "null"
        period_start:
          type:
            - string
            - "null"
          format: date-time
        period_end:
          type:
            - string
            - "null"
          format: date-time
        proration:
          type:
            - boolean
            - "null"
        proration_details: {}
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
        created_at:
          type: string
          format: date-time
      required:
        - id
        - invoice_id
        - quantity
        - unit_amount_subcents
        - amount_cents
        - created_at
    InvoiceInstallmentV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        public_id:
          type:
            - string
            - "null"
        invoice_id:
          type: string
          format: uuid
        number:
          type: integer
          description: Número sequencial da parcela (começa em 1).
        amount_cents:
          type: integer
          description: Valor da parcela em centavos (÷100 → BRL).
        due_date:
          type: string
          format: date-time
          description: Data de vencimento da parcela.
        status:
          type: string
          enum:
            - pending
            - paid
            - canceled
          description: "Status da parcela: `pending`, `paid` ou `canceled`."
        payment_id:
          type:
            - string
            - "null"
          format: uuid
        paid_at:
          type:
            - string
            - "null"
          format: date-time
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - invoice_id
        - number
        - amount_cents
        - due_date
        - status
        - created_at
        - updated_at
    InvoiceV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        number:
          type:
            - string
            - "null"
          description: Número humano-legível da fatura (gerado ao finalizar).
        billing_account_id:
          type: string
          format: uuid
          description: UUID da conta de cobrança alvo.
        company_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da empresa emissora (opcional — padrão é a `default_company` da organização).
        subscription_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da assinatura de origem, quando a fatura provém de uma assinatura.
        product_group_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do grupo de produtos, quando a fatura está restrita a um grupo.
        status:
          type: string
          enum:
            - draft
            - open
            - paid
            - void
            - uncollectible
          description: "Status: `draft`, `open`, `paid`, `void` ou `uncollectible`."
        collection_method:
          type: string
          enum:
            - charge_automatically
            - manual_charge
            - manual_invoice
          description: "Método de cobrança: `charge_automatically`, `manual_charge` ou `manual_invoice`."
        currency:
          type: string
          description: "Moeda ISO 4217 (ex.: `BRL`)."
          example: BRL
        subtotal_cents:
          type: integer
          description: Soma dos itens de linha em centavos (÷100 → BRL).
        discount_cents:
          type: integer
          description: Desconto aplicado em centavos (÷100 → BRL).
        tax_cents:
          type: integer
          description: Impostos calculados em centavos (÷100 → BRL).
        total_withheld_cents:
          type: integer
          description: Total de retenções tributárias (IRRF/ISS/INSS/CSRF) em centavos.
        net_value_cents:
          type:
            - integer
            - "null"
          description: Valor líquido após retenções, em centavos.
        total_cents:
          type: integer
          description: Valor total da fatura em centavos (÷100 → BRL).
        amount_due_cents:
          type: integer
          description: Valor devido (cobrado) em centavos.
        amount_paid_cents:
          type: integer
          description: Valor já pago em centavos.
        amount_remaining_cents:
          type: integer
          description: Valor restante a pagar em centavos.
        period_start:
          type:
            - string
            - "null"
          format: date-time
          description: Início do período de competência (faturas de assinatura).
        period_end:
          type:
            - string
            - "null"
          format: date-time
          description: Fim do período de competência (faturas de assinatura).
        due_date:
          type:
            - string
            - "null"
          format: date-time
          description: Data de vencimento.
        paid_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data e hora em que a fatura foi quitada.
        voided_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data e hora em que a fatura foi cancelada (`void`).
        finalized_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data e hora em que a fatura saiu do rascunho (`draft` → `open`).
        billing_reason:
          type:
            - string
            - "null"
          description: "Motivo da geração: `subscription_cycle`, `subscription_create`, `manual`, etc."
        description:
          type:
            - string
            - "null"
          description: Descrição livre exibida no topo da fatura.
        footer:
          type:
            - string
            - "null"
          description: Rodapé livre exibido ao final da fatura.
        hosted_invoice_url:
          type:
            - string
            - "null"
          description: URL pública hospedada da fatura.
        invoice_pdf_url:
          type:
            - string
            - "null"
          description: URL direta do PDF da fatura.
        next_payment_attempt:
          type:
            - string
            - "null"
          format: date-time
          description: Próxima tentativa de cobrança automática (dunning).
        payment_attempts:
          type: integer
          description: Quantidade de tentativas de cobrança realizadas.
        installment_count:
          type:
            - integer
            - "null"
          description: Quantidade de parcelas (quando a fatura é parcelada).
        nfe_issuance_policy:
          type:
            - string
            - "null"
          enum:
            - disabled
            - on_finalization
            - on_full_payment
            - per_installment
          description: "Política de emissão de NFe: `disabled`, `on_finalization`, `on_full_payment` ou `per_installment`."
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Campos personalizados definidos pela organização.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        line_items:
          type: array
          items:
            $ref: "#/components/schemas/InvoiceLineItemV1"
          description: Itens de linha — presente quando incluído via `include=line_items`.
        installments:
          type: array
          items:
            $ref: "#/components/schemas/InvoiceInstallmentV1"
          description: Parcelas — presente quando incluído via `include=installments`.
      required:
        - id
        - number
        - billing_account_id
        - company_id
        - subscription_id
        - product_group_id
        - status
        - collection_method
        - currency
        - subtotal_cents
        - discount_cents
        - tax_cents
        - total_withheld_cents
        - net_value_cents
        - total_cents
        - amount_due_cents
        - amount_paid_cents
        - amount_remaining_cents
        - period_start
        - period_end
        - due_date
        - paid_at
        - voided_at
        - finalized_at
        - billing_reason
        - description
        - footer
        - hosted_invoice_url
        - invoice_pdf_url
        - next_payment_attempt
        - payment_attempts
        - installment_count
        - nfe_issuance_policy
        - created_at
        - updated_at
    InvoiceListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/InvoiceV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    InvoiceResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/InvoiceV1"
      required:
        - data
    InvoiceLineItemCreateInput:
      type: object
      properties:
        description:
          type: string
          minLength: 1
          description: Descrição do item. **Obrigatório**.
        quantity:
          type: number
          minimum: 1
          description: "Quantidade. Padrão: 1."
        unit_amount_cents:
          type: number
          minimum: 0
          description: Valor unitário em centavos.
        product_id:
          type: string
          format: uuid
          description: UUID do produto (opcional).
        price_id:
          type: string
          format: uuid
          description: UUID do preço (opcional).
        service_item_id:
          type: string
          format: uuid
          description: UUID do item de serviço (opcional).
      required:
        - description
        - unit_amount_cents
    InvoiceInstallmentCreateInput:
      type: object
      properties:
        amount_cents:
          type: integer
          minimum: 1
          description: Valor da parcela em centavos.
        due_date:
          type: string
          description: Data de vencimento da parcela.
      required:
        - amount_cents
        - due_date
    InvoiceCreateRequest:
      type: object
      properties:
        billing_account_id:
          type: string
          format: uuid
          description: UUID da conta de cobrança alvo. **Obrigatório**.
        company_id:
          type: string
          format: uuid
          description: "UUID da empresa emissora. Padrão: empresa padrão da organização."
        subscription_id:
          type: string
          format: uuid
          description: UUID da assinatura de origem.
        product_group_id:
          type: string
          format: uuid
          description: UUID do grupo de produtos.
        collection_method:
          type: string
          enum:
            - charge_automatically
            - manual_charge
            - manual_invoice
          description: "Método de cobrança. Padrão: `manual_invoice`."
        due_date:
          type: string
          description: "Data de vencimento. Padrão: hoje + `payment_terms_days` da conta."
        description:
          type: string
          description: Descrição livre exibida no topo da fatura.
        footer:
          type: string
          description: Rodapé livre exibido ao final da fatura.
        line_items:
          type: array
          items:
            $ref: "#/components/schemas/InvoiceLineItemCreateInput"
          minItems: 1
          description: Itens de linha. Mínimo 1.
        discount_cents:
          type: integer
          minimum: 0
          description: Desconto fixo em centavos.
        discount_description:
          type: string
          description: 'Descrição do desconto (ex.: "Desconto por pagamento anual (20%)").'
        installments:
          type: array
          items:
            $ref: "#/components/schemas/InvoiceInstallmentCreateInput"
          minItems: 2
          description: Cronograma de parcelas (mínimo 2). Cada item tem `amount_cents` e `due_date`.
        nfe_issuance_policy:
          type: string
          enum:
            - disabled
            - on_finalization
            - on_full_payment
            - per_installment
          description: Política de emissão de NFe para faturas parceladas.
        period_start:
          type: string
          description: Início do período de competência (preenchido automaticamente em faturas de assinatura).
        period_end:
          type: string
          description: Fim do período de competência (preenchido automaticamente em faturas de assinatura).
        custom_metadata:
          type: object
          additionalProperties: {}
          description: Campos personalizados (validados contra o schema da organização).
      required:
        - billing_account_id
        - line_items
    InvoiceLineItemUpdateInput:
      type: object
      properties:
        id:
          type: string
          format: uuid
        description:
          type: string
          minLength: 1
        quantity:
          type: number
          minimum: 1
        unit_amount_cents:
          type: number
          minimum: 0
      required:
        - description
        - unit_amount_cents
    InvoiceUpdateRequest:
      type: object
      properties:
        company_id:
          type:
            - string
            - "null"
          format: uuid
          description: Atualiza a empresa emissora. Use `null` para limpar.
        collection_method:
          type: string
          enum:
            - charge_automatically
            - manual_charge
            - manual_invoice
          description: Atualiza o método de cobrança.
        due_date:
          type: string
          description: Atualiza a data de vencimento.
        description:
          type: string
        footer:
          type: string
        line_items:
          type: array
          items:
            $ref: "#/components/schemas/InvoiceLineItemUpdateInput"
          description: Substitui os itens de linha. Para preservar um item, envie seu `id`.
        nfe_issuance_policy:
          type:
            - string
            - "null"
          enum:
            - disabled
            - on_finalization
            - on_full_payment
            - per_installment
          description: Atualiza a política de NFe. Use `null` para limpar.
        custom_metadata:
          type: object
          additionalProperties: {}
    InvoiceVoidRequest:
      type: object
      properties:
        reason:
          type: string
          description: Motivo do cancelamento (registrado no audit log).
    InvoiceUndoPaymentRequest:
      type: object
      properties:
        reason:
          type: string
          description: Motivo da reversão (registrado no audit log).
    InvoicePayRequest:
      type: object
      properties:
        payment_method:
          type: string
          enum:
            - pix
            - bank_slip
            - card
          description: "Quando informado, dispara o gateway: `pix`, `bank_slip` ou `card`. Omita para marcar como paga manualmente."
        payment_method_id:
          type: string
          format: uuid
          description: "UUID de um método de pagamento salvo (ex.: cartão tokenizado)."
        card:
          type: object
          properties:
            card_token:
              type: string
              minLength: 1
              description: Token do cartão obtido no front-end via o SDK do gateway.
            holder_name:
              type: string
              minLength: 3
              description: Nome impresso no cartão (mínimo 3 caracteres).
          required:
            - card_token
            - holder_name
          description: Dados do cartão quando `payment_method = card` e não há `payment_method_id`.
        amount_cents:
          type: integer
          exclusiveMinimum: 0
          description: "Valor a cobrar em centavos. Padrão: valor restante da fatura."
        installment_ids:
          type: array
          items:
            type: string
            format: uuid
          description: UUIDs das parcelas que o pagamento cobre (faturas parceladas).
    InvoicePayResponse:
      type: object
      properties:
        data:
          type: object
          additionalProperties: {}
      required:
        - data
    InvoiceApplyCreditsRequest:
      type: object
      properties:
        credit_ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
          description: UUIDs dos créditos a aplicar (mínimo 1).
        amount_cents:
          type: integer
          exclusiveMinimum: 0
          description: "Valor a aplicar em centavos. Padrão: cobre toda a fatura."
      required:
        - credit_ids
    InvoiceCreditsResponse:
      type: object
      properties:
        data:
          type: object
          additionalProperties: {}
      required:
        - data
    InvoiceNfeResponse:
      type: object
      properties:
        data:
          type: object
          additionalProperties: {}
      required:
        - data
    InvoicePaymentMethodsResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            invoice_id:
              type: string
              format: uuid
            methods:
              type: array
              items:
                type: string
                enum:
                  - card
                  - bank_slip
                  - pix
                  - bank_transfer
            details:
              type: array
              items:
                type: object
                properties:
                  type:
                    type: string
                    enum:
                      - card
                      - bank_slip
                      - pix
                      - bank_transfer
                  gateway_id:
                    type: string
                    format: uuid
                  gateway_name:
                    type: string
                  is_default:
                    type: boolean
                required:
                  - type
                  - gateway_id
                  - gateway_name
                  - is_default
            pagarme_public_key:
              type: string
          required:
            - invoice_id
            - methods
            - details
      required:
        - data
    InvoiceInstallmentsListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/InvoiceInstallmentV1"
      required:
        - data
    InvoiceInstallmentsCreateRequest:
      type: object
      properties:
        installments:
          type: array
          items:
            $ref: "#/components/schemas/InvoiceInstallmentCreateInput"
          minItems: 2
          description: Lista de parcelas. Mínimo 2.
      required:
        - installments
    InvoiceInstallmentResponse:
      type: object
      properties:
        data:
          allOf:
            - $ref: "#/components/schemas/InvoiceInstallmentV1"
            - type:
                - object
                - "null"
      required:
        - data
    InvoiceInstallmentPayRequest:
      type: object
      properties:
        payment_method:
          type: string
          enum:
            - pix
            - bank_slip
            - card
          description: "Quando informado, dispara o gateway: `pix`, `bank_slip` ou `card`. Omita para marcar como paga manualmente."
        payment_method_id:
          type: string
          format: uuid
          description: "UUID de um método de pagamento salvo (ex.: cartão tokenizado)."
        card:
          type: object
          properties:
            card_token:
              type: string
              minLength: 1
              description: Token do cartão obtido no front-end via o SDK do gateway.
            holder_name:
              type: string
              minLength: 3
              description: Nome impresso no cartão (mínimo 3 caracteres).
          required:
            - card_token
            - holder_name
          description: Dados do cartão quando `payment_method = card` e não há `payment_method_id`.
      required:
        - payment_method
    InvoiceDeletedResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            deleted:
              type: boolean
              example: true
          required:
            - deleted
      required:
        - data
    PaymentV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        invoice_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da fatura associada, quando houver.
        billing_account_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da conta de cobrança.
        company_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da empresa emissora.
        payment_method_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do meio de pagamento utilizado.
        gateway_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do gateway que processou o pagamento.
        payment_method_type:
          type:
            - string
            - "null"
          enum:
            - card
            - bank_slip
            - pix
            - bank_transfer
          description: "Tipo do meio de pagamento: `card`, `bank_slip`, `pix` ou `bank_transfer`."
        amount_cents:
          type: integer
          description: Valor cobrado em centavos (÷100 → BRL).
          example: 10000
        paid_amount_cents:
          type:
            - integer
            - "null"
          description: Valor efetivamente recebido em centavos (÷100 → BRL).
        currency:
          type: string
          description: "Moeda ISO 4217 (ex.: `BRL`)."
          example: BRL
        status:
          type: string
          enum:
            - pending
            - processing
            - succeeded
            - failed
            - canceled
            - partial
            - refunded
            - partially_refunded
          description: "Status: `pending`, `processing`, `succeeded`, `failed`, `canceled`, `partial`, `refunded` ou `partially_refunded`."
        payment_gateway:
          type:
            - string
            - "null"
          description: "Nome do gateway upstream (ex.: `KOBANA`, `PAGARME`)."
        gateway_payment_id:
          type:
            - string
            - "null"
          description: Identificador do pagamento no gateway upstream.
        failure_code:
          type:
            - string
            - "null"
          description: Código de falha retornado pelo gateway.
        failure_message:
          type:
            - string
            - "null"
          description: Mensagem de falha retornada pelo gateway.
        idempotency_key:
          type:
            - string
            - "null"
          description: Chave de idempotência fornecida ao criar o pagamento.
        paid_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data/hora da confirmação do pagamento.
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados livres definidos pelo cliente.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - invoice_id
        - billing_account_id
        - company_id
        - payment_method_id
        - gateway_id
        - payment_method_type
        - amount_cents
        - paid_amount_cents
        - currency
        - status
        - payment_gateway
        - gateway_payment_id
        - failure_code
        - failure_message
        - idempotency_key
        - paid_at
        - custom_metadata
        - created_at
        - updated_at
    PaymentListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/PaymentV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    PaymentResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/PaymentV1"
      required:
        - data
    PaymentCreateCard:
      type: object
      properties:
        cardToken:
          type: string
          minLength: 1
          description: Token de cartão emitido pelo gateway (preferencial).
        number:
          type: string
          minLength: 13
          maxLength: 19
          description: Número do cartão (PAN). Use o token sempre que possível.
        expMonth:
          type: integer
          minimum: 1
          maximum: 12
          description: Mês de expiração (1–12).
        expYear:
          type: integer
          description: Ano de expiração (≥ ano atual).
        cvv:
          type: string
          minLength: 3
          maxLength: 4
          description: CVV/CVC do cartão (3 a 4 dígitos).
        holderName:
          type: string
          minLength: 1
          description: Nome do portador como impresso no cartão.
      required:
        - holderName
    PaymentCreatePaymentMethod:
      type: object
      properties:
        type:
          type: string
          enum:
            - card
            - bank_slip
            - pix
          description: "Tipo do meio de pagamento: `card`, `bank_slip` ou `pix`."
        card:
          allOf:
            - $ref: "#/components/schemas/PaymentCreateCard"
            - description: Dados do cartão — token (preferencial) **ou** PAN/expiração/CVV.
      required:
        - type
    PaymentCreateRequest:
      type: object
      properties:
        invoiceId:
          type: string
          format: uuid
          description: UUID da fatura a ser paga.
        paymentMethodId:
          type: string
          format: uuid
          description: UUID de um meio de pagamento previamente registrado para a conta.
        paymentMethod:
          allOf:
            - $ref: "#/components/schemas/PaymentCreatePaymentMethod"
            - description: Bloco com dados do meio de pagamento — usado quando não há `payment_method_id`.
        amountCents:
          type: integer
          minimum: 1
          description: "Valor a cobrar em centavos (÷100 → BRL). Padrão: saldo aberto da fatura."
        customMetadata:
          type: object
          additionalProperties: {}
          description: Metadados livres definidos pelo cliente para correlação interna.
      required:
        - invoiceId
    PaymentCancelRequest:
      type: object
      properties:
        reason:
          type: string
          description: Motivo do cancelamento (registrado no audit log).
        cancel_on_gateway:
          type: boolean
          description: Quando `true` (padrão), também cancela no gateway upstream.
    PaymentRetryCard:
      type: object
      properties:
        cardToken:
          type: string
          minLength: 1
          description: Token de cartão emitido pelo gateway.
        holderName:
          type: string
          minLength: 3
          description: Nome do portador como impresso no cartão.
      required:
        - cardToken
        - holderName
    PaymentRetryRequest:
      type: object
      properties:
        card:
          allOf:
            - $ref: "#/components/schemas/PaymentRetryCard"
            - description: Cartão alternativo (token e portador) para a nova tentativa.
        payment_method_id:
          type: string
          format: uuid
          description: UUID de um meio de pagamento salvo a ser usado na nova tentativa.
    PaymentChangeCardRequest:
      type: object
      properties:
        credit_card_id:
          type: string
          format: uuid
          description: UUID do cartão de crédito ativo da conta de cobrança.
      required:
        - credit_card_id
    PaymentChangeDueDateRequest:
      type: object
      properties:
        due_date:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
          description: Nova data de vencimento no formato `YYYY-MM-DD`.
          example: 2026-08-15
      required:
        - due_date
    PaymentChangeDueDateResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            due_date:
              type: string
            updated:
              type: boolean
          required:
            - due_date
            - updated
      required:
        - data
    PaymentSendEmailRequest:
      type: object
      properties:
        email:
          type: string
          format: email
          description: Endereço de e-mail do destinatário.
        message:
          type: string
          description: Mensagem opcional incluída no corpo do e-mail.
      required:
        - email
    PaymentSendEmailResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            sent:
              type: boolean
            email:
              type: string
              format: email
          required:
            - sent
            - email
      required:
        - data
    PaymentRefundRequest:
      type: object
      properties:
        amount_cents:
          type: integer
          minimum: 1
          description: "Valor a estornar em centavos (÷100 → BRL). Padrão: valor total do pagamento."
        reason:
          type: string
          description: Motivo do estorno (registrado no audit log).
    PaymentBulkUpdateInvoiceRequest:
      type: object
      properties:
        payment_ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
          description: Lista de UUIDs dos pagamentos a atualizar.
        invoice_id:
          type: string
          format: uuid
          description: UUID da fatura de destino.
      required:
        - payment_ids
        - invoice_id
    PaymentBulkUpdateInvoiceResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            updated_count:
              type: integer
          required:
            - updated_count
      required:
        - data
    PaymentDeletedResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            deleted:
              type: boolean
              example: true
          required:
            - deleted
      required:
        - data
    PaymentMethodCreditCardV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: UUID do registro de cartão.
        status:
          type: string
          enum:
            - active
            - expired
            - removed
          description: "Status do cartão: `active`, `expired`, `removed`."
        brand:
          type:
            - string
            - "null"
          description: "Bandeira do cartão (ex.: `visa`, `mastercard`)."
          example: visa
        last_four_digits:
          type:
            - string
            - "null"
          description: Últimos quatro dígitos do cartão.
          example: "4242"
        holder_name:
          type:
            - string
            - "null"
          description: Nome do portador como impresso no cartão.
        expiration_month:
          type:
            - integer
            - "null"
          description: Mês de validade (1–12).
          example: 12
        expiration_year:
          type:
            - integer
            - "null"
          description: Ano de validade (4 dígitos).
          example: 2030
      required:
        - id
        - status
        - brand
        - last_four_digits
        - holder_name
        - expiration_month
        - expiration_year
    PaymentMethodBankAccountV1:
      type: object
      properties:
        bank_code:
          type:
            - string
            - "null"
          description: Código de compensação do banco (FEBRABAN, 3 dígitos).
          example: "341"
        bank_name:
          type:
            - string
            - "null"
          description: Nome do banco, resolvido a partir do `bank_code`.
          example: Itaú
        agency:
          type:
            - string
            - "null"
          description: Agência bancária.
        account:
          type:
            - string
            - "null"
          description: Número da conta bancária.
        account_type:
          type:
            - string
            - "null"
          enum:
            - checking
            - savings
          description: "Tipo de conta: `checking` ou `savings`."
        holder_name:
          type:
            - string
            - "null"
          description: Nome do titular da conta.
      required:
        - bank_code
        - bank_name
        - agency
        - account
        - account_type
        - holder_name
    PaymentMethodV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        billing_account_id:
          type: string
          format: uuid
          description: UUID da conta de cobrança proprietária.
        credit_card_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do `credit_card` associado, quando `type=card`.
        type:
          type: string
          enum:
            - card
            - bank_slip
            - pix
            - bank_transfer
          description: "Tipo do método: `card`, `bank_slip`, `pix` ou `bank_transfer`."
        status:
          type: string
          enum:
            - active
            - expired
            - failed
            - removed
          description: "Status do método: `active`, `expired`, `failed` ou `removed`."
        is_default:
          type: boolean
          description: Indica se este é o método padrão da conta de cobrança.
        is_backup:
          type: boolean
          description: Indica se o método é usado como backup do padrão.
        billing_details:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Dados de cobrança opcionais (nome, e-mail, telefone, endereço) enviados ao gateway.
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados customizados em formato livre (`object`).
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        bank_account:
          allOf:
            - $ref: "#/components/schemas/PaymentMethodBankAccountV1"
            - description: Resumo público da conta bancária, presente quando `type=bank_transfer`. Não inclui o documento do titular.
        credit_card:
          allOf:
            - $ref: "#/components/schemas/PaymentMethodCreditCardV1"
            - description: Resumo público do cartão, presente quando `type=card`. Não inclui tokens do gateway nem fingerprint.
      required:
        - id
        - billing_account_id
        - credit_card_id
        - type
        - status
        - is_default
        - is_backup
        - created_at
        - updated_at
    PaymentMethodListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/PaymentMethodV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    PaymentMethodResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/PaymentMethodV1"
      required:
        - data
    PaymentMethodCardInput:
      type: object
      properties:
        cardToken:
          type: string
          minLength: 1
          description: Token do cartão gerado pela tokenização client-side do gateway.
        holderName:
          type: string
          minLength: 1
          description: Nome do portador como impresso no cartão.
      required:
        - cardToken
        - holderName
    PaymentMethodBankAccountInput:
      type: object
      properties:
        bankCode:
          type: string
          minLength: 3
          maxLength: 3
          description: Código de compensação do banco (FEBRABAN, 3 dígitos).
          example: "341"
        agency:
          type: string
          minLength: 1
          description: Agência bancária.
        account:
          type: string
          minLength: 1
          description: Número da conta bancária.
        accountType:
          type: string
          enum:
            - checking
            - savings
          description: "Tipo de conta: `checking` ou `savings`."
        holderName:
          type: string
          minLength: 1
          description: Nome do titular da conta.
        holderDocument:
          type: string
          minLength: 11
          maxLength: 14
          description: CPF ou CNPJ do titular (11 a 14 dígitos).
      required:
        - bankCode
        - agency
        - account
        - accountType
        - holderName
        - holderDocument
    PaymentMethodBillingAddress:
      type: object
      properties:
        street:
          type: string
        number:
          type: string
        complement:
          type: string
        neighborhood:
          type: string
        city:
          type: string
        state:
          type: string
          minLength: 2
          maxLength: 2
        zipCode:
          type: string
        country:
          type: string
      required:
        - street
        - number
        - neighborhood
        - city
        - state
        - zipCode
    PaymentMethodBillingDetailsInput:
      type: object
      properties:
        name:
          type: string
          description: Nome para os dados de cobrança.
        email:
          type: string
          format: email
          description: E-mail para os dados de cobrança.
        phone:
          type: string
          description: Telefone para os dados de cobrança.
        address:
          allOf:
            - $ref: "#/components/schemas/PaymentMethodBillingAddress"
            - description: Endereço de cobrança.
    PaymentMethodCreateRequest:
      type: object
      properties:
        billingAccountId:
          type: string
          format: uuid
          description: UUID da conta de cobrança proprietária do método de pagamento.
        type:
          type: string
          enum:
            - card
            - bank_slip
            - pix
            - bank_transfer
          description: "Tipo do método: `card`, `bank_slip`, `pix` ou `bank_transfer`."
        isDefault:
          type: boolean
          description: Quando `true`, marca este método como padrão da conta (desmarca os anteriores). O primeiro método criado para uma conta também vira padrão automaticamente.
        card:
          allOf:
            - $ref: "#/components/schemas/PaymentMethodCardInput"
            - description: Bloco de cartão. Obrigatório quando `type=card`.
        bankAccount:
          allOf:
            - $ref: "#/components/schemas/PaymentMethodBankAccountInput"
            - description: Bloco de conta bancária. Obrigatório quando `type=bank_transfer`.
        billingDetails:
          allOf:
            - $ref: "#/components/schemas/PaymentMethodBillingDetailsInput"
            - description: Dados de cobrança opcionais (nome, e-mail, telefone, endereço) usados pelo gateway.
      required:
        - billingAccountId
        - type
    PaymentMethodUpdateRequest:
      type: object
      properties:
        exp_month:
          type: integer
          minimum: 1
          maximum: 12
          description: Mês de validade do cartão (1–12).
        exp_year:
          type: integer
          description: Ano de validade do cartão (>= ano atual).
      required:
        - exp_month
        - exp_year
    NfeV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        invoice_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da fatura vinculada (quando a NFe foi emitida para uma fatura).
        transaction_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da transação de origem, quando aplicável.
        billing_account_id:
          type: string
          format: uuid
          description: UUID da conta de cobrança (tomador) da NFe.
        organization_id:
          type: string
          format: uuid
          description: UUID da organização emissora.
        company_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da empresa emissora (prestador). Opcional quando a organização tem empresa padrão.
        person_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da pessoa (tomador) associada à NFe.
        status:
          type: string
          enum:
            - draft
            - pending
            - processing
            - issued
            - pending_cancel
            - canceling
            - canceled
            - error
          description: "Status: `draft`, `pending`, `processing`, `issued`, `pending_cancel`, `canceling`, `canceled` ou `error`."
        nfe_number:
          type:
            - integer
            - "null"
          description: Número da NFe atribuído pela prefeitura (preenchido após emissão).
        nfe_series:
          type:
            - string
            - "null"
          description: Série da NFe.
        nfe_key:
          type:
            - string
            - "null"
          description: Chave de acesso única da NFe (44 ou 50 dígitos, conforme o município).
        verification_code:
          type:
            - string
            - "null"
          description: Código de verificação/autenticidade impresso no DANFSE.
        issue_date:
          type:
            - string
            - "null"
          format: date-time
          description: Data e hora de emissão pela prefeitura.
        cancelled_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data e hora do cancelamento (quando aplicável).
        amount_cents:
          type: integer
          description: Valor da NFe em centavos (÷100 → BRL).
        service_code:
          type:
            - string
            - "null"
          description: Código do serviço conforme a tabela municipal.
        service_description:
          type:
            - string
            - "null"
          description: Descrição livre do serviço prestado.
        lc116_code:
          type:
            - string
            - "null"
          description: Código LC 116 (lista nacional de serviços).
        cnae_code:
          type:
            - string
            - "null"
          description: Código CNAE da atividade.
        nbs_code:
          type:
            - string
            - "null"
          description: Código NBS (Nomenclatura Brasileira de Serviços).
        ncm_code:
          type:
            - string
            - "null"
          description: Código NCM (Nomenclatura Comum do Mercosul), quando aplicável.
        customer_snapshot:
          type: object
          additionalProperties: {}
          description: Snapshot dos dados do tomador no momento da emissão (nome, documento, endereço).
        taxes:
          type: object
          additionalProperties: {}
          description: Alíquotas e valores de impostos (ISS, PIS, COFINS, CSLL, IR, INSS).
        xml_url:
          type:
            - string
            - "null"
          description: URL pública para o XML hospedado pelo provedor.
        pdf_url:
          type:
            - string
            - "null"
          description: URL pública para o PDF (DANFE/DANFSE) hospedado pelo provedor.
        provider_company_id:
          type:
            - string
            - "null"
          description: Identificador da empresa no provedor externo.
        rps_number:
          type:
            - integer
            - "null"
          description: Número do RPS (Recibo Provisório de Serviços).
        rps_serial_number:
          type:
            - string
            - "null"
          description: Série do RPS.
        issue_attempts:
          type: integer
          description: Quantidade de tentativas de emissão realizadas.
        cancel_attempts:
          type: integer
          description: Quantidade de tentativas de cancelamento realizadas.
        next_retry_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data e hora da próxima retentativa automática (emissão ou cancelamento).
        error_message:
          type:
            - string
            - "null"
          description: Mensagem de erro retornada pelo provedor na última tentativa.
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Campos personalizados definidos pela organização.
        pdf_downloaded_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data em que o PDF foi baixado e persistido no banco.
        xml_downloaded_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data em que o XML foi baixado e persistido no banco.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - invoice_id
        - transaction_id
        - billing_account_id
        - organization_id
        - company_id
        - person_id
        - status
        - nfe_number
        - nfe_series
        - nfe_key
        - verification_code
        - issue_date
        - cancelled_at
        - amount_cents
        - service_code
        - service_description
        - lc116_code
        - cnae_code
        - nbs_code
        - ncm_code
        - customer_snapshot
        - taxes
        - xml_url
        - pdf_url
        - provider_company_id
        - rps_number
        - rps_serial_number
        - issue_attempts
        - cancel_attempts
        - next_retry_at
        - error_message
        - pdf_downloaded_at
        - xml_downloaded_at
        - created_at
        - updated_at
    NfeListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/NfeV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    NfeResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/NfeV1"
      required:
        - data
    NfeCustomerAddressInput:
      type: object
      properties:
        street:
          type: string
          description: Logradouro.
        number:
          type: string
          description: Número do endereço.
        complement:
          type: string
          description: Complemento (opcional).
        neighborhood:
          type: string
          description: Bairro.
        city:
          type: string
          description: Cidade.
        city_code:
          type: string
          description: Código IBGE da cidade (opcional).
        state:
          type: string
          description: UF (sigla de duas letras).
        zip_code:
          type: string
          description: CEP.
        country:
          type: string
          description: País (opcional, padrão `BR`).
      required:
        - street
        - number
        - neighborhood
        - city
        - state
        - zip_code
      description: Endereço do tomador.
    NfeCustomerInput:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          description: Nome ou razão social do tomador.
        email:
          type: string
          format: email
          description: E-mail do tomador.
        document_type:
          type: string
          enum:
            - cpf
            - cnpj
          description: "Tipo de documento: `cpf` ou `cnpj`."
        document_number:
          type: string
          minLength: 1
          description: Número do documento (somente dígitos ou com formatação).
        phone:
          type: string
          description: Telefone do tomador.
        address:
          $ref: "#/components/schemas/NfeCustomerAddressInput"
      required:
        - name
        - email
        - document_type
        - document_number
      description: Dados do tomador no momento da emissão. **Obrigatório**.
    NfeTaxesInput:
      type: object
      properties:
        iss_rate:
          type: number
          description: Alíquota de ISS (decimal).
        pis_rate:
          type: number
          description: Alíquota de PIS (decimal).
        cofins_rate:
          type: number
          description: Alíquota de COFINS (decimal).
        csll_rate:
          type: number
          description: Alíquota de CSLL (decimal).
        ir_rate:
          type: number
          description: Alíquota de IR (decimal).
        inss_rate:
          type: number
          description: Alíquota de INSS (decimal).
      description: "Alíquotas de impostos (em decimal, ex.: `0.05` para 5%). Aplica os defaults da empresa quando omitido."
    NfeCreateRequest:
      type: object
      properties:
        billing_account_id:
          type: string
          format: uuid
          description: UUID da conta de cobrança (tomador). **Obrigatório**.
        company_id:
          type: string
          format: uuid
          description: "UUID da empresa emissora (prestador). Padrão: empresa padrão da organização."
        invoice_id:
          type: string
          format: uuid
          description: UUID da fatura vinculada (opcional).
        transaction_id:
          type: string
          format: uuid
          description: UUID da transação de origem (opcional).
        amount_cents:
          type: integer
          exclusiveMinimum: 0
          description: Valor da NFe em centavos (÷100 → BRL). **Obrigatório**, deve ser positivo.
        service_code:
          type: string
          description: Código do serviço conforme a tabela municipal.
        service_description:
          type: string
          description: Descrição livre do serviço prestado.
        lc116_code:
          type: string
          description: Código LC 116.
        cnae_code:
          type: string
          description: Código CNAE.
        nbs_code:
          type: string
          description: Código NBS.
        rps_number:
          type: integer
          description: Número do RPS (quando a numeração é gerenciada pela aplicação).
        rps_serial_number:
          type: string
          description: Série do RPS.
        customer:
          $ref: "#/components/schemas/NfeCustomerInput"
        taxes:
          $ref: "#/components/schemas/NfeTaxesInput"
        custom_metadata:
          type: object
          additionalProperties: {}
          description: Campos personalizados (validados contra o schema da organização).
      required:
        - billing_account_id
        - amount_cents
        - customer
    NfeUpdateRequest:
      type: object
      properties:
        service_code:
          type: string
          description: Atualiza o código do serviço.
        service_description:
          type: string
          description: Atualiza a descrição do serviço.
        amount_cents:
          type: integer
          exclusiveMinimum: 0
          description: Atualiza o valor da NFe em centavos.
        lc116_code:
          type:
            - string
            - "null"
          description: Atualiza o código LC 116. Use `null` para limpar.
        cnae_code:
          type:
            - string
            - "null"
          description: Atualiza o código CNAE. Use `null` para limpar.
        nbs_code:
          type:
            - string
            - "null"
          description: Atualiza o código NBS. Use `null` para limpar.
        ncm_code:
          type:
            - string
            - "null"
          description: Atualiza o código NCM. Use `null` para limpar.
        rps_number:
          type:
            - integer
            - "null"
          description: Atualiza o número do RPS. Use `null` para limpar.
        rps_serial_number:
          type:
            - string
            - "null"
          description: Atualiza a série do RPS. Use `null` para limpar.
        customer_snapshot:
          type: object
          additionalProperties: {}
          description: Substitui o snapshot do tomador.
        taxes:
          type: object
          additionalProperties: {}
          description: Substitui as alíquotas e valores de impostos.
        custom_metadata:
          type: object
          additionalProperties: {}
          description: Atualiza os campos personalizados.
    NfeCancelRequest:
      type: object
      properties:
        reason:
          type: string
          minLength: 15
          description: Motivo do cancelamento. **Mínimo 15 caracteres**. Registrado no audit log e enviado ao provedor.
      required:
        - reason
    NfeDeletedResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            deleted:
              type: boolean
              example: true
          required:
            - deleted
      required:
        - data
    NfeBulkUpdateRequest:
      type: object
      properties:
        nfe_ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
          description: UUIDs das NFes a atualizar. Mínimo 1.
        invoice_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da fatura a vincular. Envie `null` para desvincular.
      required:
        - nfe_ids
        - invoice_id
    NfeBulkUpdateResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            updated:
              type: integer
          required:
            - updated
      required:
        - data
    NfeBulkDeleteRequest:
      type: object
      properties:
        ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
          maxItems: 100
          description: UUIDs das NFes a excluir. Mínimo 1, máximo 100.
      required:
        - ids
    NfeBulkDeleteResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            deleted_count:
              type: integer
          required:
            - deleted_count
      required:
        - data
    NfeSyncOrgResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            job_id:
              type: string
            status:
              type: string
          required:
            - job_id
            - status
      required:
        - data
    NfeRequestTryV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        nfe_id:
          type: string
          format: uuid
        action:
          type: string
          description: "Ação tentada: `issue`, `cancel` ou `query`."
        endpoint:
          type: string
          description: Endpoint do provedor chamado.
        request_body:
          type:
            - string
            - "null"
        response_body:
          type:
            - string
            - "null"
        http_status:
          type:
            - string
            - "null"
          description: Status HTTP retornado pelo provedor.
        success:
          type: boolean
        error_message:
          type:
            - string
            - "null"
        duration_ms:
          type:
            - integer
            - "null"
          description: Duração da requisição em milissegundos.
        created_at:
          type: string
          format: date-time
      required:
        - id
        - nfe_id
        - action
        - endpoint
        - request_body
        - response_body
        - http_status
        - success
        - error_message
        - duration_ms
        - created_at
    NfeRequestTryListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/NfeRequestTryV1"
      required:
        - data
    NfeRequestTryPaginatedResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/NfeRequestTryV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    NfeExternalRequestSummaryV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        nfe_id:
          type:
            - string
            - "null"
          format: uuid
        invoice_id:
          type:
            - string
            - "null"
          format: uuid
        direction:
          type: string
          enum:
            - outbound
            - inbound
          description: "Direção da requisição: `outbound` (chamada saindo) ou `inbound` (webhook recebido)."
        service:
          type:
            - string
            - "null"
          description: "Provedor/serviço externo (ex.: `nfeio`, `barueri`)."
        method:
          type: string
        endpoint:
          type: string
        http_status:
          type:
            - integer
            - "null"
        success:
          type: boolean
        error_message:
          type:
            - string
            - "null"
        duration_ms:
          type:
            - integer
            - "null"
        created_at:
          type: string
          format: date-time
      required:
        - id
        - nfe_id
        - invoice_id
        - direction
        - service
        - method
        - endpoint
        - http_status
        - success
        - error_message
        - duration_ms
        - created_at
    NfeExternalRequestV1:
      allOf:
        - $ref: "#/components/schemas/NfeExternalRequestSummaryV1"
        - type: object
          properties:
            request_headers:
              type:
                - object
                - "null"
              additionalProperties: {}
            request_body:
              type:
                - string
                - "null"
            response_headers:
              type:
                - object
                - "null"
              additionalProperties: {}
            response_body:
              type:
                - string
                - "null"
            metadata:
              type:
                - object
                - "null"
              additionalProperties: {}
          required:
            - request_headers
            - request_body
            - response_headers
            - response_body
            - metadata
    NfeExternalRequestListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/NfeExternalRequestSummaryV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    NfeExternalRequestResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/NfeExternalRequestV1"
      required:
        - data
    NfeFetchBarueriRequest:
      type: object
      properties:
        codigo_autenticidade:
          type: string
          minLength: 1
          description: Código de autenticidade impresso no DANFSE da NFS-e.
        cnpj_tomador:
          type: string
          minLength: 1
          description: CPF ou CNPJ do tomador da NFS-e (somente dígitos ou com formatação).
        ambiente:
          type: string
          enum:
            - production
            - homologation
          description: "Ambiente municipal: `production` ou `homologation`. Padrão: `production`."
      required:
        - codigo_autenticidade
        - cnpj_tomador
    NfeFetchBarueriResponse:
      type: object
      properties:
        data:
          type: object
          additionalProperties: {}
      required:
        - data
    NfeImportBarueriRequest:
      type: object
      properties:
        xml:
          type: string
          description: XML cru retornado por `POST /nfes/fetch-barueri`. Opcional — quando ausente, a NFS-e é re-buscada com `codigo_autenticidade` + `cnpj_tomador`.
        codigo_autenticidade:
          type: string
          minLength: 1
          description: Código de autenticidade impresso no DANFSE da NFS-e.
        cnpj_tomador:
          type: string
          minLength: 1
          description: CPF ou CNPJ do tomador da NFS-e (somente dígitos ou com formatação).
        ambiente:
          type: string
          enum:
            - production
            - homologation
          description: "Ambiente municipal: `production` ou `homologation`. Padrão: `production`."
      required:
        - codigo_autenticidade
        - cnpj_tomador
    NfeImportBarueriResponse:
      type: object
      properties:
        data:
          type: object
          additionalProperties: {}
      required:
        - data
    NfeValidateBarueriResponse:
      type: object
      properties:
        data:
          type: object
          additionalProperties: {}
      required:
        - data
    NfeFetchFromSefazRequest:
      type: object
      properties:
        access_key:
          type: string
          minLength: 1
          description: Chave de acesso da NFS-e (50 dígitos).
        certificate_id:
          type: string
          minLength: 1
          description: UUID do certificado digital cadastrado na organização (usado para autenticação mTLS).
        ambiente:
          anyOf:
            - type: number
              enum:
                - 1
            - type: number
              enum:
                - 2
          description: "Ambiente SEFAZ: `1` (produção) ou `2` (homologação). Padrão: `2`."
      required:
        - access_key
        - certificate_id
    NfeFetchFromSefazResponse:
      type: object
      properties:
        data:
          type: object
          additionalProperties: {}
      required:
        - data
    ProposalItemV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        proposal_id:
          type: string
          format: uuid
        product_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do produto.
        price_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do preço.
        quantity:
          type: number
          description: Quantidade.
        unit_amount_subcents:
          type: integer
          description: Valor unitário em subcentavos (÷10000 → BRL).
        setup_amount_subcents:
          type:
            - integer
            - "null"
          description: Setup unitário em subcentavos (÷10000 → BRL).
        excess_amount_subcents:
          type:
            - integer
            - "null"
          description: Valor adicional por excedente em subcentavos (÷10000 → BRL).
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - proposal_id
        - product_id
        - price_id
        - quantity
        - unit_amount_subcents
        - created_at
        - updated_at
    ProposalV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        public_id:
          type: string
          format: uuid
          description: UUID público — exposto em URLs do portal (`/p/{code}`).
        company_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da empresa emissora (opcional).
        code:
          type: string
          description: "Código curto único por organização (ex.: `PROP-0001`)."
        title:
          type: string
          description: 'Título da proposta (padrão: "Proposta Comercial").'
        description:
          type:
            - string
            - "null"
          description: Descrição livre exibida na proposta.
        billing_account_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da conta de cobrança alvo, quando a proposta é para um cliente existente.
        prospect_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do prospect (pessoa jurídica em prospecção), quando ainda não há `billing_account_id`.
        contact_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do contato (pessoa física responsável dentro do prospect).
        coupon_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do cupom aplicado à proposta.
        template_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do template usado para gerar o PDF.
        document_google_id:
          type:
            - string
            - "null"
          description: ID do Google Doc gerado pelo App Script.
        document_url:
          type:
            - string
            - "null"
          description: URL do documento Google Doc.
        pdf_url:
          type:
            - string
            - "null"
          description: URL pública do PDF da proposta.
        generated_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data e hora da última geração do PDF.
        pdf_outdated_at:
          type:
            - string
            - "null"
          format: date-time
          description: Marca quando o PDF ficou desatualizado em relação aos itens/preços atuais.
        expires_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data de expiração da proposta.
        status:
          type: string
          enum:
            - draft
            - sent
            - viewed
            - accepted
            - rejected
            - expired
            - canceled
          description: "Status: `draft`, `sent`, `viewed`, `accepted`, `rejected`, `expired` ou `canceled`."
        rejection_reason:
          type:
            - string
            - "null"
          description: Motivo de rejeição informado pelo prospect.
        setup_amount_cents:
          type: integer
          description: Valor de setup (one-time) em centavos (÷100 → BRL).
        monthly_amount_cents:
          type: integer
          description: Valor mensal recorrente em centavos (÷100 → BRL).
        notes:
          type:
            - string
            - "null"
          description: Anotações internas (não exibidas ao cliente).
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Campos personalizados definidos pela organização.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        sent_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data e hora do envio.
        viewed_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data e hora da primeira visualização pelo destinatário.
        accepted_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data e hora do aceite.
        rejected_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data e hora da rejeição.
        items:
          type: array
          items:
            $ref: "#/components/schemas/ProposalItemV1"
          description: Itens da proposta — presente quando incluído via `include=items`.
      required:
        - id
        - public_id
        - company_id
        - code
        - title
        - description
        - billing_account_id
        - prospect_id
        - contact_id
        - coupon_id
        - template_id
        - document_google_id
        - document_url
        - pdf_url
        - generated_at
        - pdf_outdated_at
        - expires_at
        - status
        - rejection_reason
        - setup_amount_cents
        - monthly_amount_cents
        - notes
        - created_at
        - updated_at
        - sent_at
        - viewed_at
        - accepted_at
        - rejected_at
    ProposalListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/ProposalV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    ProposalResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/ProposalV1"
      required:
        - data
    ProposalItemInput:
      type: object
      properties:
        product_id:
          type: string
          format: uuid
          description: UUID do produto. **Obrigatório**.
        price_id:
          type: string
          format: uuid
          description: UUID do preço. **Obrigatório**.
        quantity:
          type: number
          minimum: 1
          description: "Quantidade. Padrão: 1."
        unit_amount_subcents:
          type: number
          minimum: 0
          description: Valor unitário em subcentavos (÷10000 → BRL).
        custom_metadata:
          type: object
          additionalProperties: {}
          description: Campos personalizados do item.
      required:
        - product_id
        - price_id
        - unit_amount_subcents
    ProspectDataInput:
      type: object
      properties:
        document:
          type: string
          description: CNPJ do prospect (apenas dígitos ou formatado).
        name:
          type: string
          minLength: 1
          description: Razão social do prospect.
        legal_name:
          type: string
          description: Razão social alternativa.
        nickname:
          type: string
          description: Nome fantasia.
        email:
          type: string
          format: email
          description: E-mail principal do prospect.
        phone:
          type: string
          description: Telefone principal do prospect.
      required:
        - name
      description: Dados para criar um prospect inline (pessoa jurídica). Alternativa a `prospect_id`/`billing_account_id`.
    ContactDataInput:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          description: Nome do contato (pessoa responsável).
        email:
          type: string
          format: email
          description: E-mail do contato.
        phone:
          type: string
          description: Telefone do contato.
      required:
        - name
      description: Dados para criar um contato inline (pessoa física responsável).
    ProposalCreateRequest:
      type: object
      properties:
        company_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da empresa emissora. Use `null` para limpar.
        title:
          type: string
          minLength: 1
          maxLength: 255
          description: 'Título da proposta. Padrão: "Proposta Comercial".'
        description:
          type:
            - string
            - "null"
          description: Descrição livre da proposta.
        billing_account_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da conta de cobrança alvo (cliente existente). Obrigatório se `prospect_id` e `prospect_data` não forem informados.
        prospect_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID de um prospect existente. Alternativa a `billing_account_id`/`prospect_data`.
        contact_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID de um contato existente vinculado ao prospect.
        prospect_data:
          $ref: "#/components/schemas/ProspectDataInput"
        contact_data:
          $ref: "#/components/schemas/ContactDataInput"
        coupon_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do cupom a aplicar.
        template_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do template para gerar o PDF.
        expires_at:
          type: string
          description: Data de expiração.
        notes:
          type:
            - string
            - "null"
          description: Anotações internas.
        items:
          type: array
          items:
            $ref: "#/components/schemas/ProposalItemInput"
          minItems: 1
          description: Itens da proposta. Mínimo 1.
        custom_metadata:
          type: object
          additionalProperties: {}
          description: Campos personalizados (validados contra o schema da organização).
    ProposalUpdateRequest:
      type: object
      properties:
        company_id:
          type:
            - string
            - "null"
          format: uuid
        title:
          type: string
          minLength: 1
          maxLength: 255
          description: Atualiza o título.
        description:
          type:
            - string
            - "null"
          description: Atualiza a descrição. Use `null` para limpar.
        billing_account_id:
          type:
            - string
            - "null"
          format: uuid
        prospect_id:
          type:
            - string
            - "null"
          format: uuid
        contact_id:
          type:
            - string
            - "null"
          format: uuid
        prospect_data:
          $ref: "#/components/schemas/ProspectDataInput"
        contact_data:
          $ref: "#/components/schemas/ContactDataInput"
        coupon_id:
          type:
            - string
            - "null"
          format: uuid
        template_id:
          type:
            - string
            - "null"
          format: uuid
        expires_at:
          type:
            - string
            - "null"
          description: Atualiza a data de expiração. Use `null` para limpar.
        notes:
          type:
            - string
            - "null"
          description: Atualiza as anotações. Use `null` para limpar.
        items:
          type: array
          items:
            $ref: "#/components/schemas/ProposalItemInput"
          description: Substitui a lista de itens da proposta.
        custom_metadata:
          type: object
          additionalProperties: {}
    ProposalAcceptRequest:
      type: object
      properties:
        cycle:
          type: string
          enum:
            - monthly
            - quarterly
            - semiannual
            - annual
          description: "Ciclo de cobrança da assinatura criada no aceite: `monthly`, `quarterly`, `semiannual` ou `annual`."
      required:
        - cycle
    ProposalAcceptResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            proposal:
              $ref: "#/components/schemas/ProposalV1"
            subscription_id:
              type:
                - string
                - "null"
              format: uuid
            invoice_id:
              type:
                - string
                - "null"
              format: uuid
          required:
            - proposal
            - subscription_id
            - invoice_id
      required:
        - data
    ProposalSendRequest:
      type: object
      properties:
        subject:
          type: string
          description: "Assunto customizado do e-mail. Padrão: `Proposta {code}`."
        message:
          type: string
          description: Mensagem HTML customizada do corpo do e-mail.
    ProposalGeneratePdfResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            proposal:
              $ref: "#/components/schemas/ProposalV1"
            pdf:
              type: object
              properties:
                document_id:
                  type:
                    - string
                    - "null"
                document_url:
                  type:
                    - string
                    - "null"
                pdf_url:
                  type:
                    - string
                    - "null"
              required:
                - document_id
                - document_url
                - pdf_url
          required:
            - proposal
            - pdf
      required:
        - data
    ProposalJsonResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            template_data: {}
            proposal:
              type: object
              properties:
                id:
                  type: string
                  format: uuid
                code:
                  type: string
                template_google_doc_id:
                  type:
                    - string
                    - "null"
                document_google_id:
                  type:
                    - string
                    - "null"
              required:
                - id
                - code
                - template_google_doc_id
                - document_google_id
          required:
            - proposal
      required:
        - data
    ProposalPricingResponse:
      type: object
      properties:
        data:
          type: object
          additionalProperties: {}
      required:
        - data
    ProposalItemsListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/ProposalItemV1"
      required:
        - data
    ProposalItemResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/ProposalItemV1"
      required:
        - data
    ProposalItemUpdateRequest:
      type: object
      properties:
        quantity:
          type: integer
          minimum: 1
          description: Atualiza a quantidade.
        unit_amount_subcents:
          type: number
          minimum: 0
          description: Atualiza o valor unitário em subcentavos (÷10000 → BRL).
        setup_amount_subcents:
          type: number
          minimum: 0
          description: Atualiza o setup unitário em subcentavos (÷10000 → BRL).
        custom_metadata:
          type: object
          additionalProperties: {}
          description: proposals.items.update.body.custom_metadata
    ProposalBulkRequest:
      type: object
      properties:
        ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
          maxItems: 100
          description: Lista de UUIDs das propostas alvo. Mínimo 1, máximo 100.
      required:
        - ids
    ProposalBulkResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            success_count:
              type: integer
            failed_count:
              type: integer
            errors:
              type: array
              items:
                type: object
                additionalProperties: {}
          required:
            - success_count
            - failed_count
            - errors
      required:
        - data
    ProposalStatsResponse:
      type: object
      properties:
        data:
          type: object
          additionalProperties:
            type: integer
      required:
        - data
    ProposalDeletedResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            deleted:
              type: boolean
              example: true
          required:
            - deleted
      required:
        - data
    ProposalTemplateV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        public_id:
          type: string
          format: uuid
          description: Identificador público estável do template.
        name:
          type: string
          description: Nome do template (único por organização).
        description:
          type:
            - string
            - "null"
          description: Descrição livre do template.
        document_type:
          type: string
          enum:
            - google_doc
            - google_slides
          description: "Tipo do documento base: `google_doc` ou `google_slides`."
        google_doc_id:
          type: string
          description: ID do Google Doc/Slides usado como base do template.
        app_script_url:
          type:
            - string
            - "null"
          description: URL do Apps Script que renderiza o template, quando configurado.
        google_drive_folder_id:
          type:
            - string
            - "null"
          description: ID da pasta do Google Drive onde as cópias geradas são salvas.
        is_default:
          type: boolean
          description: Indica se este é o template padrão da organização.
        is_active:
          type: boolean
          description: Indica se o template está disponível para uso em novas propostas.
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados internos do template (estrutura livre).
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - public_id
        - name
        - description
        - document_type
        - google_doc_id
        - app_script_url
        - google_drive_folder_id
        - is_default
        - is_active
        - metadata
        - created_at
        - updated_at
    ProposalTemplateListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/ProposalTemplateV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    ProposalTemplateResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/ProposalTemplateV1"
      required:
        - data
    ProposalTemplateCreateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Nome do template (único por organização).
        description:
          type:
            - string
            - "null"
          description: Descrição opcional do template.
        documentType:
          type: string
          enum:
            - google_doc
            - google_slides
          description: "Tipo do documento base: `google_doc` ou `google_slides`. Padrão: `google_doc`."
        googleDocId:
          type: string
          minLength: 1
          description: ID do Google Doc/Slides usado como template (único por organização).
        appScriptUrl:
          type:
            - string
            - "null"
          format: uri
          description: URL do Apps Script publicado que renderiza o template, quando aplicável.
        googleDriveFolderId:
          type:
            - string
            - "null"
          description: ID da pasta do Google Drive onde as cópias geradas serão salvas.
        isDefault:
          type: boolean
          description: Quando `true`, marca este template como padrão da organização.
        isActive:
          type: boolean
          description: Quando `false`, cria o template já desativado.
        customMetadata:
          type: object
          additionalProperties: {}
          description: Metadados livres definidos pelo cliente para correlação interna.
      required:
        - name
        - googleDocId
    ProposalTemplateUpdateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 255
          description: Novo nome do template.
        description:
          type:
            - string
            - "null"
          description: Nova descrição do template.
        documentType:
          type: string
          enum:
            - google_doc
            - google_slides
          description: "Novo tipo do documento base: `google_doc` ou `google_slides`."
        googleDocId:
          type: string
          minLength: 1
          description: Novo ID do Google Doc/Slides usado como template.
        appScriptUrl:
          type:
            - string
            - "null"
          format: uri
          description: Nova URL do Apps Script publicado.
        googleDriveFolderId:
          type:
            - string
            - "null"
          description: Novo ID da pasta do Google Drive.
        isDefault:
          type: boolean
          description: Quando `true`, marca este template como padrão.
        isActive:
          type: boolean
          description: Habilita ou desabilita o template.
        customMetadata:
          type: object
          additionalProperties: {}
          description: Novos metadados livres definidos pelo cliente.
    PlanChangeV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        subscription_id:
          type: string
          format: uuid
          description: UUID da assinatura alvo da mudança.
        billing_account_id:
          type: string
          format: uuid
          description: UUID da conta de cobrança.
        organization_id:
          type: string
          format: uuid
          description: UUID da organização proprietária do recurso.
        from_plan_id:
          type: string
          format: uuid
          description: UUID do plano de origem.
        to_plan_id:
          type: string
          format: uuid
          description: UUID do plano de destino.
        change_type:
          type: string
          enum:
            - upgrade
            - downgrade
            - lateral
          description: "Tipo da mudança: `upgrade`, `downgrade` ou `lateral`."
        status:
          type: string
          enum:
            - pending
            - scheduled
            - completed
            - canceled
            - failed
          description: "Status: `pending`, `scheduled`, `completed`, `canceled` ou `failed`."
        timing:
          type: string
          enum:
            - immediate
            - end_of_period
          description: "Quando a mudança é/foi aplicada: `immediate` ou `end_of_period`."
        proration_method:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: Método de proração efetivamente usado.
        effective_date:
          type: string
          format: date-time
          description: Data em que a mudança passa a valer.
        scheduled_date:
          type:
            - string
            - "null"
          format: date-time
          description: Data agendada para aplicação (quando `timing = end_of_period`).
        completed_at:
          type:
            - string
            - "null"
          format: date-time
          description: Quando a mudança foi concluída.
        canceled_at:
          type:
            - string
            - "null"
          format: date-time
          description: Quando a mudança foi cancelada.
        from_price_subcents:
          type: integer
          description: Preço do plano de origem em subcentavos (÷10000 → BRL).
          example: 1000000
        to_price_subcents:
          type: integer
          description: Preço do plano de destino em subcentavos (÷10000 → BRL).
          example: 2000000
        price_difference_subcents:
          type: integer
          description: Diferença `to - from` em subcentavos (÷10000 → BRL).
        proration_credit_subcents:
          type: integer
          description: Crédito gerado por proração em subcentavos (÷10000 → BRL).
        proration_charge_subcents:
          type: integer
          description: Cobrança adicional por proração em subcentavos (÷10000 → BRL).
        days_remaining:
          type: integer
          description: Dias restantes no período atual no momento da mudança.
        total_days_in_period:
          type: integer
          description: Total de dias no período de cobrança.
        invoice_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da fatura de proração emitida (se houver).
        credit_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do crédito gerado (se houver).
        reason:
          type:
            - string
            - "null"
          description: Motivo registrado pelo iniciador da mudança.
        initiated_by:
          type:
            - string
            - "null"
          description: Identificador do iniciador (e-mail do usuário, nome da API key ou `api`).
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - subscription_id
        - billing_account_id
        - organization_id
        - from_plan_id
        - to_plan_id
        - change_type
        - status
        - timing
        - proration_method
        - effective_date
        - scheduled_date
        - completed_at
        - canceled_at
        - from_price_subcents
        - to_price_subcents
        - price_difference_subcents
        - proration_credit_subcents
        - proration_charge_subcents
        - days_remaining
        - total_days_in_period
        - invoice_id
        - credit_id
        - reason
        - initiated_by
        - created_at
        - updated_at
    PlanChangeListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/PlanChangeV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    PlanChangeResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/PlanChangeV1"
      required:
        - data
    PlanChangeExecuteRequest:
      type: object
      properties:
        subscription_id:
          type: string
          format: uuid
          description: UUID da assinatura que terá o plano alterado.
        to_plan_id:
          type: string
          format: uuid
          description: UUID do plano de destino.
        timing:
          type: string
          enum:
            - immediate
            - end_of_period
          description: "Quando aplicar a mudança: `immediate` (padrão para upgrades) ou `end_of_period` (padrão para downgrades)."
        reason:
          type: string
          description: Motivo da mudança (registrado no audit log).
      required:
        - subscription_id
        - to_plan_id
    PlanChangeExecuteResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            plan_change_id:
              type: string
              format: uuid
              description: UUID da mudança de plano criada.
            invoice_id:
              type:
                - string
                - "null"
              format: uuid
              description: UUID da fatura de proração emitida (se houver).
            credit_id:
              type:
                - string
                - "null"
              format: uuid
              description: UUID do crédito gerado (se houver).
          required:
            - plan_change_id
            - invoice_id
            - credit_id
      required:
        - data
    PlanChangeStatsResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            total:
              type: integer
              description: Total de mudanças na janela.
            by_type:
              type: object
              additionalProperties:
                type: integer
              description: "Contagem por tipo (chaves: `upgrade`, `downgrade`, `lateral`)."
            by_status:
              type: object
              additionalProperties:
                type: integer
              description: Contagem por status.
            upgrades:
              type: integer
              description: Quantidade de upgrades na janela.
            downgrades:
              type: integer
              description: Quantidade de downgrades na janela.
            total_proration_credits_subcents:
              type: integer
              description: Soma dos créditos de proração emitidos em subcentavos (÷10000 → BRL).
            total_proration_charges_subcents:
              type: integer
              description: Soma das cobranças de proração em subcentavos (÷10000 → BRL).
          required:
            - total
            - by_type
            - by_status
            - upgrades
            - downgrades
            - total_proration_credits_subcents
            - total_proration_charges_subcents
      required:
        - data
    PlanChangeConfigV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type: string
          format: uuid
          description: UUID da organização proprietária da configuração.
        allow_upgrade:
          type: boolean
          description: Upgrades estão habilitados.
        allow_downgrade:
          type: boolean
          description: Downgrades estão habilitados.
        upgrade_proration:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: Método de proração padrão para upgrades.
        downgrade_proration:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: Método de proração padrão para downgrades.
        upgrade_timing:
          type: string
          enum:
            - immediate
            - end_of_period
          description: Quando aplicar upgrades por padrão.
        downgrade_timing:
          type: string
          enum:
            - immediate
            - end_of_period
          description: Quando aplicar downgrades por padrão.
        refund_on_downgrade:
          type: boolean
          description: Estorna a diferença ao fazer downgrade.
        credit_on_downgrade:
          type: boolean
          description: Gera crédito ao fazer downgrade.
        apply_discount_on_change:
          type: boolean
          description: Mantém descontos ativos ao mudar de plano.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - organization_id
        - allow_upgrade
        - allow_downgrade
        - upgrade_proration
        - downgrade_proration
        - upgrade_timing
        - downgrade_timing
        - refund_on_downgrade
        - credit_on_downgrade
        - apply_discount_on_change
        - created_at
        - updated_at
    PlanChangeConfigResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/PlanChangeConfigV1"
      required:
        - data
    PlanChangeConfigUpdateRequest:
      type: object
      properties:
        allow_upgrade:
          type: boolean
          description: Habilita upgrades de plano para a organização.
        allow_downgrade:
          type: boolean
          description: Habilita downgrades de plano para a organização.
        upgrade_proration:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: "Método de proração padrão para upgrades: `full_proration`, `no_proration` ou `partial_proration`."
        downgrade_proration:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: Método de proração padrão para downgrades.
        upgrade_timing:
          type: string
          enum:
            - immediate
            - end_of_period
          description: "Quando aplicar upgrades: `immediate` ou `end_of_period`."
        downgrade_timing:
          type: string
          enum:
            - immediate
            - end_of_period
          description: "Quando aplicar downgrades: `immediate` ou `end_of_period`."
        refund_on_downgrade:
          type: boolean
          description: Estorna a diferença ao fazer downgrade.
        credit_on_downgrade:
          type: boolean
          description: Gera crédito (em vez de estorno) ao fazer downgrade.
        apply_discount_on_change:
          type: boolean
          description: Mantém descontos ativos ao mudar de plano.
    PlanChangeRuleV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        from_plan_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do plano de origem ou `null` para qualquer.
        to_plan_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do plano de destino ou `null` para qualquer.
        change_type:
          type:
            - string
            - "null"
          enum:
            - upgrade
            - downgrade
            - lateral
          description: "Tipo de mudança coberto: `upgrade`, `downgrade` ou `lateral` (ou `null` para qualquer)."
        allowed:
          type: boolean
          description: Se `false`, a transição é bloqueada.
        timing:
          type:
            - string
            - "null"
          enum:
            - immediate
            - end_of_period
          description: Timing sobrescrito por esta regra.
        proration_method:
          type:
            - string
            - "null"
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: Método de proração sobrescrito por esta regra.
        discount_percent:
          type:
            - integer
            - "null"
          description: Desconto percentual (0–100) aplicado.
        bonus_days:
          type:
            - integer
            - "null"
          description: Dias bônus concedidos.
        message:
          type:
            - string
            - "null"
          description: Mensagem exibida ao cliente.
        is_active:
          type: boolean
          description: A regra está ativa.
        priority:
          type: integer
          description: Prioridade na resolução de conflitos (maior vence).
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - from_plan_id
        - to_plan_id
        - change_type
        - allowed
        - timing
        - proration_method
        - discount_percent
        - bonus_days
        - message
        - is_active
        - priority
        - created_at
        - updated_at
    PlanChangeRuleListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/PlanChangeRuleV1"
      required:
        - data
    PlanChangeRuleResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/PlanChangeRuleV1"
      required:
        - data
    PlanChangeRuleCreateRequest:
      type: object
      properties:
        from_plan_id:
          type: string
          format: uuid
          description: UUID do plano de origem. Quando ausente, a regra cobre qualquer plano de origem.
        to_plan_id:
          type: string
          format: uuid
          description: UUID do plano de destino. Quando ausente, a regra cobre qualquer plano de destino.
        change_type:
          type: string
          enum:
            - upgrade
            - downgrade
            - lateral
          description: "Tipo da mudança: `upgrade`, `downgrade` ou `lateral`."
        allowed:
          type: boolean
          description: Se `false`, bloqueia explicitamente a transição.
        timing:
          type: string
          enum:
            - immediate
            - end_of_period
          description: "Sobrescreve o timing da mudança: `immediate` ou `end_of_period`."
        proration_method:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: "Sobrescreve o método de proração: `full_proration`, `no_proration` ou `partial_proration`."
        discount_percent:
          type: number
          minimum: 0
          maximum: 100
          description: Desconto percentual aplicado quando esta regra é usada (0 a 100).
        bonus_days:
          type: integer
          minimum: 0
          description: Dias bônus adicionados ao período corrente quando esta regra é aplicada.
        message:
          type: string
          description: "Mensagem livre exibida no portal/checkout (ex.: motivo do bloqueio)."
        priority:
          type: integer
          description: Prioridade para resolução de conflito quando múltiplas regras casam (maior vence).
    PlanChangeRuleUpdateRequest:
      type: object
      properties:
        allowed:
          type: boolean
          description: Se `false`, bloqueia explicitamente a transição.
        timing:
          type: string
          enum:
            - immediate
            - end_of_period
          description: "Sobrescreve o timing da mudança: `immediate` ou `end_of_period`."
        proration_method:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: "Sobrescreve o método de proração: `full_proration`, `no_proration` ou `partial_proration`."
        discount_percent:
          type: number
          minimum: 0
          maximum: 100
          description: Desconto percentual aplicado quando esta regra é usada (0 a 100).
        bonus_days:
          type: integer
          minimum: 0
          description: Dias bônus adicionados ao período corrente quando esta regra é aplicada.
        message:
          type: string
          description: "Mensagem livre exibida no portal/checkout (ex.: motivo do bloqueio)."
        priority:
          type: integer
          description: Prioridade para resolução de conflito quando múltiplas regras casam (maior vence).
        is_active:
          type: boolean
          description: Desativa a regra sem removê-la.
    PlanChangeRuleDeletedResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            deleted:
              type: boolean
              example: true
          required:
            - deleted
      required:
        - data
    SubscriptionChangeConfigV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organizationId:
          type: string
          format: uuid
          description: UUID da organização dona da configuração.
        allowItemAdd:
          type: boolean
          description: Se `true`, permite adicionar novos itens à assinatura.
        allowItemRemove:
          type: boolean
          description: Se `true`, permite remover itens da assinatura.
        allowQuantityChange:
          type: boolean
          description: Se `true`, permite alterar a quantidade de itens existentes.
        allowPriceSwap:
          type: boolean
          description: Se `true`, permite trocar o preço (variação) de um item sem removê-lo.
        addProration:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: Método de proporção padrão ao adicionar itens.
        removeProration:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: Método de proporção padrão ao remover itens.
        quantityUpProration:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: Método de proporção padrão ao aumentar quantidade.
        quantityDownProration:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: Método de proporção padrão ao reduzir quantidade.
        addTiming:
          type: string
          enum:
            - immediate
            - end_of_period
          description: Momento de aplicação padrão ao adicionar itens.
        removeTiming:
          type: string
          enum:
            - immediate
            - end_of_period
          description: Momento de aplicação padrão ao remover itens.
        quantityUpTiming:
          type: string
          enum:
            - immediate
            - end_of_period
          description: Momento de aplicação padrão ao aumentar quantidade.
        quantityDownTiming:
          type: string
          enum:
            - immediate
            - end_of_period
          description: Momento de aplicação padrão ao reduzir quantidade.
        refundOnRemove:
          type: boolean
          description: Se `true`, emite reembolso ao remover itens. Exige `creditOnRemove`.
        creditOnRemove:
          type: boolean
          description: Se `true`, gera crédito para o cliente ao remover itens.
        portalSelfService:
          type: boolean
          description: Se `true`, libera o self-service do cliente no portal.
        portalRequireConfirmation:
          type: boolean
          description: Se `true`, exige confirmação explícita do cliente no portal.
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados livres associados à configuração.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - organizationId
        - allowItemAdd
        - allowItemRemove
        - allowQuantityChange
        - allowPriceSwap
        - addProration
        - removeProration
        - quantityUpProration
        - quantityDownProration
        - addTiming
        - removeTiming
        - quantityUpTiming
        - quantityDownTiming
        - refundOnRemove
        - creditOnRemove
        - portalSelfService
        - portalRequireConfirmation
        - metadata
        - created_at
        - updated_at
    SubscriptionChangeConfigResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organizationId:
          type: string
          format: uuid
          description: UUID da organização dona da configuração.
        allowItemAdd:
          type: boolean
          description: Se `true`, permite adicionar novos itens à assinatura.
        allowItemRemove:
          type: boolean
          description: Se `true`, permite remover itens da assinatura.
        allowQuantityChange:
          type: boolean
          description: Se `true`, permite alterar a quantidade de itens existentes.
        allowPriceSwap:
          type: boolean
          description: Se `true`, permite trocar o preço (variação) de um item sem removê-lo.
        addProration:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: Método de proporção padrão ao adicionar itens.
        removeProration:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: Método de proporção padrão ao remover itens.
        quantityUpProration:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: Método de proporção padrão ao aumentar quantidade.
        quantityDownProration:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: Método de proporção padrão ao reduzir quantidade.
        addTiming:
          type: string
          enum:
            - immediate
            - end_of_period
          description: Momento de aplicação padrão ao adicionar itens.
        removeTiming:
          type: string
          enum:
            - immediate
            - end_of_period
          description: Momento de aplicação padrão ao remover itens.
        quantityUpTiming:
          type: string
          enum:
            - immediate
            - end_of_period
          description: Momento de aplicação padrão ao aumentar quantidade.
        quantityDownTiming:
          type: string
          enum:
            - immediate
            - end_of_period
          description: Momento de aplicação padrão ao reduzir quantidade.
        refundOnRemove:
          type: boolean
          description: Se `true`, emite reembolso ao remover itens. Exige `creditOnRemove`.
        creditOnRemove:
          type: boolean
          description: Se `true`, gera crédito para o cliente ao remover itens.
        portalSelfService:
          type: boolean
          description: Se `true`, libera o self-service do cliente no portal.
        portalRequireConfirmation:
          type: boolean
          description: Se `true`, exige confirmação explícita do cliente no portal.
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados livres associados à configuração.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - organizationId
        - allowItemAdd
        - allowItemRemove
        - allowQuantityChange
        - allowPriceSwap
        - addProration
        - removeProration
        - quantityUpProration
        - quantityDownProration
        - addTiming
        - removeTiming
        - quantityUpTiming
        - quantityDownTiming
        - refundOnRemove
        - creditOnRemove
        - portalSelfService
        - portalRequireConfirmation
        - metadata
        - created_at
        - updated_at
    SubscriptionChangeConfigUpdateRequest:
      type: object
      properties:
        allow_item_add:
          type: boolean
          description: Permite adicionar novos itens a uma assinatura existente.
        allow_item_remove:
          type: boolean
          description: Permite remover itens de uma assinatura existente.
        allow_quantity_change:
          type: boolean
          description: Permite alterar a quantidade de itens já presentes na assinatura.
        allow_price_swap:
          type: boolean
          description: Permite trocar o preço (variação) de um item existente sem removê-lo.
        add_proration:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: "Método de proporção ao adicionar itens: `full_proration`, `no_proration` ou `partial_proration`."
        remove_proration:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: "Método de proporção ao remover itens: `full_proration`, `no_proration` ou `partial_proration`."
        quantity_up_proration:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: Método de proporção ao aumentar a quantidade de um item.
        quantity_down_proration:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: Método de proporção ao reduzir a quantidade de um item.
        add_timing:
          type: string
          enum:
            - immediate
            - end_of_period
          description: "Momento de aplicação ao adicionar itens: `immediate` ou `end_of_period`."
        remove_timing:
          type: string
          enum:
            - immediate
            - end_of_period
          description: "Momento de aplicação ao remover itens: `immediate` ou `end_of_period`."
        quantity_up_timing:
          type: string
          enum:
            - immediate
            - end_of_period
          description: "Momento de aplicação ao aumentar quantidade: `immediate` ou `end_of_period`."
        quantity_down_timing:
          type: string
          enum:
            - immediate
            - end_of_period
          description: "Momento de aplicação ao reduzir quantidade: `immediate` ou `end_of_period`."
        refund_on_remove:
          type: boolean
          description: Quando `true`, gera reembolso ao cliente ao remover itens. Exige `credit_on_remove` habilitado.
        credit_on_remove:
          type: boolean
          description: Quando `true`, gera crédito a favor do cliente ao remover itens.
        portal_self_service:
          type: boolean
          description: Quando `true`, libera ao cliente alterar a própria assinatura no portal.
        portal_require_confirmation:
          type: boolean
          description: Quando `true`, exige confirmação explícita do cliente antes de aplicar a mudança no portal.
    SubscriptionItemChangeV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        publicId:
          type: string
          format: uuid
          description: Identificador público (UUID) usado para integração externa.
        organizationId:
          type: string
          format: uuid
          description: UUID da organização dona da mudança.
        subscriptionId:
          type: string
          format: uuid
          description: UUID da assinatura alvo da mudança.
        billingAccountId:
          type: string
          format: uuid
          description: UUID da conta de cobrança da assinatura.
        status:
          type: string
          enum:
            - pending
            - scheduled
            - completed
            - canceled
            - failed
          description: "Status: `pending`, `scheduled`, `completed`, `canceled` ou `failed`."
        timing:
          type: string
          enum:
            - immediate
            - end_of_period
          description: "Momento de aplicação: `immediate` ou `end_of_period`."
        initiatedByRole:
          type: string
          description: "Origem da mudança: `dashboard`, `portal` ou `api`."
        initiatedBy:
          type:
            - string
            - "null"
          description: Identificador do usuário/integração que iniciou a mudança.
        prorationMethod:
          type: string
          enum:
            - full_proration
            - no_proration
            - partial_proration
          description: "Método de proporção efetivamente aplicado: `full_proration`, `no_proration` ou `partial_proration`."
        prorationCreditSubcents:
          type: integer
          description: Crédito de proporção em subcents (÷10000 → BRL) gerado para o cliente.
          example: 1000000
        prorationChargeSubcents:
          type: integer
          description: Cobrança de proporção em subcents (÷10000 → BRL) gerada para o cliente.
          example: 0
        daysRemaining:
          type: integer
          description: Dias restantes do período de cobrança no momento da aplicação.
        totalDaysInPeriod:
          type: integer
          description: Total de dias do período de cobrança usado no cálculo da proporção.
        changes:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: 'Snapshot do batch de operações aplicado. Cada entrada tem o formato `{ op: "add"|"remove"|"update_qty"|"update_price", productId, priceId, quantity, prevQuantity?, prevPriceId?, prevUnitAmountSubcents?, unitAmountSubcents }`.'
        effectiveDate:
          type: string
          format: date-time
          description: Data efetiva da mudança (quando ela passa a valer).
        scheduledDate:
          type:
            - string
            - "null"
          format: date-time
          description: Data agendada para aplicação, quando `timing = end_of_period`.
        completedAt:
          type:
            - string
            - "null"
          format: date-time
          description: Data/hora em que a mudança foi efetivamente aplicada.
        canceledAt:
          type:
            - string
            - "null"
          format: date-time
          description: Data/hora em que a mudança foi cancelada, quando aplicável.
        invoiceId:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da fatura gerada pela mudança, quando houver.
        creditId:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do crédito gerado pela mudança, quando houver.
        reason:
          type:
            - string
            - "null"
          description: Motivo livre informado pelo operador ao registrar a mudança.
        idempotencyKey:
          type:
            - string
            - "null"
          description: Chave de idempotência por organização — permite reexecutar com segurança.
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados livres definidos pelo cliente.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - publicId
        - organizationId
        - subscriptionId
        - billingAccountId
        - status
        - timing
        - initiatedByRole
        - initiatedBy
        - prorationMethod
        - prorationCreditSubcents
        - prorationChargeSubcents
        - daysRemaining
        - totalDaysInPeriod
        - changes
        - effectiveDate
        - scheduledDate
        - completedAt
        - canceledAt
        - invoiceId
        - creditId
        - reason
        - idempotencyKey
        - metadata
        - created_at
        - updated_at
    SubscriptionItemChangeListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/SubscriptionItemChangeV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    SubscriptionItemChangeResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/SubscriptionItemChangeV1"
      required:
        - data
    UsageRecordV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        subscription_item_id:
          type: string
          format: uuid
          description: UUID do item de assinatura ao qual o uso pertence.
        quantity:
          type: number
          description: Quantidade reportada no registro.
          example: 5
        action:
          type: string
          enum:
            - increment
            - set
          description: "Tipo da ação: `increment` (soma) ou `set` (substitui valores anteriores do período)."
        timestamp:
          type: string
          format: date-time
          description: Data/hora do uso (ISO 8601).
        idempotency_key:
          type:
            - string
            - "null"
          description: Chave de idempotência usada na criação, se houver.
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados livres definidos pelo cliente.
        created_at:
          type: string
          format: date-time
      required:
        - id
        - subscription_item_id
        - quantity
        - action
        - timestamp
        - idempotency_key
        - metadata
        - created_at
    UsageListMeta:
      type: object
      properties:
        total:
          type: integer
        limit:
          type: integer
        offset:
          type: integer
        total_quantity:
          type: number
        product_slug:
          type: string
        customer_id:
          type: string
      required:
        - total
        - limit
        - offset
        - total_quantity
    UsageListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/UsageRecordV1"
        meta:
          $ref: "#/components/schemas/UsageListMeta"
      required:
        - data
        - meta
    UsageRecordCreateInput:
      type: object
      properties:
        subscription_item_id:
          type: string
          format: uuid
          description: UUID do item de assinatura (opção 1 — alternativa a `product_slug` + `customer_id`).
        product_slug:
          type: string
          description: Slug do produto (opção 2). Combine com `customer_id` para localizar a assinatura ativa.
        customer_id:
          type: string
          description: Identificador externo do cliente (`external_id` do `billing_account`). Combine com `product_slug`.
        quantity:
          type: number
          minimum: 0
          description: "Quantidade a registrar — número não negativo. Ex.: `5`, `0`, `1500`."
          example: 5
        action:
          type: string
          enum:
            - increment
            - set
          description: "`increment` (padrão) soma à quantidade do período; `set` substitui qualquer valor anterior do período até o momento."
        timestamp:
          type: string
          format: date-time
          description: "Data/hora do uso em ISO 8601. Padrão: agora."
        idempotency_key:
          type: string
          description: "Chave de idempotência opcional. Se já existir um registro com a mesma chave para o item, retorna o existente com `duplicate: true`."
        custom_metadata:
          type: object
          additionalProperties: {}
          description: usage.create.body.custom_metadata
      required:
        - quantity
    UsageRecordBatchCreateInput:
      type: object
      properties:
        records:
          type: array
          items:
            $ref: "#/components/schemas/UsageRecordCreateInput"
          minItems: 1
          maxItems: 100
          description: Lote de registros (1 a 100). Quando presente, processa em lote e ignora o registro de topo.
      required:
        - records
    UsageRecordCreateRequest:
      anyOf:
        - $ref: "#/components/schemas/UsageRecordCreateInput"
        - $ref: "#/components/schemas/UsageRecordBatchCreateInput"
    UsageRecordBatchResult:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: UUID do registro criado ou já existente.
        subscription_item_id:
          type: string
          format: uuid
        product_slug:
          type: string
        customer_id:
          type: string
        success:
          type: boolean
          description: Indica se o registro foi processado com sucesso.
        duplicate:
          type: boolean
          description: Quando `true`, indica que o registro já existia com a mesma `idempotency_key`.
        error:
          type: string
          description: Mensagem de erro quando `success` é `false`.
      required:
        - success
    UsageRecordCreateResponse:
      type: object
      properties:
        success:
          type: boolean
        processed:
          type: integer
        failed:
          type: integer
        partial:
          type: boolean
        results:
          anyOf:
            - $ref: "#/components/schemas/UsageRecordBatchResult"
            - type: array
              items:
                $ref: "#/components/schemas/UsageRecordBatchResult"
      required:
        - success
        - processed
        - results
    UsageSummaryProduct:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: UUID do produto associado ao item de assinatura.
        name:
          type: string
          description: Nome do produto.
        slug:
          type: string
          description: Slug do produto.
      required:
        - id
        - name
        - slug
    UsageSummaryPeriod:
      type: object
      properties:
        start:
          type: string
          format: date-time
          description: Início do período considerado na agregação (ISO 8601).
        end:
          type: string
          format: date-time
          description: Fim do período considerado na agregação (ISO 8601).
      required:
        - start
        - end
    UsageSummaryUsage:
      type: object
      properties:
        total_quantity:
          type: number
          description: Quantidade total consolidada no período.
        record_count:
          type: integer
          description: Número de registros considerados.
        first_record_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data/hora do primeiro registro no período (ISO 8601).
        last_record_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data/hora do último registro no período (ISO 8601).
      required:
        - total_quantity
        - record_count
        - first_record_at
        - last_record_at
    UsageSummaryBilling:
      type: object
      properties:
        estimated_cost_cents:
          type:
            - integer
            - "null"
          description: Custo estimado em centavos (÷100 → BRL). `null` quando o preço não permite cálculo.
        price_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do preço utilizado para a estimativa.
        usage_type:
          type:
            - string
            - "null"
          description: "Tipo de uso configurado no preço (ex.: `metered`, `licensed`)."
      required:
        - estimated_cost_cents
        - price_id
        - usage_type
    UsageSummaryResponse:
      type: object
      properties:
        subscription_item_id:
          type: string
          format: uuid
          description: UUID do item de assinatura ao qual o uso pertence.
        subscription_id:
          type: string
          format: uuid
          description: UUID da assinatura.
        subscription_status:
          type: string
          description: "Status atual da assinatura (ex.: `active`, `trialing`)."
        product:
          allOf:
            - $ref: "#/components/schemas/UsageSummaryProduct"
            - type:
                - object
                - "null"
        customer_id:
          type: string
        period:
          $ref: "#/components/schemas/UsageSummaryPeriod"
        usage:
          $ref: "#/components/schemas/UsageSummaryUsage"
        billing:
          $ref: "#/components/schemas/UsageSummaryBilling"
      required:
        - subscription_item_id
        - subscription_id
        - subscription_status
        - product
        - period
        - usage
        - billing
    UsageDailySnapshotV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type: string
          format: uuid
          description: UUID da organização dona do snapshot.
        billing_account_id:
          type: string
          format: uuid
          description: UUID da conta de cobrança associada ao snapshot.
        product_group_id:
          type: string
          format: uuid
          description: UUID do grupo de produtos.
        product_id:
          type: string
          format: uuid
          description: UUID do produto.
        snapshot_date:
          type: string
          format: date-time
          description: Data do snapshot (ISO 8601, granularidade diária).
        quantity:
          type: number
          description: Quantidade reportada no registro.
        idempotency_key:
          type: string
          description: Chave de idempotência usada na criação, se houver.
        calculated_at:
          type: string
          format: date-time
          description: Data/hora em que o snapshot foi calculado (ISO 8601).
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados livres definidos pelo cliente.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - organization_id
        - billing_account_id
        - product_group_id
        - product_id
        - snapshot_date
        - quantity
        - idempotency_key
        - calculated_at
        - metadata
        - created_at
        - updated_at
    UsageSnapshotListMeta:
      type: object
      properties:
        total:
          type: integer
        limit:
          type: integer
        offset:
          type: integer
      required:
        - total
        - limit
        - offset
    UsageDailySnapshotListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/UsageDailySnapshotV1"
        meta:
          $ref: "#/components/schemas/UsageSnapshotListMeta"
      required:
        - data
        - meta
    UsageDailySnapshotCreateInput:
      type: object
      properties:
        billing_account_id:
          type: string
          format: uuid
          description: UUID da conta de cobrança. Alternativa a `billing_account_public_id`.
        billing_account_public_id:
          type: string
          description: Identificador público da conta de cobrança. Alternativa a `billing_account_id`.
        product_group_slug:
          type: string
          description: Slug do grupo de produtos — obrigatório. Escopa a busca de `product_slug`/`product_id`.
        product_slug:
          type: string
          description: Slug do produto dentro do grupo. Alternativa a `product_id`.
        product_id:
          type: string
          format: uuid
          description: UUID do produto dentro do grupo. Alternativa a `product_slug`.
        snapshot_date:
          type: string
          description: Data do snapshot em formato `YYYY-MM-DD` (ISO 8601).
          example: 2026-03-15
        quantity:
          type: number
          minimum: 0
          description: Quantidade consolidada do dia — número não negativo.
        idempotency_key:
          type: string
          minLength: 1
          description: Chave de idempotência **obrigatória**. Deve ser única entre snapshots.
        calculated_at:
          type: string
          format: date-time
          description: "Data/hora em que a quantidade foi calculada (ISO 8601). Padrão: agora."
        custom_metadata:
          type: object
          additionalProperties: {}
          description: usage.daily_snapshots.create.body.custom_metadata
      required:
        - product_group_slug
        - snapshot_date
        - quantity
        - idempotency_key
    UsageDailySnapshotBatchCreateInput:
      type: object
      properties:
        records:
          type: array
          items:
            $ref: "#/components/schemas/UsageDailySnapshotCreateInput"
          minItems: 1
          maxItems: 100
          description: Lote de snapshots diários (1 a 100).
      required:
        - records
    UsageDailySnapshotCreateRequest:
      anyOf:
        - $ref: "#/components/schemas/UsageDailySnapshotCreateInput"
        - $ref: "#/components/schemas/UsageDailySnapshotBatchCreateInput"
    UsageDailySnapshotBatchResult:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: UUID do registro criado ou já existente.
        billing_account_id:
          type: string
          format: uuid
        product_id:
          type: string
          format: uuid
        success:
          type: boolean
          description: Indica se o registro foi processado com sucesso.
        overwritten:
          type: boolean
          description: Quando `true`, indica que um snapshot pré-existente foi sobrescrito.
        error:
          type: string
          description: Mensagem de erro quando `success` é `false`.
        data:
          $ref: "#/components/schemas/UsageDailySnapshotV1"
      required:
        - success
    UsageDailySnapshotCreateResponse:
      type: object
      properties:
        success:
          type: boolean
        processed:
          type: integer
        failed:
          type: integer
        partial:
          type: boolean
        results:
          anyOf:
            - $ref: "#/components/schemas/UsageDailySnapshotBatchResult"
            - type: array
              items:
                $ref: "#/components/schemas/UsageDailySnapshotBatchResult"
      required:
        - success
        - processed
        - results
    UsageMonthlySnapshotV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type: string
          format: uuid
          description: UUID da organização dona do snapshot.
        billing_account_id:
          type: string
          format: uuid
          description: UUID da conta de cobrança associada ao snapshot.
        product_group_id:
          type: string
          format: uuid
          description: UUID do grupo de produtos.
        product_id:
          type: string
          format: uuid
          description: UUID do produto.
        month:
          type: string
          format: date-time
          description: Mês de referência (ISO 8601 — primeiro dia do mês).
        total_quantity:
          type: number
          description: Quantidade total acumulada no mês.
        avg_daily_quantity:
          type: number
          description: Média diária de uso no mês.
        days_with_usage:
          type: integer
          description: Número de dias com uso registrado no mês.
        plan_limit:
          type:
            - number
            - "null"
          description: Limite contratado do plano para o período. `null` quando ilimitado.
        excess_quantity:
          type: number
          description: Quantidade excedente sobre o `plan_limit`.
        idempotency_key:
          type: string
          description: Chave de idempotência usada na criação, se houver.
        calculated_at:
          type: string
          format: date-time
          description: Data/hora em que o snapshot foi calculado (ISO 8601).
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados livres definidos pelo cliente.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - organization_id
        - billing_account_id
        - product_group_id
        - product_id
        - month
        - total_quantity
        - avg_daily_quantity
        - days_with_usage
        - plan_limit
        - excess_quantity
        - idempotency_key
        - calculated_at
        - metadata
        - created_at
        - updated_at
    UsageMonthlySnapshotListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/UsageMonthlySnapshotV1"
        meta:
          $ref: "#/components/schemas/UsageSnapshotListMeta"
      required:
        - data
        - meta
    UsageMonthlySnapshotCreateInput:
      type: object
      properties:
        billing_account_id:
          type: string
          format: uuid
          description: UUID da conta de cobrança. Alternativa a `billing_account_public_id`.
        billing_account_public_id:
          type: string
          description: Identificador público da conta de cobrança. Alternativa a `billing_account_id`.
        product_group_slug:
          type: string
          description: Slug do grupo de produtos — obrigatório.
        product_slug:
          type: string
          description: Slug do produto dentro do grupo. Alternativa a `product_id`.
        product_id:
          type: string
          format: uuid
          description: UUID do produto dentro do grupo. Alternativa a `product_slug`.
        month:
          type: string
          description: "Mês de referência em formato `YYYY-MM-DD` (use o primeiro dia do mês, ex.: `2026-03-01`)."
          example: 2026-03-01
        total_quantity:
          type: number
          minimum: 0
          description: Quantidade total acumulada do mês — número não negativo.
        avg_daily_quantity:
          type: number
          minimum: 0
          description: Média diária de uso no mês — número não negativo.
        days_with_usage:
          type: integer
          minimum: 0
          description: Número de dias com uso registrado (inteiro não negativo).
        plan_limit:
          type:
            - number
            - "null"
          description: Limite contratado do plano para o período (opcional). Use `null` quando ilimitado.
        excess_quantity:
          type: number
          minimum: 0
          description: Quantidade excedente sobre o `plan_limit` — número não negativo.
        idempotency_key:
          type: string
          minLength: 1
          description: Chave de idempotência **obrigatória**. Deve ser única entre snapshots.
        calculated_at:
          type: string
          format: date-time
          description: "Data/hora em que os números foram calculados (ISO 8601). Padrão: agora."
        custom_metadata:
          type: object
          additionalProperties: {}
          description: usage.monthly_snapshots.create.body.custom_metadata
      required:
        - product_group_slug
        - month
        - total_quantity
        - avg_daily_quantity
        - days_with_usage
        - excess_quantity
        - idempotency_key
    UsageMonthlySnapshotBatchCreateInput:
      type: object
      properties:
        records:
          type: array
          items:
            $ref: "#/components/schemas/UsageMonthlySnapshotCreateInput"
          minItems: 1
          maxItems: 100
          description: Lote de snapshots mensais (1 a 100).
      required:
        - records
    UsageMonthlySnapshotCreateRequest:
      anyOf:
        - $ref: "#/components/schemas/UsageMonthlySnapshotCreateInput"
        - $ref: "#/components/schemas/UsageMonthlySnapshotBatchCreateInput"
    UsageMonthlySnapshotBatchResult:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: UUID do registro criado ou já existente.
        billing_account_id:
          type: string
          format: uuid
        product_id:
          type: string
          format: uuid
        success:
          type: boolean
          description: Indica se o registro foi processado com sucesso.
        overwritten:
          type: boolean
          description: Quando `true`, indica que um snapshot pré-existente foi sobrescrito.
        error:
          type: string
          description: Mensagem de erro quando `success` é `false`.
        data:
          $ref: "#/components/schemas/UsageMonthlySnapshotV1"
      required:
        - success
    UsageMonthlySnapshotCreateResponse:
      type: object
      properties:
        success:
          type: boolean
        processed:
          type: integer
        failed:
          type: integer
        partial:
          type: boolean
        results:
          anyOf:
            - $ref: "#/components/schemas/UsageMonthlySnapshotBatchResult"
            - type: array
              items:
                $ref: "#/components/schemas/UsageMonthlySnapshotBatchResult"
      required:
        - success
        - processed
        - results
    TaxRuleItemV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tax_rule_id:
          type: string
          format: uuid
          description: UUID da regra à qual o item pertence.
        tax_type:
          type: string
          enum:
            - iss
            - pis
            - cofins
            - csll
            - irpj
            - irrf
            - csrf
            - inss
            - cbs
            - ibs
          description: "Tributo: `iss`, `pis`, `cofins`, `csll`, `irpj`, `irrf`, `csrf`, `inss`, `cbs` ou `ibs`."
        rate:
          type: number
          description: "Alíquota percentual (0–100), até 2 casas decimais. Ex.: `5.00` = 5%."
          example: 5
        is_withheld:
          type: boolean
          description: Quando `true`, o tributo é retido na fonte.
        base_type:
          type: string
          enum:
            - service_value
            - service_value_minus_iss
            - presumed_base
          description: "Base de cálculo: `service_value`, `service_value_minus_iss` ou `presumed_base`."
        is_exempt:
          type: boolean
          description: Quando `true`, indica isenção do tributo.
        exemption_reason:
          type:
            - string
            - "null"
          description: Justificativa da isenção, quando `is_exempt = true`.
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tax_rule_id
        - tax_type
        - rate
        - is_withheld
        - base_type
        - is_exempt
        - exemption_reason
        - created_at
    TaxRuleV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        scope:
          type: string
          enum:
            - global
            - organization
            - company
            - service
            - customer
            - municipality
          description: "Escopo da regra: `global`, `organization`, `company`, `service`, `customer` ou `municipality`."
        priority:
          type: integer
          description: Prioridade. Maior valor sobrescreve regras de menor prioridade.
          example: 0
        company_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da empresa quando `scope = company`.
        service_item_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do item de serviço quando `scope = service`.
        billing_account_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da conta de cobrança quando `scope = customer`.
        customer_tax_type:
          type:
            - string
            - "null"
          enum:
            - pessoa_fisica
            - pessoa_juridica
            - mei
            - simples_optante
            - entidade_publica
          description: Tipo tributário do cliente que a regra cobre.
        municipality:
          type:
            - string
            - "null"
          description: Código IBGE do município (7 dígitos) quando `scope = municipality`.
        operation_type:
          type:
            - string
            - "null"
          enum:
            - interno
            - externo
          description: "Tipo de operação: `interno` ou `externo`."
        name:
          type: string
          description: Nome legível da regra.
        description:
          type:
            - string
            - "null"
          description: Descrição da regra.
        is_active:
          type: boolean
          description: Indica se a regra está ativa.
        effective_from:
          type: string
          format: date-time
          description: Data/hora ISO 8601 a partir da qual a regra vale.
        effective_to:
          type:
            - string
            - "null"
          format: date-time
          description: Data/hora ISO 8601 em que a regra deixa de valer. `null` significa vigência indeterminada.
        items:
          type: array
          items:
            $ref: "#/components/schemas/TaxRuleItemV1"
          description: Lista de itens da regra — uma entrada por tributo.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - scope
        - priority
        - company_id
        - service_item_id
        - billing_account_id
        - customer_tax_type
        - municipality
        - operation_type
        - name
        - description
        - is_active
        - effective_from
        - effective_to
        - items
        - created_at
        - updated_at
    TaxRuleListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/TaxRuleV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    TaxRuleResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/TaxRuleV1"
      required:
        - data
    TaxRuleItemInput:
      type: object
      properties:
        tax_type:
          type: string
          enum:
            - iss
            - pis
            - cofins
            - csll
            - irpj
            - irrf
            - csrf
            - inss
            - cbs
            - ibs
          description: "Tributo: `iss`, `pis`, `cofins`, `csll`, `irpj`, `irrf`, `csrf`, `inss`, `cbs` ou `ibs`."
        rate:
          type: number
          minimum: 0
          maximum: 100
          description: "Alíquota percentual (0–100), até 2 casas decimais. Ex.: `5.00` = 5%."
          example: 5
        is_withheld:
          type: boolean
          description: Quando `true`, o tributo é retido na fonte.
        base_type:
          type: string
          enum:
            - service_value
            - service_value_minus_iss
            - presumed_base
          description: "Base de cálculo: `service_value`, `service_value_minus_iss` ou `presumed_base`."
        is_exempt:
          type: boolean
          description: Quando `true`, indica isenção do tributo.
        exemption_reason:
          type:
            - string
            - "null"
          description: Justificativa da isenção, quando `is_exempt = true`.
      required:
        - tax_type
        - rate
    TaxRuleCreateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          description: Nome legível da regra.
        description:
          type:
            - string
            - "null"
          description: Descrição opcional da regra.
        scope:
          type: string
          enum:
            - global
            - organization
            - company
            - service
            - customer
            - municipality
          description: "Escopo da regra: `global`, `organization`, `company`, `service`, `customer` ou `municipality`."
        priority:
          type: integer
          description: "Prioridade da regra. Maior valor sobrescreve regras de menor prioridade. Padrão: `0`."
          example: 0
        company_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da empresa quando `scope = company`. A empresa precisa pertencer à organização atual.
        service_item_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID do item de serviço quando `scope = service`. O item precisa pertencer à organização atual.
        billing_account_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da conta de cobrança quando `scope = customer`. A conta precisa pertencer à organização atual.
        customer_tax_type:
          type:
            - string
            - "null"
          enum:
            - pessoa_fisica
            - pessoa_juridica
            - mei
            - simples_optante
            - entidade_publica
          description: "Tipo tributário do cliente: `pessoa_fisica`, `pessoa_juridica`, `mei`, `simples_optante` ou `entidade_publica`."
        municipality:
          type:
            - string
            - "null"
          description: Código IBGE do município (7 dígitos) quando `scope = municipality`.
        operation_type:
          type:
            - string
            - "null"
          enum:
            - interno
            - externo
          description: "Tipo de operação: `interno` (mesmo município) ou `externo` (município diferente)."
        effective_from:
          type: string
          format: date-time
          description: Data/hora ISO 8601 em que a regra passa a valer.
        effective_to:
          type:
            - string
            - "null"
          format: date-time
          description: Data/hora ISO 8601 em que a regra deixa de valer. `null` significa vigência indeterminada.
        items:
          type: array
          items:
            $ref: "#/components/schemas/TaxRuleItemInput"
          minItems: 1
          description: Lista de itens (alíquotas por tributo). Obrigatório ao menos 1 item.
      required:
        - name
        - scope
        - items
    TaxRuleUpdateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          description: Novo nome da regra.
        description:
          type:
            - string
            - "null"
          description: Nova descrição da regra.
        priority:
          type: integer
          description: Nova prioridade da regra.
        is_active:
          type: boolean
          description: Quando `false`, desativa a regra sem removê-la.
        effective_to:
          type:
            - string
            - "null"
          format: date-time
          description: Nova data/hora ISO 8601 de fim de vigência (ou `null` para indeterminada).
        items:
          type: array
          items:
            $ref: "#/components/schemas/TaxRuleItemInput"
          description: Quando informado, substitui integralmente a lista de itens da regra.
    TaxRuleDeletedResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            deleted:
              type: boolean
              example: true
          required:
            - deleted
      required:
        - data
    TaxPeriodV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        company_id:
          type: string
          format: uuid
          description: UUID da empresa emissora.
        period_type:
          type: string
          enum:
            - monthly
            - quarterly
          description: "Tipo do período: `monthly` (mensal) ou `quarterly` (trimestral)."
        year:
          type: integer
          description: Ano de competência.
          example: 2026
        month:
          type:
            - integer
            - "null"
          minimum: 1
          maximum: 12
          description: Mês de competência (1 a 12) — preenchido apenas em períodos mensais.
        quarter:
          type:
            - integer
            - "null"
          minimum: 1
          maximum: 4
          description: Trimestre de competência (1 a 4) — preenchido apenas em períodos trimestrais.
        status:
          type: string
          enum:
            - open
            - calculated
            - closed
          description: "Status do período: `open`, `calculated` ou `closed`."
        gross_revenue_cents:
          type: integer
          description: Receita bruta apurada no período, em centavos (÷100 → BRL).
          example: 100000
        taxable_revenue_cents:
          type: integer
          description: Receita tributável no período, em centavos (÷100 → BRL).
        iss_due_cents:
          type: integer
          description: ISS devido no período, em centavos (÷100 → BRL).
        pis_due_cents:
          type: integer
          description: PIS devido no período, em centavos (÷100 → BRL).
        cofins_due_cents:
          type: integer
          description: COFINS devido no período, em centavos (÷100 → BRL).
        irpj_due_cents:
          type: integer
          description: IRPJ devido (estimativa mensal), em centavos (÷100 → BRL).
        csll_due_cents:
          type: integer
          description: CSLL devido (estimativa mensal), em centavos (÷100 → BRL).
        irrf_to_compensate_cents:
          type: integer
          description: IRRF retido a compensar no período, em centavos (÷100 → BRL).
        csrf_to_compensate_cents:
          type: integer
          description: CSRF (PIS/COFINS/CSLL retidos) a compensar no período, em centavos (÷100 → BRL).
        iss_to_compensate_cents:
          type: integer
          description: ISS retido a compensar no período, em centavos (÷100 → BRL).
        das_estimated_cents:
          type:
            - integer
            - "null"
          description: DAS estimado (Simples Nacional), em centavos (÷100 → BRL).
        simples_effective_rate:
          type:
            - string
            - "null"
          description: Alíquota efetiva do Simples Nacional aplicada no período (percentual).
        simples_annex:
          type:
            - string
            - "null"
          description: "Anexo do Simples Nacional aplicável (ex.: `annex_iii`, `annex_v`)."
        cbs_due_cents:
          type: integer
          description: CBS devido (reforma tributária 2026+), em centavos (÷100 → BRL).
        ibs_due_cents:
          type: integer
          description: IBS devido (reforma tributária 2026+), em centavos (÷100 → BRL).
        calculation_log:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Registro JSON da memória de cálculo (regime, NFes consideradas, alíquotas).
        closed_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data/hora em que o período foi encerrado.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - company_id
        - period_type
        - year
        - month
        - quarter
        - status
        - gross_revenue_cents
        - taxable_revenue_cents
        - iss_due_cents
        - pis_due_cents
        - cofins_due_cents
        - irpj_due_cents
        - csll_due_cents
        - irrf_to_compensate_cents
        - csrf_to_compensate_cents
        - iss_to_compensate_cents
        - das_estimated_cents
        - simples_effective_rate
        - simples_annex
        - cbs_due_cents
        - ibs_due_cents
        - calculation_log
        - closed_at
        - created_at
        - updated_at
    TaxPeriodListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/TaxPeriodV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    TaxPeriodResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/TaxPeriodV1"
      required:
        - data
    TaxPeriodCreateRequest:
      type: object
      properties:
        company_id:
          type: string
          format: uuid
          description: UUID da empresa emissora. Omita para usar a empresa padrão da organização.
        year:
          type: integer
          minimum: 2020
          maximum: 2100
          description: "Ano de competência (ex.: `2026`)."
          example: 2026
        month:
          type: integer
          minimum: 1
          maximum: 12
          description: Mês de competência (1 a 12).
          example: 6
      required:
        - year
        - month
    TaxPeriodUpdateRequest:
      type: object
      properties:
        action:
          type: string
          enum:
            - recalculate
            - close
            - reopen
          description: "Ação a executar: `recalculate`, `close` ou `reopen`."
      required:
        - action
    TaxPeriodDeletedResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            deleted:
              type: boolean
              example: true
          required:
            - deleted
      required:
        - data
    WithholdingV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type: string
          format: uuid
          description: UUID da organização proprietária da retenção.
        invoice_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da fatura associada, quando houver.
        nfe_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da NF-e associada, quando houver.
        tax_type:
          type: string
          enum:
            - iss
            - pis
            - cofins
            - csll
            - irpj
            - irrf
            - csrf
            - inss
            - cbs
            - ibs
          description: "Tipo do tributo retido: `iss`, `pis`, `cofins`, `csll`, `irpj`, `irrf`, `csrf`, `inss`, `cbs` ou `ibs`."
        base_cents:
          type: integer
          description: Base de cálculo em centavos (÷100 → BRL).
          example: 100000
        rate:
          type: number
          description: "Alíquota aplicada em percentual (ex.: `1.5` para 1,5%)."
          example: 1.5
        amount_cents:
          type: integer
          description: Valor retido em centavos (÷100 → BRL).
          example: 1500
        withholder_id:
          type: string
          format: uuid
          description: UUID da conta de cobrança do retentor (quem reteve o tributo).
        status:
          type: string
          enum:
            - retained
            - compensated
            - partially_compensated
          description: "Status da retenção: `retained`, `compensated` ou `partially_compensated`."
        compensated_cents:
          type: integer
          description: Valor já compensado/convertido em crédito, em centavos (÷100 → BRL).
          example: 0
        competence_month:
          type: integer
          minimum: 1
          maximum: 12
          description: Mês de competência (1–12).
        competence_year:
          type: integer
          description: Ano de competência (2000–3000).
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados livres associados à retenção.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - organization_id
        - invoice_id
        - nfe_id
        - tax_type
        - base_cents
        - rate
        - amount_cents
        - withholder_id
        - status
        - compensated_cents
        - competence_month
        - competence_year
        - metadata
        - created_at
        - updated_at
    WithholdingListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/WithholdingV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    WithholdingResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/WithholdingV1"
      required:
        - data
    WithholdingConvertToCreditRequest:
      type: object
      properties:
        amount_cents:
          type: integer
          exclusiveMinimum: 0
          description: "Valor a converter em centavos (÷100 → BRL). Padrão: saldo pendente da retenção."
    WithholdingConvertToCreditResponse:
      type: object
      properties:
        credit:
          allOf:
            - $ref: "#/components/schemas/CreditV1"
            - description: Crédito gerado pela conversão da retenção.
      required:
        - credit
    WithholdingBulkConvertRequest:
      type: object
      properties:
        tax_type:
          type: string
          enum:
            - iss
            - pis
            - cofins
            - csll
            - irpj
            - irrf
            - csrf
            - inss
            - cbs
            - ibs
          description: "Restringe a conversão a um tipo de tributo (ex.: `irrf`, `pis`, `cofins`)."
        competence_year:
          type: integer
          minimum: 2000
          maximum: 3000
          description: Restringe a conversão ao ano de competência informado.
        competence_month:
          type: integer
          minimum: 1
          maximum: 12
          description: Restringe a conversão ao mês de competência informado (1–12).
    WithholdingBulkConvertResponse:
      type: object
      properties:
        credits:
          type: array
          items:
            $ref: "#/components/schemas/CreditV1"
          description: Lista de créditos gerados pela conversão.
        total_converted:
          type: integer
          description: Quantidade total de retenções convertidas em créditos.
        total_amount_cents:
          type: integer
          description: Soma dos valores convertidos em centavos (÷100 → BRL).
      required:
        - credits
        - total_converted
        - total_amount_cents
    ServiceItemV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type: string
          format: uuid
        company_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da empresa emissora associada ao item. `null` quando o item vale para todas as empresas da organização.
        name:
          type: string
          description: Nome do item de serviço (exibido em faturas e NFS-e).
        description:
          type:
            - string
            - "null"
          description: Descrição opcional do serviço.
        internal_code:
          type: string
          description: Código interno do item — imutável depois da criação.
        lc116_code:
          type: string
          description: "Código de serviço conforme Lei Complementar 116/2003 (ex.: `01.05`)."
          example: "01.05"
        municipal_code:
          type:
            - string
            - "null"
          description: Código municipal do serviço, quando o município exige codificação própria.
        nbs_code:
          type:
            - string
            - "null"
          description: Código NBS — Nomenclatura Brasileira de Serviços.
        cnae_code:
          type:
            - string
            - "null"
          description: Código CNAE relacionado ao serviço prestado.
        simples_annex:
          type:
            - string
            - "null"
          enum:
            - annex_iii
            - annex_iv
            - annex_v
          description: "Anexo do Simples Nacional aplicável ao serviço: `annex_iii`, `annex_iv` ou `annex_v`."
        default_iss_rate:
          type:
            - string
            - "null"
          description: "Alíquota padrão de ISS em pontos percentuais (ex.: `2.5` representa 2,5%). Decimal com até duas casas."
          example: "2.50"
        subject_to_irrf:
          type: boolean
          description: Indica se o item sofre retenção de IRRF por padrão.
        subject_to_csrf:
          type: boolean
          description: Indica se o item sofre retenção de CSRF (PIS/COFINS/CSLL) por padrão.
        subject_to_inss:
          type: boolean
          description: Indica se o item sofre retenção de INSS por padrão.
        subject_to_iss_withholding:
          type: boolean
          description: Indica se o item sofre retenção de ISS por padrão.
        c_class_trib:
          type:
            - string
            - "null"
          description: Classificação tributária (CST IBS/CBS) aplicável ao item.
        cbs_ibs_category:
          type:
            - string
            - "null"
          description: Categoria CBS/IBS do item, conforme a reforma tributária.
        indop_code:
          type:
            - string
            - "null"
          description: Indicador de Operação (`indOp`) usado na NFS-e SNNFSE.
        is_active:
          type: boolean
          description: Quando `false`, o item não pode ser selecionado em novas faturas ou NFS-e.
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados internos do item (uso da plataforma).
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados arbitrários definidos pelo cliente (chave/valor).
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - organization_id
        - company_id
        - name
        - description
        - internal_code
        - lc116_code
        - municipal_code
        - nbs_code
        - cnae_code
        - simples_annex
        - default_iss_rate
        - subject_to_irrf
        - subject_to_csrf
        - subject_to_inss
        - subject_to_iss_withholding
        - c_class_trib
        - cbs_ibs_category
        - indop_code
        - is_active
        - metadata
        - custom_metadata
        - created_at
        - updated_at
    ServiceItemListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/ServiceItemV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    ServiceItemResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/ServiceItemV1"
      required:
        - data
    ServiceItemCreateRequest:
      type: object
      properties:
        company_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da empresa emissora associada. Omita ou envie `null` para um item aplicável a todas as empresas.
        name:
          type: string
          minLength: 1
          description: Nome do item de serviço.
        description:
          type:
            - string
            - "null"
          description: Descrição opcional.
        internal_code:
          type: string
          minLength: 1
          description: Código interno do item — imutável depois da criação.
        lc116_code:
          type: string
          minLength: 1
          description: "Código LC 116/2003 do serviço (ex.: `01.05`)."
          example: "01.05"
        municipal_code:
          type:
            - string
            - "null"
          description: Código municipal do serviço, quando aplicável.
        nbs_code:
          type:
            - string
            - "null"
          description: Código NBS.
        cnae_code:
          type:
            - string
            - "null"
          description: Código CNAE relacionado.
        simples_annex:
          type:
            - string
            - "null"
          enum:
            - annex_iii
            - annex_iv
            - annex_v
          description: "Anexo do Simples Nacional aplicável: `annex_iii`, `annex_iv` ou `annex_v`."
        default_iss_rate:
          type:
            - number
            - "null"
          description: "Alíquota padrão de ISS em pontos percentuais (ex.: `2.5`)."
          example: 2.5
        subject_to_irrf:
          type: boolean
          description: "Indica se o item sofre retenção de IRRF. Padrão: `true`."
        subject_to_csrf:
          type: boolean
          description: "Indica se o item sofre retenção de CSRF. Padrão: `true`."
        subject_to_inss:
          type: boolean
          description: "Indica se o item sofre retenção de INSS. Padrão: `false`."
        subject_to_iss_withholding:
          type: boolean
          description: "Indica se o item sofre retenção de ISS. Padrão: `false`."
        c_class_trib:
          type:
            - string
            - "null"
          description: Classificação tributária CST IBS/CBS.
        cbs_ibs_category:
          type:
            - string
            - "null"
          description: Categoria CBS/IBS do item.
        indop_code:
          type:
            - string
            - "null"
          description: Indicador de Operação (`indOp`) da NFS-e SNNFSE.
        custom_metadata:
          type: object
          additionalProperties: {}
          description: Metadados arbitrários definidos pelo cliente (chave/valor).
      required:
        - name
        - internal_code
        - lc116_code
    ServiceItemUpdateRequest:
      type: object
      properties:
        company_id:
          type:
            - string
            - "null"
          format: uuid
          description: Nova empresa emissora associada. Envie `null` para desassociar.
        name:
          type: string
          minLength: 1
          description: Novo nome do item.
        description:
          type:
            - string
            - "null"
          description: Nova descrição. Envie `null` para limpar.
        lc116_code:
          type: string
          minLength: 1
          description: Novo código LC 116/2003.
        municipal_code:
          type:
            - string
            - "null"
          description: Novo código municipal. Envie `null` para limpar.
        nbs_code:
          type:
            - string
            - "null"
          description: Novo código NBS. Envie `null` para limpar.
        cnae_code:
          type:
            - string
            - "null"
          description: Novo código CNAE. Envie `null` para limpar.
        simples_annex:
          type:
            - string
            - "null"
          enum:
            - annex_iii
            - annex_iv
            - annex_v
          description: Novo anexo do Simples Nacional. Envie `null` para limpar.
        default_iss_rate:
          type:
            - number
            - "null"
          description: Nova alíquota padrão de ISS em pontos percentuais. Envie `null` para limpar.
        subject_to_irrf:
          type: boolean
          description: Atualiza a sujeição a IRRF.
        subject_to_csrf:
          type: boolean
          description: Atualiza a sujeição a CSRF.
        subject_to_inss:
          type: boolean
          description: Atualiza a sujeição a INSS.
        subject_to_iss_withholding:
          type: boolean
          description: Atualiza a sujeição a retenção de ISS.
        c_class_trib:
          type:
            - string
            - "null"
          description: Nova classificação tributária CST IBS/CBS. Envie `null` para limpar.
        cbs_ibs_category:
          type:
            - string
            - "null"
          description: Nova categoria CBS/IBS. Envie `null` para limpar.
        indop_code:
          type:
            - string
            - "null"
          description: Novo Indicador de Operação (`indOp`). Envie `null` para limpar.
        is_active:
          type: boolean
          description: Ativa (`true`) ou desativa (`false`) o item de serviço.
        custom_metadata:
          type: object
          additionalProperties: {}
          description: Metadados arbitrários definidos pelo cliente (chave/valor).
    DashboardUserRoleSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: UUID do papel.
        name:
          type: string
          description: Nome do papel.
        slug:
          type: string
          description: Slug (identificador estável) do papel.
      required:
        - id
        - name
        - slug
    DashboardUserV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type: string
          format: uuid
          description: UUID da organização à qual o usuário pertence.
        person_id:
          type:
            - string
            - "null"
          format: uuid
          description: UUID da pessoa (registro de identidade) associada ao usuário, quando houver.
        external_id:
          type: string
          description: Identificador externo do usuário no Kobana OAuth.
        email:
          type: string
          format: email
          description: E-mail do usuário.
        name:
          type:
            - string
            - "null"
          description: Nome de exibição.
        picture:
          type:
            - string
            - "null"
          description: URL da foto do usuário.
        status:
          type: string
          enum:
            - active
            - pending_invitation
            - suspended
          description: "Status atual do usuário: `active`, `pending_invitation` ou `suspended`."
        permissions:
          type: array
          items:
            type: string
          description: Permissões ad-hoc atribuídas diretamente ao usuário (além das herdadas dos papéis).
        last_login_at:
          type:
            - string
            - "null"
          format: date-time
          description: Data/hora do último login.
        login_count:
          type: integer
          description: Quantidade total de logins realizados.
        show_getting_started:
          type: boolean
          description: Indica se o painel "Primeiros passos" deve ser exibido ao usuário.
        email_signature:
          type:
            - string
            - "null"
          description: Assinatura de e-mail configurada pelo usuário.
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados internos do sistema.
        custom_metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados livres definidos pelo cliente.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        roles:
          type: array
          items:
            $ref: "#/components/schemas/DashboardUserRoleSummary"
          description: Papéis atribuídos ao usuário, expandidos como `{ id, name, slug }`.
      required:
        - id
        - organization_id
        - person_id
        - external_id
        - email
        - name
        - picture
        - status
        - permissions
        - last_login_at
        - login_count
        - show_getting_started
        - email_signature
        - metadata
        - custom_metadata
        - created_at
        - updated_at
    DashboardUserListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/DashboardUserV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    DashboardUserResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/DashboardUserV1"
      required:
        - data
    DashboardUserCreateRequest:
      type: object
      properties:
        email:
          type: string
          format: email
          description: E-mail do usuário a ser convidado.
        name:
          type: string
          description: Nome do usuário (opcional — pode ser preenchido pelo usuário no primeiro acesso).
        external_id:
          type: string
          description: Identificador externo do usuário no Kobana OAuth, quando já conhecido.
        role_ids:
          type: array
          items:
            type: string
            format: uuid
          minItems: 1
          description: Lista de UUIDs de papéis (`team_roles`) a atribuir ao usuário. Deve conter ao menos um item.
        permissions:
          type: array
          items:
            type: string
          description: Permissões ad-hoc adicionais (além das herdadas pelos papéis). Aceita os mesmos slugs de permissão.
      required:
        - email
        - role_ids
    DashboardUserUpdateRequest:
      type: object
      properties:
        name:
          type: string
          description: Novo nome de exibição.
        picture:
          type: string
          description: URL da foto do usuário.
        status:
          type: string
          enum:
            - active
            - pending_invitation
            - suspended
          description: "Novo status: `active`, `pending_invitation` ou `suspended`."
        permissions:
          type: array
          items:
            type: string
          description: Lista completa de permissões ad-hoc (substitui as anteriores).
        role_ids:
          type: array
          items:
            type: string
            format: uuid
          description: Lista completa de UUIDs de papéis (substitui as atribuições atuais).
    TeamRoleV1:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type: string
          format: uuid
          description: UUID da organização à qual o papel pertence.
        name:
          type: string
          description: Nome do papel.
        slug:
          type: string
          description: Slug estável do papel.
        description:
          type:
            - string
            - "null"
          description: Descrição do papel.
        permissions:
          type: array
          items:
            type: string
          description: Slugs de permissão concedidas pelo papel.
        is_system:
          type: boolean
          description: Indica se o papel é gerenciado pelo sistema (não editável/removível).
        is_active:
          type: boolean
          description: Indica se o papel está ativo e disponível para atribuição.
        display_order:
          type: integer
          description: Ordem de exibição do papel nas interfaces.
        metadata:
          type:
            - object
            - "null"
          additionalProperties: {}
          description: Metadados internos do papel.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        users_count:
          type: integer
          description: Quantidade de usuários atualmente vinculados ao papel.
      required:
        - id
        - organization_id
        - name
        - slug
        - description
        - permissions
        - is_system
        - is_active
        - display_order
        - metadata
        - created_at
        - updated_at
    TeamRoleListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/TeamRoleV1"
        meta:
          $ref: "#/components/schemas/PaginationMeta"
      required:
        - data
        - meta
    TeamRoleResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/TeamRoleV1"
      required:
        - data
    TeamRoleCreateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          description: Nome do papel (exibido na interface).
        slug:
          type: string
          pattern: ^[a-z][a-z0-9_]*$
          description: "Slug estável usado para referenciar o papel (ex.: `billing_manager`)."
          example: billing_manager
        description:
          type: string
          description: Descrição opcional do que o papel concede.
        permissions:
          type: array
          items:
            type: string
          description: Lista de slugs de permissão concedidas pelo papel.
        is_active:
          type: boolean
          description: Indica se o papel está ativo e pode ser atribuído.
      required:
        - name
        - slug
        - permissions
    TeamRoleUpdateRequest:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          description: Novo nome do papel.
        slug:
          type: string
          pattern: ^[a-z][a-z0-9_]*$
          description: Novo slug do papel (mesmas regras da criação).
        description:
          type: string
          description: Nova descrição.
        permissions:
          type: array
          items:
            type: string
          description: Lista completa de permissões (substitui as anteriores).
        is_active:
          type: boolean
          description: Ativa ou desativa o papel.
    ProposalItemCreateRequest:
      type: object
      properties:
        product_id:
          type: string
          format: uuid
          description: UUID do produto. **Obrigatório**.
        price_id:
          type: string
          format: uuid
          description: UUID do preço. **Obrigatório**.
        quantity:
          type: number
          minimum: 1
          description: "Quantidade. Padrão: 1."
        unit_amount_subcents:
          type: number
          minimum: 0
          description: Valor unitário em subcentavos (÷10000 → BRL).
        metadata:
          type: object
          additionalProperties: {}
          description: Metadados arbitrários do item.
        custom_metadata:
          type: object
          additionalProperties: {}
          description: Campos personalizados do item.
      required:
        - product_id
        - price_id
        - unit_amount_subcents
  parameters: {}
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: "Envie o cabeçalho `Authorization: Bearer <jwt>`. Formato do token: HS512."
paths:
  /v1/subscriptions:
    get:
      tags:
        - Assinaturas
      summary: Listar assinaturas
      description: Retorna uma lista paginada das assinaturas da organização atual.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - draft
              - trialing
              - active
              - past_due
              - canceled
              - paused
            description: Filtra por status da assinatura.
          required: false
          name: status
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por plano.
          required: false
          name: plan_id
          in: query
        - schema:
            type: string
            enum:
              - monthly
              - quarterly
              - semiannual
              - annual
            description: Filtra por periodicidade de cobrança.
          required: false
          name: billing_cycle
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por conta de cobrança.
          required: false
          name: billing_account_id
          in: query
        - schema:
            type: string
            description: Busca textual livre.
          required: false
          name: search
          in: query
        - schema:
            type: string
            format: date-time
            description: Data inicial (ISO 8601).
          required: false
          name: date_from
          in: query
        - schema:
            type: string
            format: date-time
            description: Data final (ISO 8601).
          required: false
          name: date_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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de assinaturas.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubscriptionListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-subscriptions
    post:
      tags:
        - Assinaturas
      summary: Criar assinatura
      description: Cria uma assinatura. É obrigatório enviar `plan_id` ou `items`.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SubscriptionCreateRequest"
      responses:
        "201":
          description: Assinatura criada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubscriptionResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-subscriptions
      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.
          schema:
            type: string
            format: uuid
  /v1/subscriptions/{id}:
    get:
      tags:
        - Assinaturas
      summary: Obter assinatura
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da assinatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe da assinatura.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubscriptionResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-subscriptions-id
    patch:
      tags:
        - Assinaturas
      summary: Atualizar assinatura
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da assinatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SubscriptionUpdateRequest"
      responses:
        "200":
          description: Assinatura atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubscriptionResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-subscriptions-id
    delete:
      tags:
        - Assinaturas
      summary: Cancelar e remover assinatura (soft delete)
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da assinatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Confirmação de soft delete.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-subscriptions-id
  /v1/subscriptions/{id}/pause:
    post:
      tags:
        - Assinaturas
      summary: Pausar assinatura
      description: Suspende a cobrança mantendo a assinatura aberta. `behavior` controla como faturas geradas durante a pausa são tratadas.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da assinatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SubscriptionPauseRequest"
      responses:
        "200":
          description: Assinatura pausada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubscriptionResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-subscriptions-id-pause
  /v1/subscriptions/{id}/resume:
    post:
      tags:
        - Assinaturas
      summary: Retomar assinatura pausada
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da assinatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Assinatura retomada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubscriptionResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-subscriptions-id-resume
  /v1/subscriptions/{id}/cancel:
    post:
      tags:
        - Assinaturas
      summary: Cancelar assinatura
      description: Cancela imediatamente, ou agenda para o fim do período quando `cancel_at_period_end=true`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da assinatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SubscriptionCancelRequest"
      responses:
        "200":
          description: Assinatura cancelada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubscriptionResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-subscriptions-id-cancel
  /v1/subscriptions/{id}/activate:
    post:
      tags:
        - Assinaturas
      summary: Ativar assinatura em rascunho/confirmada
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da assinatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Assinatura ativada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubscriptionResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-subscriptions-id-activate
  /v1/subscriptions/{id}/change-plan:
    post:
      tags:
        - Assinaturas
      summary: Trocar o plano da assinatura
      description: Upgrade ou downgrade. A proração segue o `proration_behavior` da assinatura.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da assinatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SubscriptionChangePlanRequest"
      responses:
        "200":
          description: Assinatura atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubscriptionResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-subscriptions-id-change-plan
  /v1/subscriptions/{id}/revert-to-confirmed:
    post:
      tags:
        - Assinaturas
      summary: Reverter assinatura para o estado confirmado
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da assinatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Assinatura revertida.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubscriptionResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-subscriptions-id-revert-to-confirmed
  /v1/subscriptions/{id}/create-invoice:
    post:
      tags:
        - Assinaturas
      summary: Gerar uma fatura avulsa para a assinatura
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da assinatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "201":
          description: Fatura gerada.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data: {}
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-subscriptions-id-create-invoice
  /v1/subscriptions/{id}/items:
    get:
      tags:
        - Assinaturas
      summary: Listar itens da assinatura
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da assinatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista de itens.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items: {}
                required:
                  - data
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-subscriptions-id-items
  /v1/subscriptions/{id}/sync-plan-items:
    post:
      tags:
        - Assinaturas
      summary: Ressincronizar itens com o plano atual
      description: Realinha os itens da assinatura com o template de plan-items (reconciliação manual).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da assinatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Assinatura sincronizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubscriptionResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-subscriptions-id-sync-plan-items
  /v1/billing_accounts:
    get:
      tags:
        - Contas de Cobrança
      summary: Listar contas de cobrança
      description: Retorna uma lista paginada das contas de cobrança da organização atual.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - active
              - suspended
              - closed
            description: Filtra por status da conta de cobrança.
          required: false
          name: status
          in: query
        - schema:
            type: string
            description: Busca textual livre.
          required: false
          name: search
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de contas de cobrança.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingAccountListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-billing-accounts
    post:
      tags:
        - Contas de Cobrança
      summary: Criar conta de cobrança
      description: Cria uma conta de cobrança associada a um customer. O bloco `customer` localiza um customer existente por `id`, `external_id` ou `document_number`; quando não encontrado, cria um novo (exige `name` e `document_number`).
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/BillingAccountCreateRequest"
      responses:
        "201":
          description: Conta de cobrança criada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingAccountResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-billing-accounts
      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.
          schema:
            type: string
            format: uuid
  /v1/billing_accounts/{id}:
    get:
      tags:
        - Contas de Cobrança
      summary: Obter conta de cobrança
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da conta de cobrança.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe da conta de cobrança.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingAccountResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-billing-accounts-id
    patch:
      tags:
        - Contas de Cobrança
      summary: Atualizar conta de cobrança
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da conta de cobrança.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/BillingAccountUpdateRequest"
      responses:
        "200":
          description: Conta de cobrança atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingAccountResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-billing-accounts-id
    delete:
      tags:
        - Contas de Cobrança
      summary: Fechar conta de cobrança
      description: Encerra a conta de cobrança (equivalente a `POST /billing_accounts/{id}/close`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da conta de cobrança.
          required: true
          name: id
          in: path
        - schema:
            type: string
            description: Motivo do fechamento (registrado no audit log).
          required: false
          name: reason
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Conta de cobrança fechada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingAccountResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-billing-accounts-id
  /v1/billing_accounts/{id}/close:
    post:
      tags:
        - Contas de Cobrança
      summary: Fechar conta de cobrança (POST /close)
      description: Encerra a conta de cobrança. O motivo (`reason`) é registrado no audit log.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da conta de cobrança.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/BillingAccountReasonRequest"
      responses:
        "200":
          description: Conta de cobrança fechada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingAccountResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-billing-accounts-id-close
  /v1/billing_accounts/{id}/suspend:
    post:
      tags:
        - Contas de Cobrança
      summary: Suspender conta de cobrança
      description: Suspende a conta. O motivo (`reason`) é registrado no audit log.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da conta de cobrança.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/BillingAccountReasonRequest"
      responses:
        "200":
          description: Conta de cobrança suspensa.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingAccountResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-billing-accounts-id-suspend
  /v1/billing_accounts/{id}/reactivate:
    post:
      tags:
        - Contas de Cobrança
      summary: Reativar conta de cobrança
      description: Reativa uma conta de cobrança suspensa.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da conta de cobrança.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Conta de cobrança reativada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BillingAccountResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-billing-accounts-id-reactivate
  /v1/billing_accounts/{id}/invoices:
    get:
      tags:
        - Contas de Cobrança
      summary: Listar faturas da conta
      description: Retorna uma lista paginada das faturas da conta de cobrança.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da conta de cobrança.
          required: true
          name: id
          in: path
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de faturas.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items: {}
                required:
                  - data
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-billing-accounts-id-invoices
  /v1/billing_accounts/{id}/subscriptions:
    get:
      tags:
        - Contas de Cobrança
      summary: Listar assinaturas da conta
      description: Retorna uma lista paginada das assinaturas da conta de cobrança.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da conta de cobrança.
          required: true
          name: id
          in: path
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de assinaturas.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items: {}
                required:
                  - data
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-billing-accounts-id-subscriptions
  /v1/billing_accounts/{id}/credits:
    get:
      tags:
        - Contas de Cobrança
      summary: Listar créditos da conta
      description: Retorna uma lista paginada dos créditos da conta de cobrança.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da conta de cobrança.
          required: true
          name: id
          in: path
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - "true"
              - "false"
            description: Inclui créditos expirados quando `true`.
          required: false
          name: include_expired
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de créditos.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items: {}
                required:
                  - data
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-billing-accounts-id-credits
  /v1/customers:
    get:
      tags:
        - Clientes
      summary: Listar clientes
      description: Retorna uma lista paginada dos clientes da organização atual.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            description: Busca textual livre por nome, documento ou e-mail.
          required: false
          name: search
          in: query
        - schema:
            type: string
            enum:
              - natural
              - juridical
            description: "Filtra por tipo de pessoa: `natural` (PF) ou `juridical` (PJ)."
          required: false
          name: kind
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de clientes.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomerListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-customers
    post:
      tags:
        - Clientes
      summary: Criar cliente
      description: Cria um cliente e, por padrão, uma conta de cobrança associada. Use `create_billing_account=false` para criar apenas o cliente.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CustomerCreateRequest"
      responses:
        "201":
          description: Cliente criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomerCreateResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-customers
      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.
          schema:
            type: string
            format: uuid
  /v1/customers/{id}:
    get:
      tags:
        - Clientes
      summary: Obter cliente
      description: O parâmetro `{id}` aceita o UUID do cliente ou o `external_id`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            description: UUID do cliente ou `external_id`.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do cliente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomerResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-customers-id
    patch:
      tags:
        - Clientes
      summary: Atualizar cliente
      description: O parâmetro `{id}` aceita o UUID do cliente ou o `external_id`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            description: UUID do cliente ou `external_id`.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CustomerUpdateRequest"
      responses:
        "200":
          description: Cliente atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomerResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-customers-id
    delete:
      tags:
        - Clientes
      summary: Remover cliente (soft delete)
      description: Marca o cliente como removido sem apagar registros históricos.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            description: UUID do cliente ou `external_id`.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Confirmação de soft delete.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-customers-id
  /v1/customers/{id}/statement:
    get:
      tags:
        - Clientes
      summary: Listar extrato financeiro do cliente
      description: Retorna os lançamentos do extrato (faturas, pagamentos, aplicações de crédito) da conta de cobrança do cliente. Quando o cliente possui múltiplas contas, informe `billing_account_id`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            description: UUID do cliente ou `external_id`.
          required: true
          name: id
          in: path
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            format: uuid
            description: Necessário quando o cliente possui múltiplas contas de cobrança.
          required: false
          name: billing_account_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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de itens do extrato.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomerStatementListResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-customers-id-statement
  /v1/customers/{id}/statement/sync:
    post:
      tags:
        - Clientes
      summary: Reconstruir o extrato a partir do histórico
      description: Recria os itens do extrato a partir das faturas, pagamentos e aplicações de crédito existentes. Retorna o resumo do que foi criado.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            description: UUID do cliente ou `external_id`.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CustomerStatementSyncRequest"
      responses:
        "200":
          description: Extrato reconstruído.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomerStatementSyncResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-customers-id-statement-sync
  /v1/customers/{id}/recalculate-mrr:
    post:
      tags:
        - Clientes
      summary: Recalcular o MRR do cliente
      description: Recalcula o MRR (Monthly Recurring Revenue) das contas de cobrança do cliente a partir das assinaturas ativas.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            description: UUID do cliente ou `external_id`.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: MRR recalculado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomerRecalculateMrrResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-customers-id-recalculate-mrr
  /v1/customers/{id}/users:
    get:
      tags:
        - Clientes
      summary: Listar usuários do portal do cliente
      description: Retorna usuários com acesso ao portal vinculados à conta de cobrança do cliente.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            description: UUID do cliente ou `external_id`.
          required: true
          name: id
          in: path
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - active
              - pending_verification
              - pending_invitation
              - suspended
              - locked
            description: Filtra usuários do portal por status.
          required: false
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de usuários do portal.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomerPortalUserListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-customers-id-users
    post:
      tags:
        - Clientes
      summary: Convidar usuário do portal
      description: Cria um convite de acesso ao portal para o e-mail informado. O convite expira em 7 dias.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            description: UUID do cliente ou `external_id`.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CustomerPortalUserInviteRequest"
      responses:
        "201":
          description: Convite criado e e-mail enfileirado para envio.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomerPortalUserResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "409":
          description: Já existe um usuário ou convite para este e-mail.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-customers-id-users
  /v1/customers/{id}/users/invite:
    post:
      tags:
        - Clientes
      summary: Convidar usuário do portal (verbo)
      description: Equivalente ao `POST /customers/{id}/users`. Disponível como rota de verbo para SDKs que preferem URLs descritivas.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            description: UUID do cliente ou `external_id`.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CustomerPortalUserInviteRequest"
      responses:
        "201":
          description: Convite criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomerPortalUserResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-customers-id-users-invite
  /v1/customers/{id}/users/{user_id}:
    get:
      tags:
        - Clientes
      summary: Obter usuário do portal
      description: O parâmetro `{user_id}` aceita o UUID ou o `external_id` do usuário.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            description: UUID do cliente ou `external_id`.
          required: true
          name: id
          in: path
        - schema:
            type: string
            description: UUID do usuário do portal ou seu `external_id`.
          required: true
          name: user_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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do usuário do portal.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomerPortalUserResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-customers-id-users-user-id
    patch:
      tags:
        - Clientes
      summary: Atualizar usuário do portal
      description: "Atualiza `email`, `external_id`, `sso_only` e `status`. Transições de status permitidas: `active` ↔ `suspended`."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            description: UUID do cliente ou `external_id`.
          required: true
          name: id
          in: path
        - schema:
            type: string
            description: UUID do usuário do portal ou seu `external_id`.
          required: true
          name: user_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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CustomerPortalUserUpdateRequest"
      responses:
        "200":
          description: Usuário atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomerPortalUserResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-customers-id-users-user-id
    delete:
      tags:
        - Clientes
      summary: Remover usuário do portal
      description: Convites pendentes são removidos definitivamente; usuários ativos são suspensos.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            description: UUID do cliente ou `external_id`.
          required: true
          name: id
          in: path
        - schema:
            type: string
            description: UUID do usuário do portal ou seu `external_id`.
          required: true
          name: user_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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Confirmação de remoção.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-customers-id-users-user-id
  /v1/customers/{id}/users/{user_id}/email-preview:
    get:
      tags:
        - Clientes
      summary: Pré-visualizar e-mail do usuário do portal
      description: Retorna o assunto e mensagem do e-mail de convite ou verificação que seria enviado ao usuário, sem disparar o envio. Disponível apenas para usuários `pending_invitation` ou `pending_verification`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            description: UUID do cliente ou `external_id`.
          required: true
          name: id
          in: path
        - schema:
            type: string
            description: UUID do usuário do portal ou seu `external_id`.
          required: true
          name: user_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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Pré-visualização do e-mail.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomerPortalUserEmailPreviewResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-customers-id-users-user-id-email-preview
  /v1/customers/{id}/users/{user_id}/resend:
    post:
      tags:
        - Clientes
      summary: Reenviar e-mail de convite ou verificação
      description: Reenvia o e-mail de convite (para `pending_invitation`, com rotação de token) ou de verificação (para `pending_verification`). Demais status retornam 400.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            description: UUID do cliente ou `external_id`.
          required: true
          name: id
          in: path
        - schema:
            type: string
            description: UUID do usuário do portal ou seu `external_id`.
          required: true
          name: user_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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: E-mail reenviado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomerPortalUserResendResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-customers-id-users-user-id-resend
  /v1/plans:
    get:
      tags:
        - Planos
      summary: Listar planos
      description: Retorna uma lista paginada dos planos da organização atual.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - draft
              - active
              - archived
            description: Filtra por status do plano.
          required: false
          name: status
          in: query
        - schema:
            type: string
            enum:
              - standard
              - custom
              - promotional
            description: Filtra por tipo do plano.
          required: false
          name: plan_type
          in: query
        - schema:
            type: string
            enum:
              - public
              - private
            description: Filtra por visibilidade.
          required: false
          name: visibility
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por grupo de planos.
          required: false
          name: plan_group_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por empresa emissora.
          required: false
          name: company_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra planos custom associados a uma conta de cobrança.
          required: false
          name: billing_account_id
          in: query
        - schema:
            type: string
            description: Busca textual livre.
          required: false
          name: search
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de planos.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-plans
    post:
      tags:
        - Planos
      summary: Criar plano
      description: Cria um plano para a organização autenticada.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlanCreateRequest"
      responses:
        "201":
          description: Plano criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-plans
      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.
          schema:
            type: string
            format: uuid
  /v1/plans/{id}:
    get:
      tags:
        - Planos
      summary: Obter plano
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do plano.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do plano.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-plans-id
    patch:
      tags:
        - Planos
      summary: Atualizar plano
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do plano.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlanUpdateRequest"
      responses:
        "200":
          description: Plano atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-plans-id
    delete:
      tags:
        - Planos
      summary: Arquivar ou excluir plano
      description: Por padrão arquiva o plano (soft delete). Use `?hard=true` para excluir permanentemente um plano em rascunho.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do plano.
          required: true
          name: id
          in: path
        - schema:
            type:
              - boolean
              - "null"
            description: Quando `true`, exclui o plano permanentemente (apenas rascunhos).
          required: false
          name: hard
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Confirmação de arquivamento ou exclusão.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-plans-id
  /v1/plans/{id}/duplicate:
    post:
      tags:
        - Planos
      summary: Duplicar plano
      description: Cria uma cópia do plano (incluindo seus itens) no estado de rascunho.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do plano.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "201":
          description: Plano duplicado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-plans-id-duplicate
  /v1/plans/{id}/items:
    get:
      tags:
        - Planos
      summary: Listar itens do plano
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do plano.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista de itens do plano.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanItemListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-plans-id-items
    put:
      tags:
        - Planos
      summary: Substituir itens do plano
      description: Substitui de forma atômica todos os itens do plano. Apenas produtos raiz são aceitos e cada `product_id` deve ser único na lista.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do plano.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlanItemsReplaceRequest"
      responses:
        "200":
          description: Itens do plano substituídos.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanItemsReplaceResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: put-plans-id-items
  /v1/plans/bulk-archive:
    post:
      tags:
        - Planos
      summary: Arquivar planos em lote
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlanBulkIdsRequest"
      responses:
        "200":
          description: Resumo do arquivamento em lote.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanBulkArchiveResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-plans-bulk-archive
      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.
          schema:
            type: string
            format: uuid
  /v1/plans/bulk-delete:
    post:
      tags:
        - Planos
      summary: Excluir planos em lote
      description: Exclui permanentemente os planos informados. Planos com assinaturas ativas são pulados e retornados em `skipped_ids`.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlanBulkIdsRequest"
      responses:
        "200":
          description: Resumo da exclusão em lote.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanBulkDeleteResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-plans-bulk-delete
      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.
          schema:
            type: string
            format: uuid
  /v1/plans/bulk-move-group:
    post:
      tags:
        - Planos
      summary: Mover planos para outro grupo em lote
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlanBulkMoveGroupRequest"
      responses:
        "200":
          description: Resumo da movimentação em lote.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanBulkMoveGroupResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-plans-bulk-move-group
      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.
          schema:
            type: string
            format: uuid
  /v1/plan_groups:
    get:
      tags:
        - Grupos de Plano
      summary: Listar grupos de planos
      description: Retorna todos os grupos de planos da organização atual ordenados por `display_order`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            description: Busca textual livre pelo nome ou slug.
          required: false
          name: search
          in: query
        - schema:
            type: string
            enum:
              - "true"
              - "false"
            description: Quando `true`, inclui grupos arquivados na lista.
          required: false
          name: include_archived
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista de grupos de planos.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanGroupListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-plan-groups
    post:
      tags:
        - Grupos de Plano
      summary: Criar grupo de planos
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlanGroupCreateRequest"
      responses:
        "201":
          description: Grupo de planos criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanGroupResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-plan-groups
      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.
          schema:
            type: string
            format: uuid
  /v1/plan_groups/{id}:
    get:
      tags:
        - Grupos de Plano
      summary: Obter grupo de planos
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do grupo de planos.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do grupo de planos.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanGroupResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-plan-groups-id
    patch:
      tags:
        - Grupos de Plano
      summary: Atualizar grupo de planos
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do grupo de planos.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlanGroupUpdateRequest"
      responses:
        "200":
          description: Grupo de planos atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanGroupResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-plan-groups-id
    delete:
      tags:
        - Grupos de Plano
      summary: Remover grupo de planos
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do grupo de planos.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Confirmação de remoção.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-plan-groups-id
  /v1/plan_groups/reorder:
    post:
      tags:
        - Grupos de Plano
      summary: Reordenar grupos de planos
      description: Atualiza o `display_order` dos grupos conforme a ordem do array `group_ids`. Todos os grupos devem pertencer à organização atual.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlanGroupReorderRequest"
      responses:
        "200":
          description: Ordem atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanGroupReorderResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-plan-groups-reorder
      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.
          schema:
            type: string
            format: uuid
  /v1/plan_groups/{id}/archive:
    post:
      tags:
        - Grupos de Plano
      summary: Arquivar grupo de planos
      description: Marca o grupo como arquivado preenchendo `archived_at`. Grupos arquivados ficam ocultos das listagens padrão.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do grupo de planos.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Grupo de planos arquivado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanGroupResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-plan-groups-id-archive
  /v1/products:
    get:
      tags:
        - Produtos
      summary: Listar produtos
      description: Retorna uma lista paginada dos produtos da organização atual.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - all
              - draft
              - active
              - archived
            description: Filtra por status do produto.
          required: false
          name: status
          in: query
        - schema:
            type: string
            enum:
              - public
              - private
            description: Filtra por visibilidade.
          required: false
          name: visibility
          in: query
        - schema:
            type: string
            enum:
              - base
              - addon_quantity
              - addon_fixed
              - metered
              - one_time_fixed
              - one_time_quantity
            description: Filtra por tipo de produto.
          required: false
          name: productType
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por grupo de produto.
          required: false
          name: productGroupId
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por empresa.
          required: false
          name: companyId
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por produto pai.
          required: false
          name: parentProductId
          in: query
        - schema:
            type:
              - boolean
              - "null"
            description: Quando `true`, retorna apenas produtos raiz (sem pai).
          required: false
          name: rootOnly
          in: query
        - schema:
            type: string
            description: Busca textual livre (nome, slug).
          required: false
          name: search
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de produtos.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-products
    post:
      tags:
        - Produtos
      summary: Criar produto
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductCreateRequest"
      responses:
        "201":
          description: Produto criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-products
      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.
          schema:
            type: string
            format: uuid
  /v1/products/{id}:
    get:
      tags:
        - Produtos
      summary: Obter produto
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do produto.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do produto.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-products-id
    patch:
      tags:
        - Produtos
      summary: Atualizar produto
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do produto.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductUpdateRequest"
      responses:
        "200":
          description: Produto atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-products-id
    delete:
      tags:
        - Produtos
      summary: Arquivar produto (soft delete)
      description: Arquiva o produto. Retorna 422 quando o produto está em uso por assinaturas ativas.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do produto.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Confirmação de soft delete.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-products-id
  /v1/products/{id}/archive:
    post:
      tags:
        - Produtos
      summary: Arquivar produto
      description: Arquiva o produto. Retorna 422 quando o produto está em uso por assinaturas ativas ou já está arquivado.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do produto.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Produto arquivado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-products-id-archive
  /v1/products/{id}/publish:
    post:
      tags:
        - Produtos
      summary: Publicar produto
      description: Promove um produto em rascunho para o status ativo.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do produto.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Produto publicado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-products-id-publish
  /v1/products/{id}/restore:
    post:
      tags:
        - Produtos
      summary: Restaurar produto arquivado
      description: Restaura um produto arquivado de volta para o status ativo.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do produto.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Produto restaurado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-products-id-restore
  /v1/products/reorder:
    post:
      tags:
        - Produtos
      summary: Reordenar produtos
      description: Atualiza a ordem de exibição dos produtos. O índice 0 do array vira o primeiro item da lista.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductReorderRequest"
      responses:
        "200":
          description: Ordem atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductBulkResultResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-products-reorder
      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.
          schema:
            type: string
            format: uuid
    put:
      tags:
        - Produtos
      summary: Reordenar produtos (PUT /reorder)
      description: Alias `PUT` para `/products/reorder`. Mesmo comportamento da versão `POST`.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductReorderRequest"
      responses:
        "200":
          description: Ordem atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductBulkResultResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: put-products-reorder
      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.
          schema:
            type: string
            format: uuid
  /v1/products/bulk-archive:
    post:
      tags:
        - Produtos
      summary: Arquivar produtos em lote
      description: Arquiva múltiplos produtos. IDs em uso por assinaturas ativas ou já arquivados são ignorados e reportados na resposta.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductBulkArchiveRequest"
      responses:
        "200":
          description: Resultado da operação em lote.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductBulkResultResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-products-bulk-archive
      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.
          schema:
            type: string
            format: uuid
  /v1/products/bulk-delete:
    post:
      tags:
        - Produtos
      summary: Excluir produtos em lote
      description: Exclui permanentemente múltiplos produtos. IDs em uso por assinaturas ativas são ignorados e reportados na resposta.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductBulkDeleteRequest"
      responses:
        "200":
          description: Resultado da operação em lote.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductBulkResultResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-products-bulk-delete
      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.
          schema:
            type: string
            format: uuid
  /v1/products/bulk-visibility:
    post:
      tags:
        - Produtos
      summary: Alterar visibilidade em lote
      description: Atualiza a visibilidade (`public` ou `private`) de múltiplos produtos.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductBulkVisibilityRequest"
      responses:
        "200":
          description: Resultado da operação em lote.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductBulkResultResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-products-bulk-visibility
      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.
          schema:
            type: string
            format: uuid
  /v1/products/bulk-move-group:
    post:
      tags:
        - Produtos
      summary: Mover produtos para outro grupo
      description: "Move múltiplos produtos para um grupo de produto. Envie `product_group_id: null` para remover do grupo atual."
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductBulkMoveGroupRequest"
      responses:
        "200":
          description: Resultado da operação em lote.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductBulkResultResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-products-bulk-move-group
      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.
          schema:
            type: string
            format: uuid
  /v1/products/bulk-change-company:
    post:
      tags:
        - Produtos
      summary: Trocar empresa de produtos em lote
      description: "Reatribui múltiplos produtos a outra empresa. Envie `company_id: null` para limpar o vínculo."
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductBulkChangeCompanyRequest"
      responses:
        "200":
          description: Resultado da operação em lote.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductBulkResultResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-products-bulk-change-company
      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.
          schema:
            type: string
            format: uuid
  /v1/product_groups:
    get:
      tags:
        - Grupos de Produto
      summary: Listar grupos de produto
      description: Retorna uma lista paginada dos grupos de produto da organização atual.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            description: Busca textual livre pelo nome do grupo.
          required: false
          name: search
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por empresa emissora associada.
          required: false
          name: company_id
          in: query
        - schema:
            type:
              - boolean
              - "null"
            description: "Quando `true`, inclui grupos arquivados na listagem. Padrão: `false`."
          required: false
          name: include_archived
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de grupos de produto.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductGroupListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-product-groups
    post:
      tags:
        - Grupos de Produto
      summary: Criar grupo de produto
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductGroupCreateRequest"
      responses:
        "201":
          description: Grupo de produto criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductGroupResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-product-groups
      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.
          schema:
            type: string
            format: uuid
  /v1/product_groups/{id}:
    get:
      tags:
        - Grupos de Produto
      summary: Obter grupo de produto
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do grupo de produto.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do grupo de produto.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductGroupResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-product-groups-id
    patch:
      tags:
        - Grupos de Produto
      summary: Atualizar grupo de produto
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do grupo de produto.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductGroupUpdateRequest"
      responses:
        "200":
          description: Grupo de produto atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductGroupResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-product-groups-id
    delete:
      tags:
        - Grupos de Produto
      summary: Remover grupo de produto
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do grupo de produto.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Confirmação de remoção.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductGroupDeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-product-groups-id
  /v1/product_groups/{id}/archive:
    post:
      tags:
        - Grupos de Produto
      summary: Arquivar grupo de produto
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do grupo de produto.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Grupo de produto arquivado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductGroupResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-product-groups-id-archive
    delete:
      tags:
        - Grupos de Produto
      summary: Desarquivar grupo de produto
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do grupo de produto.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Grupo de produto desarquivado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductGroupResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-product-groups-id-archive
  /v1/product_groups/reorder:
    post:
      tags:
        - Grupos de Produto
      summary: Reordenar grupos de produto
      description: Atualiza a ordem de exibição dos grupos de produto. O array `group_ids` define a nova ordem — índice 0 vira o primeiro grupo.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductGroupReorderRequest"
      responses:
        "200":
          description: Ordem atualizada com sucesso.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductGroupReorderResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-product-groups-reorder
      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.
          schema:
            type: string
            format: uuid
    put:
      tags:
        - Grupos de Produto
      summary: Reordenar grupos de produto (alias PUT)
      description: Alias `PUT` para `POST /product_groups/reorder`. Mesmo contrato.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProductGroupReorderRequest"
      responses:
        "200":
          description: Ordem atualizada com sucesso.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProductGroupReorderResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: put-product-groups-reorder
      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.
          schema:
            type: string
            format: uuid
  /v1/organization:
    get:
      tags:
        - Organização
      summary: Obter organização atual
      description: Retorna os dados da organização à qual o token autenticado pertence. Não há parâmetro `:id` — a organização é sempre resolvida a partir da chave da API.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Detalhe da organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OrganizationResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-organization
      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.
          schema:
            type: string
            format: uuid
    patch:
      tags:
        - Organização
      summary: Atualizar organização atual
      description: Atualiza o perfil cadastral da organização autenticada. Apenas os campos abaixo podem ser modificados — identidade (`id`, `external_id`, `status`) não é alterável por este endpoint.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/OrganizationUpdateRequest"
      responses:
        "200":
          description: Organização atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OrganizationResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-organization
      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.
          schema:
            type: string
            format: uuid
  /v1/companies:
    get:
      tags:
        - Empresas
      summary: Listar empresas
      description: Retorna uma lista paginada das empresas (matrizes e filiais) da organização atual.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - active
              - inactive
            description: "Filtra por status: `active` ou `inactive`."
          required: false
          name: status
          in: query
        - schema:
            type: string
            description: Busca textual por nome, razão social, e-mail ou documento.
          required: false
          name: search
          in: query
        - schema:
            type: string
            enum:
              - "true"
              - "false"
            description: Filtra apenas a empresa marcada como padrão da organização.
          required: false
          name: is_default
          in: query
        - schema:
            type: string
            description: Filtra filiais por matriz. Use o UUID da matriz para listar suas filiais.
          required: false
          name: parent_company_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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de empresas.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-companies
    post:
      tags:
        - Empresas
      summary: Criar empresa
      description: Cria uma empresa (matriz ou filial). Para criar uma filial, informe `parent_company_id` — o CNPJ deve compartilhar o mesmo prefixo da matriz. Apenas empresas com CNPJ podem ter filiais. A primeira empresa criada na organização é marcada como `is_default` automaticamente.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CompanyCreateRequest"
      responses:
        "201":
          description: Empresa criada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-companies
      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.
          schema:
            type: string
            format: uuid
  /v1/companies/matriz:
    get:
      tags:
        - Empresas
      summary: Listar matrizes
      description: Lista as empresas matrizes (sem `parent_company_id`) ativas da organização. Útil para selecionar a matriz ao criar uma filial. Apenas empresas com CNPJ aparecem aqui.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Lista de empresas matrizes.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyMatrizListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-companies-matriz
      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.
          schema:
            type: string
            format: uuid
  /v1/companies/{id}:
    get:
      tags:
        - Empresas
      summary: Obter empresa
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da empresa.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe da empresa.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-companies-id
    patch:
      tags:
        - Empresas
      summary: Atualizar empresa
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da empresa.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CompanyUpdateRequest"
      responses:
        "200":
          description: Empresa atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-companies-id
    delete:
      tags:
        - Empresas
      summary: Desativar empresa
      description: Desativa a empresa (soft delete — equivalente a `POST /companies/{id}/deactivate`). Não é possível desativar a única empresa ativa nem uma empresa com assinaturas ativas ou em período de teste.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da empresa.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Empresa desativada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyDeleteResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-companies-id
  /v1/companies/{id}/set-default:
    post:
      tags:
        - Empresas
      summary: Definir empresa padrão
      description: Marca a empresa como padrão da organização. A empresa padrão anterior é desmarcada na mesma transação.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da empresa.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Empresa definida como padrão.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-companies-id-set-default
  /v1/companies/{id}/deactivate:
    post:
      tags:
        - Empresas
      summary: Desativar empresa (POST /deactivate)
      description: Desativa a empresa. Não é possível desativar a única empresa ativa, nem uma empresa com assinaturas ativas ou em período de teste. Se a empresa desativada era a padrão, outra empresa ativa é promovida automaticamente.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da empresa.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Empresa desativada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-companies-id-deactivate
  /v1/companies/{id}/reactivate:
    post:
      tags:
        - Empresas
      summary: Reativar empresa
      description: Reativa uma empresa previamente desativada. Retorna **422** quando a empresa já está ativa.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da empresa.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Empresa reativada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-companies-id-reactivate
  /v1/companies/{id}/fiscal:
    get:
      tags:
        - Empresas
      summary: Obter perfil fiscal
      description: Retorna o perfil fiscal da empresa, ou `null` quando ainda não foi configurado.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da empresa.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Perfil fiscal da empresa (ou `null`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyFiscalProfileResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-companies-id-fiscal
    patch:
      tags:
        - Empresas
      summary: Atualizar perfil fiscal
      description: Cria ou atualiza (upsert) o perfil fiscal da empresa. Inclui regime tributário, alíquotas (ISS, PIS, COFINS, CSLL, IRPJ) e configurações de CBS/IBS.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da empresa.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CompanyFiscalProfileUpsertRequest"
      responses:
        "200":
          description: Perfil fiscal atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyFiscalProfileResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-companies-id-fiscal
  /v1/companies/{id}/fiscal-profile:
    get:
      tags:
        - Empresas
      summary: Obter perfil fiscal (alias)
      description: Alias de `GET /companies/{id}/fiscal` — mesma representação e comportamento.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da empresa.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Perfil fiscal da empresa (ou `null`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyFiscalProfileResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-companies-id-fiscal-profile
    patch:
      tags:
        - Empresas
      summary: Atualizar perfil fiscal (alias)
      description: Alias de `PATCH /companies/{id}/fiscal` — mesma representação e comportamento.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da empresa.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CompanyFiscalProfileUpsertRequest"
      responses:
        "200":
          description: Perfil fiscal atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyFiscalProfileResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-companies-id-fiscal-profile
  /v1/certificates:
    get:
      tags:
        - Certificados
      summary: Listar certificados digitais
      description: Retorna uma lista paginada dos certificados digitais (A1) da organização atual. Por segurança, a resposta **nunca** inclui a chave privada nem a senha do PFX — apenas metadados extraídos do certificado.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - active
              - expired
              - revoked
              - expiring_soon
            description: Filtra por status do certificado. `expiring_soon` retorna certificados ativos que vencem nos próximos 30 dias.
          required: false
          name: status
          in: query
        - schema:
            type: string
            description: Busca textual em `name`, `common_name`, `document` ou `organization_name`.
          required: false
          name: search
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de certificados.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CertificateListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-certificates
    post:
      tags:
        - Certificados
      summary: Enviar certificado digital
      description: |-
        Envia um certificado digital A1 via `multipart/form-data`. A chave privada e a senha são criptografadas em repouso e **nunca** retornadas pela API. O endpoint detecta duplicidade pelo `thumbprint` e associa automaticamente a um `person` pelo CNPJ/CPF extraído.

        Valores aceitos para `type`:
        - `pfx` — envia `file` (PFX/P12 binário) e `password`.
        - `cert_key` — envia `cert_file` (PEM do certificado) e `key_file` (PEM da chave).
        - `combined_pem` — envia `file` (PEM contendo certificado + chave).
        - `cert_key_password` — envia `cert_file`, `key_file` e `password` (chave protegida por senha).
      security:
        - bearerAuth: []
      requestBody:
        content:
          multipart/form-data:
            schema:
              $ref: "#/components/schemas/CertificateUploadRequest"
      responses:
        "201":
          description: Certificado enviado e armazenado com sucesso.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CertificateResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-certificates
      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.
          schema:
            type: string
            format: uuid
  /v1/certificates/{id}:
    get:
      tags:
        - Certificados
      summary: Obter certificado
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do certificado.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do certificado (sem dados sensíveis).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CertificateResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-certificates-id
    delete:
      tags:
        - Certificados
      summary: Remover certificado
      description: Remove o certificado por **soft delete**. Os dados criptografados permanecem no banco apenas para fins de auditoria.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do certificado.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Certificado removido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-certificates-id
  /v1/coupons:
    get:
      tags:
        - Cupons
      summary: Listar cupons
      description: Retorna uma lista paginada dos cupons da organização atual.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - "true"
              - "false"
            description: "Filtra por status: `true` retorna apenas cupons ativos; `false`, apenas inativos."
          required: false
          name: is_active
          in: query
        - schema:
            type: string
            description: Busca textual livre em `code` e `name`.
          required: false
          name: search
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de cupons.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CouponListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-coupons
    post:
      tags:
        - Cupons
      summary: Criar cupom
      description: Cria um cupom de desconto. O `code` deve ser único por organização. Use `discount_type=percentage` com `discount_value` entre `0` e `100`, ou `discount_type=fixed_amount` com `discount_value` em centavos (÷100 → BRL).
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CouponCreateRequest"
      responses:
        "201":
          description: Cupom criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CouponResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-coupons
      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.
          schema:
            type: string
            format: uuid
  /v1/coupons/{id}:
    get:
      tags:
        - Cupons
      summary: Obter cupom
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do cupom.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do cupom.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CouponResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-coupons-id
    patch:
      tags:
        - Cupons
      summary: Atualizar cupom
      description: Atualiza campos editáveis do cupom. `code`, `discount_type`, `discount_value` e `currency` são imutáveis depois da criação.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do cupom.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CouponUpdateRequest"
      responses:
        "200":
          description: Cupom atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CouponResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-coupons-id
    delete:
      tags:
        - Cupons
      summary: Excluir cupom
      description: Exclui o cupom permanentemente. Só é permitido enquanto o cupom **não tiver resgates registrados** — caso contrário, use `POST /coupons/{id}/deactivate` para preservar o histórico.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do cupom.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Cupom excluído.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-coupons-id
  /v1/coupons/{id}/deactivate:
    post:
      tags:
        - Cupons
      summary: Desativar cupom
      description: "Desativa o cupom: novos resgates passam a ser bloqueados, mas os resgates anteriores são preservados."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do cupom.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Cupom desativado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CouponResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-coupons-id-deactivate
  /v1/coupons/{id}/redemptions:
    get:
      tags:
        - Cupons
      summary: Listar resgates do cupom
      description: Retorna uma lista paginada dos resgates registrados para o cupom.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do cupom.
          required: true
          name: id
          in: path
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de resgates do cupom.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CouponRedemptionListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-coupons-id-redemptions
  /v1/credits:
    get:
      tags:
        - Créditos
      summary: Listar créditos
      description: Retorna uma lista paginada dos créditos da organização atual. Por padrão, créditos expirados são omitidos — use `usage` ou `include_expired` para incluí-los.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra créditos pela conta de cobrança.
          required: false
          name: billing_account_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra créditos pela `company` vinculada.
          required: false
          name: company_id
          in: query
        - schema:
            type: string
            enum:
              - promotional
              - adjustment
              - refund
              - manual
            description: "Filtra pelo tipo do crédito: `promotional`, `adjustment`, `refund` ou `manual`."
          required: false
          name: type
          in: query
        - schema:
            type: string
            enum:
              - available
              - used
              - expired
            description: Filtra pelo estado de uso — `available` (saldo remanescente e não expirado), `used` (consumido integralmente) ou `expired` (expirado).
          required: false
          name: usage
          in: query
        - schema:
            type: string
            enum:
              - "true"
              - "false"
            description: Inclui créditos expirados quando `true`. Ignorado se `usage` for informado.
          required: false
          name: include_expired
          in: query
        - schema:
            type: string
            format: date-time
            description: Limite inferior de `created_at` (ISO8601, inclusivo).
          required: false
          name: date_from
          in: query
        - schema:
            type: string
            format: date-time
            description: Limite superior de `created_at` (ISO8601, inclusivo).
          required: false
          name: date_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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de créditos.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreditListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-credits
    post:
      tags:
        - Créditos
      summary: Adicionar crédito
      description: Adiciona um crédito a uma conta de cobrança. O valor é creditado no `balance_cents` da `BillingAccount` e fica disponível para abater faturas futuras. Quando `company_id` é informado, o crédito só pode ser aplicado a faturas da mesma `company`.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreditCreateRequest"
      responses:
        "201":
          description: Crédito criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreditResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-credits
      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.
          schema:
            type: string
            format: uuid
  /v1/credits/{id}:
    get:
      tags:
        - Créditos
      summary: Obter crédito
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do crédito.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do crédito.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreditResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-credits-id
    patch:
      tags:
        - Créditos
      summary: Atualizar crédito
      description: Ajusta o crédito (tipo, valor, descrição ou data de expiração). O `amount_cents` só pode ser alterado se nenhum centavo do crédito tiver sido consumido — caso contrário a API responde `400`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do crédito.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreditUpdateRequest"
      responses:
        "200":
          description: Crédito atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreditResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-credits-id
    delete:
      tags:
        - Créditos
      summary: Excluir crédito
      description: Remove o crédito e estorna o saldo correspondente da conta de cobrança. Só é permitido se nenhum centavo do crédito tiver sido consumido — caso contrário a API responde `400`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do crédito.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Crédito excluído.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreditDeleteResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-credits-id
  /v1/invoices:
    get:
      tags:
        - Faturas
      summary: Listar faturas
      description: Retorna uma lista paginada de faturas da organização atual.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - draft
              - open
              - paid
              - void
              - uncollectible
            description: "Filtra por status: `draft`, `open`, `paid`, `void` ou `uncollectible`."
          required: false
          name: status
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por `billing_account_id`.
          required: false
          name: billing_account_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por `company_id` emissor.
          required: false
          name: company_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por `subscription_id` de origem.
          required: false
          name: subscription_id
          in: query
        - schema:
            type: string
            description: Filtra por `due_date` inicial (inclusivo).
          required: false
          name: due_date_from
          in: query
        - schema:
            type: string
            description: Filtra por `due_date` final (inclusivo).
          required: false
          name: due_date_to
          in: query
        - schema:
            type: string
            description: Filtra por `created_at` inicial (inclusivo).
          required: false
          name: date_from
          in: query
        - schema:
            type: string
            description: Filtra por `created_at` final (inclusivo).
          required: false
          name: date_to
          in: query
        - schema:
            type: string
            description: Busca textual livre.
          required: false
          name: search
          in: query
        - schema:
            type:
              - integer
              - "null"
            description: Filtra por valor total exato (em centavos).
          required: false
          name: total_cents
          in: query
        - schema:
            type: string
            description: Filtra por CPF/CNPJ do cliente.
          required: false
          name: document_number
          in: query
        - schema:
            type: string
            enum:
              - "true"
              - "false"
            description: Quando `true`, retorna apenas faturas sem pagamentos associados.
          required: false
          name: without_payments
          in: query
        - schema:
            type: string
            enum:
              - all
              - with_plan
              - without_plan
            description: "Filtra por origem: `all`, `with_plan` (com assinatura) ou `without_plan` (avulsa)."
          required: false
          name: plan_filter
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de faturas.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-invoices
    post:
      tags:
        - Faturas
      summary: Criar fatura
      description: Cria uma fatura para uma conta de cobrança. Aceita itens de linha, parcelas opcionais (`installments`, mínimo 2) e política de emissão de NFe.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/InvoiceCreateRequest"
      responses:
        "201":
          description: Fatura criada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-invoices
      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.
          schema:
            type: string
            format: uuid
  /v1/invoices/pending-payment:
    get:
      tags:
        - Faturas
      summary: Listar faturas com pagamento pendente
      description: Retorna faturas finalizadas (`status = open`) cuja `due_date` já passou.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por `billing_account_id`.
          required: false
          name: billing_account_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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de faturas com pagamento pendente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-invoices-pending-payment
  /v1/invoices/pending-nfe:
    get:
      tags:
        - Faturas
      summary: Listar faturas com NFe pendente
      description: Retorna faturas pagas, mas com emissão de NFe pendente — sem NFe, ou com NFe em status `pending`, `processing` ou `error`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por `billing_account_id`.
          required: false
          name: billing_account_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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de faturas com NFe pendente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-invoices-pending-nfe
  /v1/invoices/{id}:
    get:
      tags:
        - Faturas
      summary: Obter fatura
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe da fatura.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-invoices-id
    patch:
      tags:
        - Faturas
      summary: Atualizar fatura
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/InvoiceUpdateRequest"
      responses:
        "200":
          description: Fatura atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-invoices-id
    delete:
      tags:
        - Faturas
      summary: Excluir fatura
      description: Exclui uma fatura em rascunho (`draft`). Faturas finalizadas devem ser canceladas via `POST /invoices/{id}/void`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Fatura excluída.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceDeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-invoices-id
  /v1/invoices/{id}/finalize:
    post:
      tags:
        - Faturas
      summary: Finalizar fatura
      description: Finaliza uma fatura em rascunho (`draft` → `open`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Fatura finalizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-invoices-id-finalize
  /v1/invoices/{id}/void:
    post:
      tags:
        - Faturas
      summary: Cancelar (void) fatura
      description: Cancela uma fatura aberta (`open` → `void`). O motivo (`reason`) é registrado no audit log.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/InvoiceVoidRequest"
      responses:
        "200":
          description: Fatura cancelada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-invoices-id-void
  /v1/invoices/{id}/undo-payment:
    post:
      tags:
        - Faturas
      summary: Desfazer pagamento da fatura
      description: Reverte o pagamento da fatura (`paid` → `open`). O motivo (`reason`) é registrado no audit log.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/InvoiceUndoPaymentRequest"
      responses:
        "200":
          description: Pagamento desfeito.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-invoices-id-undo-payment
  /v1/invoices/{id}/pay:
    post:
      tags:
        - Faturas
      summary: Pagar fatura
      description: "Dois modos: (a) quando `payment_method` é informado, cria um pagamento via gateway (`pix`, `bank_slip` ou `card`) e retorna os artefatos do método (QR code, código de barras ou status do cartão); (b) quando omitido, marca a fatura como paga manualmente (reconciliação)."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/InvoicePayRequest"
      responses:
        "200":
          description: Resultado do pagamento ou fatura marcada como paga.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoicePayResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-invoices-id-pay
  /v1/invoices/{id}/send-reminder:
    post:
      tags:
        - Faturas
      summary: Enviar lembrete de cobrança
      description: Envia por e-mail um lembrete de cobrança da fatura para o `billing_email` da conta.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lembrete enviado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-invoices-id-send-reminder
  /v1/invoices/{id}/issue-nfe:
    post:
      tags:
        - Faturas
      summary: Emitir NFe para fatura
      description: Dispara a emissão da NFe (Nota Fiscal Eletrônica) para a fatura.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: NFe enfileirada/emitida.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceNfeResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-invoices-id-issue-nfe
  /v1/invoices/{id}/apply-credits:
    post:
      tags:
        - Faturas
      summary: Aplicar créditos na fatura
      description: Aplica créditos da conta de cobrança em uma fatura aberta (`status = open`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/InvoiceApplyCreditsRequest"
      responses:
        "200":
          description: Créditos aplicados.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceCreditsResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-invoices-id-apply-credits
  /v1/invoices/{id}/remove-credits:
    post:
      tags:
        - Faturas
      summary: Remover créditos aplicados
      description: Remove todos os créditos aplicados na fatura, devolvendo-os à conta de cobrança. Só funciona em faturas abertas (`status = open`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Créditos removidos.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceCreditsResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-invoices-id-remove-credits
  /v1/invoices/{id}/pdf:
    get:
      tags:
        - Faturas
      summary: Baixar PDF da fatura
      description: Gera e baixa o PDF da fatura como anexo binário (`application/pdf`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: PDF da fatura.
          content:
            application/pdf:
              schema:
                type: string
                format: binary
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-invoices-id-pdf
  /v1/invoices/{id}/payment-methods:
    get:
      tags:
        - Faturas
      summary: Listar métodos de pagamento disponíveis
      description: Lista os métodos de pagamento que podem ser usados para pagar esta fatura, com base nos gateways ativos da organização e nas configurações do portal.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Métodos de pagamento disponíveis.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoicePaymentMethodsResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-invoices-id-payment-methods
  /v1/invoices/{id}/installments:
    get:
      tags:
        - Faturas
      summary: Listar parcelas da fatura
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista de parcelas.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceInstallmentsListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-invoices-id-installments
    post:
      tags:
        - Faturas
      summary: Criar/atualizar parcelamento
      description: Cria ou substitui o cronograma de parcelas da fatura. Mínimo de 2 parcelas.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/InvoiceInstallmentsCreateRequest"
      responses:
        "201":
          description: Parcelamento criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceInstallmentsListResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-invoices-id-installments
  /v1/invoices/{id}/installments/{installmentId}/mark-paid:
    post:
      tags:
        - Faturas
      summary: Marcar parcela como paga
      description: Marca manualmente uma parcela como paga (reconciliação, sem chamada ao gateway).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          name: id
          in: path
        - schema:
            type: string
            format: uuid
            description: UUID da parcela.
          required: true
          name: installmentId
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Parcela marcada como paga.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceInstallmentResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-invoices-id-installments-installmentid-mark-paid
  /v1/invoices/{id}/installments/{installmentId}/pay:
    post:
      tags:
        - Faturas
      summary: Pagar parcela
      description: Processa o pagamento de uma parcela via gateway. A parcela anterior deve estar paga.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da fatura.
          required: true
          name: id
          in: path
        - schema:
            type: string
            format: uuid
            description: UUID da parcela.
          required: true
          name: installmentId
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/InvoiceInstallmentPayRequest"
      responses:
        "200":
          description: Resultado do pagamento da parcela.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoicePayResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-invoices-id-installments-installmentid-pay
  /v1/payments:
    get:
      tags:
        - Pagamentos
      summary: Listar pagamentos
      description: Retorna uma lista paginada dos pagamentos da organização atual.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - pending
              - processing
              - succeeded
              - failed
              - canceled
              - partial
              - refunded
              - partially_refunded
            description: Filtra por status do pagamento.
          required: false
          name: status
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelos pagamentos de uma fatura específica.
          required: false
          name: invoiceId
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelos pagamentos de uma conta de cobrança.
          required: false
          name: billingAccountId
          in: query
        - schema:
            type: string
            description: Data inicial (criação) — formato ISO 8601.
          required: false
          name: dateFrom
          in: query
        - schema:
            type: string
            description: Data final (criação) — formato ISO 8601.
          required: false
          name: dateTo
          in: query
        - schema:
            type: string
            description: Data inicial de pagamento — formato ISO 8601.
          required: false
          name: paidDateFrom
          in: query
        - schema:
            type: string
            description: Data final de pagamento — formato ISO 8601.
          required: false
          name: paidDateTo
          in: query
        - schema:
            type: string
            enum:
              - all
              - with_invoice
              - without_invoice
            description: "Filtra por presença de fatura: `all`, `with_invoice` ou `without_invoice`."
          required: false
          name: invoiceFilter
          in: query
        - schema:
            type: string
            enum:
              - card
              - bank_slip
              - pix
              - bank_transfer
            description: "Filtra por meio de pagamento: `card`, `bank_slip`, `pix` ou `bank_transfer`."
          required: false
          name: paymentMethodType
          in: query
        - schema:
            type:
              - integer
              - "null"
            minimum: 0
            description: Valor mínimo em centavos (÷100 → BRL).
          required: false
          name: amountMinCents
          in: query
        - schema:
            type:
              - integer
              - "null"
            minimum: 0
            description: Valor máximo em centavos (÷100 → BRL).
          required: false
          name: amountMaxCents
          in: query
        - schema:
            type: string
            description: Busca textual livre.
          required: false
          name: search
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de pagamentos.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-payments
    post:
      tags:
        - Pagamentos
      summary: Processar pagamento
      description: Processa um pagamento para uma fatura existente. Aceita um `payment_method_id` previamente registrado **ou** um bloco `payment_method` com dados de cartão/PIX/boleto. Quando `amount_cents` é omitido, cobra o saldo aberto da fatura.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PaymentCreateRequest"
      responses:
        "201":
          description: Pagamento criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-payments
      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.
          schema:
            type: string
            format: uuid
  /v1/payments/bulk-update-invoice:
    post:
      tags:
        - Pagamentos
      summary: Reatribuir pagamentos a outra fatura
      description: Atualiza em massa a fatura associada aos pagamentos informados. Útil para corrigir vínculos quando pagamentos chegaram apontando para a fatura errada.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PaymentBulkUpdateInvoiceRequest"
      responses:
        "200":
          description: Pagamentos reatribuídos.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentBulkUpdateInvoiceResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-payments-bulk-update-invoice
      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.
          schema:
            type: string
            format: uuid
  /v1/payments/{id}:
    get:
      tags:
        - Pagamentos
      summary: Obter pagamento
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do pagamento.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do pagamento.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-payments-id
    delete:
      tags:
        - Pagamentos
      summary: Excluir pagamento
      description: Remove um pagamento. Pagamentos já confirmados não podem ser excluídos — use `cancel` ou `refund`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do pagamento.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Pagamento removido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentDeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-payments-id
  /v1/payments/{id}/cancel:
    post:
      tags:
        - Pagamentos
      summary: Cancelar pagamento
      description: Cancela um pagamento em aberto. Quando `cancel_on_gateway` é `true` (padrão), o cancelamento é propagado ao gateway.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do pagamento.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PaymentCancelRequest"
      responses:
        "200":
          description: Pagamento cancelado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-payments-id-cancel
  /v1/payments/{id}/retry:
    post:
      tags:
        - Pagamentos
      summary: Tentar pagamento novamente
      description: Reprocessa um pagamento falho. Pode opcionalmente trocar para um cartão novo (via `card`) ou para um meio de pagamento salvo (`payment_method_id`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do pagamento.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PaymentRetryRequest"
      responses:
        "200":
          description: Pagamento reprocessado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-payments-id-retry
  /v1/payments/{id}/change-card:
    post:
      tags:
        - Pagamentos
      summary: Trocar cartão do pagamento
      description: Troca o cartão de crédito de um pagamento falho processado pelo Pagar.me. O novo cartão precisa estar registrado previamente em `payment_methods`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do pagamento.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PaymentChangeCardRequest"
      responses:
        "200":
          description: Cartão trocado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-payments-id-change-card
  /v1/payments/{id}/change-due-date:
    post:
      tags:
        - Pagamentos
      summary: Alterar vencimento do boleto
      description: Altera o vencimento de um pagamento em boleto pendente emitido via gateway Kobana. A nova data precisa ser futura.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do pagamento.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PaymentChangeDueDateRequest"
      responses:
        "200":
          description: Vencimento atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentChangeDueDateResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-payments-id-change-due-date
  /v1/payments/{id}/send-email:
    post:
      tags:
        - Pagamentos
      summary: Enviar boleto por e-mail
      description: Envia o link do boleto por e-mail para o destinatário informado. Disponível apenas para pagamentos em boleto pendentes.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do pagamento.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PaymentSendEmailRequest"
      responses:
        "200":
          description: E-mail enviado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentSendEmailResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-payments-id-send-email
  /v1/payments/{id}/sync:
    post:
      tags:
        - Pagamentos
      summary: Sincronizar pagamento com gateway
      description: Sincroniza o status do pagamento com o gateway upstream (PIX/boleto Kobana ou estorno Pagar.me). Retorna o pagamento atualizado.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do pagamento.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Pagamento sincronizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-payments-id-sync
  /v1/payments/{id}/refund:
    post:
      tags:
        - Pagamentos
      summary: Estornar pagamento
      description: Estorna um pagamento bem-sucedido. Sem `amount_cents`, estorna o valor total; com valor parcial, gera estorno parcial.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do pagamento.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PaymentRefundRequest"
      responses:
        "200":
          description: Pagamento estornado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-payments-id-refund
  /v1/payment_methods:
    get:
      tags:
        - Métodos de Pagamento
      summary: Listar métodos de pagamento
      description: "Retorna uma lista paginada dos métodos de pagamento da organização atual. Filtros opcionais: `billing_account_id`, `type`, `status`."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por UUID da conta de cobrança.
          required: false
          name: billingAccountId
          in: query
        - schema:
            type: string
            enum:
              - card
              - bank_slip
              - pix
              - bank_transfer
            description: "Filtra por tipo: `card`, `bank_slip`, `pix` ou `bank_transfer`."
          required: false
          name: type
          in: query
        - schema:
            type: string
            enum:
              - active
              - expired
              - failed
            description: "Filtra por status: `active`, `expired` ou `failed`."
          required: false
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de métodos de pagamento.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentMethodListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-payment-methods
    post:
      tags:
        - Métodos de Pagamento
      summary: Criar método de pagamento
      description: Cria um método de pagamento associado a uma conta de cobrança. Para `type=card`, envie o bloco `card` com o `cardToken` gerado pela tokenização client-side. Para `type=bank_transfer`, envie o bloco `bankAccount`. Para `bank_slip` e `pix`, basta o `type` — o gateway padrão é resolvido pela organização.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PaymentMethodCreateRequest"
      responses:
        "201":
          description: Método de pagamento criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentMethodResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-payment-methods
      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.
          schema:
            type: string
            format: uuid
  /v1/payment_methods/{id}:
    get:
      tags:
        - Métodos de Pagamento
      summary: Obter método de pagamento
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do método de pagamento.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do método de pagamento.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentMethodResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-payment-methods-id
    patch:
      tags:
        - Métodos de Pagamento
      summary: Atualizar validade do cartão
      description: Atualiza apenas mês e ano de validade do cartão associado ao método. Falha quando `type` não é `card`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do método de pagamento.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PaymentMethodUpdateRequest"
      responses:
        "200":
          description: Método de pagamento atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentMethodResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-payment-methods-id
    delete:
      tags:
        - Métodos de Pagamento
      summary: Remover método de pagamento
      description: Soft delete do método de pagamento (marca como `removed`). Falha quando há pagamentos pendentes ou em processamento. Se era o padrão, outro método ativo é promovido automaticamente.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do método de pagamento.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Método de pagamento removido.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      deleted:
                        type: boolean
                    required:
                      - deleted
                required:
                  - data
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-payment-methods-id
  /v1/payment_methods/{id}/set-default:
    post:
      tags:
        - Métodos de Pagamento
      summary: Definir método como padrão
      description: Marca o método como padrão da conta de cobrança e desmarca os anteriores. Falha quando o método não está `active`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do método de pagamento.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Método de pagamento definido como padrão.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PaymentMethodResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-payment-methods-id-set-default
  /v1/nfes:
    get:
      tags:
        - NF-e
      summary: Listar NFes
      description: Retorna uma lista paginada de NFes (Notas Fiscais Eletrônicas) da organização atual.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por `billing_account_id`.
          required: false
          name: billingAccountId
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por `company_id` emissor.
          required: false
          name: companyId
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por `invoice_id` vinculado.
          required: false
          name: invoiceId
          in: query
        - schema:
            type: string
            enum:
              - draft
              - pending
              - processing
              - issued
              - pending_cancel
              - canceling
              - canceled
              - error
            description: "Filtra por status: `draft`, `pending`, `processing`, `issued`, `pending_cancel`, `canceling`, `canceled` ou `error`."
          required: false
          name: status
          in: query
        - schema:
            type: string
            enum:
              - with
              - without
            description: "Filtra pela presença de fatura: `with` (apenas com fatura) ou `without` (apenas avulsas)."
          required: false
          name: invoiceFilter
          in: query
        - schema:
            type: string
            description: Filtra por `created_at` inicial (inclusivo).
          required: false
          name: dateFrom
          in: query
        - schema:
            type: string
            description: Filtra por `created_at` final (inclusivo).
          required: false
          name: dateTo
          in: query
        - schema:
            type: string
            description: Filtra por `issue_date` inicial (inclusivo).
          required: false
          name: issueDateFrom
          in: query
        - schema:
            type: string
            description: Filtra por `issue_date` final (inclusivo).
          required: false
          name: issueDateTo
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de NFes.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-nfes
    post:
      tags:
        - NF-e
      summary: Criar NFe (rascunho)
      description: Cria uma NFe em rascunho (`draft`) para emissão posterior via `POST /nfes/{id}/issue`. Aceita dados do tomador (`customer`) e alíquotas opcionais.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NfeCreateRequest"
      responses:
        "201":
          description: NFe criada em rascunho.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-nfes
      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.
          schema:
            type: string
            format: uuid
  /v1/nfes/sync:
    post:
      tags:
        - NF-e
      summary: Sincronizar NFes da organização
      description: Dispara um job em background para sincronizar todas as NFes da organização com o provedor (atualiza status, baixa PDFs/XMLs pendentes). Retorna o `job_id` para acompanhamento. Recusa se já existir uma sync ativa.
      security:
        - bearerAuth: []
      responses:
        "201":
          description: Sync enfileirada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeSyncOrgResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-nfes-sync
      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.
          schema:
            type: string
            format: uuid
  /v1/nfes/bulk:
    post:
      tags:
        - NF-e
      summary: Atualizar NFes em lote
      description: Atualiza várias NFes de uma vez. Hoje suporta vincular ou desvincular uma fatura (`invoice_id`) em até 100 NFes por requisição.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NfeBulkUpdateRequest"
      responses:
        "200":
          description: Quantidade de NFes atualizadas.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeBulkUpdateResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-nfes-bulk
      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.
          schema:
            type: string
            format: uuid
  /v1/nfes/bulk-delete:
    post:
      tags:
        - NF-e
      summary: Excluir NFes em lote
      description: Exclui até 100 NFes de uma vez. Todas devem estar em status `draft` e pertencer à organização atual.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NfeBulkDeleteRequest"
      responses:
        "200":
          description: Quantidade de NFes excluídas.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeBulkDeleteResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-nfes-bulk-delete
      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.
          schema:
            type: string
            format: uuid
  /v1/nfes/request-tries:
    get:
      tags:
        - NF-e
      summary: Listar tentativas de requisição (organização)
      description: Lista todas as tentativas de requisição ao provedor de NFe da organização, paginadas e ordenadas por data decrescente.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de tentativas.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeRequestTryPaginatedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-nfes-request-tries
  /v1/nfes/fetch-from-sefaz:
    post:
      tags:
        - NF-e
      summary: Buscar NFS-e no ADN (SEFAZ)
      description: Busca uma NFS-e no Ambiente de Dados Nacional (ADN) usando uma chave de acesso de 50 dígitos e um certificado digital previamente cadastrado (autenticação mTLS).
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NfeFetchFromSefazRequest"
      responses:
        "200":
          description: Resultado da busca no ADN.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeFetchFromSefazResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-nfes-fetch-from-sefaz
      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.
          schema:
            type: string
            format: uuid
  /v1/nfes/fetch-barueri:
    post:
      tags:
        - NF-e
      summary: Buscar NFS-e em Barueri
      description: Busca uma NFS-e no endpoint municipal de Barueri usando o `codigo_autenticidade` impresso no DANFSE e o CPF/CNPJ do tomador. Retorna o XML cru e, quando encontrada, a NFe já existente na organização.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NfeFetchBarueriRequest"
      responses:
        "200":
          description: Resultado da busca com XML e referência à NFe existente, quando houver.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeFetchBarueriResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-nfes-fetch-barueri
      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.
          schema:
            type: string
            format: uuid
  /v1/nfes/import-barueri:
    post:
      tags:
        - NF-e
      summary: Importar NFS-e Barueri
      description: Importa uma NFS-e de Barueri para o banco. Aceita um XML cru (retornado por `POST /nfes/fetch-barueri`) ou o `codigo_autenticidade` + `cnpj_tomador` para re-buscar antes de importar. Cria a `BillingAccount` do tomador quando ainda não existir.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NfeImportBarueriRequest"
      responses:
        "200":
          description: Resultado da importação com flags `created`/`updated` e NFe persistida.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeImportBarueriResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-nfes-import-barueri
      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.
          schema:
            type: string
            format: uuid
  /v1/nfes/{id}:
    get:
      tags:
        - NF-e
      summary: Obter NFe
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da NFe.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe da NFe.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-nfes-id
    patch:
      tags:
        - NF-e
      summary: Atualizar NFe (rascunho)
      description: Atualiza campos da NFe. Apenas NFes em `draft` aceitam mudanças nos valores e códigos fiscais.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da NFe.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NfeUpdateRequest"
      responses:
        "200":
          description: NFe atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-nfes-id
    delete:
      tags:
        - NF-e
      summary: Excluir NFe
      description: Exclui uma NFe. Permitido apenas para os status `draft`, `pending`, `processing`, `error` ou `canceled`. NFes `issued` devem ser canceladas via `POST /nfes/{id}/cancel`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da NFe.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: NFe excluída.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeDeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-nfes-id
  /v1/nfes/{id}/issue:
    post:
      tags:
        - NF-e
      summary: Emitir NFe
      description: Emite uma NFe em rascunho (`draft`) ou retenta uma NFe em `pending`/`error`. Envia a requisição para o provedor configurado na organização.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da NFe.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: NFe enfileirada/emitida.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-nfes-id-issue
  /v1/nfes/{id}/cancel:
    post:
      tags:
        - NF-e
      summary: Cancelar NFe
      description: Cancela uma NFe emitida. Enfileira o cancelamento de forma assíncrona junto ao provedor. O motivo (`reason`) deve ter no mínimo 15 caracteres e é registrado no audit log.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da NFe.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NfeCancelRequest"
      responses:
        "200":
          description: Cancelamento enfileirado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-nfes-id-cancel
  /v1/nfes/{id}/retry-cancel:
    post:
      tags:
        - NF-e
      summary: Retentar cancelamento da NFe
      description: Retenta o cancelamento de uma NFe travada em `pending_cancel`, `canceling` ou `error`. Reenfileira o job de cancelamento.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da NFe.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Retentativa de cancelamento enfileirada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-nfes-id-retry-cancel
  /v1/nfes/{id}/sync:
    post:
      tags:
        - NF-e
      summary: Sincronizar PDF/XML da NFe
      description: Baixa do provedor o PDF e o XML da NFe e persiste no banco de dados.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da NFe.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: PDF/XML sincronizados.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-nfes-id-sync
  /v1/nfes/{id}/pdf:
    get:
      tags:
        - NF-e
      summary: Baixar PDF da NFe
      description: Baixa o PDF da NFe (DANFE) como anexo binário (`application/pdf`). Serve do banco quando disponível; caso contrário, busca no provedor.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da NFe.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: PDF da NFe.
          content:
            application/pdf:
              schema:
                type: string
                format: binary
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-nfes-id-pdf
  /v1/nfes/{id}/xml:
    get:
      tags:
        - NF-e
      summary: Baixar XML da NFe
      description: Baixa o XML da NFe como anexo binário (`application/xml`). Serve do banco quando disponível; caso contrário, busca no provedor.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da NFe.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: XML da NFe.
          content:
            application/xml:
              schema:
                type: string
                format: binary
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-nfes-id-xml
  /v1/nfes/{id}/request-tries:
    get:
      tags:
        - NF-e
      summary: Listar tentativas de requisição da NFe
      description: Lista as tentativas (`NfeRequestTry`) feitas ao provedor para esta NFe — uma entrada por chamada, com endpoint, status HTTP, duração e mensagens de erro.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da NFe.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista de tentativas.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeRequestTryListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-nfes-id-request-tries
  /v1/nfes/{id}/requests:
    get:
      tags:
        - NF-e
      summary: Listar requisições externas da NFe
      description: Lista as requisições HTTP capturadas para esta NFe (chamadas ao provedor e webhooks recebidos), com paginação. Use `direction` para filtrar entre `outbound` e `inbound`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da NFe.
          required: true
          name: id
          in: path
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - outbound
              - inbound
            description: "Filtra requisições por direção: `outbound` (chamadas saindo) ou `inbound` (webhooks recebidos)."
          required: false
          name: direction
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de requisições.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeExternalRequestListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-nfes-id-requests
  /v1/nfes/{id}/requests/{requestId}:
    get:
      tags:
        - NF-e
      summary: Obter requisição externa
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da NFe.
          required: true
          name: id
          in: path
        - schema:
            type: string
            format: uuid
            description: UUID da requisição externa.
          required: true
          name: requestId
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe da requisição externa, incluindo cabeçalhos e corpos.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeExternalRequestResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-nfes-id-requests-requestid
  /v1/nfes/{id}/validate-barueri:
    post:
      tags:
        - NF-e
      summary: Validar NFS-e Barueri
      description: Re-busca a NFS-e na prefeitura de Barueri e compara com o registro local, devolvendo a lista de diferenças e o XML atualizado para reaplicação via `POST /nfes/import-barueri`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da NFe.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Resultado da validação com diferenças e XML atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NfeValidateBarueriResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-nfes-id-validate-barueri
  /v1/proposals:
    get:
      tags:
        - Propostas
      summary: Listar propostas
      description: Retorna uma lista paginada de propostas comerciais da organização atual.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - draft
              - sent
              - viewed
              - accepted
              - rejected
              - expired
              - canceled
            description: "Filtra por status: `draft`, `sent`, `viewed`, `accepted`, `rejected`, `expired` ou `canceled`."
          required: false
          name: status
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por `billing_account_id` vinculado.
          required: false
          name: billing_account_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por `prospect_id`.
          required: false
          name: prospect_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por `company_id` emissor.
          required: false
          name: company_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por `template_id` usado para gerar o PDF.
          required: false
          name: template_id
          in: query
        - schema:
            type: string
            description: Busca textual livre.
          required: false
          name: search
          in: query
        - schema:
            type: string
            description: Filtra propostas com `expires_at` ≥ valor (ISO 8601).
          required: false
          name: expires_after
          in: query
        - schema:
            type: string
            description: Filtra propostas com `expires_at` ≤ valor (ISO 8601).
          required: false
          name: expires_before
          in: query
        - schema:
            type: string
            description: Filtra por `created_at` inicial (inclusivo).
          required: false
          name: date_from
          in: query
        - schema:
            type: string
            description: Filtra por `created_at` final (inclusivo).
          required: false
          name: date_to
          in: query
        - schema:
            type: string
            description: Filtra por `accepted_at` inicial.
          required: false
          name: accepted_from
          in: query
        - schema:
            type: string
            description: Filtra por `accepted_at` final.
          required: false
          name: accepted_to
          in: query
        - schema:
            type:
              - integer
              - "null"
            minimum: 0
            description: Filtra por `setup_amount_cents` mínimo (em centavos).
          required: false
          name: setup_amount_min
          in: query
        - schema:
            type:
              - integer
              - "null"
            minimum: 0
            description: Filtra por `setup_amount_cents` máximo (em centavos).
          required: false
          name: setup_amount_max
          in: query
        - schema:
            type:
              - integer
              - "null"
            minimum: 0
            description: Filtra por `monthly_amount_cents` mínimo (em centavos).
          required: false
          name: monthly_amount_min
          in: query
        - schema:
            type:
              - integer
              - "null"
            minimum: 0
            description: Filtra por `monthly_amount_cents` máximo (em centavos).
          required: false
          name: monthly_amount_max
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de propostas.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-proposals
    post:
      tags:
        - Propostas
      summary: Criar proposta
      description: Cria uma proposta comercial. É obrigatório informar `billing_account_id`, `prospect_id` ou `prospect_data` (criação inline do prospect).
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProposalCreateRequest"
      responses:
        "201":
          description: Proposta criada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposals
      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.
          schema:
            type: string
            format: uuid
  /v1/proposals/stats:
    get:
      tags:
        - Propostas
      summary: Obter estatísticas de propostas
      description: Retorna contagens de propostas por status (`draft`, `sent`, `viewed`, `accepted`, `rejected`, `expired`, `canceled`) para a organização atual.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Estatísticas de propostas.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalStatsResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-proposals-stats
      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.
          schema:
            type: string
            format: uuid
  /v1/proposals/bulk-cancel:
    post:
      tags:
        - Propostas
      summary: Cancelar propostas em lote
      description: Cancela várias propostas de uma vez (até 100). Retorna contagens de sucesso/falha e erros por id.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProposalBulkRequest"
      responses:
        "200":
          description: Resultado do cancelamento em lote.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalBulkResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposals-bulk-cancel
      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.
          schema:
            type: string
            format: uuid
  /v1/proposals/bulk-delete:
    post:
      tags:
        - Propostas
      summary: Excluir propostas em lote
      description: Exclui várias propostas de uma vez (até 100). Retorna contagens de sucesso/falha e erros por id.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProposalBulkRequest"
      responses:
        "200":
          description: Resultado da exclusão em lote.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalBulkResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposals-bulk-delete
      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.
          schema:
            type: string
            format: uuid
  /v1/proposals/bulk-send:
    post:
      tags:
        - Propostas
      summary: Enviar propostas em lote
      description: Envia várias propostas de uma vez (até 100). Retorna contagens de sucesso/falha e erros por id.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProposalBulkRequest"
      responses:
        "200":
          description: Resultado do envio em lote.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalBulkResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposals-bulk-send
      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.
          schema:
            type: string
            format: uuid
  /v1/proposals/{id}:
    get:
      tags:
        - Propostas
      summary: Obter proposta
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe da proposta.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-proposals-id
    patch:
      tags:
        - Propostas
      summary: Atualizar proposta
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProposalUpdateRequest"
      responses:
        "200":
          description: Proposta atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-proposals-id
    delete:
      tags:
        - Propostas
      summary: Excluir proposta
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Proposta excluída.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalDeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-proposals-id
  /v1/proposals/{id}/accept:
    post:
      tags:
        - Propostas
      summary: Aceitar proposta
      description: Aceita a proposta e cria (ou confirma) a assinatura correspondente no ciclo informado.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProposalAcceptRequest"
      responses:
        "200":
          description: Proposta aceita — retorna a proposta, `subscription_id` e `invoice_id` quando aplicáveis.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalAcceptResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposals-id-accept
  /v1/proposals/{id}/cancel:
    post:
      tags:
        - Propostas
      summary: Cancelar proposta
      description: Cancela a proposta (`status → canceled`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Proposta cancelada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposals-id-cancel
  /v1/proposals/{id}/duplicate:
    post:
      tags:
        - Propostas
      summary: Duplicar proposta
      description: Cria uma nova proposta a partir da proposta original (rascunho), preservando itens e configurações.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "201":
          description: Proposta duplicada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposals-id-duplicate
  /v1/proposals/{id}/send:
    post:
      tags:
        - Propostas
      summary: Enviar proposta por e-mail
      description: "Envia (ou reenvia) a proposta por e-mail ao destinatário. Estados aceitos: `draft`, `sent` ou `viewed`. Opcionalmente, é possível customizar `subject` e `message` (HTML)."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProposalSendRequest"
      responses:
        "200":
          description: Proposta enviada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposals-id-send
  /v1/proposals/{id}/publish:
    post:
      tags:
        - Propostas
      summary: Publicar proposta
      description: Publica a proposta (`draft → sent`) sem disparar o e-mail, tornando-a acessível no portal.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Proposta publicada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposals-id-publish
  /v1/proposals/{id}/unpublish:
    post:
      tags:
        - Propostas
      summary: Despublicar proposta
      description: Volta a proposta para rascunho (`sent`/`viewed` → `draft`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Proposta despublicada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposals-id-unpublish
  /v1/proposals/{id}/undo-accept:
    post:
      tags:
        - Propostas
      summary: Desfazer aceite da proposta
      description: "Desfaz a aceitação: remove a assinatura vinculada e volta o status para `sent`."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Aceitação desfeita.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposals-id-undo-accept
  /v1/proposals/{id}/generate-pdf:
    post:
      tags:
        - Propostas
      summary: Gerar PDF da proposta
      description: Gera (ou regenera) o PDF da proposta via Google App Scripts. Requer um `template` com `app_script_url` configurado.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: PDF gerado — retorna a proposta atualizada e as URLs do documento/PDF.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalGeneratePdfResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposals-id-generate-pdf
  /v1/proposals/{id}/json:
    get:
      tags:
        - Propostas
      summary: Obter snapshot JSON da proposta
      description: Retorna o snapshot completo dos dados usados para renderizar o template do PDF (espelha o que o AppScript recebe).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Snapshot JSON da proposta.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalJsonResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-proposals-id-json
  /v1/proposals/{id}/pricing:
    get:
      tags:
        - Propostas
      summary: Obter cálculo de preço da proposta
      description: Retorna o detalhamento de preços por ciclo de cobrança (mensal, trimestral, semestral, anual), com setup e descontos aplicados.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhamento de preços.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalPricingResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-proposals-id-pricing
  /v1/proposals/{id}/items:
    get:
      tags:
        - Propostas
      summary: Listar itens da proposta
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista de itens.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalItemsListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-proposals-id-items
    post:
      tags:
        - Propostas
      summary: Adicionar item à proposta
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProposalItemCreateRequest"
      responses:
        "201":
          description: Item criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalItemResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposals-id-items
  /v1/proposals/{id}/items/{itemId}:
    get:
      tags:
        - Propostas
      summary: Obter item da proposta
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          name: id
          in: path
        - schema:
            type: string
            format: uuid
            description: UUID do item da proposta.
          required: true
          name: itemId
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do item.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalItemResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-proposals-id-items-itemid
    patch:
      tags:
        - Propostas
      summary: Atualizar item da proposta
      description: Atualiza um item. Só é permitido em propostas em rascunho (`status = draft`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          name: id
          in: path
        - schema:
            type: string
            format: uuid
            description: UUID do item da proposta.
          required: true
          name: itemId
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProposalItemUpdateRequest"
      responses:
        "200":
          description: Item atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalItemResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-proposals-id-items-itemid
    delete:
      tags:
        - Propostas
      summary: Excluir item da proposta
      description: Remove um item. Só é permitido em propostas em rascunho (`status = draft`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da proposta.
          required: true
          name: id
          in: path
        - schema:
            type: string
            format: uuid
            description: UUID do item da proposta.
          required: true
          name: itemId
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Item excluído.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalDeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-proposals-id-items-itemid
  /v1/proposal_templates:
    get:
      tags:
        - Templates de Proposta
      summary: Listar templates de proposta
      description: Retorna uma lista paginada dos templates de proposta da organização atual.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            description: Busca textual por nome ou descrição.
          required: false
          name: search
          in: query
        - schema:
            type: boolean
            description: Filtra por templates ativos (`true`) ou desativados (`false`).
          required: false
          name: isActive
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de templates de proposta.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalTemplateListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-proposal-templates
    post:
      tags:
        - Templates de Proposta
      summary: Criar template de proposta
      description: Cria um template de proposta vinculado a um Google Doc ou Google Slides. O `google_doc_id` precisa ser único por organização.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProposalTemplateCreateRequest"
      responses:
        "201":
          description: Template de proposta criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalTemplateResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposal-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.
          schema:
            type: string
            format: uuid
  /v1/proposal_templates/{id}:
    get:
      tags:
        - Templates de Proposta
      summary: Obter template de proposta
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do template de proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do template de proposta.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalTemplateResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-proposal-templates-id
    patch:
      tags:
        - Templates de Proposta
      summary: Atualizar template de proposta
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do template de proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProposalTemplateUpdateRequest"
      responses:
        "200":
          description: Template de proposta atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalTemplateResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-proposal-templates-id
    delete:
      tags:
        - Templates de Proposta
      summary: Excluir template de proposta
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do template de proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Template de proposta removido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-proposal-templates-id
  /v1/proposal_templates/{id}/activate:
    post:
      tags:
        - Templates de Proposta
      summary: Ativar template de proposta
      description: Ativa um template de proposta previamente desativado, tornando-o disponível para uso em novas propostas.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do template de proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Template de proposta ativado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalTemplateResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposal-templates-id-activate
  /v1/proposal_templates/{id}/deactivate:
    post:
      tags:
        - Templates de Proposta
      summary: Desativar template de proposta
      description: Desativa um template de proposta. Templates desativados não podem ser usados em novas propostas, mas as propostas já criadas permanecem inalteradas.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do template de proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Template de proposta desativado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalTemplateResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposal-templates-id-deactivate
  /v1/proposal_templates/{id}/duplicate:
    post:
      tags:
        - Templates de Proposta
      summary: Duplicar template de proposta
      description: Cria uma cópia do template informado, mantendo configuração e metadados. O novo template recebe um nome derivado e nunca herda a flag `is_default`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do template de proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "201":
          description: Template de proposta duplicado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalTemplateResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposal-templates-id-duplicate
  /v1/proposal_templates/{id}/set-default:
    post:
      tags:
        - Templates de Proposta
      summary: Definir template como padrão
      description: Marca o template informado como padrão da organização e remove a flag dos demais. Apenas um template pode ser padrão por vez.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do template de proposta.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Template definido como padrão.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProposalTemplateResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-proposal-templates-id-set-default
  /v1/plan_changes:
    get:
      tags:
        - Mudanças de Plano
      summary: Listar mudanças de plano
      description: Retorna o histórico paginado de mudanças de plano (upgrades, downgrades e laterais) da organização atual.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelas mudanças de uma assinatura.
          required: false
          name: subscription_id
          in: query
        - schema:
            type: string
            enum:
              - upgrade
              - downgrade
              - lateral
            description: "Filtra pelo tipo: `upgrade`, `downgrade` ou `lateral`."
          required: false
          name: change_type
          in: query
        - schema:
            type: string
            enum:
              - pending
              - scheduled
              - completed
              - canceled
              - failed
            description: "Filtra pelo status: `pending`, `scheduled`, `completed`, `canceled` ou `failed`."
          required: false
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de mudanças de plano.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanChangeListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-plan-changes
    post:
      tags:
        - Mudanças de Plano
      summary: Executar mudança de plano
      description: Executa uma mudança de plano para uma assinatura existente. O `timing` controla se a mudança é aplicada imediatamente (com proração) ou no fim do período atual. Quando bem-sucedido, retorna os UUIDs do `plan_change`, da fatura de proração (se houver) e do crédito gerado (se houver).
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlanChangeExecuteRequest"
      responses:
        "201":
          description: Mudança de plano executada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanChangeExecuteResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-plan-changes
      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.
          schema:
            type: string
            format: uuid
  /v1/plan_changes/stats:
    get:
      tags:
        - Mudanças de Plano
      summary: Estatísticas de mudanças de plano
      description: Retorna agregados de mudanças de plano (totais por tipo, por status, créditos e cobranças de proração) para uma janela em dias.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Janela em dias para os agregados (padrão: `30`)."
            example: 30
          required: false
          name: days
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Estatísticas agregadas de mudanças de plano.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanChangeStatsResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-plan-changes-stats
  /v1/plan_changes/config:
    get:
      tags:
        - Mudanças de Plano
      summary: Obter configuração de mudança de plano
      description: Retorna a configuração padrão da organização para upgrades e downgrades — comportamento de proração, timing e geração de crédito/refund.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Configuração atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanChangeConfigResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-plan-changes-config
      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.
          schema:
            type: string
            format: uuid
    patch:
      tags:
        - Mudanças de Plano
      summary: Atualizar configuração de mudança de plano
      description: Atualiza parcialmente (PATCH) a configuração de mudança de plano da organização. Todos os campos são opcionais.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlanChangeConfigUpdateRequest"
      responses:
        "200":
          description: Configuração atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanChangeConfigResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-plan-changes-config
      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.
          schema:
            type: string
            format: uuid
  /v1/plan_changes/rules:
    get:
      tags:
        - Mudanças de Plano
      summary: Listar regras de mudança de plano
      description: Lista as regras customizadas que sobrescrevem o comportamento padrão para transições específicas entre planos.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Lista de regras de mudança de plano.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanChangeRuleListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-plan-changes-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.
          schema:
            type: string
            format: uuid
    post:
      tags:
        - Mudanças de Plano
      summary: Criar regra de mudança de plano
      description: Cria uma nova regra para uma transição entre planos. Permite bloquear/permitir a transição, definir timing, proração, descontos e dias bônus.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlanChangeRuleCreateRequest"
      responses:
        "201":
          description: Regra criada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanChangeRuleResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-plan-changes-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.
          schema:
            type: string
            format: uuid
  /v1/plan_changes/rules/{id}:
    get:
      tags:
        - Mudanças de Plano
      summary: Obter regra de mudança de plano
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da regra de mudança de plano.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe da regra.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanChangeRuleResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-plan-changes-rules-id
    patch:
      tags:
        - Mudanças de Plano
      summary: Atualizar regra de mudança de plano
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da regra de mudança de plano.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlanChangeRuleUpdateRequest"
      responses:
        "200":
          description: Regra atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanChangeRuleResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-plan-changes-rules-id
    delete:
      tags:
        - Mudanças de Plano
      summary: Excluir regra de mudança de plano
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da regra de mudança de plano.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Regra removida.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanChangeRuleDeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-plan-changes-rules-id
  /v1/plan_changes/{id}:
    get:
      tags:
        - Mudanças de Plano
      summary: Obter mudança de plano
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da mudança de plano.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe da mudança de plano.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlanChangeResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-plan-changes-id
  /v1/subscription_changes/config:
    get:
      tags:
        - Mudanças de Assinatura
      summary: Obter configuração de mudanças de assinatura
      description: Retorna a configuração da organização para mudanças em itens de assinaturas — operações permitidas (incluir/remover/alterar quantidade/trocar preço), método de proporção (proration) por operação, momento de aplicação (`immediate` ou `end_of_period`), reembolso/crédito na remoção e self-service no portal. Se ainda não existir, é criada com os defaults na primeira leitura.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Configuração da organização.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubscriptionChangeConfigResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-subscription-changes-config
      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.
          schema:
            type: string
            format: uuid
    put:
      tags:
        - Mudanças de Assinatura
      summary: Atualizar configuração de mudanças de assinatura
      description: Atualiza parcialmente a configuração. Apenas os campos enviados são alterados. `refund_on_remove` exige que `credit_on_remove` também esteja habilitado — reembolso é uma variante de crédito.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SubscriptionChangeConfigUpdateRequest"
      responses:
        "200":
          description: Configuração atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubscriptionChangeConfigResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: put-subscription-changes-config
      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.
          schema:
            type: string
            format: uuid
  /v1/subscription_item_changes:
    get:
      tags:
        - Mudanças de Assinatura
      summary: Listar mudanças de itens de assinatura
      description: Retorna uma lista paginada das mudanças aplicadas (ou agendadas) sobre itens de assinaturas da organização — adições, remoções, alterações de quantidade e trocas de preço. Cada registro inclui o snapshot das operações, os valores de proporção (proration) em **subcents** (÷10000 → BRL) e os ponteiros para a fatura/credit gerados.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelas mudanças de uma assinatura específica.
          required: false
          name: subscription_id
          in: query
        - schema:
            type: string
            enum:
              - pending
              - scheduled
              - completed
              - canceled
              - failed
            description: "Filtra por status: `pending`, `scheduled`, `completed`, `canceled` ou `failed`."
          required: false
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de mudanças de itens.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubscriptionItemChangeListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-subscription-item-changes
  /v1/subscription_item_changes/{id}:
    get:
      tags:
        - Mudanças de Assinatura
      summary: Obter mudança de item de assinatura
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da mudança de item.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe da mudança de item.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SubscriptionItemChangeResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-subscription-item-changes-id
  /v1/usage:
    get:
      tags:
        - Uso (Metered)
      summary: Listar registros de uso
      description: Retorna os registros de uso (metered) de um item de assinatura. Identifique o item por `subscription_item_id` **ou** pela combinação `product_slug` + `customer_id`. Suporta filtros por intervalo de datas e janela com `limit`/`offset`.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do item de assinatura. Alternativa a `product_slug` + `customer_id`.
          required: false
          name: subscription_item_id
          in: query
        - schema:
            type: string
            description: Slug do produto. Combine com `customer_id`.
          required: false
          name: product_slug
          in: query
        - schema:
            type: string
            description: Identificador externo do cliente. Combine com `product_slug`.
          required: false
          name: customer_id
          in: query
        - schema:
            type: string
            description: Data/hora inicial do filtro — formato ISO 8601.
          required: false
          name: start_date
          in: query
        - schema:
            type: string
            description: Data/hora final do filtro — formato ISO 8601.
          required: false
          name: end_date
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 1000
            description: "Itens por página. Padrão: `100`. Máximo: `1000`."
          required: false
          name: limit
          in: query
        - schema:
            type:
              - integer
              - "null"
            minimum: 0
            description: "Deslocamento (offset) para paginação. Padrão: `0`."
          required: false
          name: offset
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista de registros de uso com agregação `total_quantity` no `meta`.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageListResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-usage
    post:
      tags:
        - Uso (Metered)
      summary: Reportar uso (metered)
      description: "Reporta uso para faturamento metered. Aceita um registro único **ou** um lote `{ records: [...] }` com até **100** itens. Cada registro precisa identificar o item de assinatura por `subscription_item_id` **ou** por `product_slug` + `customer_id` (recomendado para integrações externas). O preço/produto deve estar configurado como `usage_type=metered` e a assinatura precisa estar `active` ou `trialing`. Use `idempotency_key` para evitar duplicidade — em caso de chave já vista, a resposta marca `duplicate: true`. Lotes com falhas parciais retornam **207 Multi-Status**."
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UsageRecordCreateRequest"
      responses:
        "200":
          description: Resultado do processamento (registro único ou lote).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageRecordCreateResponse"
        "207":
          description: Resultado do processamento (registro único ou lote).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageRecordCreateResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-usage
      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.
          schema:
            type: string
            format: uuid
  /v1/usage/summary:
    get:
      tags:
        - Uso (Metered)
      summary: Resumo de uso do período
      description: Retorna a agregação de uso de um item de assinatura no período de cobrança vigente (ou em um período arbitrário via `period_start`/`period_end`). Considera registros `set` (substituem) e somatórios de `increment` posteriores. Quando o preço é tiered ou unitário, calcula um custo estimado em `estimated_cost_cents` (÷100 → BRL).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do item de assinatura. Alternativa a `product_slug` + `customer_id`.
          required: false
          name: subscription_item_id
          in: query
        - schema:
            type: string
            description: Slug do produto. Combine com `customer_id`.
          required: false
          name: product_slug
          in: query
        - schema:
            type: string
            description: Identificador externo do cliente. Combine com `product_slug`.
          required: false
          name: customer_id
          in: query
        - schema:
            type: string
            description: "Início do período (ISO 8601). Padrão: `current_period_start` da assinatura."
          required: false
          name: period_start
          in: query
        - schema:
            type: string
            description: "Fim do período (ISO 8601). Padrão: `current_period_end` da assinatura."
          required: false
          name: period_end
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Resumo de uso, período e custo estimado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageSummaryResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-usage-summary
  /v1/usage/snapshots/daily:
    get:
      tags:
        - Uso (Metered)
      summary: Listar snapshots diários de uso
      description: "Lista os snapshots diários de uso da organização. Filtros opcionais: `billing_account_id`, `product_id` e janela `start_date`/`end_date`. Suporta paginação por `limit`/`offset`."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Filtra snapshots por UUID da conta de cobrança.
          required: false
          name: billing_account_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra snapshots por UUID do produto.
          required: false
          name: product_id
          in: query
        - schema:
            type: string
            description: Data/hora inicial do filtro — formato ISO 8601.
          required: false
          name: start_date
          in: query
        - schema:
            type: string
            description: Data/hora final do filtro — formato ISO 8601.
          required: false
          name: end_date
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 1000
            description: "Itens por página. Padrão: `100`. Máximo: `1000`."
          required: false
          name: limit
          in: query
        - schema:
            type:
              - integer
              - "null"
            minimum: 0
            description: "Deslocamento (offset) para paginação. Padrão: `0`."
          required: false
          name: offset
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista de snapshots diários com `meta` contendo `total`, `limit`, `offset`.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageDailySnapshotListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-usage-snapshots-daily
    post:
      tags:
        - Uso (Metered)
      summary: Criar snapshots diários de uso
      description: "Cria snapshots diários de uso, registro único **ou** em lote `{ records: [...] }` com até **100** itens. O conjunto natural (organização, conta de cobrança, produto, data) é único: se já existir, o snapshot é sobrescrito (`overwritten: true`). Resolva a conta por `billing_account_id` **ou** `billing_account_public_id` e o produto por `product_slug` **ou** `product_id` dentro do `product_group_slug` informado. Lotes com falhas parciais retornam **207 Multi-Status**."
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UsageDailySnapshotCreateRequest"
      responses:
        "200":
          description: Resultado do processamento (registro único ou lote).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageDailySnapshotCreateResponse"
        "207":
          description: Resultado do processamento (registro único ou lote).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageDailySnapshotCreateResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-usage-snapshots-daily
      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.
          schema:
            type: string
            format: uuid
  /v1/usage/snapshots/monthly:
    get:
      tags:
        - Uso (Metered)
      summary: Listar snapshots mensais de uso
      description: "Lista os snapshots mensais de uso da organização. Filtros opcionais: `billing_account_id`, `product_id` e janela `start_month`/`end_month`. Suporta paginação por `limit`/`offset`."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: Filtra snapshots por UUID da conta de cobrança.
          required: false
          name: billing_account_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra snapshots por UUID do produto.
          required: false
          name: product_id
          in: query
        - schema:
            type: string
            description: Mês inicial do filtro em formato `YYYY-MM-DD` (primeiro dia do mês).
          required: false
          name: start_month
          in: query
        - schema:
            type: string
            description: Mês final do filtro em formato `YYYY-MM-DD` (primeiro dia do mês).
          required: false
          name: end_month
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 1000
            description: "Itens por página. Padrão: `100`. Máximo: `1000`."
          required: false
          name: limit
          in: query
        - schema:
            type:
              - integer
              - "null"
            minimum: 0
            description: "Deslocamento (offset) para paginação. Padrão: `0`."
          required: false
          name: offset
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista de snapshots mensais com `meta` contendo `total`, `limit`, `offset`.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageMonthlySnapshotListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-usage-snapshots-monthly
    post:
      tags:
        - Uso (Metered)
      summary: Criar snapshots mensais de uso
      description: "Cria snapshots mensais de uso, registro único **ou** em lote `{ records: [...] }` com até **100** itens. O conjunto natural (organização, conta de cobrança, produto, mês) é único: se já existir, o snapshot é sobrescrito (`overwritten: true`). Resolva a conta por `billing_account_id` **ou** `billing_account_public_id` e o produto por `product_slug` **ou** `product_id` dentro do `product_group_slug`. Lotes com falhas parciais retornam **207 Multi-Status**."
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UsageMonthlySnapshotCreateRequest"
      responses:
        "200":
          description: Resultado do processamento (registro único ou lote).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageMonthlySnapshotCreateResponse"
        "207":
          description: Resultado do processamento (registro único ou lote).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageMonthlySnapshotCreateResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-usage-snapshots-monthly
      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.
          schema:
            type: string
            format: uuid
  /v1/tax_rules:
    get:
      tags:
        - Regras Tributárias
      summary: Listar regras tributárias
      description: Retorna uma lista paginada das regras tributárias da organização atual. Use os filtros de `scope`, `company_id`, `service_item_id`, `billing_account_id` e `is_active` para restringir o resultado.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - global
              - organization
              - company
              - service
              - customer
              - municipality
            description: "Filtra pelo escopo: `global`, `organization`, `company`, `service`, `customer` ou `municipality`."
          required: false
          name: scope
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelas regras de uma empresa específica.
          required: false
          name: company_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelas regras de um item de serviço específico.
          required: false
          name: service_item_id
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelas regras de uma conta de cobrança específica.
          required: false
          name: billing_account_id
          in: query
        - schema:
            type: string
            enum:
              - "true"
              - "false"
            description: Quando `true`, retorna apenas regras ativas; quando `false`, apenas inativas.
          required: false
          name: is_active
          in: query
        - schema:
            type: string
            description: Busca textual em `name` e `description`.
          required: false
          name: search
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de regras tributárias.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TaxRuleListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-tax-rules
    post:
      tags:
        - Regras Tributárias
      summary: Criar regra tributária
      description: Cria uma nova regra tributária com seus itens (alíquotas por tributo). O `scope` define o nível de aplicação e a `priority` define a precedência — regras de maior prioridade sobrescrevem as menores. É obrigatório informar ao menos um item em `items`.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TaxRuleCreateRequest"
      responses:
        "201":
          description: Regra tributária criada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TaxRuleResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-tax-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.
          schema:
            type: string
            format: uuid
  /v1/tax_rules/{id}:
    get:
      tags:
        - Regras Tributárias
      summary: Obter regra tributária
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da regra tributária.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe da regra tributária.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TaxRuleResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-tax-rules-id
    patch:
      tags:
        - Regras Tributárias
      summary: Atualizar regra tributária
      description: Atualiza campos editáveis da regra. Quando `items` é informado, **substitui** integralmente a lista de itens existente.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da regra tributária.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TaxRuleUpdateRequest"
      responses:
        "200":
          description: Regra tributária atualizada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TaxRuleResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-tax-rules-id
    delete:
      tags:
        - Regras Tributárias
      summary: Excluir regra tributária
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da regra tributária.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Regra tributária removida.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TaxRuleDeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-tax-rules-id
  /v1/tax_periods:
    get:
      tags:
        - Períodos Tributários
      summary: Listar períodos tributários
      description: Retorna uma lista paginada dos períodos tributários (mensais ou trimestrais) da organização. Permite filtrar por empresa, tipo de período, ano e status.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por empresa emissora.
          required: false
          name: company_id
          in: query
        - schema:
            type: string
            enum:
              - monthly
              - quarterly
            description: "Filtra pelo tipo de período: `monthly` ou `quarterly`."
          required: false
          name: period_type
          in: query
        - schema:
            type: string
            pattern: ^\d+$
            description: "Filtra pelo ano de competência (ex.: `2026`)."
          required: false
          name: year
          in: query
        - schema:
            type: string
            enum:
              - open
              - calculated
              - closed
            description: "Filtra pelo status: `open`, `calculated` ou `closed`."
          required: false
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de períodos tributários.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TaxPeriodListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-tax-periods
    post:
      tags:
        - Períodos Tributários
      summary: Processar período tributário mensal
      description: Cria (ou recupera) o período tributário mensal informado e calcula os impostos devidos (ISS, PIS, COFINS, IRPJ, CSLL, CBS, IBS) com base nas NFes emitidas e nas retenções a compensar. Quando `company_id` é omitido, usa a empresa padrão da organização.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TaxPeriodCreateRequest"
      responses:
        "201":
          description: Período tributário processado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TaxPeriodResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-tax-periods
      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.
          schema:
            type: string
            format: uuid
  /v1/tax_periods/{id}:
    get:
      tags:
        - Períodos Tributários
      summary: Obter período tributário
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do período tributário.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do período tributário.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TaxPeriodResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-tax-periods-id
    patch:
      tags:
        - Períodos Tributários
      summary: Executar ação no período tributário
      description: "Aplica uma ação sobre o período: `recalculate` recalcula os impostos (somente períodos mensais), `close` encerra o período e `reopen` o reabre."
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do período tributário.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TaxPeriodUpdateRequest"
      responses:
        "200":
          description: Período tributário atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TaxPeriodResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-tax-periods-id
    delete:
      tags:
        - Períodos Tributários
      summary: Excluir período tributário
      description: Remove permanentemente o período tributário. Use com cautela — períodos encerrados normalmente não devem ser excluídos.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do período tributário.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Período tributário removido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TaxPeriodDeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-tax-periods-id
  /v1/withholdings:
    get:
      tags:
        - Retenções
      summary: Listar retenções
      description: Retorna uma lista paginada das retenções tributárias da organização atual. Suporta filtros por tipo de tributo, status, retentor, fatura, NF-e e competência.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            enum:
              - iss
              - pis
              - cofins
              - csll
              - irpj
              - irrf
              - csrf
              - inss
              - cbs
              - ibs
            description: "Filtra por tipo de tributo: `iss`, `pis`, `cofins`, `csll`, `irpj`, `irrf`, `csrf`, `inss`, `cbs` ou `ibs`."
          required: false
          name: taxType
          in: query
        - schema:
            type: string
            enum:
              - retained
              - compensated
              - partially_compensated
            description: "Filtra por status: `retained`, `compensated` ou `partially_compensated`."
          required: false
          name: status
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelas retenções de um retentor (conta de cobrança) específico.
          required: false
          name: withholderId
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelas retenções associadas a uma fatura.
          required: false
          name: invoiceId
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra pelas retenções associadas a uma NF-e.
          required: false
          name: nfeId
          in: query
        - schema:
            type: integer
            minimum: 2000
            maximum: 3000
            description: Filtra pelo ano de competência (2000–3000).
          required: false
          name: competenceYear
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 12
            description: Filtra pelo mês de competência (1–12).
          required: false
          name: competenceMonth
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de retenções.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WithholdingListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-withholdings
  /v1/withholdings/convert-to-credits:
    post:
      tags:
        - Retenções
      summary: Converter retenções pendentes em créditos (em lote)
      description: Converte todas as retenções pendentes da organização — opcionalmente restritas por `tax_type` e/ou competência — em créditos. Retorna a lista de créditos gerados, a quantidade total convertida e o valor total em centavos.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WithholdingBulkConvertRequest"
      responses:
        "200":
          description: Lote de retenções convertido em créditos.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WithholdingBulkConvertResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-withholdings-convert-to-credits
      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.
          schema:
            type: string
            format: uuid
  /v1/withholdings/{id}:
    get:
      tags:
        - Retenções
      summary: Obter retenção
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da retenção.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe da retenção.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WithholdingResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-withholdings-id
  /v1/withholdings/{id}/convert-to-credit:
    post:
      tags:
        - Retenções
      summary: Converter retenção em crédito
      description: Converte uma retenção (total ou parcialmente) em um crédito na conta de cobrança derivada da fatura associada — ou, na ausência dela, do próprio retentor. Quando `amount_cents` é omitido, converte o saldo pendente da retenção.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID da retenção.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WithholdingConvertToCreditRequest"
      responses:
        "201":
          description: Crédito gerado a partir da retenção.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WithholdingConvertToCreditResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-withholdings-id-convert-to-credit
  /v1/service_items:
    get:
      tags:
        - Itens de Serviço (LC 116)
      summary: Listar itens de serviço
      description: Retorna uma lista paginada dos itens de serviço (catálogo LC 116/2003) da organização atual. Use os filtros para restringir por empresa, código LC 116, NBS, classificação tributária, indicador de operação ou anexo do Simples.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            format: uuid
            description: Filtra por UUID da empresa emissora associada ao item.
          required: false
          name: company_id
          in: query
        - schema:
            type: string
            description: Busca textual livre em `name`, `internal_code` e `description`.
          required: false
          name: search
          in: query
        - schema:
            type: string
            enum:
              - "true"
              - "false"
            description: "Filtra por status: `true` retorna apenas itens ativos; `false`, apenas inativos."
          required: false
          name: is_active
          in: query
        - schema:
            type: string
            description: "Filtra pelo código LC 116/2003 (ex.: `01.05`)."
          required: false
          name: lc116_code
          in: query
        - schema:
            type: string
            description: Filtra pelo código NBS (Nomenclatura Brasileira de Serviços).
          required: false
          name: nbs_code
          in: query
        - schema:
            type: string
            description: Filtra pelo CST IBS/CBS (`c_class_trib`).
          required: false
          name: c_class_trib
          in: query
        - schema:
            type: string
            description: Filtra pelo Indicador de Operação (`indop_code`) usado na NFS-e SNNFSE.
          required: false
          name: indop_code
          in: query
        - schema:
            type: string
            enum:
              - annex_iii
              - annex_iv
              - annex_v
            description: "Filtra pelo anexo do Simples Nacional aplicável: `annex_iii`, `annex_iv` ou `annex_v`."
          required: false
          name: simples_annex
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de itens de serviço.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ServiceItemListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-service-items
    post:
      tags:
        - Itens de Serviço (LC 116)
      summary: Criar item de serviço
      description: "Cria um item de serviço no catálogo LC 116/2003. O `internal_code` é o identificador interno do item e o `lc116_code` deve seguir o catálogo da Lei Complementar 116/2003 (ex.: `01.05`). Quando `company_id` for informado, a empresa precisa pertencer à organização autenticada."
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ServiceItemCreateRequest"
      responses:
        "201":
          description: Item de serviço criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ServiceItemResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-service-items
      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.
          schema:
            type: string
            format: uuid
  /v1/service_items/{id}:
    get:
      tags:
        - Itens de Serviço (LC 116)
      summary: Obter item de serviço
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do item de serviço.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do item de serviço.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ServiceItemResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-service-items-id
    patch:
      tags:
        - Itens de Serviço (LC 116)
      summary: Atualizar item de serviço
      description: Atualiza campos editáveis do item de serviço. O `internal_code` é imutável depois da criação. Use `is_active=false` para desativar o item sem excluí-lo.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do item de serviço.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ServiceItemUpdateRequest"
      responses:
        "200":
          description: Item de serviço atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ServiceItemResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-service-items-id
    delete:
      tags:
        - Itens de Serviço (LC 116)
      summary: Excluir item de serviço
      description: Exclui o item de serviço permanentemente. Para preservar o histórico em faturas ou NFS-e já emitidas, prefira desativar o item (`PATCH` com `is_active=false`).
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do item de serviço.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Item de serviço excluído.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-service-items-id
  /v1/dashboard_users:
    get:
      tags:
        - Administração da Conta
      summary: Listar usuários do dashboard
      description: Retorna uma lista paginada dos usuários do dashboard (membros do time) da organização atual.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            description: Busca textual por nome ou e-mail.
          required: false
          name: search
          in: query
        - schema:
            type: string
            enum:
              - all
              - active
              - pending_invitation
              - suspended
            description: "Filtra por status: `all` (padrão), `active`, `pending_invitation` ou `suspended`."
          required: false
          name: status
          in: query
        - schema:
            type: string
            description: Filtra pelos usuários que possuem o papel informado (slug do papel).
          required: false
          name: role
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de usuários do dashboard.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DashboardUserListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-dashboard-users
    post:
      tags:
        - Administração da Conta
      summary: Convidar usuário do dashboard
      description: Convida um novo membro para o time da organização. É obrigatório informar `email` e ao menos um papel em `role_ids`. O usuário recebe um convite por e-mail e entra com status `pending_invitation`.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DashboardUserCreateRequest"
      responses:
        "201":
          description: Usuário convidado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DashboardUserResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-dashboard-users
      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.
          schema:
            type: string
            format: uuid
  /v1/dashboard_users/{id}:
    get:
      tags:
        - Administração da Conta
      summary: Obter usuário do dashboard
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do usuário do dashboard.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do usuário do dashboard.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DashboardUserResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-dashboard-users-id
    patch:
      tags:
        - Administração da Conta
      summary: Atualizar usuário do dashboard
      description: Atualiza nome, foto, status, permissões e/ou papéis do usuário. Apenas os campos enviados são alterados.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do usuário do dashboard.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DashboardUserUpdateRequest"
      responses:
        "200":
          description: Usuário atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DashboardUserResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-dashboard-users-id
    delete:
      tags:
        - Administração da Conta
      summary: Remover usuário do dashboard
      description: Remove o usuário do dashboard da organização. Ação irreversível — o usuário precisa ser convidado novamente para recuperar o acesso.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do usuário do dashboard.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Usuário removido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-dashboard-users-id
  /v1/team_roles:
    get:
      tags:
        - Administração da Conta
      summary: Listar papéis do time
      description: Retorna a lista paginada de papéis (roles) configurados para o time da organização. Inclui tanto papéis de sistema (`is_system = true`) quanto papéis customizados.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: integer
            minimum: 1
            description: "Página (começa em 1). Padrão: `1`."
            example: 1
          required: false
          name: page
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: "Itens por página. Padrão: `20`. Máximo: `100`."
            example: 20
          required: false
          name: per_page
          in: query
        - schema:
            type: string
            description: Campo de ordenação. Padrão depende do recurso.
          required: false
          name: sort_by
          in: query
        - schema:
            type: string
            enum:
              - asc
              - desc
            description: "Direção da ordenação. Padrão: `desc`."
          required: false
          name: sort_order
          in: query
        - schema:
            type: string
            description: Busca textual por nome ou slug.
          required: false
          name: search
          in: query
        - schema:
            type:
              - boolean
              - "null"
            description: Filtra por papéis ativos (`true`) ou inativos (`false`).
          required: false
          name: is_active
          in: query
        - schema:
            type:
              - boolean
              - "null"
            description: Filtra por papéis de sistema (`true`) ou customizados (`false`).
          required: false
          name: is_system
          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>
        - 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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada de papéis.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TeamRoleListResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-team-roles
    post:
      tags:
        - Administração da Conta
      summary: Criar papel customizado
      description: Cria um papel customizado. O `slug` deve começar com letra minúscula e conter apenas letras minúsculas, números e `_`.
      security:
        - bearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TeamRoleCreateRequest"
      responses:
        "201":
          description: Papel criado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TeamRoleResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: post-team-roles
      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.
          schema:
            type: string
            format: uuid
  /v1/team_roles/{id}:
    get:
      tags:
        - Administração da Conta
      summary: Obter papel
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do papel.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Detalhe do papel.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TeamRoleResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: get-team-roles-id
    patch:
      tags:
        - Administração da Conta
      summary: Atualizar papel
      description: Atualiza os campos do papel. Apenas os campos enviados são alterados. Papéis de sistema têm restrições adicionais.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do papel.
          required: true
          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.
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TeamRoleUpdateRequest"
      responses:
        "200":
          description: Papel atualizado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TeamRoleResponse"
        "400":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "422":
          description: Corpo da requisição falhou na validação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: patch-team-roles-id
    delete:
      tags:
        - Administração da Conta
      summary: Remover papel
      description: Realiza soft delete do papel. Papéis de sistema (`is_system = true`) não podem ser removidos.
      security:
        - bearerAuth: []
      parameters:
        - schema:
            type: string
            format: uuid
            description: UUID do papel.
          required: true
          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.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Papel removido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeletedResponse"
        "401":
          description: Token bearer ausente ou inválido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "403":
          description: Token válido, porém sem permissão para esta operação.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "404":
          description: Recurso não encontrado na organização atual.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "429":
          description: Limite de requisições excedido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
        "500":
          description: Erro inesperado no servidor.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiV1Error"
      operationId: delete-team-roles-id
webhooks: {}
