Como consumir API de CPF em Astro com endpoints de servidor

Aprenda a consumir a API de consulta de CPF da CPFHub.io em Astro usando server endpoints para validação segura no backend.

Redação CPFHub.io
Redação CPFHub.io
··7 min de leitura
Como consumir API de CPF em Astro com endpoints de servidor

O Astro permite criar server endpoints que executam exclusivamente no backend, o que torna a integração com a API da CPFHub.io segura por design: a chave de API nunca chega ao navegador. Com o adapter de servidor configurado, você cria um arquivo em src/pages/api/ e o Astro expõe uma rota HTTP que seu frontend chama normalmente. A latência da API gira em torno de ~900ms, então configure sempre um timeout adequado nas suas requisições.


1. Pré-requisitos

  • Astro 4+ configurado com npm create astro@latest.

  • Um adapter de servidor instalado (Node.js, Vercel, Netlify ou Cloudflare).

  • Uma conta na CPFHub.io


2. Configure o adapter e variáveis de ambiente

Instale o adapter para Node.js (ou outro de sua escolha):

npx astro add node

Crie o arquivo .env na raiz do projeto:

CPFHUB_API_KEY=SUA_CHAVE_DE_API

No arquivo astro.config.mjs, confirme que o output é server ou hybrid:

import { defineConfig } from 'astro/config';
import node from '@astrojs/node';

export default defineConfig({
    output: 'server',
    adapter: node({
    mode: 'standalone'
    })
});

3. Crie o server endpoint

Crie o arquivo src/pages/api/cpf/[cpf].ts:

import type { APIRoute } from 'astro';

export const GET: APIRoute = async ({ params }) => {
    const cpf = params.cpf?.replace(/\D/g, '');

    if (!cpf || cpf.length !== 11) {
    return new Response(
    JSON.stringify({ error: 'CPF deve conter 11 dígitos' }),
    { status: 400, headers: { 'Content-Type': 'application/json' } }
    );
    }

    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 5000);

    try {
    const response = await fetch(`https://api.cpfhub.io/cpf/${cpf}`, {
    method: 'GET',
    headers: {
    'x-api-key': import.meta.env.CPFHUB_API_KEY,
    'Accept': 'application/json'
    },
    signal: controller.signal
    });

    clearTimeout(timeoutId);

    if (!response.ok) {
    return new Response(
    JSON.stringify({ error: `API retornou HTTP ${response.status}` }),
    { status: response.status, headers: { 'Content-Type': 'application/json' } }
    );
    }

    const data = await response.json();
    return new Response(JSON.stringify(data), {
    status: 200,
    headers: { 'Content-Type': 'application/json' }
    });
    } catch (error) {
    clearTimeout(timeoutId);
    return new Response(
    JSON.stringify({ error: 'Timeout ou falha na consulta' }),
    { status: 502, headers: { 'Content-Type': 'application/json' } }
    );
    }
};

O endpoint fica acessível em GET /api/cpf/{cpf} e a chave de API permanece exclusivamente no servidor.


4. Página com formulário de validação

Crie src/pages/validar-cpf.astro com renderização no servidor:

---
// src/pages/validar-cpf.astro
let resultado = null;
let erro = null;

if (Astro.request.method === 'POST') {
    const formData = await Astro.request.formData();
    const cpf = (formData.get('cpf') as string)?.replace(/\D/g, '');

    if (!cpf || cpf.length !== 11) {
    erro = 'CPF deve conter 11 dígitos';
    } else {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 5000);

    try {
    const response = await fetch(`https://api.cpfhub.io/cpf/${cpf}`, {
    method: 'GET',
    headers: {
    'x-api-key': import.meta.env.CPFHUB_API_KEY,
    'Accept': 'application/json'
    },
    signal: controller.signal
    });

    clearTimeout(timeoutId);

    if (response.ok) {
    resultado = await response.json();
    } else {
    erro = `Erro na consulta: HTTP ${response.status}`;
    }
    } catch (e) {
    clearTimeout(timeoutId);
    erro = 'Timeout ou falha na conexão';
    }
    }
}
---

<html lang="pt-BR">
<head>
    <meta charset="UTF-8" />
    <title>Validar CPF</title>
</head>
<body>
    <h1>Validar CPF</h1>

    <form method="POST">
    <label for="cpf">CPF:</label>
    <input type="text" id="cpf" name="cpf" placeholder="Somente números" maxlength="14" required />
    <button type="submit">Validar</button>
    </form>

    {erro && <p style="color: red;">{erro}</p>}

    {resultado?.success && (
    <div>
    <h2>Resultado</h2>
    <p><strong>Nome:</strong> {resultado.data.name}</p>
    <p><strong>CPF:</strong> {resultado.data.cpf}</p>
    <p><strong>Gênero:</strong> {resultado.data.gender === 'M' ? 'Masculino' : 'Feminino'}</p>
    <p><strong>Data de Nascimento:</strong> {resultado.data.birthDate}</p>
    </div>
    )}
</body>
</html>

5. Teste com cURL

Teste o server endpoint diretamente:

curl -X GET http://localhost:4321/api/cpf/12345678900 \
    -H "Accept: application/json"

Resposta esperada:

{
    "success": true,
    "data": {
    "cpf": "12345678900",
    "name": "João da Silva",
    "nameUpper": "JOÃO DA SILVA",
    "gender": "M",
    "birthDate": "15/06/1990",
    "day": 15,
    "month": 6,
    "year": 1990
    }
}

6. Chamada via JavaScript no cliente

Para uma experiência interativa sem recarregar a página, chame o endpoint via fetch no cliente:

---
// src/pages/consulta-interativa.astro
---

<html lang="pt-BR">
<head>
    <meta charset="UTF-8" />
    <title>Consulta de CPF</title>
</head>
<body>
    <h1>Consulta de CPF</h1>
    <input type="text" id="cpfInput" placeholder="Digite o CPF" maxlength="14" />
    <button id="btnConsultar">Consultar</button>
    <pre id="resultado"></pre>

    <script>
    document.getElementById('btnConsultar').addEventListener('click', async () => {
    const cpf = document.getElementById('cpfInput').value.replace(/\D/g, '');
    const resultadoEl = document.getElementById('resultado');

    if (cpf.length !== 11) {
    resultadoEl.textContent = 'CPF deve conter 11 dígitos';
    return;
    }

    resultadoEl.textContent = 'Consultando...';

    try {
    const response = await fetch(`/api/cpf/${cpf}`);
    const data = await response.json();
    resultadoEl.textContent = JSON.stringify(data, null, 2);
    } catch (error) {
    resultadoEl.textContent = 'Erro na consulta';
    }
    });
    </script>
</body>
</html>

Nesse modelo, o navegador chama /api/cpf/{cpf} e o server endpoint faz a chamada segura à CPFHub.io.


7. Boas práticas

  • Server-only -- A chave de API é acessada via import.meta.env.CPFHUB_API_KEY e nunca exposta ao cliente.

  • Timeout -- Todos os exemplos usam AbortController com 5 segundos de timeout.

  • Validação local -- Verifique o formato do CPF (11 dígitos) antes de chamar a API para economizar consultas.

  • Adapter -- Escolha o adapter adequado ao seu deploy: Node.js para servidores tradicionais, Vercel/Netlify para serverless.

  • Rate limit -- O plano Gratuito oferece 50 consultas/mês. Para produção, o plano Pro inclui 1.000 consultas por R$ 149/mês.


Perguntas frequentes

O que é necessário para implementar validação de CPF no Astro?

Para integrar a API da CPFHub.io no Astro você precisa de: Astro 4+ com um adapter de servidor ativo (Node.js, Vercel ou Netlify), uma variável de ambiente CPFHUB_API_KEY configurada no .env, e um arquivo de endpoint em src/pages/api/. O adapter é o ponto crítico — sem ele o Astro roda no modo estático e os server endpoints não funcionam.

Como garantir que a chave de API não vaze para o navegador?

No Astro, variáveis de ambiente sem o prefixo PUBLIC_ ficam disponíveis somente no servidor. Use import.meta.env.CPFHUB_API_KEY dentro do arquivo de endpoint (.ts) e nunca em componentes .astro que sejam hidratados no cliente. Dessa forma, a chave trafega apenas entre o seu servidor e a API da CPFHub.io.

Como garantir conformidade com a LGPD ao usar uma API de CPF no Astro?

Use o CPF apenas para a finalidade declarada ao titular, não armazene o dado cru em logs de servidor se um identificador interno bastar, e implemente controle de acesso às rotas de consulta. A ANPD orienta que dados de identificação devem ser tratados com o princípio da necessidade — isso inclui APIs de terceiros que processam CPFs em seu nome.

Quanto custa usar a API CPFHub.io além do limite do plano?

O plano Gratuito cobre 50 consultas por mês sem cartão de crédito. Se o limite for ultrapassado, a API não interrompe o serviço: cada consulta adicional é cobrada a R$ 0,15. Para volumes maiores, o plano Pro oferece 1.000 consultas mensais por R$ 149, com o mesmo modelo de excedente.

Qual timeout é recomendado para chamadas à API CPFHub.io no Astro?

Configure pelo menos 5 segundos de timeout via AbortController, como mostrado nos exemplos deste artigo. A latência da API é de ~900ms em condições normais, mas picos de rede ou concorrência podem aumentar esse tempo. Um timeout muito curto gera erros 502 desnecessários no seu endpoint; um timeout muito longo trava requisições na fila do servidor.


Conclusão

O Astro com server endpoints é uma excelente opção para consumir a API da CPFHub.io

Cadastre-se em cpfhub.io

CPFHub.io

Pronto para integrar a API?

50 consultas gratuitas para testar agora. Sem cartão de crédito. Acesso imediato à documentação.

Redação CPFHub.io

Sobre a redação

Redação CPFHub.io

Time editorial especializado em APIs de CPF, identidade digital e compliance no mercado brasileiro. Produzimos guias técnicos, análises regulatórias e tutoriais sobre LGPD e KYC para desenvolvedores e líderes de produto.

WhatsAppFale conosco via WhatsApp