> ## Documentation Index
> Fetch the complete documentation index at: https://docs.unifokal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OCR do documento de empresa

> O módulo cnpj_ocr lê o documento societário enviado pela empresa (cartão CNPJ, contrato social, certidão) e extrai os campos impressos.

## OCR do documento de empresa

O módulo `cnpj_ocr` lê o **documento societário** que a empresa enviou (cartão CNPJ, CCMEI, contrato social, alteração contratual registrada na Junta, certidão, estatuto ou ata) e extrai os campos **impressos nele**. Diferente do documento de pessoa, aqui **não há câmera**: é envio de arquivo, e o documento pode ter várias páginas.

> [!WARNING]
>
> **Tudo aqui é o que o PAPEL diz, na data em que o papel foi emitido.** Inclusive `registration_status` e `cnae_principal`: eles são **leitura do documento**, e não consulta à Receita. Para a situação cadastral **vigente** você precisa de `cnpj_registration` ou `cnpj_realtime`, que perguntam à fonte. Tratar o campo lido do papel como situação atual é a confusão mais cara desta seção, porque uma certidão de 2019 diz "ATIVA" para sempre.

**Campo que o documento não trazia simplesmente não aparece no objeto.** Ele não vem `null`: a chave não existe. A única que sempre existe é `cnpj`, e ela pode vir **string vazia**, o que é um resultado **legítimo** e não uma falha: contrato de constituição original não traz CNPJ, porque a empresa ainda não tinha um. Vazio também é o que sai quando o documento cita mais de um CNPJ sem rótulo que desempate, porque **preferimos não responder a chutar** entre a empresa titular e uma sócia pessoa jurídica. Quando resolvemos, o número vem com **14 posições e dígito verificador conferido** (inclusive no formato alfanumérico da Receita), nunca um número que não fecha.

```
// cnpj_ocr no check_details: o que foi LIDO do documento societário
{ "module": "cnpj_ocr", "passed": true, "outcome": "approved", "score": 90,
  "data": { "cnpj": "11222333000181",
            "legal_name": "EMPRESA MOCK LTDA",
            "trade_name": "MOCK",
            "nire": "31201234567",              // registro na Junta, NÃO é o CNPJ
            "document_type": "cartao_cnpj",    // cartao_cnpj | ccmei | contrato_social |
                                                // alteracao_contratual | certidao |
                                                // estatuto_ata | requerimento_empresario | outro
            "registration_status": "ATIVA",      // IMPRESSA no papel, não consultada
            "cnae_principal": "6201-5/01 Desenvolvimento de programas de computador sob encomenda",
            "opening_date": "01/06/2015",
            "partners": [ { "name": "SOCIO MOCK UM", "qualification": "Administrador",
                          "share": "60%" } ] } }
// contrato de constituição original, que ainda não tem CNPJ: resultado VÁLIDO
{ "module": "cnpj_ocr", "passed": true, "outcome": "approved", "score": 90,
  "data": { "cnpj": "", "legal_name": "EMPRESA NOVA LTDA",
            "document_type": "contrato_social", "opening_date": "12/08/2026" } }
```

> [!WARNING]
>
> **O sandbox deste módulo emite os mesmos nomes de campo da produção**, então dá para fixar o shape contra ele. O que muda entre os dois ambientes é só o conteúdo: no sandbox os valores são fixos e nenhum documento é lido de verdade. Continua valendo a regra de cima: campo que o documento não trazia **não aparece** no objeto, então programe por presença de chave e não por posição.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.