Documentação Técnica
API OpenCNPJ
Documentação completa da API pública para consulta de dados empresariais brasileiros. Gratuita, rápida e sem necessidade de autenticação.
Quick Start
URL Base
https://opencnpj.com/api
Autenticação
✅ Não requer autenticação
✅ Completamente gratuita
⚡ Rate limit: 50 req/s
📡 Endpoints Disponíveis
GET
/{cnpj}
Consultar Empresa por CNPJ
Retorna informações completas de uma empresa brasileira através do seu CNPJ.
Parâmetros
Parâmetro | Tipo | Obrigatório | Descrição |
---|---|---|---|
cnpj | string | ✅ Sim | CNPJ da empresa (com ou sem formatação). Deve conter 14 dígitos. |
Exemplo de Requisição
curl -X GET "https://opencnpj.com/api/11222333000181" \
-H "Accept: application/json"
Exemplo de Resposta (200 OK)
{
"cnpj": "11.222.333/0001-81",
"identificador_matriz_filial": 1,
"descricao_matriz_filial": "MATRIZ",
"razao_social": "EMPRESA EXEMPLO LTDA",
"nome_fantasia": "EXEMPLO",
"situacao_cadastral": 2,
"descricao_situacao_cadastral": "ATIVA",
"data_situacao_cadastral": "2020-01-15",
"motivo_situacao_cadastral": 0,
"nome_cidade_exterior": null,
"codigo_natureza_juridica": 2062,
"data_inicio_atividade": "2020-01-15",
"cnae_fiscal": 6201500,
"cnae_fiscal_descricao": "Desenvolvimento de programas de computador sob encomenda",
"descricao_tipo_logradouro": "RUA",
"logradouro": "DAS FLORES",
"numero": "123",
"complemento": "SALA 456",
"bairro": "CENTRO",
"cep": "01234567",
"uf": "SP",
"codigo_municipio": 7107,
"municipio": "SAO PAULO",
"ddd_telefone_1": "11987654321",
"ddd_telefone_2": null,
"ddd_fax": null,
"qualificacao_do_responsavel": 10,
"capital_social": 50000.00,
"porte": "05",
"descricao_porte": "DEMAIS",
"opcao_pelo_simples": true,
"data_opcao_pelo_simples": "2020-02-01",
"data_exclusao_do_simples": null,
"opcao_pelo_mei": false,
"situacao_especial": null,
"data_situacao_especial": null
}
GET
/info
Informações da Base de Dados
Retorna informações sobre a base de dados, incluindo data da última atualização e estatísticas.
Exemplo de Requisição
curl -X GET "https://opencnpj.com/api/info" \
-H "Accept: application/json"
Exemplo de Resposta (200 OK)
{
"ultima_atualizacao": "2024-01-15T10:30:00Z",
"total_empresas": 54789123,
"empresas_ativas": 45123789,
"versao_base": "2024.01",
"fonte": "Receita Federal do Brasil",
"status": "online"
}
📊 Códigos de Status HTTP
Código | Status | Descrição | Possíveis Causas |
---|---|---|---|
200 | Sucesso | Empresa encontrada e dados retornados | Requisição válida com CNPJ existente |
400 | Requisição Inválida | Parâmetros inválidos ou malformados | CNPJ com formato inválido ou ausente |
404 | Não Encontrado | CNPJ não encontrado na base de dados | CNPJ não existe ou não está ativo |
429 | Muitas Requisições | Rate limit excedido | Mais de 50 requisições por segundo |
500 | Erro Interno do Servidor | Erro interno temporário | Problema temporário no servidor |
503 | Service Unavailable | Serviço temporariamente indisponível | Manutenção programada ou sobrecarga |
💻 Exemplos de Implementação
⚡JavaScript
Usando fetch (nativo)
async function consultarCNPJ(cnpj) {
try {
const response = await fetch(`https://opencnpj.com/api/${cnpj}`, {
method: 'GET',
headers: {
'Accept': 'application/json',
'User-Agent': 'MeuApp/1.0'
}
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const empresa = await response.json();
console.log('Empresa encontrada:', empresa);
return empresa;
} catch (error) {
console.error('Erro ao consultar CNPJ:', error);
throw error;
}
}
// Uso
consultarCNPJ('11222333000181')
.then(empresa => {
console.log(`Razão Social: ${empresa.razao_social}`);
console.log(`CNAE: ${empresa.cnae_fiscal_descricao}`);
})
.catch(error => {
console.error('Falha na consulta:', error);
});
Usando axios
const axios = require('axios');
// Configuração do cliente
const apiClient = axios.create({
baseURL: 'https://opencnpj.com/api',
timeout: 30000,
headers: {
'Accept': 'application/json',
'User-Agent': 'MeuApp/1.0'
}
});
// Interceptor para retry automático
apiClient.interceptors.response.use(
response => response,
async error => {
if (error.response?.status === 429) {
await new Promise(resolve => setTimeout(resolve, 2000));
return apiClient.request(error.config);
}
return Promise.reject(error);
}
);
async function consultarCNPJ(cnpj) {
try {
const response = await apiClient.get(`/${cnpj}`);
return response.data;
} catch (error) {
if (error.response?.status === 404) {
throw new Error('CNPJ não encontrado');
} else if (error.response?.status === 400) {
throw new Error('CNPJ inválido');
} else {
throw new Error('Erro na consulta: ' + error.message);
}
}
}
// Uso
consultarCNPJ('11222333000181')
.then(empresa => {
console.log(`Empresa: ${empresa.razao_social}`);
})
.catch(error => {
console.error(error.message);
});
🐍Python
Implementação completa com requests
import requests
import time
from typing import Optional, Dict, Any
class OpenCNPJClient:
def __init__(self, base_url: str = "https://opencnpj.com/api"):
self.base_url = base_url
self.session = requests.Session()
self.session.headers.update({
'Accept': 'application/json',
'User-Agent': 'MeuApp/1.0'
})
self.session.timeout = 30
def consultar_cnpj(self, cnpj: str) -> Optional[Dict[str, Any]]:
"""
Consulta informações de uma empresa pelo CNPJ
Args:
cnpj (str): CNPJ da empresa (com ou sem formatação)
Returns:
Dict com informações da empresa ou None se não encontrada
Raises:
ValueError: Se o CNPJ for inválido
requests.RequestException: Se houver erro na requisição
"""
# Remove formatação do CNPJ
cnpj_limpo = ''.join(filter(str.isdigit, cnpj))
if not self.validar_cnpj(cnpj_limpo):
raise ValueError("CNPJ inválido")
url = f"{self.base_url}/{cnpj_limpo}"
try:
response = self.session.get(url)
if response.status_code == 200:
return response.json()
elif response.status_code == 404:
return None
elif response.status_code == 429:
# Rate limit - aguarda e tenta novamente
time.sleep(2)
response = self.session.get(url)
if response.status_code == 200:
return response.json()
else:
response.raise_for_status()
else:
response.raise_for_status()
except requests.RequestException as e:
raise requests.RequestException(f"Erro na consulta: {e}")
def obter_info(self) -> Dict[str, Any]:
"""Obtém informações sobre a base de dados"""
url = f"{self.base_url}/info"
response = self.session.get(url)
response.raise_for_status()
return response.json()
def validar_cnpj(self, cnpj: str) -> bool:
"""Valida se o CNPJ possui formato correto"""
return len(cnpj) == 14 and cnpj.isdigit()
# Exemplo de uso
if __name__ == "__main__":
client = OpenCNPJClient()
try:
# Consultar empresa
empresa = client.consultar_cnpj("11.222.333/0001-81")
if empresa:
print(f"Razão Social: {empresa['razao_social']}")
print(f"CNAE: {empresa['cnae_fiscal_descricao']}")
print(f"Situação: {empresa['descricao_situacao_cadastral']}")
else:
print("Empresa não encontrada")
# Obter informações da base
info = client.obter_info()
print(f"Última atualização: {info['ultima_atualizacao']}")
except ValueError as e:
print(f"Erro de validação: {e}")
except requests.RequestException as e:
print(f"Erro na requisição: {e}")
☕Java
Implementação com HttpClient (Java 11+)
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class OpenCNPJClient {
private final HttpClient httpClient;
private final ObjectMapper objectMapper;
private final String baseUrl;
public OpenCNPJClient() {
this.baseUrl = "https://opencnpj.com/api";
this.httpClient = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(30))
.build();
this.objectMapper = new ObjectMapper();
}
public JsonNode consultarCNPJ(String cnpj) throws Exception {
// Remove formatação do CNPJ
String cnpjLimpo = cnpj.replaceAll("[^0-9]", "");
if (!validarCNPJ(cnpjLimpo)) {
throw new IllegalArgumentException("CNPJ inválido");
}
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + "/" + cnpjLimpo))
.header("Accept", "application/json")
.header("User-Agent", "MeuApp/1.0")
.timeout(Duration.ofSeconds(30))
.GET()
.build();
try {
HttpResponse<String> response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
switch (response.statusCode()) {
case 200:
return objectMapper.readTree(response.body());
case 404:
return null;
case 429:
// Rate limit - aguarda e tenta novamente
Thread.sleep(2000);
HttpResponse<String> retryResponse = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
if (retryResponse.statusCode() == 200) {
return objectMapper.readTree(retryResponse.body());
}
throw new RuntimeException("Rate limit excedido");
default:
throw new RuntimeException("Erro HTTP: " + response.statusCode());
}
} catch (Exception e) {
throw new Exception("Erro na consulta: " + e.getMessage(), e);
}
}
public CompletableFuture<JsonNode> consultarCNPJAsync(String cnpj) {
return CompletableFuture.supplyAsync(() -> {
try {
return consultarCNPJ(cnpj);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
public JsonNode obterInfo() throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + "/info"))
.header("Accept", "application/json")
.timeout(Duration.ofSeconds(30))
.GET()
.build();
HttpResponse<String> response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
return objectMapper.readTree(response.body());
} else {
throw new RuntimeException("Erro HTTP: " + response.statusCode());
}
}
private boolean validarCNPJ(String cnpj) {
return cnpj != null && cnpj.length() == 14 && cnpj.matches("\\d+");
}
// Exemplo de uso
public static void main(String[] args) {
OpenCNPJClient client = new OpenCNPJClient();
try {
// Consulta síncrona
JsonNode empresa = client.consultarCNPJ("11.222.333/0001-81");
if (empresa != null) {
System.out.println("Razão Social: " +
empresa.get("razao_social").asText());
System.out.println("CNAE: " +
empresa.get("cnae_fiscal_descricao").asText());
// Processar sócios (QSA)
if (empresa.has("QSA") && empresa.get("QSA").isArray()) {
System.out.println("Sócios:");
empresa.get("QSA").forEach(socio -> {
System.out.println("- " + socio.get("nome").asText());
});
}
} else {
System.out.println("Empresa não encontrada");
}
// Consulta assíncrona
client.consultarCNPJAsync("11222333000181")
.thenAccept(result -> {
if (result != null) {
System.out.println("Consulta assíncrona concluída");
}
})
.join();
} catch (Exception e) {
System.err.println("Erro: " + e.getMessage());
}
}
}
🔧 Guia de Integração
✅ Boas Práticas
- •Implemente cache local para evitar requisições desnecessárias
- •Valide o CNPJ antes de fazer a requisição
- •Trate todos os códigos de erro adequadamente
- •Use timeouts apropriados (30s recomendado)
- •Implemente retry com backoff exponencial
- •Monitore o rate limit através dos headers
❌ Evite Fazer
- •Não faça mais de 50 requisições por segundo
- •Não ignore os códigos de erro HTTP
- •Não faça requisições paralelas excessivas
- •Não armazene dados por mais de 30 dias
- •Não use a API para scraping em massa
- •Não redistribua os dados sem autorização
⚖️ Limitações e Termos de Uso
Limitações Técnicas
- • Rate Limit: 50 requisições/segundo por IP
- • Timeout: 30 segundos por requisição
- • Dados: Atualizados mensalmente
- • Disponibilidade: 99.5% SLA (não garantido)
- • Cache: Recomendado cache local de 24h
Termos de Uso
- • Uso gratuito para fins legítimos
- • Proibido uso para spam ou atividades ilegais
- • Dados são públicos da Receita Federal
- • Sem garantias de disponibilidade
- • Respeite os limites de rate limiting
🤝 Suporte e Comunidade
Precisa de ajuda? Nossa comunidade está aqui para apoiar!