openapi: 3.0.3
info:
  title: Fides — API de dados cadastrais e compliance de CNPJ
  version: 0.1.0
  description: |
    Dados da Receita Federal servidos da nossa infra (latência de milissegundos,
    não proxy) + sinais de compliance: sanções CEIS/CNEP da empresa **e dos
    sócios**, score de risco cadastral e busca reversa por sócio.

    ## Autenticação
    Todas as rotas `/v1/*` exigem o header `X-API-Key`. As respostas incluem
    `X-RateLimit-Limit` e `X-RateLimit-Remaining` (limite mensal do plano).

    | Plano | Consultas/mês | Batch | Busca reversa |
    |---|---|---|---|
    | free | 50 | — | — |
    | starter | 2.500 | — | — |
    | pro | 15.000 | ✔ | — |
    | scale | 60.000 | ✔ | ✔ |
servers:
  - url: https://fides.api.br
    description: produção
  - url: http://localhost:8080
    description: desenvolvimento
security:
  - ApiKeyAuth: []
paths:
  /v1/cnpj/{cnpj}:
    get:
      summary: Ficha completa do CNPJ
      description: Cadastro + endereço + CNAEs traduzidos + quadro societário.
      parameters:
        - $ref: '#/components/parameters/cnpj'
      responses:
        '200':
          description: Ficha do CNPJ
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FichaCNPJ'
        '400': { $ref: '#/components/responses/CNPJInvalido' }
        '401': { $ref: '#/components/responses/NaoAutorizado' }
        '404': { $ref: '#/components/responses/NaoEncontrado' }
        '429': { $ref: '#/components/responses/LimiteExcedido' }
  /v1/cnpj/{cnpj}/sancoes:
    get:
      summary: Sanções CEIS/CNEP da empresa e dos sócios
      description: |
        Checa a empresa (pela raiz do CNPJ — cobre matriz e filiais) e cada
        sócio do QSA (match por CPF parcial + similaridade de nome) contra os
        cadastros de sanções da CGU, atualizados diariamente.
      parameters:
        - $ref: '#/components/parameters/cnpj'
      responses:
        '200':
          description: Sanções encontradas
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResultadoSancoes'
        '400': { $ref: '#/components/responses/CNPJInvalido' }
        '401': { $ref: '#/components/responses/NaoAutorizado' }
        '429': { $ref: '#/components/responses/LimiteExcedido' }
  /v1/cnpj/{cnpj}/score:
    get:
      summary: Score de risco cadastral (0–100)
      description: |
        Agregação transparente de sinais públicos — cada dedução vem
        explicada em `sinais`. Não é score de crédito.
      parameters:
        - $ref: '#/components/parameters/cnpj'
      responses:
        '200':
          description: Score e sinais
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Score'
        '400': { $ref: '#/components/responses/CNPJInvalido' }
        '401': { $ref: '#/components/responses/NaoAutorizado' }
        '404': { $ref: '#/components/responses/NaoEncontrado' }
        '429': { $ref: '#/components/responses/LimiteExcedido' }
  /v1/socios/busca:
    get:
      summary: Busca reversa por sócio (plano scale)
      description: De um nome de pessoa para todas as empresas em que aparece no QSA.
      parameters:
        - name: nome
          in: query
          required: true
          schema: { type: string, minLength: 5 }
          example: JOSE APARECIDO LOPES
        - name: limit
          in: query
          schema: { type: integer, default: 20, maximum: 100 }
      responses:
        '200':
          description: Empresas da pessoa
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResultadoBusca'
        '400': { $ref: '#/components/responses/BuscaInvalida' }
        '401': { $ref: '#/components/responses/NaoAutorizado' }
        '403': { $ref: '#/components/responses/PlanoInsuficiente' }
        '429': { $ref: '#/components/responses/LimiteExcedido' }
  /v1/batch:
    post:
      summary: Consulta em lote (planos pro e scale)
      description: |
        Até 1.000 CNPJs por chamada; um CNPJ inválido não derruba o lote.
        **Cada CNPJ do lote consome 1 consulta da franquia mensal** — um lote
        de 500 debita 500. Se o lote não couber na franquia restante, a
        chamada retorna 429 e nada é debitado além da própria request.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [cnpjs]
              properties:
                cnpjs:
                  type: array
                  maxItems: 1000
                  items: { type: string }
              example: { cnpjs: ["54977486000222", "13451109000197"] }
      responses:
        '200':
          description: Resultados do lote
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResultadoBatch'
        '400': { $ref: '#/components/responses/BuscaInvalida' }
        '401': { $ref: '#/components/responses/NaoAutorizado' }
        '403': { $ref: '#/components/responses/PlanoInsuficiente' }
        '429': { $ref: '#/components/responses/LimiteExcedido' }
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
  parameters:
    cnpj:
      name: cnpj
      in: path
      required: true
      description: CNPJ com 14 dígitos, com ou sem máscara
      schema: { type: string }
      example: "54977486000222"
  responses:
    CNPJInvalido:
      description: CNPJ malformado ou dígitos verificadores inválidos
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Erro' }
    BuscaInvalida:
      description: Parâmetros inválidos
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Erro' }
    NaoAutorizado:
      description: X-API-Key ausente, inválida ou revogada
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Erro' }
    PlanoInsuficiente:
      description: Recurso não incluído no plano da chave
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Erro' }
    NaoEncontrado:
      description: CNPJ não encontrado na base
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Erro' }
    LimiteExcedido:
      description: Limite mensal do plano excedido
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Erro' }
  schemas:
    Erro:
      type: object
      properties:
        error: { type: string }
    CodigoDescricao:
      type: object
      properties:
        codigo: { type: string }
        descricao: { type: string }
    FichaCNPJ:
      type: object
      properties:
        cnpj: { type: string }
        razao_social: { type: string }
        nome_fantasia: { type: string }
        natureza_juridica: { $ref: '#/components/schemas/CodigoDescricao' }
        porte: { $ref: '#/components/schemas/CodigoDescricao' }
        capital_social: { type: number }
        matriz_filial: { $ref: '#/components/schemas/CodigoDescricao' }
        situacao_cadastral:
          type: object
          properties:
            codigo: { type: integer }
            descricao: { type: string }
            data: { type: string, format: date-time }
            motivo: { $ref: '#/components/schemas/CodigoDescricao' }
        data_inicio_atividade: { type: string, format: date-time }
        cnae_principal: { $ref: '#/components/schemas/CodigoDescricao' }
        cnaes_secundarios:
          type: array
          items: { $ref: '#/components/schemas/CodigoDescricao' }
        endereco:
          type: object
          properties:
            tipo_logradouro: { type: string }
            logradouro: { type: string }
            numero: { type: string }
            complemento: { type: string }
            bairro: { type: string }
            cep: { type: string }
            municipio: { type: string }
            uf: { type: string }
        contato:
          type: object
          properties:
            telefone_1: { type: string }
            telefone_2: { type: string }
            email: { type: string }
        quadro_societario:
          type: array
          items:
            type: object
            properties:
              nome: { type: string }
              documento: { type: string, description: CPF mascarado como na origem }
              tipo: { $ref: '#/components/schemas/CodigoDescricao' }
              qualificacao: { $ref: '#/components/schemas/CodigoDescricao' }
              data_entrada: { type: string, format: date-time }
              faixa_etaria: { $ref: '#/components/schemas/CodigoDescricao' }
    SancaoEmpresa:
      type: object
      properties:
        fonte: { type: string, enum: [CEIS, CNEP] }
        categoria: { type: string }
        processo: { type: string }
        valor_multa: { type: number }
        data_inicio: { type: string, format: date-time }
        data_fim: { type: string, format: date-time }
        orgao: { type: string }
        uf_orgao: { type: string }
        esfera: { type: string }
        vigente: { type: boolean }
    ResultadoSancoes:
      type: object
      properties:
        cnpj: { type: string }
        total: { type: integer }
        alerta: { type: boolean, description: true se há sanção vigente }
        empresa:
          type: array
          items: { $ref: '#/components/schemas/SancaoEmpresa' }
        socios:
          type: array
          items:
            allOf:
              - $ref: '#/components/schemas/SancaoEmpresa'
              - type: object
                properties:
                  socio: { type: string }
                  nome_no_cadastro: { type: string }
                  similaridade: { type: number }
    Score:
      type: object
      properties:
        cnpj: { type: string }
        score: { type: integer, minimum: 0, maximum: 100 }
        risco: { type: string, enum: [baixo, medio, alto] }
        sinais:
          type: array
          items:
            type: object
            properties:
              codigo: { type: string }
              descricao: { type: string }
              impacto: { type: integer }
        gerado_em: { type: string, format: date-time }
    ResultadoBusca:
      type: object
      properties:
        nome_buscado: { type: string }
        total: { type: integer }
        resultados:
          type: array
          items:
            type: object
            properties:
              nome_socio: { type: string }
              documento: { type: string }
              similaridade: { type: number }
              cnpj_basico: { type: string }
              razao_social: { type: string }
              qualificacao: { type: string }
              data_entrada: { type: string, format: date-time }
    ResultadoBatch:
      type: object
      properties:
        total: { type: integer }
        sucessos: { type: integer }
        falhas: { type: integer }
        resultados:
          type: array
          items:
            type: object
            properties:
              cnpj: { type: string }
              ficha: { $ref: '#/components/schemas/FichaCNPJ' }
              erro: { type: string }
