# Como implementar o princípio da necessidade ao consultar dados de CPF via API

> Saiba como aplicar o princípio da necessidade da LGPD ao consultar dados de CPF via API, minimizando dados coletados e processados.

**Publicado:** 24/09/2025
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/implementar-principio-necessidade-consultar-cpf-api

---


O princípio da necessidade, previsto no artigo 6°, inciso III da LGPD, exige que sua aplicação solicite, processe e armazene apenas os campos de CPF estritamente necessários para cada finalidade declarada — nada além disso. A CPFHub.io retorna um objeto JSON completo com CPF, nome, gênero e data de nascimento, mas cabe à sua arquitetura filtrar e descartar os campos desnecessários antes de qualquer persistência. Implementar esse controle reduz o risco regulatório e demonstra conformidade ativa à ANPD.

## Introdução

O princípio da necessidade, previsto no artigo 6, inciso III da LGPD, determina que o tratamento de dados pessoais deve se limitar ao mínimo necessário para a realização de suas finalidades. Na prática, isso significa que, ao consultar dados de CPF via API, sua aplicação deve solicitar, armazenar e processar apenas os campos estritamente indispensáveis para a finalidade declarada.

---

## O que é o princípio da necessidade

A LGPD define o princípio da necessidade como a "limitação do tratamento ao mínimo necessário para a realização de suas finalidades, com abrangência dos dados pertinentes, proporcionais e não excessivos em relação às finalidades do tratamento de dados".

### Na prática, isso significa

- Não coletar dados "por precaução" ou "para uso futuro".
- Filtrar campos desnecessários antes de armazenar.
- Limitar o acesso a dados conforme a função do usuário.
- Definir regras claras de retenção por finalidade.
- Documentar a justificativa para cada campo utilizado.

---

## Mapeamento de finalidade vs. campos necessários

Antes de integrar qualquer API de dados de CPF, mapeie quais campos são realmente necessários para cada caso de uso.

| Finalidade | Campos necessários | Campos desnecessários |
|-----------|-------------------|---------------------|
| Validação de CPF | cpf | name, birthDate, gender |
| Verificação de identidade | cpf, name | birthDate, gender |
| Análise de crédito | cpf, name, birthDate | gender |
| Onboarding completo | cpf, name, birthDate, gender | -- |

---

## Implementação de filtro de necessidade

### Proxy de minimização de dados

```python
import requests
import json
import logging
from flask import Flask, request, jsonify
from functools import wraps
from datetime import datetime, timezone

app = Flask(__name__)

logging.basicConfig(
 filename="necessidade_audit.log",
 level=logging.INFO,
 format="%(asctime)s | %(message)s"
)

# Mapeamento de finalidade para campos permitidos
POLITICA_NECESSIDADE = {
 "validacao_cpf": {
 "campos_permitidos": ["cpf"],
 "retencao_horas": 0,
 "descricao": "Apenas validar se o CPF existe"
 },
 "verificacao_identidade": {
 "campos_permitidos": ["cpf", "name"],
 "retencao_horas": 24,
 "descricao": "Verificar identidade do titular"
 },
 "analise_credito": {
 "campos_permitidos": ["cpf", "name", "birthDate"],
 "retencao_horas": 720,
 "descricao": "Análise de crédito para contratação"
 },
 "onboarding": {
 "campos_permitidos": ["cpf", "name", "birthDate", "gender"],
 "retencao_horas": 8760,
 "descricao": "Cadastro completo do cliente"
 }
}

def aplicar_necessidade(func):
 """Middleware que filtra campos de acordo com a finalidade."""
 @wraps(func)
 def wrapper(*args, **kwargs):
 finalidade = request.headers.get("X-Finalidade")

 if not finalidade:
 return jsonify({
 "error": "Header X-Finalidade é obrigatório",
 "finalidades_validas": list(POLITICA_NECESSIDADE.keys())
 }), 400

 if finalidade not in POLITICA_NECESSIDADE:
 return jsonify({
 "error": f"Finalidade '{finalidade}' não reconhecida",
 "finalidades_validas": list(POLITICA_NECESSIDADE.keys())
 }), 400

 # Executar consulta
 resultado = func(*args, **kwargs)

 if isinstance(resultado, tuple):
 dados, status = resultado
 else:
 dados, status = resultado, 200

 # Filtrar campos conforme política de necessidade
 if isinstance(dados, dict) and "data" in dados:
 politica = POLITICA_NECESSIDADE[finalidade]
 campos_permitidos = politica["campos_permitidos"]

 dados_originais = dados["data"]
 dados_filtrados = {
 k: v for k, v in dados_originais.items()
 if k in campos_permitidos
 }

 campos_removidos = [
 k for k in dados_originais.keys()
 if k not in campos_permitidos
 ]

 # Log de auditoria
 logging.info(json.dumps({
 "timestamp": datetime.now(timezone.utc).isoformat(),
 "finalidade": finalidade,
 "campos_retornados": list(dados_filtrados.keys()),
 "campos_removidos": campos_removidos,
 "retencao_horas": politica["retencao_horas"],
 "usuario": request.headers.get("X-User-ID", "anonimo")
 }))

 dados["data"] = dados_filtrados
 dados["_necessidade"] = {
 "finalidade": finalidade,
 "campos_filtrados": campos_removidos,
 "retencao_max_horas": politica["retencao_horas"]
 }

 return jsonify(dados), status

 return wrapper

@app.route("/api/cpf/<cpf>")
@aplicar_necessidade
def consultar_cpf(cpf: str):
 """Consulta CPF com filtro de necessidade aplicado."""

 try:
 response = requests.get(
 f"https://api.cpfhub.io/cpf/{cpf}",
 headers={
 "x-api-key": "SUA_API_KEY",
 "Accept": "application/json"
 },
 timeout=30
 )

 if response.status_code == 200:
 return response.json(), 200

 except requests.exceptions.Timeout:
 return {"error": "Timeout na consulta"}, 504

 return {"error": "CPF não encontrado"}, 404
```

### Testes via cURL com diferentes finalidades

```bash
# Validação simples -- retorna apenas cpf
curl -X GET "https://api.cpfhub.io/cpf/12345678901" \
 -H "x-api-key: SUA_API_KEY" \
 -H "Accept: application/json" \
 -H "X-Finalidade: validacao_cpf" \
 --max-time 30

# Verificação de identidade -- retorna cpf e name
curl -X GET "https://api.cpfhub.io/cpf/12345678901" \
 -H "x-api-key: SUA_API_KEY" \
 -H "Accept: application/json" \
 -H "X-Finalidade: verificacao_identidade" \
 --max-time 30

# Análise de crédito -- retorna cpf, name e birthDate
curl -X GET "https://api.cpfhub.io/cpf/12345678901" \
 -H "x-api-key: SUA_API_KEY" \
 -H "Accept: application/json" \
 -H "X-Finalidade: analise_credito" \
 --max-time 30
```

---

## Controle de retenção por finalidade

Cada finalidade possui um tempo máximo de retenção diferente. Implemente limpeza automática:

```python
from datetime import datetime, timezone, timedelta
import sqlite3

class ControladorRetencao:
 """Controla a retenção de dados de CPF por finalidade."""

 def __init__(self, db_path: str = "retencao.db"):
 self.conn = sqlite3.connect(db_path)
 self._criar_tabela()

 def _criar_tabela(self):
 self.conn.execute("""
 CREATE TABLE IF NOT EXISTS dados_cpf (
 id INTEGER PRIMARY KEY AUTOINCREMENT,
 cpf_hash TEXT NOT NULL,
 finalidade TEXT NOT NULL,
 dados TEXT NOT NULL,
 criado_em TEXT NOT NULL,
 expira_em TEXT NOT NULL
 )
 """)
 self.conn.commit()

 def armazenar(self, cpf_hash: str, finalidade: str, dados: dict, retencao_horas: int):
 """Armazena dados com prazo de expiração automático."""

 agora = datetime.now(timezone.utc)
 expiracao = agora + timedelta(hours=retencao_horas)

 self.conn.execute(
 "INSERT INTO dados_cpf (cpf_hash, finalidade, dados, criado_em, expira_em) VALUES (?, ?, ?, ?, ?)",
 (cpf_hash, finalidade, json.dumps(dados), agora.isoformat(), expiracao.isoformat())
 )
 self.conn.commit()

 def limpar_expirados(self) -> int:
 """Remove dados que ultrapassaram o prazo de retenção."""

 agora = datetime.now(timezone.utc).isoformat()
 cursor = self.conn.execute(
 "DELETE FROM dados_cpf WHERE expira_em < ?",
 (agora,)
 )
 self.conn.commit()
 return cursor.rowcount

 def relatorio_retencao(self) -> list:
 """Gera relatório de dados armazenados por finalidade."""

 cursor = self.conn.execute("""
 SELECT finalidade, COUNT(*) as total,
 MIN(criado_em) as mais_antigo,
 MAX(expira_em) as ultima_expiracao
 FROM dados_cpf
 GROUP BY finalidade
 """)
 return [
 {"finalidade": row[0], "total": row[1],
 "mais_antigo": row[2], "ultima_expiracao": row[3]}
 for row in cursor.fetchall()
 ]
```

---

## Documentação de justificativa

Para cada campo de CPF utilizado, mantenha documentação que justifique a necessidade:

```python
JUSTIFICATIVAS = {
 "cpf": {
 "campo": "CPF (número)",
 "justificativa": "Identificador único necessário para consulta cadastral",
 "base_legal": "execucao_contrato",
 "alternativas_avaliadas": "Nenhuma -- CPF é o único identificador aceito",
 "aprovado_por": "DPO",
 "data_aprovacao": "2025-01-15"
 },
 "name": {
 "campo": "Nome completo",
 "justificativa": "Necessário para verificação de identidade cruzada",
 "base_legal": "execucao_contrato",
 "alternativas_avaliadas": "Iniciais do nome -- insuficiente para verificação",
 "aprovado_por": "DPO",
 "data_aprovacao": "2025-01-15"
 },
 "birthDate": {
 "campo": "Data de nascimento",
 "justificativa": "Necessário para cálculo de elegibilidade em análise de crédito",
 "base_legal": "execucao_contrato",
 "alternativas_avaliadas": "Apenas faixa etária -- insuficiente para scoring",
 "aprovado_por": "DPO",
 "data_aprovacao": "2025-01-15"
 },
 "gender": {
 "campo": "Gênero",
 "justificativa": "Necessário apenas para personalização de comunicação no onboarding",
 "base_legal": "consentimento",
 "alternativas_avaliadas": "Comunicação neutra -- avaliada e descartada por pesquisa UX",
 "aprovado_por": "DPO",
 "data_aprovacao": "2025-01-15"
 }
}
```

---

## Auditoria de conformidade com o princípio

Realize auditorias periódicas para verificar se a política de necessidade está sendo respeitada:

- Compare os campos efetivamente acessados com os campos autorizados por finalidade.
- Identifique padrões de consulta que possam indicar coleta excessiva.
- Revise as justificativas documentadas com o DPO.
- Atualize o mapeamento sempre que novas funcionalidades forem implementadas.

---

## Perguntas frequentes

### O que é o princípio da necessidade na LGPD e por que ele se aplica a consultas de CPF via API?

O princípio da necessidade está previsto no artigo 6°, inciso III da [LGPD](https://www.planalto.gov.br/ccivil_03/_ato2015-2018/2018/lei/l13709.htm) e limita o tratamento de dados pessoais ao mínimo indispensável para a finalidade declarada. Ao consultar CPF via API, a resposta pode conter nome, data de nascimento e gênero — mas se sua finalidade é apenas validar a existência do CPF, armazenar os demais campos viola o princípio. Cada campo extra aumenta o escopo de risco regulatório.

### Como implementar o filtro de necessidade sem modificar a API que consome?

A abordagem recomendada é criar um proxy interno que intercepta a resposta da API de CPF e remove os campos não autorizados antes de retornar ao sistema consumidor. O middleware `aplicar_necessidade` mostrado neste artigo faz exatamente isso: lê o header `X-Finalidade`, aplica a política correspondente e descarta os campos desnecessários, registrando tudo em log de auditoria.

### Como documentar o cumprimento do princípio da necessidade para uma auditoria da ANPD?

Mantenha três artefatos: (1) o mapeamento de finalidade vs. campos permitidos, aprovado pelo DPO; (2) os logs de auditoria com timestamp, finalidade, campos retornados e campos descartados por consulta; (3) as justificativas documentadas para cada campo utilizado, com base legal e alternativas avaliadas. Esses documentos são a evidência concreta de conformidade ativa em caso de inspeção.

### A API CPFHub.io retorna todos os campos sempre, ou é possível solicitar apenas os necessários?

A CPFHub.io retorna o objeto completo `{"cpf","name","nameUpper","gender","birthDate","day","month","year"}` em toda consulta. O filtro de necessidade deve ser aplicado na sua camada de aplicação, descartando os campos que não são necessários para a finalidade declarada antes de qualquer persistência. O plano gratuito oferece 50 consultas mensais sem cartão de crédito; se o limite for ultrapassado, a API cobra R$0,15 por consulta adicional sem bloquear o serviço.

### Leia também

- [IA generativa e fraudes de identidade: por que validação de CPF é mais importante que nunca](https://cpfhub.io/blog/ia-generativa-e-fraudes-de-identidade-por-que-validacao-de-cpf-e-mais-importante-que-nunca)
- [Diferença entre validação de CPF e consulta de CPF: quando usar cada uma](https://cpfhub.io/blog/diferenca-entre-validacao-de-cpf-e-consulta-de-cpf-quando-usar-cada-uma)
- [SLA de API de CPF: níveis de disponibilidade e o que exigir do seu provedor](https://cpfhub.io/blog/sla-api-cpf-niveis-disponibilidade)
- [API de CPF grátis para desenvolvedores: como começar em 5 minutos](https://cpfhub.io/blog/api-cpf-gratis-desenvolvedores-comecar-5-minutos)

---

## Conclusão

O princípio da necessidade é um dos pilares mais práticos da LGPD e tem impacto direto na forma como sistemas consomem APIs de dados de CPF. Ao implementar filtros de necessidade por finalidade, controles de retenção automáticos e documentação de justificativas, sua empresa demonstra conformidade ativa e reduz significativamente os riscos associados ao tratamento de dados pessoais.

A API do [**CPFHub.io**](https://www.cpfhub.io/) entrega os dados necessários em ~900ms e você controla o que sua aplicação armazena — exatamente o que o princípio da necessidade exige.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) — 50 consultas mensais gratuitas, sem cartão de crédito — e comece hoje mesmo.

