Consultar CNPJ no Lovable

Este guia mostra como colocar a consulta de CNPJ num app feito no Lovable: o usuário digita o CNPJ e o app mostra Razão Social, situação cadastral e atividade principal, vindos da API da CNPJAPI. Você não precisa programar: o guia traz um prompt pronto para colar no Lovable e o código de referência para conferir o que a IA gerou.

O ponto mais importante é onde fica a sua API key. Ela vai num segredo do backend do projeto, nunca no código da página. O guia explica por quê e como.

Antes de começar: crie a conta e gere a API key

Para consultar pela API você precisa de uma API key (uma chave que identifica a sua conta). É de graça para começar.

  1. Acesse https://app.cnpjapi.com.br e crie sua conta no plano gratuito (não pede cartão).
  2. Confirme o seu e-mail e faça login no portal.
  3. Já dentro do portal, gere a sua API key. Ela começa com cnpj_ (por exemplo, cnpj_a1b2c3...). Copie e guarde num lugar seguro - a chave é mostrada uma vez.
  4. Essa chave vai no cabeçalho Authorization, no formato Bearer cnpj_sua_chave, em cada requisição.

Detalhes em Autenticação. Trate a chave como uma senha: quem tem a chave consome a sua cota.

Como funciona no Lovable

O Lovable não tem um conector oficial da CNPJAPI. A integração é uma função no servidor do app, que recebe o CNPJ da tela, chama a API com a sua chave e devolve o resultado. Conforme o tipo de projeto, o Lovable cria essa função como uma Edge Function do Supabase (Lovable Cloud) ou como uma rota de API do próprio app. Para você, tanto faz: o prompt abaixo funciona nos dois casos.

Por que não chamar a API direto da página? Porque tudo o que está na página vai para o navegador do visitante. Uma chave no código da página pode ser copiada por qualquer pessoa que abra o inspetor do navegador, e quem tem a chave gasta a sua cota. Na função do servidor a chave fica guardada como segredo e nunca sai de lá.

A função também precisa aceitar só usuário logado no app. Sem isso, qualquer pessoa que descubra o endereço da função consegue chamá-la e gastar a sua cota do mesmo jeito.

Passo a passo

  1. No seu projeto do Lovable, ative o backend (Lovable Cloud ou a integração com o Supabase) e o login de usuários, se ainda não estiverem ligados.
  2. Cole o prompt abaixo na conversa com o Lovable.
  3. Quando o Lovable pedir a chave da CNPJAPI, cole a sua cnpj_... no campo de segredos que ele mostrar. Não cole a chave na conversa: o que você escreve na conversa fica no histórico do projeto.
  4. Teste com um CNPJ conhecido, por exemplo 00.776.574/0001-56, logado no app.

Prompt pronto para colar

Quero uma tela de consulta de CNPJ usando a API da CNPJAPI (https://api.cnpjapi.com.br).

Regras de segurança (obrigatórias):
- A chave da API é secreta. Guarde-a como segredo do backend com o nome CNPJAPI_KEY
  e me peça o valor pelo campo de segredos. Nunca coloque a chave no código do frontend.
- Crie no servidor uma função chamada consultar-cnpj: uma Edge Function do Supabase ou,
  se este projeto não aceitar Edge Function, uma rota de API do próprio app. Só ela chama
  a CNPJAPI.
- A função só atende usuário logado: tire o token do cabeçalho Authorization da
  requisição, valide com supabase.auth.getUser(token) e responda 401 se não houver
  usuário. A chave pública (anon) do projeto não conta como usuário logado.
- No CORS da função, libere os métodos POST e OPTIONS e os cabeçalhos que o
  supabase-js manda (authorization, x-client-info, apikey, content-type e os
  x-supabase-client-*).
- Qualquer falha inesperada (rede, resposta inválida) responde 502, nunca um erro sem CORS.

Como a função chama a API:
- Recebe { cnpj } no corpo (JSON). Remove pontos, barra, hífen e espaços e converte
  para maiúsculas. Aceita 14 caracteres: 12 letras ou números seguidos de 2 números.
  Se não bater, responde 400 com { erro: "CNPJ inválido." }.
- Faz GET https://api.cnpjapi.com.br/{cnpj} com o cabeçalho
  Authorization: Bearer <valor de CNPJAPI_KEY>.
- Se a API responder 200, devolve o JSON como veio.
- 404: responde 404 com { erro: "CNPJ não encontrado." }.
- 422: responde 400 com { erro: "CNPJ inválido." }.
- 429: responde 429 com uma mensagem no campo erro. O corpo da CNPJAPI traz o campo
  codigo: se for "cota_diaria", use "Limite diário de consultas atingido. Tente de novo
  amanhã."; se for "cota_mensal", use "Cota mensal de consultas atingida."; nos outros
  casos, se o cabeçalho Retry-After tiver até 120 segundos, use "Muitas consultas
  seguidas. Tente de novo em N segundos."; senão, "Limite de consultas atingido. Tente
  mais tarde.".
- Qualquer outro erro: responde 502 com { erro: "Não foi possível consultar o CNPJ agora." }.

Tela:
- Um campo de CNPJ e um botão Consultar, visíveis só para usuário logado.
- Chame a função mandando o token da sessão no cabeçalho Authorization (com
  supabase.functions.invoke, se for Edge Function, ou fetch, se for rota do app).
- Mostre RazaoSocial, NomeFantasia, SituacaoCadastral.Descricao e AtividadePrincipal.Descricao.
- Em caso de erro, leia o JSON da resposta da função e mostre o campo erro.

Código de referência da função

Se quiser conferir o que o Lovable gerou, abaixo está a função na versão Edge Function do Supabase. Se o seu projeto ganhou uma rota de API do app no lugar, o código muda de forma, mas os passos são os mesmos: tirar o token do cabeçalho, conferir o usuário, chamar a API com a chave do segredo e traduzir os erros.

// supabase/functions/consultar-cnpj/index.ts
import { createClient } from "jsr:@supabase/supabase-js@2";

const cors = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Methods": "POST, OPTIONS",
  "Access-Control-Allow-Headers":
    "authorization, x-client-info, apikey, content-type, x-supabase-client-platform, " +
    "x-supabase-client-platform-version, x-supabase-client-runtime, x-supabase-client-runtime-version",
};

const responder = (corpo: unknown, status = 200) =>
  new Response(JSON.stringify(corpo), {
    status,
    headers: { ...cors, "Content-Type": "application/json" },
  });

const mensagensDeCota: Record<string, string> = {
  cota_diaria: "Limite diário de consultas atingido. Tente de novo amanhã.",
  cota_mensal: "Cota mensal de consultas atingida.",
};

Deno.serve(async (req) => {
  if (req.method === "OPTIONS") return new Response("ok", { headers: cors });

  try {
    // 1. Só usuário logado no app (a chave pública do projeto não basta).
    const token = (req.headers.get("Authorization") ?? "").replace(/^Bearer /, "");
    const supabase = createClient(
      Deno.env.get("SUPABASE_URL")!,
      Deno.env.get("SUPABASE_ANON_KEY")!,
    );
    const { data } = await supabase.auth.getUser(token);
    if (!data?.user) return responder({ erro: "Faça login para consultar." }, 401);

    // 2. CNPJ com 14 caracteres (aceita pontuação e o CNPJ alfanumérico).
    const corpo = (await req.json().catch(() => null)) ?? {};
    const limpo = String(corpo.cnpj ?? "").replace(/[.\/\-\s]/g, "").toUpperCase();
    if (!/^[0-9A-Z]{12}[0-9]{2}$/.test(limpo)) {
      return responder({ erro: "CNPJ inválido." }, 400);
    }

    // 3. Chamada à CNPJAPI com a chave guardada no segredo CNPJAPI_KEY.
    const resp = await fetch(`https://api.cnpjapi.com.br/${limpo}`, {
      headers: { Authorization: `Bearer ${Deno.env.get("CNPJAPI_KEY")}` },
    });

    if (resp.ok) return responder(await resp.json());
    if (resp.status === 404) return responder({ erro: "CNPJ não encontrado." }, 404);
    if (resp.status === 422) return responder({ erro: "CNPJ inválido." }, 400);
    if (resp.status === 429) {
      const limite = await resp.json().catch(() => ({}));
      const segundos = parseInt(resp.headers.get("Retry-After") ?? "", 10);
      const erro = mensagensDeCota[limite.codigo] ??
        (segundos > 0 && segundos <= 120
          ? `Muitas consultas seguidas. Tente de novo em ${segundos} segundos.`
          : "Limite de consultas atingido. Tente mais tarde.");
      return responder({ erro }, 429);
    }
    // 401/403 aqui = chave da CNPJAPI errada ou revogada (problema de configuração).
    return responder({ erro: "Não foi possível consultar o CNPJ agora." }, 502);
  } catch {
    return responder({ erro: "Não foi possível consultar o CNPJ agora." }, 502);
  }
});

E, na tela, a chamada à Edge Function com o tratamento de erro (numa rota do app, o mesmo com fetch, mandando Authorization: Bearer com o token da sessão):

const { data, error } = await supabase.functions.invoke("consultar-cnpj", {
  body: { cnpj },
});
if (error) {
  const corpo = await error.context?.json?.().catch(() => null);
  mostrarErro(corpo?.erro ?? "Não foi possível consultar o CNPJ agora.");
} else {
  mostrarEmpresa({
    razaoSocial: data.RazaoSocial,
    nomeFantasia: data.NomeFantasia,
    situacao: data.SituacaoCadastral?.Descricao,
    atividade: data.AtividadePrincipal?.Descricao,
  });
}

Os campos principais da resposta:

  • RazaoSocial - razão social;
  • NomeFantasia - nome fantasia (pode vir vazio);
  • SituacaoCadastral.Descricao - "Ativa", "Baixada", etc.;
  • AtividadePrincipal.Descricao - CNAE principal por extenso.

A lista completa está em Consulta de CNPJ.

"Não encontrado" e limite de requisições

A API responde 404 quando o CNPJ não existe na base pública e 429 quando você passa do limite por minuto, do teto diário ou da cota mensal. A função acima transforma cada caso numa mensagem pronta para a tela.

No plano gratuito da CNPJAPI, a API aceita um número limitado de consultas por minuto, por dia e por mês. Um app aberto para muitos usuários chega nesse limite rápido. Para volumes maiores, faça upgrade para um plano com limite maior e cota mensal folgada. Veja os limites por plano.

Checklist de segurança

  • A chave cnpj_... não aparece em nenhum arquivo do frontend (procure por cnpj_ no código do projeto).
  • A chave está guardada como segredo CNPJAPI_KEY do backend, não na conversa com o Lovable.
  • A função responde 401 quando chamada sem login: saia da conta e chame o endereço da função (ou da rota) direto, sem o token.
  • Se o cadastro do seu app é aberto para qualquer pessoa, lembre que todo usuário cadastrado consome a sua cota. Se o app é interno, desligue o cadastro aberto; se é público, exija confirmação de e-mail.
  • Um usuário logado ainda pode clicar sem parar. Se o app é público, peça ao Lovable um limite por usuário (por exemplo, no máximo 30 consultas por hora por conta, contadas numa tabela do banco).
  • Se a chave vazar, revogue-a no portal e gere outra; depois atualize o segredo.

Observações

  • Não há conector oficial da CNPJAPI no Lovable - é uma função no servidor do app que chama a API.
  • O mesmo caminho serve para qualquer app com backend no Supabase, feito ou não no Lovable.

Próximos passos

Crie sua conta gratuita em https://app.cnpjapi.com.br e coloque a consulta de CNPJ no seu app hoje.