{
  "openapi": "3.0.3",
  "info": {
    "title": "NoLapis API Integrador SaaS",
    "version": "1.0.0",
    "description": "API REST para integradores SaaS (ex.: Shipper) consumirem billing, assinaturas e cobrança recorrente\nhospedados no **NoLapis ERP**.\n\n## Modelo de integração\n\n- O integrador é um **cliente fino**: chama esta API e recebe **webhooks** outbound.\n- **Cartão de crédito**: nunca envie PAN/CVV para esta API. Use `POST /assinantes/{ref}/cartao/sessao`\n  e redirecione o usuário para o **checkout hospedado** NoLapis.\n- **Gateway de pagamento**: Asaas **BYOK** — configure a API key em *Admin → Cobrança integrada*.\n- **Autenticação**: API key gerada em *Admin → API Integrador SaaS*.\n\n## Fluxo típico\n\n1. `GET /planos` — catálogo\n2. `POST /planos` — vincular `ref` externa (opcional, se plano já existe no NoLapis)\n3. `POST /assinantes` — criar assinante + contrato recorrente\n4. `POST /assinantes/{ref}/cartao/sessao` — obter `checkout_url`\n5. Redirect do usuário para checkout NoLapis\n6. Receber webhook `cartao.associado` + redirect para `return_url`\n7. Cobranças recorrentes automáticas → webhooks `cobranca.gerada`, `cobranca.paga`, etc.\n",
    "contact": {
      "name": "NoLapis",
      "url": "https://nolapis.com.br"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://api.nolapis.com.br/v1",
      "description": "Produção — API Integrador SaaS"
    },
    {
      "url": "{baseUrl}/v1",
      "description": "Ambiente configurável (NOLAPIS_API_URL)",
      "variables": {
        "baseUrl": {
          "default": "https://api.nolapis.com.br",
          "description": "URL base da API (sem /v1)"
        }
      }
    }
  ],
  "tags": [
    {
      "name": "Planos",
      "description": "Catálogo comercial e vínculo de referências externas"
    },
    {
      "name": "Assinantes",
      "description": "Cadastro de assinantes finais (Pessoa + Contrato recorrente)"
    },
    {
      "name": "Cartão",
      "description": "Checkout hospedado NoLapis (sem tokenização no integrador)"
    },
    {
      "name": "Cobranças",
      "description": "Histórico financeiro de parcelas a receber"
    },
    {
      "name": "Contratos",
      "description": "Upgrade, downgrade e cancelamento"
    },
    {
      "name": "Webhooks outbound",
      "description": "Eventos enviados pelo NoLapis para a URL configurada em *Admin → API Integrador SaaS*.\n\n**Headers enviados:**\n- `Content-Type: application/json`\n- `X-NoLapis-Event`: nome do evento (ex. `cobranca.paga`)\n- `X-NoLapis-Delivery-Id`: UUID de idempotência\n- `X-NoLapis-Signature`: `sha256={hmac}` — HMAC-SHA256 do body JSON com o webhook secret\n\n**Validação:** recalcule `hash_hmac('sha256', $body, $webhook_secret)` e compare com o header.\n"
    }
  ],
  "security": [
    {
      "IntegradorApiKey": []
    }
  ],
  "paths": {
    "/planos": {
      "get": {
        "tags": [
          "Planos"
        ],
        "summary": "Listar planos ativos",
        "description": "Retorna o catálogo de planos do tenant integrador com referências externas quando vinculadas.",
        "operationId": "listarPlanos",
        "responses": {
          "200": {
            "description": "Lista de planos",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Plano"
                      }
                    }
                  }
                },
                "examples": {
                  "sucesso": {
                    "value": {
                      "data": [
                        {
                          "ref": "pro",
                          "nolapis_plano_id": 3,
                          "codigo": "pro",
                          "nome": "Plano Pro",
                          "valor_mensal": 199.9,
                          "valor_anual": 1999.0,
                          "oferece_anual": true,
                          "status": "ATIVO"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NaoAutorizado"
          }
        }
      },
      "post": {
        "tags": [
          "Planos"
        ],
        "summary": "Vincular referência externa a plano existente",
        "description": "O plano deve existir previamente no NoLapis (admin). Esta rota apenas associa\na `ref` usada pelo integrador ao `idplano` interno.\n",
        "operationId": "vincularPlano",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlanoVincularRequest"
              },
              "examples": {
                "vincular": {
                  "value": {
                    "ref": "shipper_pro"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Plano vinculado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Plano"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NaoAutorizado"
          },
          "422": {
            "$ref": "#/components/responses/ErroValidacao"
          }
        }
      }
    },
    "/assinantes": {
      "post": {
        "tags": [
          "Assinantes"
        ],
        "summary": "Criar ou atualizar assinante",
        "description": "Cria/atualiza **Pessoa** (cliente) + **Contrato** de recorrência (`integrador_assinatura`).\nA mesma `ref` identifica pessoa e contrato no integrador.\n",
        "operationId": "upsertAssinante",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssinanteRequest"
              },
              "examples": {
                "pessoa_fisica": {
                  "value": {
                    "ref": "tenant_shipper_12345",
                    "plano_ref": "pro",
                    "cpf_cnpj": "12345678901",
                    "nome": "Maria Silva",
                    "email": "maria@empresa.com",
                    "telefone": "11999998888",
                    "periodicidade": "mensal",
                    "dia_vencimento": 10
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Assinante sincronizado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Assinante"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NaoAutorizado"
          },
          "422": {
            "$ref": "#/components/responses/ErroValidacao"
          }
        }
      }
    },
    "/assinantes/{ref}": {
      "get": {
        "tags": [
          "Assinantes"
        ],
        "summary": "Consultar assinante",
        "operationId": "obterAssinante",
        "parameters": [
          {
            "$ref": "#/components/parameters/RefAssinante"
          }
        ],
        "responses": {
          "200": {
            "description": "Dados do assinante",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Assinante"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NaoAutorizado"
          },
          "404": {
            "$ref": "#/components/responses/NaoEncontrado"
          }
        }
      }
    },
    "/assinantes/{ref}/cartao/sessao": {
      "post": {
        "tags": [
          "Cartão"
        ],
        "summary": "Abrir sessão de checkout de cartão",
        "description": "Retorna `checkout_url` — página **hospedada pelo NoLapis** onde o assinante cadastra o cartão.\nO integrador deve redirecionar o browser ou abrir em iframe.\n\n**Após sucesso:** redirect para `return_url` com query params `status=success`, `session_id`, `ref`.\n**Webhook:** `cartao.associado`.\n\nCheckout público (sem API key): `GET {APP_URL}/integrador/checkout/cartao/{token}`\n(domínio principal do ERP, não o subdomínio api.*)\n",
        "operationId": "criarSessaoCartao",
        "parameters": [
          {
            "$ref": "#/components/parameters/RefAssinante"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CartaoSessaoRequest"
              },
              "examples": {
                "sessao": {
                  "value": {
                    "return_url": "https://app.shipper.com.br/assinatura/cartao-ok",
                    "cancel_url": "https://app.shipper.com.br/assinatura/cartao-cancelado"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Sessão criada",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CartaoSessao"
                    }
                  }
                },
                "examples": {
                  "sucesso": {
                    "value": {
                      "data": {
                        "session_id": "42",
                        "checkout_url": "https://seu-dominio.nolapis.com.br/integrador/checkout/cartao/abc123...",
                        "expires_at": "2026-07-08T20:30:00+00:00"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NaoAutorizado"
          },
          "422": {
            "$ref": "#/components/responses/ErroValidacao"
          }
        }
      }
    },
    "/assinantes/{ref}/cobrancas": {
      "get": {
        "tags": [
          "Cobranças"
        ],
        "summary": "Histórico de cobranças do assinante",
        "description": "Últimas 50 parcelas a receber (NF) vinculadas à pessoa do assinante.",
        "operationId": "listarCobrancasAssinante",
        "parameters": [
          {
            "$ref": "#/components/parameters/RefAssinante"
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de cobranças",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Cobranca"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NaoAutorizado"
          },
          "404": {
            "$ref": "#/components/responses/NaoEncontrado"
          }
        }
      }
    },
    "/contratos/{ref}": {
      "patch": {
        "tags": [
          "Contratos"
        ],
        "summary": "Alterar contrato (plano ou status)",
        "operationId": "alterarContrato",
        "parameters": [
          {
            "$ref": "#/components/parameters/RefContrato"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContratoUpdateRequest"
              },
              "examples": {
                "upgrade": {
                  "value": {
                    "plano_ref": "enterprise",
                    "periodicidade": "anual"
                  }
                },
                "cancelar": {
                  "value": {
                    "status": "CANCELADO"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contrato atualizado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Assinante"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NaoAutorizado"
          },
          "422": {
            "$ref": "#/components/responses/ErroValidacao"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "IntegradorApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API Key",
        "description": "API key gerada em **Admin → API Integrador SaaS**.\nFormato: `nlp_live_...`\n\nAlternativa: header `X-NoLapis-Api-Key: {api_key}`\n"
      }
    },
    "parameters": {
      "RefAssinante": {
        "name": "ref",
        "in": "path",
        "required": true,
        "description": "Referência externa do assinante (mesma enviada no POST /assinantes)",
        "schema": {
          "type": "string",
          "maxLength": 128
        },
        "example": "tenant_shipper_12345"
      },
      "RefContrato": {
        "name": "ref",
        "in": "path",
        "required": true,
        "description": "Referência externa do contrato (geralmente igual à ref do assinante)",
        "schema": {
          "type": "string",
          "maxLength": 128
        },
        "example": "tenant_shipper_12345"
      }
    },
    "responses": {
      "NaoAutorizado": {
        "description": "API key ausente ou inválida",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Erro"
            },
            "example": {
              "message": "API key inválida ou integrador inativo."
            }
          }
        }
      },
      "NaoEncontrado": {
        "description": "Recurso não encontrado",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Erro"
            },
            "example": {
              "message": "Assinante não encontrado."
            }
          }
        }
      },
      "ErroValidacao": {
        "description": "Erro de validação ou regra de negócio",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Erro"
            }
          }
        }
      }
    },
    "schemas": {
      "Erro": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          }
        },
        "required": [
          "message"
        ]
      },
      "Plano": {
        "type": "object",
        "properties": {
          "ref": {
            "type": "string",
            "description": "Referência externa (integrador)"
          },
          "nolapis_plano_id": {
            "type": "integer"
          },
          "codigo": {
            "type": "string",
            "nullable": true
          },
          "nome": {
            "type": "string"
          },
          "valor_mensal": {
            "type": "number",
            "format": "float"
          },
          "valor_anual": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "oferece_anual": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "example": "ATIVO"
          }
        }
      },
      "PlanoVincularRequest": {
        "type": "object",
        "required": [
          "ref"
        ],
        "properties": {
          "ref": {
            "type": "string",
            "maxLength": 128,
            "description": "ID do plano no sistema integrador"
          }
        }
      },
      "AssinanteRequest": {
        "type": "object",
        "required": [
          "ref",
          "plano_ref",
          "cpf_cnpj",
          "nome"
        ],
        "properties": {
          "ref": {
            "type": "string",
            "maxLength": 128,
            "description": "ID único do assinante no integrador"
          },
          "plano_ref": {
            "type": "string",
            "maxLength": 128
          },
          "cpf_cnpj": {
            "type": "string",
            "maxLength": 20,
            "description": "CPF ou CNPJ (somente dígitos ou formatado)"
          },
          "nome": {
            "type": "string",
            "maxLength": 200
          },
          "razao_social": {
            "type": "string",
            "maxLength": 200,
            "nullable": true
          },
          "email": {
            "type": "string",
            "format": "email",
            "nullable": true
          },
          "telefone": {
            "type": "string",
            "maxLength": 30,
            "nullable": true
          },
          "periodicidade": {
            "type": "string",
            "enum": [
              "mensal",
              "anual"
            ],
            "default": "mensal"
          },
          "dia_vencimento": {
            "type": "integer",
            "minimum": 1,
            "maximum": 28,
            "nullable": true
          },
          "cep": {
            "type": "string",
            "nullable": true
          },
          "endereco": {
            "type": "string",
            "nullable": true
          },
          "numero": {
            "type": "string",
            "nullable": true
          },
          "complemento": {
            "type": "string",
            "nullable": true
          },
          "bairro": {
            "type": "string",
            "nullable": true
          },
          "cidade": {
            "type": "string",
            "nullable": true
          },
          "estado": {
            "type": "string",
            "maxLength": 2,
            "nullable": true
          }
        }
      },
      "Assinante": {
        "type": "object",
        "properties": {
          "ref": {
            "type": "string"
          },
          "nolapis_pessoa_id": {
            "type": "integer"
          },
          "nolapis_contrato_id": {
            "type": "integer"
          },
          "plano_ref": {
            "type": "string"
          },
          "plano_nome": {
            "type": "string"
          },
          "status_contrato": {
            "type": "string",
            "enum": [
              "ATIVO",
              "PENDENTE",
              "CANCELADO",
              "INATIVO",
              "TRIAL"
            ]
          },
          "periodicidade": {
            "type": "string",
            "enum": [
              "mensal",
              "anual",
              "trimestral",
              "semestral"
            ]
          },
          "valor": {
            "type": "number",
            "format": "float"
          },
          "cartao": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/CartaoResumo"
              }
            ]
          }
        }
      },
      "CartaoResumo": {
        "type": "object",
        "properties": {
          "bandeira": {
            "type": "string",
            "example": "VISA"
          },
          "final4": {
            "type": "string",
            "example": "4242"
          },
          "status": {
            "type": "string",
            "example": "ATIVO"
          }
        }
      },
      "CartaoSessaoRequest": {
        "type": "object",
        "required": [
          "return_url"
        ],
        "properties": {
          "return_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 500,
            "description": "URL de retorno após cadastro do cartão"
          },
          "cancel_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 500,
            "nullable": true,
            "description": "URL se o usuário cancelar no checkout"
          }
        }
      },
      "CartaoSessao": {
        "type": "object",
        "properties": {
          "session_id": {
            "type": "string"
          },
          "checkout_url": {
            "type": "string",
            "format": "uri",
            "description": "Redirecionar o assinante para esta URL"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Validade da sessão (padrão 15 minutos)"
          }
        }
      },
      "Cobranca": {
        "type": "object",
        "properties": {
          "nolapis_parcela_id": {
            "type": "integer"
          },
          "nolapis_nf_id": {
            "type": "integer"
          },
          "parcela": {
            "type": "integer"
          },
          "valor": {
            "type": "number",
            "format": "float"
          },
          "vencimento": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "PENDENTE, QUITADO, etc."
          },
          "pago_em": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "ContratoUpdateRequest": {
        "type": "object",
        "properties": {
          "plano_ref": {
            "type": "string",
            "maxLength": 128
          },
          "periodicidade": {
            "type": "string",
            "enum": [
              "mensal",
              "anual"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "ATIVO",
              "CANCELADO",
              "INATIVO"
            ]
          }
        }
      },
      "WebhookEnvelope": {
        "type": "object",
        "description": "Corpo JSON enviado pelo NoLapis ao webhook do integrador",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "ID de idempotência da entrega"
          },
          "evento": {
            "type": "string",
            "enum": [
              "cartao.associado",
              "cartao.removido",
              "cobranca.gerada",
              "cobranca.paga",
              "cobranca.falhou",
              "cobranca.vencida",
              "contrato.alterado",
              "assinatura.suspensa",
              "assinatura.reativada",
              "nfse.emitida"
            ]
          },
          "criado_em": {
            "type": "string",
            "format": "date-time"
          },
          "dados": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "id",
          "evento",
          "criado_em",
          "dados"
        ]
      },
      "WebhookCartaoAssociado": {
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEnvelope"
          },
          {
            "type": "object",
            "example": {
              "id": "550e8400-e29b-41d4-a716-446655440000",
              "evento": "cartao.associado",
              "criado_em": "2026-07-08T20:15:00+00:00",
              "dados": {
                "ref": "tenant_shipper_12345",
                "bandeira": "VISA",
                "final4": "4242",
                "status": "ATIVO"
              }
            }
          }
        ]
      },
      "WebhookCobrancaPaga": {
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEnvelope"
          },
          {
            "type": "object",
            "example": {
              "id": "550e8400-e29b-41d4-a716-446655440001",
              "evento": "cobranca.paga",
              "criado_em": "2026-07-08T20:20:00+00:00",
              "dados": {
                "ref": "tenant_shipper_12345",
                "valor": 199.9,
                "pago_em": "2026-07-08T20:20:00+00:00",
                "forma": "credit_card",
                "nolapis_parcela_id": 1001,
                "gateway_payment_id": "pay_abc123"
              }
            }
          }
        ]
      }
    }
  },
  "x-webhooks": {
    "cartao.associado": {
      "post": {
        "tags": [
          "Webhooks outbound"
        ],
        "summary": "Cartão cadastrado no checkout",
        "description": "Enviado após conclusão do checkout hospedado.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookCartaoAssociado"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Integrador confirmou recebimento"
          }
        }
      }
    },
    "cobranca.gerada": {
      "post": {
        "tags": [
          "Webhooks outbound"
        ],
        "summary": "Nova cobrança (parcela) gerada",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEnvelope"
                  },
                  {
                    "example": {
                      "evento": "cobranca.gerada",
                      "dados": {
                        "ref": "tenant_shipper_12345",
                        "valor": 199.9,
                        "vencimento": "2026-08-10",
                        "nolapis_nf_id": 500,
                        "nolapis_parcela_id": 1001,
                        "gateway_payment_id": "pay_abc123"
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "cobranca.paga": {
      "post": {
        "tags": [
          "Webhooks outbound"
        ],
        "summary": "Cobrança quitada",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookCobrancaPaga"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "cobranca.falhou": {
      "post": {
        "tags": [
          "Webhooks outbound"
        ],
        "summary": "Falha na cobrança recorrente",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEnvelope"
                  },
                  {
                    "example": {
                      "evento": "cobranca.falhou",
                      "dados": {
                        "ref": "tenant_shipper_12345",
                        "motivo": "Pagamento recusado pelo emissor.",
                        "nolapis_parcela_id": 1001
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "contrato.alterado": {
      "post": {
        "tags": [
          "Webhooks outbound"
        ],
        "summary": "Contrato alterado (upgrade/downgrade/cancelamento)",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEnvelope"
                  },
                  {
                    "example": {
                      "evento": "contrato.alterado",
                      "dados": {
                        "ref": "tenant_shipper_12345",
                        "plano_ref": "enterprise",
                        "status_contrato": "ATIVO",
                        "periodicidade": "anual",
                        "valor": 999.9
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "nfse.emitida": {
      "post": {
        "tags": [
          "Webhooks outbound"
        ],
        "summary": "NFS-e emitida (roadmap)",
        "description": "Evento previsto — emissão fiscal pós-quitação. Payload sujeito a extensão.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WebhookEnvelope"
                  },
                  {
                    "example": {
                      "evento": "nfse.emitida",
                      "dados": {
                        "ref": "tenant_shipper_12345",
                        "numero": "12345",
                        "pdf_url": "https://...",
                        "xml_url": "https://...",
                        "valor": 199.9
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "x-tagGroups": [
    {
      "name": "API REST (integrador → NoLapis)",
      "tags": [
        "Planos",
        "Assinantes",
        "Cartão",
        "Cobranças",
        "Contratos"
      ]
    },
    {
      "name": "Webhooks (NoLapis → integrador)",
      "tags": [
        "Webhooks outbound"
      ]
    }
  ]
}
