Antes de migrar uma API gratuita de CPF para uma versão paga, meça confiabilidade, latência, cobertura de campos e adequação ao volume real do negócio durante pelo menos 7 dias — a decisão de migrar deve ser baseada em dados coletados em produção, não em estimativas.
Introdução
Adotar uma API gratuita de CPF é o primeiro passo natural para validar a necessidade do seu negócio. Porém, a transição para uma versão paga deve ser baseada em dados e não em suposições. Muitas empresas migram cedo demais (pagando por capacidade que não usam) ou tarde demais (sofrendo com limitações que já impactam a operação).
Framework de avaliação em quatro dimensões
Uma avaliação completa deve cobrir confiabilidade, performance, funcionalidade e adequação ao negócio.
| Dimensão | O que medir | Peso |
|---|---|---|
| Confiabilidade | Uptime, taxa de erros, consistência | Alto |
| Performance | Latência, throughput, timeout rate | Médio |
| Funcionalidade | Campos retornados, formatos, validações | Médio |
| Adequação | Limites vs demanda, suporte, documentação | Alto |
- Confiabilidade -- a API responde corretamente quando você precisa dela
- Performance -- a API responde rápido o suficiente para o seu caso de uso
- Funcionalidade -- a API retorna os dados que você precisa no formato correto
- Adequação -- os limites gratuitos atendem ao volume atual e projetado do negócio
Implementando o teste de confiabilidade
Monitore a API durante pelo menos 7 dias para capturar padrões de disponibilidade e falhas.
import requests
import time
import json
import os
from datetime import datetime
from statistics import mean, stdev
class MonitorAPI:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.cpfhub.io/cpf"
self.resultados = []
self.cpf_teste = "12345678909"
def executar_teste(self) -> dict:
inicio = time.time()
try:
response = requests.get(
f"{self.base_url}/{self.cpf_teste}",
headers={"x-api-key": self.api_key},
timeout=15
)
duracao = (time.time() - inicio) * 1000
resultado = {
"timestamp": datetime.now().isoformat(),
"status_code": response.status_code,
"duracao_ms": round(duracao, 2),
"sucesso": response.status_code == 200,
"erro": None
}
except requests.exceptions.Timeout:
resultado = {
"timestamp": datetime.now().isoformat(),
"status_code": None,
"duracao_ms": 15000,
"sucesso": False,
"erro": "timeout"
}
except Exception as e:
resultado = {
"timestamp": datetime.now().isoformat(),
"status_code": None,
"duracao_ms": None,
"sucesso": False,
"erro": str(e)
}
self.resultados.append(resultado)
return resultado
def gerar_relatorio(self) -> dict:
if not self.resultados:
return {"erro": "Nenhum teste executado"}
sucessos = [r for r in self.resultados if r["sucesso"]]
falhas = [r for r in self.resultados if not r["sucesso"]]
latencias = [r["duracao_ms"] for r in sucessos if r["duracao_ms"]]
return {
"periodo": {
"inicio": self.resultados[0]["timestamp"],
"fim": self.resultados[-1]["timestamp"],
"total_testes": len(self.resultados)
},
"disponibilidade": {
"uptime": f"{len(sucessos)/len(self.resultados)*100:.2f}%",
"total_sucesso": len(sucessos),
"total_falha": len(falhas)
},
"latencia": {
"media_ms": round(mean(latencias), 2) if latencias else 0,
"desvio_ms": round(stdev(latencias), 2) if len(latencias) > 1 else 0,
"p50_ms": round(sorted(latencias)[len(latencias)//2], 2) if latencias else 0,
"p99_ms": round(sorted(latencias)[int(len(latencias)*0.99)], 2) if latencias else 0,
}
}
| Métrica | Bom | Aceitável | Ruim |
|---|---|---|---|
| Uptime | > 99,5% | 98-99,5% | < 98% |
| Latência média | < 200ms | 200-500ms | > 500ms |
| Latência p99 | < 1s | 1-3s | > 3s |
| Taxa de timeout | < 0,1% | 0,1-1% | > 1% |
- Teste contínuo -- execute o monitor a cada 5 minutos durante pelo menos uma semana
- Períodos de pico -- preste atenção especial ao horário comercial e início de mês
- Variação -- o desvio padrão da latência indica a previsibilidade da API
Teste de funcionalidade e cobertura de dados
Verifique se os campos retornados atendem às necessidades do seu sistema.
class TesteFuncionalidade:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.cpfhub.io/cpf"
def verificar_campos(self, cpf: str) -> dict:
response = requests.get(
f"{self.base_url}/{cpf}",
headers={"x-api-key": self.api_key},
timeout=10
)
if response.status_code != 200:
return {"erro": f"Status {response.status_code}"}
dados = response.json()
if not dados.get("success"):
return {"erro": "CPF não encontrado"}
data = dados["data"]
campos_esperados = {
"cpf": str, "name": str, "nameUpper": str,
"gender": str, "birthDate": str,
"day": str, "month": str, "year": str
}
relatorio = {}
for campo, tipo in campos_esperados.items():
presente = campo in data
tipo_correto = isinstance(data.get(campo), tipo) if presente else False
nao_vazio = bool(data.get(campo)) if presente else False
relatorio[campo] = {
"presente": presente,
"tipo_correto": tipo_correto,
"nao_vazio": nao_vazio,
"valor_exemplo": data.get(campo, "ausente")
}
campos_ok = sum(
1 for r in relatorio.values()
if r["presente"] and r["tipo_correto"] and r["nao_vazio"]
)
return {
"cobertura": f"{campos_ok}/{len(campos_esperados)}",
"campos": relatorio
}
- Verificação de tipos -- garante que a API retorna os tipos corretos para cada campo
- Campos não vazios -- um campo presente mas vazio é tão problemático quanto ausente
- Cobertura -- métrica simples que mostra a porcentagem de campos disponíveis
Definindo critérios de migração para plano pago
Com os dados coletados, estabeleça critérios claros e mensuráveis para decidir a migração.
| Critério | Gatilho para migrar | Medição |
|---|---|---|
| Volume | Atingiu 80% do limite gratuito | Contador mensal |
| SLA necessário | Precisa de > 99,9% uptime | Relatório do monitor |
| Suporte | Precisa de atendimento dedicado | Incidentes sem resolução |
| Funcionalidade | Precisa de campos adicionais | Análise de requisitos |
| Escala | Crescimento de > 30%/mês | Tendência de uso |
class AnaliseMigracao:
def __init__(self, relatorio_monitor: dict, uso_mensal: int, limite_gratuito: int):
self.relatorio = relatorio_monitor
self.uso = uso_mensal
self.limite = limite_gratuito
def avaliar(self) -> dict:
fatores = []
# Fator 1: Volume
uso_percentual = (self.uso / self.limite) * 100
if uso_percentual > 80:
fatores.append({
"fator": "Volume próximo do limite",
"valor": f"{uso_percentual:.0f}%",
"urgencia": "alta"
})
elif uso_percentual > 50:
fatores.append({
"fator": "Volume em crescimento",
"valor": f"{uso_percentual:.0f}%",
"urgencia": "media"
})
# Fator 2: Disponibilidade insuficiente
uptime = float(
self.relatorio["disponibilidade"]["uptime"].replace("%", "")
)
if uptime < 99.0:
fatores.append({
"fator": "Uptime abaixo do aceitável",
"valor": f"{uptime}%",
"urgencia": "alta"
})
# Fator 3: Latência alta
p99 = self.relatorio["latencia"]["p99_ms"]
if p99 > 2000:
fatores.append({
"fator": "Latência p99 acima de 2s",
"valor": f"{p99}ms",
"urgencia": "media"
})
recomendacao = "migrar" if any(
f["urgencia"] == "alta" for f in fatores
) else "monitorar"
return {
"recomendacao": recomendacao,
"fatores": fatores,
"resumo": f"{len(fatores)} fatores identificados"
}
- Critérios objetivos -- decisões baseadas em números, não em sensações
- Urgência graduada -- nem todos os fatores exigem migração imediata
- Monitoramento contínuo -- reavalie mensalmente até que a migração seja justificada
Perguntas frequentes
O que acontece se eu ultrapassar o limite de 50 consultas do plano gratuito?
A API da CPFHub.io não bloqueia a operação nem retorna erro por volume excedido. Ao ultrapassar as 50 consultas mensais do plano gratuito, cada consulta adicional é cobrada automaticamente a R$0,15 — a API continua funcionando normalmente. O histórico de consumo e os custos ficam disponíveis em app.cpfhub.io/settings/billing.
Qual é o sinal mais confiável de que chegou a hora de migrar para o plano pago?
O sinal mais confiável é atingir 80% do limite gratuito de forma recorrente (dois meses consecutivos). A isso some: se os custos de consultas excedentes já ultrapassam R$149/mês, o plano Pro (1.000 consultas + R$0,15/extra) se paga sozinho. O OWASP API Security Guide também recomenda ter SLAs documentados antes de levar APIs para produção crítica.
Por que medir latência p99 e não só a média?
A média mascara picos de lentidão que afetam uma minoria de usuários — mas essa minoria pode corresponder a transações de alto valor ou clientes em momentos críticos. O p99 revela o pior caso real de 99% das requisições; se for acima de 2 segundos, a experiência do usuário já está comprometida em situações de carga moderada.
Quantas consultas devo fazer no período de teste para ter uma amostra confiável?
Pelo menos 200 consultas distribuídas ao longo de 7 dias, cobrindo horários de pico e fora de pico. Para APIs com latência variável (~900ms em média), amostras menores tendem a subestimar o p99 real. Execute o monitor a cada 5 minutos e registre todos os resultados para análise estatística.
Conclusão
Testar uma API gratuita de CPF de forma estruturada antes de migrar para uma versão paga evita tanto o investimento prematuro quanto o risco de operar com uma solução que já não atende. Monitore confiabilidade, meça performance, verifique funcionalidade e defina critérios claros de migração baseados em dados reais. Cadastre-se em cpfhub.io — 50 consultas mensais gratuitas, sem cartão de crédito — e comece a coletar métricas reais da API antes de tomar qualquer decisão de migração.
CPFHub.io
Pronto para integrar a API?
50 consultas gratuitas para testar agora. Sem cartão de crédito. Acesso imediato à documentação.
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.



