Documentação da API.
Consulta de dados públicos de CNPJ sem chave e sem cadastro, com resposta em JSON. Exemplos em cURL, JavaScript, Python, PHP, Go, Java, C# e outras linguagens.
Introdução
A API do openCNPJ retorna, em JSON, os dados públicos de empresas brasileiras a partir do CNPJ. Ela é gratuita, não exige cadastro nem chave de acesso e funciona por HTTPS.
| Item | Valor |
|---|---|
| Base URL | https://api.opencnpj.com.br |
| Formato | JSON (application/json; charset=utf-8) |
| Autenticação | Nenhuma |
| Limite | 10 requisições por segundo por IP |
| CORS | Liberado (Access-Control-Allow-Origin: *) |
Início rápido
Faça uma requisição GET com o CNPJ de 14 caracteres, sem pontuação:
curl https://api.opencnpj.com.br/cnpj/06990590000123
A resposta é um objeto JSON com os dados da empresa (matriz), do estabelecimento consultado, dos sócios e do Simples Nacional.
Consultar um CNPJ
GET/cnpj/{cnpj}
Parâmetro
| Nome | Onde | Descrição |
|---|---|---|
cnpj | caminho | CNPJ completo com 14 caracteres, sem pontos, barra ou hífen. Aceita o formato numérico e o alfanumérico: os 12 primeiros caracteres podem ser letras A–Z ou números, e os 2 últimos são sempre números. Letras minúsculas são convertidas para maiúsculas. |
Não há parâmetros de consulta nem corpo de requisição. Os métodos aceitos são GET, HEAD e OPTIONS.
Exemplos
cURL
curl -s https://api.opencnpj.com.br/cnpj/06990590000123JavaScript
const cnpj = '06990590000123';
const resposta = await fetch(`https://api.opencnpj.com.br/cnpj/${cnpj}`);
if (!resposta.ok) {
throw new Error(`HTTP ${resposta.status}`);
}
const empresa = await resposta.json();
console.log(empresa.razao_social);
console.log(empresa.estabelecimento.situacao_cadastral);Funciona no navegador e no Node.js 18+ (fetch nativo).
Python
import requests
cnpj = "06990590000123"
resposta = requests.get(f"https://api.opencnpj.com.br/cnpj/{cnpj}", timeout=10)
resposta.raise_for_status()
empresa = resposta.json()
print(empresa["razao_social"])
print(empresa["estabelecimento"]["situacao_cadastral"])Requer a biblioteca requests (pip install requests).
PHP
<?php
$cnpj = '06990590000123';
$ch = curl_init("https://api.opencnpj.com.br/cnpj/{$cnpj}");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
throw new RuntimeException("HTTP {$status}");
}
$empresa = json_decode($body, true);
echo $empresa['razao_social'], PHP_EOL;
echo $empresa['estabelecimento']['situacao_cadastral'], PHP_EOL;Go
package main
import (
"encoding/json"
"fmt"
"net/http"
)
type Empresa struct {
RazaoSocial string `json:"razao_social"`
Estabelecimento struct {
SituacaoCadastral string `json:"situacao_cadastral"`
} `json:"estabelecimento"`
}
func main() {
resp, err := http.Get("https://api.opencnpj.com.br/cnpj/06990590000123")
if err != nil {
panic(err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
panic(fmt.Sprintf("HTTP %d", resp.StatusCode))
}
var empresa Empresa
if err := json.NewDecoder(resp.Body).Decode(&empresa); err != nil {
panic(err)
}
fmt.Println(empresa.RazaoSocial)
fmt.Println(empresa.Estabelecimento.SituacaoCadastral)
}Java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class ConsultaCnpj {
public static void main(String[] args) throws Exception {
String cnpj = "06990590000123";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.opencnpj.com.br/cnpj/" + cnpj))
.header("Accept", "application/json")
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new RuntimeException("HTTP " + response.statusCode());
}
System.out.println(response.body());
}
}Java 11+. Para mapear o JSON em objetos, use Jackson ou Gson.
C#
using System.Net.Http.Json;
using System.Text.Json;
var cnpj = "06990590000123";
using var http = new HttpClient();
var empresa = await http.GetFromJsonAsync<JsonElement>(
$"https://api.opencnpj.com.br/cnpj/{cnpj}");
Console.WriteLine(empresa.GetProperty("razao_social").GetString());
Console.WriteLine(empresa.GetProperty("estabelecimento")
.GetProperty("situacao_cadastral").GetString());.NET 6+. GetFromJsonAsync lança HttpRequestException em respostas de erro.
Ruby
require "net/http"
require "json"
cnpj = "06990590000123"
resposta = Net::HTTP.get_response(URI("https://api.opencnpj.com.br/cnpj/#{cnpj}"))
raise "HTTP #{resposta.code}" unless resposta.is_a?(Net::HTTPSuccess)
empresa = JSON.parse(resposta.body)
puts empresa["razao_social"]
puts empresa.dig("estabelecimento", "situacao_cadastral")Rust
fn main() -> Result<(), Box<dyn std::error::Error>> {
let cnpj = "06990590000123";
let url = format!("https://api.opencnpj.com.br/cnpj/{cnpj}");
let empresa: serde_json::Value = reqwest::blocking::get(url)?
.error_for_status()?
.json()?;
println!("{}", empresa["razao_social"]);
println!("{}", empresa["estabelecimento"]["situacao_cadastral"]);
Ok(())
}Dependências: reqwest = { version = "0.12", features = ["blocking", "json"] } e serde_json = "1".
Dart
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<void> main() async {
const cnpj = '06990590000123';
final resposta = await http.get(Uri.parse('https://api.opencnpj.com.br/cnpj/$cnpj'));
if (resposta.statusCode != 200) {
throw Exception('HTTP ${resposta.statusCode}');
}
final empresa = jsonDecode(utf8.decode(resposta.bodyBytes)) as Map<String, dynamic>;
print(empresa['razao_social']);
print(empresa['estabelecimento']['situacao_cadastral']);
}Requer o pacote http (dart pub add http). Funciona também no Flutter.
Swift
import Foundation
struct Empresa: Decodable {
let razaoSocial: String?
let estabelecimento: Estabelecimento
struct Estabelecimento: Decodable {
let situacaoCadastral: String?
}
}
let url = URL(string: "https://api.opencnpj.com.br/cnpj/06990590000123")!
let (data, response) = try await URLSession.shared.data(from: url)
guard (response as? HTTPURLResponse)?.statusCode == 200 else {
throw URLError(.badServerResponse)
}
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let empresa = try decoder.decode(Empresa.self, from: data)
print(empresa.razaoSocial ?? "")
print(empresa.estabelecimento.situacaoCadastral ?? "")Progress 4GL
USING OpenEdge.Net.HTTP.*.
USING Progress.Json.ObjectModel.*.
DEFINE VARIABLE oClient AS IHttpClient NO-UNDO.
DEFINE VARIABLE oRequest AS IHttpRequest NO-UNDO.
DEFINE VARIABLE oResponse AS IHttpResponse NO-UNDO.
DEFINE VARIABLE oEmpresa AS JsonObject NO-UNDO.
DEFINE VARIABLE cCnpj AS CHARACTER NO-UNDO INITIAL "06990590000123".
oClient = ClientBuilder:Build():Client.
oRequest = RequestBuilder:Get("https://api.opencnpj.com.br/cnpj/" + cCnpj):Request.
oResponse = oClient:Execute(oRequest).
IF oResponse:StatusCode = 200 THEN DO:
oEmpresa = CAST(oResponse:Entity, JsonObject).
MESSAGE oEmpresa:GetCharacter("razao_social") VIEW-AS ALERT-BOX.
END.
ELSE
MESSAGE "Erro HTTP" oResponse:StatusCode VIEW-AS ALERT-BOX.OpenEdge 11.5+ (cliente HTTP OpenEdge.Net). Para HTTPS, os certificados da cadeia precisam estar no certstore do OpenEdge (certutil).
ADVPL
#include "totvs.ch"
User Function OpenCNPJ()
Local cCnpj := "06990590000123"
Local oRest := FWRest():New("https://api.opencnpj.com.br")
Local aHeader := {"Accept: application/json"}
Local oJson := JsonObject():New()
oRest:SetPath("/cnpj/" + cCnpj)
If oRest:Get(aHeader)
oJson:FromJson(oRest:GetResult())
ConOut(oJson["razao_social"])
ConOut(oJson["estabelecimento"]["situacao_cadastral"])
Else
ConOut("Erro: " + oRest:GetLastError())
EndIf
ReturnTOTVS Protheus 12, com as classes FWRest e JsonObject.
Resposta
Quando o CNPJ é encontrado, a API responde 200 OK com o objeto abaixo. Campos sem informação na fonte vêm como null. Listas vazias vêm como [].
Exemplo completo
Resposta real, resumida: cada lista mostra apenas o primeiro item, e nome e CPF do sócio foram substituídos por marcadores.
{
"cnpj_raiz": "06990590",
"razao_social": "GOOGLE BRASIL INTERNET LTDA.",
"capital_social": "200000000.00",
"responsavel_federativo": "",
"observacao": null,
"atualizado_em": null,
"porte": {
"id": "05",
"descricao": "Demais"
},
"natureza_juridica": {
"id": "2062",
"descricao": "Sociedade Empresária Limitada"
},
"qualificacao_do_responsavel": {
"id": 5,
"descricao": "Administrador"
},
"simples": {
"simples": "Não",
"data_opcao_simples": null,
"data_exclusao_simples": null,
"mei": "Não",
"data_opcao_mei": null,
"data_exclusao_mei": null,
"atualizado_em": null
},
"estabelecimento": {
"cnpj": "06990590000123",
"cnpj_raiz": "06990590",
"cnpj_ordem": "0001",
"cnpj_digito_verificador": "23",
"tipo": "Matriz",
"nome_fantasia": null,
"situacao_cadastral": "Ativa",
"data_situacao_cadastral": null,
"motivo_situacao_cadastral": null,
"situacao_especial": null,
"data_situacao_especial": null,
"data_inicio_atividade": "2004-09-01",
"tipo_logradouro": "AVENIDA",
"logradouro": "BRIG FARIA LIMA",
"numero": "3477",
"complemento": "ANDAR 17A20 TSUL 2 17A20",
"bairro": "ITAIM BIBI",
"cep": "04538133",
"nome_cidade_exterior": null,
"ddd1": "11",
"telefone1": "23958400",
"ddd2": null,
"telefone2": null,
"ddd_fax": "11",
"fax": "37971128",
"email": "[email protected]",
"atualizado_em": null,
"cidade": {
"nome": "São Paulo",
"ibge_id": 3550308,
"siafi_id": "7107"
},
"estado": {
"sigla": "SP",
"nome": "São Paulo",
"ibge_id": 35
},
"pais": {
"id": "1058",
"nome": "Brasil",
"iso2": "BR",
"iso3": "BRA",
"comex_id": "105"
},
"atividade_principal": {
"id": "6319400",
"descricao": "Portais, provedores de conteúdo e outros serviços de informação na internet",
"secao": "J",
"divisao": "63",
"grupo": "63.1",
"classe": "63.19-4",
"subclasse": "6319-4/00"
},
"atividades_secundarias": [
{
"id": "4751201",
"descricao": "Comércio varejista especializado de equipamentos e suprimentos de informática",
"secao": "G",
"divisao": "47",
"grupo": "47.5",
"classe": "47.51-2",
"subclasse": "4751-2/01"
}
],
"regimes_tributarios": [
{
"ano": 2024,
"regime_tributario": "LUCRO REAL",
"forma_de_tributacao": "LUCRO REAL",
"atualizado_em": null
}
],
"inscricoes_estaduais": []
},
"socios": [
{
"nome": "NOME DO SÓCIO",
"tipo": "Pessoa Física",
"cpf_cnpj_socio": "***000000**",
"data_entrada": "2014-08-26",
"faixa_etaria": "61 a 70 anos",
"pais_id": "1058",
"nome_representante": null,
"cpf_representante_legal": "***000000**",
"atualizado_em": null,
"qualificacao_socio": {
"id": 5,
"descricao": "Administrador"
},
"qualificacao_representante": null,
"pais": {
"id": "1058",
"nome": "Brasil",
"iso2": "BR",
"iso3": "BRA",
"comex_id": "105"
}
}
]
}
Empresa
Dados da raiz do CNPJ (os 8 primeiros caracteres), comuns à matriz e às filiais.
| Campo | Tipo | Descrição |
|---|---|---|
cnpj_raiz | string | 8 primeiros caracteres do CNPJ |
razao_social | string | null | Nome empresarial |
capital_social | string | null | Valor decimal com 2 casas, como texto (ex.: "1000.00") |
porte | objeto | null | id e descricao: Não informado, Micro Empresa, Empresa de Pequeno Porte ou Demais |
natureza_juridica | objeto | null | id (código) e descricao |
qualificacao_do_responsavel | objeto | null | id (número) e descricao |
responsavel_federativo | string | Ente federativo responsável. Vazio ("") quando não se aplica |
socios | lista | Quadro societário, ver Sócios |
simples | objeto | Opção pelo Simples e MEI, ver Simples Nacional |
estabelecimento | objeto | Unidade consultada, ver Estabelecimento |
observacao, atualizado_em | null | Reservados, sempre null |
Estabelecimento
Dados da unidade (matriz ou filial) do CNPJ consultado.
| Campo | Tipo | Descrição |
|---|---|---|
cnpj | string | CNPJ completo, 14 caracteres |
cnpj_raiz, cnpj_ordem, cnpj_digito_verificador | string | Partes do CNPJ (8 + 4 + 2) |
tipo | string | null | Matriz ou Filial |
nome_fantasia | string | null | Nome fantasia |
situacao_cadastral | string | null | Ativa, Suspensa, Inapta, Baixada ou Nula |
data_situacao_cadastral | data | null | Data da situação atual |
motivo_situacao_cadastral | string | null | Motivo da situação, quando houver |
situacao_especial, data_situacao_especial | string | null | Situação especial e respectiva data |
data_inicio_atividade | data | null | Início das atividades |
atividade_principal | objeto | null | CNAE principal, ver CNAE |
atividades_secundarias | lista | CNAEs secundários, no mesmo formato |
tipo_logradouro, logradouro, numero, complemento, bairro, cep | string | null | Endereço. O CEP vem só com números |
cidade | objeto | null | nome, ibge_id e siafi_id |
estado | objeto | null | sigla, nome e ibge_id |
pais | objeto | null | Ver País |
nome_cidade_exterior | string | null | Cidade, para endereços no exterior |
ddd1, telefone1, ddd2, telefone2, ddd_fax, fax | string | null | Telefones, conforme divulgados na fonte |
email | string | null | E-mail em letras minúsculas |
regimes_tributarios | lista | Itens com ano (número), regime_tributario e forma_de_tributacao |
inscricoes_estaduais | lista | Reservado, sempre [] |
atualizado_em | null | Reservado, sempre null |
Sócios
Cada item da lista socios representa um integrante do quadro societário da matriz.
| Campo | Tipo | Descrição |
|---|---|---|
nome | string | null | Nome do sócio |
tipo | string | null | Pessoa Física, Pessoa Jurídica ou Estrangeiro |
cpf_cnpj_socio | string | null | CPF (mascarado na fonte) ou CNPJ do sócio |
qualificacao_socio | objeto | null | id (número) e descricao |
data_entrada | data | null | Data de entrada na sociedade |
faixa_etaria | string | null | Ex.: 31 a 40 anos |
pais_id, pais | string, objeto | null | País do sócio, ver País |
nome_representante, cpf_representante_legal | string | null | Representante legal, quando houver |
qualificacao_representante | objeto | null | id e descricao do representante |
atualizado_em | null | Reservado, sempre null |
Simples Nacional
| Campo | Tipo | Descrição |
|---|---|---|
simples | string | Sim ou Não |
data_opcao_simples, data_exclusao_simples | data | null | Opção e exclusão do Simples |
mei | string | Sim ou Não |
data_opcao_mei, data_exclusao_mei | data | null | Opção e exclusão do MEI |
atualizado_em | null | Reservado, sempre null |
Objetos auxiliares
CNAE (atividade_principal e itens de atividades_secundarias): id (7 dígitos), secao (letra), divisao, grupo, classe, subclasse (já formatados) e descricao.
País: id (código da Receita Federal), nome, iso2, iso3 e comex_id.
Tipos: datas usam o formato AAAA-MM-DD. CNPJ, CEP e telefones são strings, o que preserva os zeros à esquerda. capital_social é string decimal.
Erros
Os erros seguem o mesmo formato JSON:
{
"status": 404,
"titulo": "CNPJ não encontrado",
"detalhes": "O CNPJ 00000000000000 não foi localizado na base local.",
"validacao": []
}
| Status | Quando acontece |
|---|---|
200 | CNPJ encontrado |
204 | Resposta a OPTIONS (preflight CORS) |
400 | CNPJ com formato inválido |
404 | CNPJ não encontrado na base ou rota inexistente |
405 | Método diferente de GET, HEAD ou OPTIONS |
429 | Limite de requisições excedido |
500 | Erro interno durante a consulta |
Headers
| Header | Descrição |
|---|---|
Content-Type | application/json; charset=utf-8 |
Cache-Control | no-store |
X-Response-Time-Ms | Tempo de processamento na API, em milissegundos |
Server-Timing | O mesmo tempo, no formato app;dur=... |
Access-Control-Allow-Origin | *, então a API pode ser chamada direto do navegador |
O tempo informado é o processamento dentro da API e não inclui a latência de rede até o cliente.
Limites e boas práticas
- O limite é de 10 requisições por segundo por IP. Acima disso, a API responde
429. - Envie o CNPJ sem pontos, barra ou hífen.
- Trate os status
404,429e500e defina um timeout nas requisições. - Se você consulta o mesmo CNPJ com frequência, guarde o resultado em cache no seu sistema.
- Os dados refletem a última base pública processada. Eles não substituem certidões nem a consulta oficial na Receita Federal.
Fonte dos dados
As informações vêm dos dados abertos do CNPJ publicados pela Receita Federal, complementados por bases públicas de localidades e regimes tributários. Veja os detalhes em Origem dos dados.