Validação de CPF em .NET/C#: consumindo a API SmartCPF com HttpClient
Tutorial prático de como validar e consultar CPF em aplicações .NET usando HttpClient e a API SmartCPF v2.

Integrar validação de CPF em aplicações .NET costuma envolver bibliotecas locais que apenas verificam o dígito verificador, sem confirmar se o documento realmente existe na base da Receita Federal ou se está regular. A API SmartCPF resolve isso expondo um endpoint REST que valida o formato, consulta a situação cadastral e retorna dados enriquecidos — nome, data de nascimento, e-mails, telefones e endereços — em uma única chamada. Este artigo mostra como consumir o endpoint GET /v2/individuals/{cpf} a partir de uma aplicação .NET usando HttpClient com autenticação via header X-API-KEY.
O endpoint de consulta individual
A SmartCPF disponibiliza a rota GET https://api.smartcpf.com.br/v2/individuals/{cpf}?package=X onde {cpf} pode ser enviado com ou sem formatação (pontos e traço) e o parâmetro package define o nível de detalhe do retorno. A autenticação é obrigatória e feita exclusivamente pelo header X-API-KEY — não há suporte a Authorization: Bearer, query string api_key ou qualquer outro esquema. O resposta segue um envelope padronizado com meta (metadados da consulta como consultId, balance, executionTimeMs) e result (dados do CPF consultado). Códigos de status HTTP: 200 para sucesso, 401 para chave inválida, 404 quando o CPF não é encontrado, 422 para CPF malformado e 429 quando o limite de requisições é excedido.
Vantagens de usar a API SmartCPF em .NET
1. Validação real, não apenas sintática
Bibliotecas locais conferem apenas o algoritmo do dígito verificador. A SmartCPF confirma se o CPF existe na base oficial e qual sua situação (Regular, Suspenso, Cancelado, Nulo).
2. Dados enriquecidos prontos para uso
O retorno já traz nome completo, data de nascimento, idade, nome da mãe, gênero, e-mails, telefones com operadora e tipo, e endereços — dispensando parsing ou cruzamento de bases.
3. Controle de custos via créditos
O campo balance no meta mostra o saldo de créditos em tempo real, permitindo implementar alertas ou bloqueios automáticos antes que a aplicação fique sem quota.
4. Rastreabilidade com consultId
Cada consulta recebe um UUID único (consultId), essencial para auditoria, suporte e idempotência em retentativas.
5. Latência baixa e previsível
O executionTimeMs costuma ficar abaixo de 100 ms, adequado para fluxos síncronos como cadastro de usuários ou checkout.
6. Sem dependências pesadasHttpClient nativo do .NET basta; não há necessidade de SDKs específicos, facilitando manutenção e versionamento.
Desafios ao integrar validação de CPF via API
1. Gestão de chaves de API
A X-API-KEY deve ser armazenada com segurança (Key Vault, variáveis de ambiente, User Secrets) e rotacionada periodicamente — vazamento permite consumo indevido de créditos.
2. Tratamento de erros HTTP específicos
Códigos 401, 404, 422, 429 exigem caminhos distintos: reautenticação, validação de entrada, backoff exponencial ou fila de retentativa.
3. Dependência de rede externa
Falhas de conectividade, DNS ou timeout da API impactam a aplicação. Requer circuit breaker, timeout configurável e fallback (ex.: validação local apenas de dígito como degradação graciosa).
4. Conformidade LGPD
O retorno contém dados pessoais sensíveis. A aplicação deve garantir log mínimo (nunca logar result), criptografia em trânsito e retenção apenas pelo tempo necessário.
5. Versionamento da API
Mudanças no contrato (v2 → v3) podem quebrar integração. Monitorar changelog e testar em staging antes de promover é obrigatório.
Como implementar com a SmartCPF
O exemplo abaixo usa HttpClient configurado via IHttpClientFactory (padrão recomendado no .NET 6+), injeta a API key via IConfiguration, trata códigos de erro comuns e desserializa o envelope de resposta. O pacote System.Text.Json nativo cuida da serialização; nenhum pacote extra é necessário.
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace SmartCpfIntegration
{
/// <summary>
/// Cliente tipado para consumir a API SmartCPF v2.
/// Registre no DI: services.AddHttpClient<SmartCpfClient>();
/// </summary>
public class SmartCpfClient
{
private readonly HttpClient _httpClient;
private readonly string _apiKey;
private readonly ILogger<SmartCpfClient> _logger;
// Modelos mínimos para desserialização do envelope de resposta
public class SmartCpfResponse
{
public Meta Meta { get; set; } = new();
public Result Result { get; set; } = new();
public bool Success { get; set; }
public string[] Errors { get; set; } = Array.Empty<string>();
}
public class Meta
{
public string SearchType { get; set; } = "";
public string ConsultId { get; set; } = "";
public string User { get; set; } = "";
public string Message { get; set; } = "";
public string Ip { get; set; } = "";
public bool Success { get; set; }
public string ApiVersion { get; set; } = "";
public DateTime Date { get; set; }
public double ExecutionTimeMs { get; set; }
public decimal Balance { get; set; }
}
public class Result
{
public string Cpf { get; set; } = "";
public string Name { get; set; } = "";
public string BirthDate { get; set; } = "";
public int Age { get; set; }
public string MotherName { get; set; } = "";
public string Gender { get; set; } = "";
public string Status { get; set; } = "";
public string[] Emails { get; set; } = Array.Empty<string>();
public Phone[] Phones { get; set; } = Array.Empty<Phone>();
public Address[] Addresses { get; set; } = Array.Empty<Address>();
}
public class Phone
{
public string Number { get; set; } = "";
public bool BlockedTelemarketing { get; set; }
public string Operator { get; set; } = "";
public string Type { get; set; } = "";
public bool Whatsapp { get; set; }
}
public class Address
{
public string ZipCode { get; set; } = "";
public string Street { get; set; } = "";
public string Number { get; set; } = "";
public string Complement { get; set; } = "";
public string Neighborhood { get; set; } = "";
public string City { get; set; } = "";
public string State { get; set; } = "";
}
public SmartCpfClient(HttpClient httpClient, IConfiguration configuration, ILogger<SmartCpfClient> logger)
{
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
// BaseAddress já configurada no Program.cs via AddHttpClient
_apiKey = configuration["SmartCpf:ApiKey"]
?? throw new InvalidOperationException("SmartCpf:ApiKey não configurada.");
// Header de autenticação obrigatório em TODA requisição
_httpClient.DefaultRequestHeaders.Add("X-API-KEY", _apiKey);
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
/// <summary>
/// Consulta um CPF na API SmartCPF v2.
/// </summary>
/// <param name="cpf">CPF com ou sem formatação (pontos/traço).</param>
/// <param name="package">Pacote de dados (ex.: "X").</param>
/// <returns>Resposta desserializada ou null em falhas não retentáveis.</returns>
/// <exception cref="HttpRequestException">Erros de rede, 401, 429, 5xx.</exception>
public async Task<SmartCpfResponse?> ConsultarCpfAsync(string cpf, string package = "X")
{
if (string.IsNullOrWhiteSpace(cpf))
throw new ArgumentException("CPF não pode ser vazio.", nameof(cpf));
// Remove formatação para garantir consistência
var cpfLimpo = cpf.Replace(".", "").Replace("-", "").Trim();
var url = $"v2/individuals/{cpfLimpo}?package={Uri.EscapeDataString(package)}";
_logger.LogDebug("Consultando CPF {Cpf} na SmartCPF (package={Package})", cpfLimpo, package);
HttpResponseMessage response;
try
{
response = await _httpClient.GetAsync(url).ConfigureAwait(false);
}
catch (HttpRequestException ex)
{
_logger.LogError(ex, "Falha de rede ao consultar CPF {Cpf}", cpfLimpo);
throw; // Deixa o chamador decidir retentativa (Polly, etc.)
}
// Tratamento por código de status
switch (response.StatusCode)
{
case System.Net.HttpStatusCode.OK:
break; // Sucesso, continua para desserialização
case System.Net.HttpStatusCode.Unauthorized:
_logger.LogError("API Key inválida ou expirada (401).");
throw new HttpRequestException("Autenticação falhou: X-API-KEY inválida.", null, response.StatusCode);
case System.Net.HttpStatusCode.NotFound:
_logger.LogWarning("CPF {Cpf} não encontrado na base (404).", cpfLimpo);
return null; // Não encontrado não é erro de rede — chamador decide o que fazer
case System.Net.HttpStatusCode.UnprocessableEntity:
_logger.LogWarning("CPF {Cpf} malformado (422).", cpfLimpo);
throw new HttpRequestException($"CPF inválido: {cpfLimpo}", null, response.StatusCode);
case System.Net.HttpStatusCode.TooManyRequests:
var retryAfter = response.Headers.RetryAfter?.Delta ?? TimeSpan.FromSeconds(60);
_logger.LogWarning("Rate limit excedido (429). Retry-After: {RetryAfter}", retryAfter);
throw new HttpRequestException("Limite de requisições excedido.", null, response.StatusCode);
default:
var errorBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
_logger.LogError("Erro inesperado {StatusCode}: {Body}", response.StatusCode, errorBody);
throw new HttpRequestException($"Erro da API: {(int)response.StatusCode} - {errorBody}", null, response.StatusCode);
}
// Desserialização com opções tolerantes a caso
var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
var result = JsonSerializer.Deserialize<SmartCpfResponse>(json, options);
if (result is null || !result.Success)
{
_logger.LogWarning("Resposta da API indica falha: {Errors}", result?.Errors ?? Array.Empty<string>());
return null;
}
_logger.LogInformation("Consulta realizada com sucesso. ConsultId: {ConsultId}, Balance: {Balance}, Tempo: {Ms}ms",
result.Meta.ConsultId, result.Meta.Balance, result.Meta.ExecutionTimeMs);
return result;
}
}
// Exemplo de uso em um serviço de aplicação
public class CpfValidationService
{
private readonly SmartCpfClient _client;
private readonly ILogger<CpfValidationService> _logger;
public CpfValidationService(SmartCpfClient client, ILogger<CpfValidationService> logger)
{
_client = client;
_logger = logger;
}
public async Task<bool> ValidarCpfParaCadastroAsync(string cpf)
{
try
{
var response = await _client.ConsultarCpfAsync(cpf, "X");
if (response is null)
{
_logger.LogInformation("CPF {Cpf} não encontrado ou inválido.", cpf);
return false;
}
// Regras de negócio baseadas no retorno
var status = response.Result.Status?.ToUpperInvariant();
var isRegular = status == "REGULAR";
_logger.LogInformation(
"CPF {Cpf} - Nome: {Nome}, Status: {Status}, Idade: {Idade}, E-mails: {EmailCount}, Telefones: {PhoneCount}, Saldo: {Balance}",
cpf,
response.Result.Name,
response.Result.Status,
response.Result.Age,
response.Result.Emails.Length,
response.Result.Phones.Length,
response.Meta.Balance);
// Alerta de saldo baixo (ex.: menos de 5 créditos)
if (response.Meta.Balance < 5)
{
_logger.LogWarning("Saldo de créditos baixo: {Balance}. Considere recarregar.", response.Meta.Balance);
}
return isRegular;
}
catch (HttpRequestException ex) when (ex.StatusCode == System.Net.HttpStatusCode.TooManyRequests)
{
// Exemplo: enfileirar para retentativa posterior
_logger.LogWarning("Rate limit atingido. CPF {Cpf} será reavaliado depois.", cpf);
throw; // Ou retornar false e agendar retry
}
catch (Exception ex)
{
_logger.LogError(ex, "Erro ao validar CPF {Cpf}", cpf);
throw; // Deixa bubblar para middleware global de erro
}
}
}
}
Resposta da API
{
"meta": {
"searchType": "CPF C",
"consultId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"user": "Fulano de Tal",
"message": "CPF encontrado com sucesso",
"ip": "127.0.0.1",
"success": true,
"apiVersion": "v2",
"date": "2026-08-11T14:32:10.123Z",
"executionTimeMs": 74.1,
"balance": 9.77
},
"result": {
"cpf": "111.111.111-11",
"name": "João da Silva",
"birthDate": "10/09/1992",
"age": 33,
"motherName": "Maria da Silva",
"gender": "M",
"status": "Regular",
"emails": ["[email protected]"],
"phones": [
{
"number": "(55) 99999-9999",
"blockedTelemarketing": false,
"operator": "VIVO",
"type": "CELULAR",
"whatsapp": false
}
],
"addresses": []
},
"success": true,
"errors": []
}
O fluxo demonstrado resolve na prática:
- Validação real de existência e regularidade — o campo
result.status("Regular") confirma se o CPF está ativo na Receita Federal. - Rastreabilidade total —
meta.consultId(UUID) permite auditar cada consulta em logs, suporte ou conciliação de faturamento. - Controle de custos automático —
meta.balance(9.77) expõe o saldo de créditos restante, viabilizando alertas proativos antes de interromper a operação. - Dados prontos para KYC/onboarding —
result.name,birthDate,age,motherName,gender,emails,phones(com operadora, tipo e WhatsApp) eaddresseseliminam necessidade de APIs adicionais. - Observabilidade de performance —
meta.executionTimeMs(74.1 ms) permite SLA interno e alertas de degradação de latência.
Por que usar a SmartCPF em aplicações .NET
- Integração nativa sem SDK —
HttpClient+System.Text.Jsondispensam dependências extras e mantêm o projeto leve. - Modelo de créditos previsível — pagamento por consulta com saldo em tempo real no header da resposta, sem surpresas na fatura.
- Escalabilidade horizontal — a API aceita alto volume de requisições paralelas; basta configurar
HttpClientcomPooledConnectionLifetimeeMaxConnectionsPerServeradequados. - Contrato estável e versionado — rota
v2garante que breaking changes só ocorram em nova versão, dando tempo de migração planejada. - Suporte a idempotência — o
consultIdpermite deduplicar retentativas em caso de timeout de rede, evitando cobrança duplicada.
Conclusão
Validar CPF apenas pelo dígito verificador deixa lacunas de fraude e cadastro sujo. Consumir a API SmartCPF via HttpClient em .NET exige poucas linhas de código, traz dados completos para decisões de negócio (onboarding, KYC, antifraude) e expõe métricas operacionais (consultId, balance, executionTimeMs) essenciais para produção. O padrão IHttpClientFactory garante gerenciamento correto de conexões e DNS, enquanto o tratamento explícito de 401, 404, 422 e 429 torna a integração resiliente. Crie sua conta na SmartCPF e faça sua primeira consulta em minutos.
Sobre a redação
Redação Smart CPF
Autor do blog
Mais artigos

Venda nominal de ingressos com validação de CPF: evite fraudes e cambismo
Como implementar validação de CPF em tempo real na venda de ingressos nominais usando a API SmartCPF para coibir fraudes e revenda irregular.

Consumindo a SmartCPF em Supabase Edge Functions
Tutorial técnico: integre a API SmartCPF v2 em Supabase Edge Functions com TypeScript, autenticação X-API-KEY e tratamento de erros.

Validação de CPF em Vercel Edge Functions com SmartCPF
Como implementar validação de CPF em tempo real nas Edge Functions do Vercel usando a API SmartCPF, com autenticação X-API-KEY e baixa latência.

Integrando SmartCPF em Google Cloud Functions com Python
Tutorial prático para consultar CPF via API SmartCPF em Cloud Functions, com autenticação X-API-KEY, tratamento de erros e exemplo completo em Python.
Pronto para validar CPFs em segundos?
Consultas gratuitas para testar agora. Acesso imediato à documentação.