# Como integrar validação de CPF em Azure Functions com C#

> Aprenda a criar uma Azure Function em C# que consome a API de CPF da CPFHub.io com HttpClient, Key Vault e deploy automatizado.

**Publicado:** 20/09/2026
**Autor:** Redação CPFHub.io
**URL:** https://www.cpfhub.io/blog/como-integrar-validacao-cpf-azure-functions-csharp

---


Para integrar validação de CPF em Azure Functions com C#, crie um HTTP trigger que recebe o número do documento via rota, consulta a API da CPFHub.io usando `HttpClient` com o header `x-api-key` e retorna os dados do titular em JSON. A chave de API deve ser armazenada no Azure Key Vault e injetada via `DefaultAzureCredential` durante a inicialização do host. A [documentação oficial das Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-overview) cobre as opções de trigger HTTP, injeção de dependência e planos de consumo disponíveis para o ecossistema .NET.

---

## Estrutura do projeto

Crie o projeto usando o Azure Functions Core Tools:

```bash
func init CpfValidator --dotnet --worker-runtime dotnet-isolated
cd CpfValidator
dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Http
dotnet add package Azure.Identity
dotnet add package Azure.Security.KeyVault.Secrets
```

A estrutura resultante:

```
CpfValidator/
 Models/
 CpfApiResponse.cs
 CpfValidationResult.cs
 Services/
 CpfHubService.cs
 Functions/
 ValidarCpfFunction.cs
 Program.cs
 host.json
 local.settings.json
```

---

## Modelos de dados

Defina os modelos que representam a resposta da API e o resultado da validação:

```csharp
// Models/CpfApiResponse.cs
using System.Text.Json.Serialization;

namespace CpfValidator.Models;

public class CpfApiResponse
{
 [JsonPropertyName("success")]
 public bool Success { get; set; }

 [JsonPropertyName("data")]
 public CpfData? Data { get; set; }
}

public class CpfData
{
 [JsonPropertyName("cpf")]
 public string Cpf { get; set; } = string.Empty;

 [JsonPropertyName("name")]
 public string Name { get; set; } = string.Empty;

 [JsonPropertyName("nameUpper")]
 public string NameUpper { get; set; } = string.Empty;

 [JsonPropertyName("gender")]
 public string Gender { get; set; } = string.Empty;

 [JsonPropertyName("birthDate")]
 public string BirthDate { get; set; } = string.Empty;

 [JsonPropertyName("day")]
 public int Day { get; set; }

 [JsonPropertyName("month")]
 public int Month { get; set; }

 [JsonPropertyName("year")]
 public int Year { get; set; }
}

public class CpfValidationResult
{
 public bool Valido { get; set; }
 public string? Nome { get; set; }
 public string? Genero { get; set; }
 public string? DataNascimento { get; set; }
 public string? Erro { get; set; }
}
```

---

## Serviço de consulta de CPF

O serviço encapsula a lógica de comunicação com a API, utilizando HttpClient com timeout configurado:

```csharp
// Services/CpfHubService.cs
using System.Net.Http.Json;
using System.Text.RegularExpressions;
using CpfValidator.Models;
using Microsoft.Extensions.Logging;

namespace CpfValidator.Services;

public interface ICpfHubService
{
 Task<CpfValidationResult> ConsultarAsync(string cpf);
}

public class CpfHubService : ICpfHubService
{
 private readonly HttpClient _httpClient;
 private readonly ILogger<CpfHubService> _logger;
 private const string BaseUrl = "https://api.cpfhub.io/cpf";

 public CpfHubService(HttpClient httpClient, ILogger<CpfHubService> logger)
 {
 _httpClient = httpClient;
 _httpClient.Timeout = TimeSpan.FromSeconds(10);
 _logger = logger;
 }

 public async Task<CpfValidationResult> ConsultarAsync(string cpf)
 {
 var cpfLimpo = Regex.Replace(cpf, @"\D", "");

 if (cpfLimpo.Length != 11)
 {
 return new CpfValidationResult
 {
 Valido = false,
 Erro = "CPF deve conter 11 digitos"
 };
 }

 if (cpfLimpo.Distinct().Count() == 1)
 {
 return new CpfValidationResult
 {
 Valido = false,
 Erro = "CPF invalido"
 };
 }

 try
 {
 using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));

 var response = await _httpClient.GetAsync(
 $"{BaseUrl}/{cpfLimpo}",
 cts.Token
 );

 response.EnsureSuccessStatusCode();

 var resultado = await response.Content
 .ReadFromJsonAsync<CpfApiResponse>(cancellationToken: cts.Token);

 if (resultado is null || !resultado.Success || resultado.Data is null)
 {
 return new CpfValidationResult
 {
 Valido = false,
 Erro = "CPF nao encontrado"
 };
 }

 return new CpfValidationResult
 {
 Valido = true,
 Nome = resultado.Data.Name,
 Genero = resultado.Data.Gender,
 DataNascimento = resultado.Data.BirthDate
 };
 }
 catch (TaskCanceledException)
 {
 _logger.LogWarning("Timeout na consulta do CPF {Cpf}", cpfLimpo);
 return new CpfValidationResult
 {
 Valido = false,
 Erro = "Timeout na consulta de CPF"
 };
 }
 catch (HttpRequestException ex)
 {
 _logger.LogError(ex, "Erro HTTP na consulta do CPF {Cpf}", cpfLimpo);
 return new CpfValidationResult
 {
 Valido = false,
 Erro = $"Erro na comunicacao com a API: {ex.Message}"
 };
 }
 }
}
```

---

## Configuração com injecao de dependência

O `Program.cs` configura o HttpClient com a chave de API recuperada do Key Vault:

```csharp
// Program.cs
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
using CpfValidator.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
 .ConfigureFunctionsWorkerDefaults()
 .ConfigureServices((context, services) =>
 {
 var keyVaultUrl = context.Configuration["KeyVaultUrl"];
 string apiKey;

 if (!string.IsNullOrEmpty(keyVaultUrl))
 {
 var secretClient = new SecretClient(
 new Uri(keyVaultUrl),
 new DefaultAzureCredential()
 );
 var secret = secretClient.GetSecret("cpfhub-api-key");
 apiKey = secret.Value.Value;
 }
 else
 {
 apiKey = context.Configuration["CPFHUB_API_KEY"]
 ?? throw new InvalidOperationException(
 "CPFHUB_API_KEY nao configurada"
 );
 }

 services.AddHttpClient<ICpfHubService, CpfHubService>(client =>
 {
 client.DefaultRequestHeaders.Add("x-api-key", apiKey);
 client.DefaultRequestHeaders.Add("Accept", "application/json");
 });
 })
 .Build();

host.Run();
```

---

## Azure Function HTTP trigger

A função HTTP que expoe o endpoint de validação:

```csharp
// Functions/ValidarCpfFunction.cs
using System.Net;
using CpfValidator.Services;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;

namespace CpfValidator.Functions;

public class ValidarCpfFunction
{
 private readonly ICpfHubService _cpfService;
 private readonly ILogger<ValidarCpfFunction> _logger;

 public ValidarCpfFunction(
 ICpfHubService cpfService,
 ILogger<ValidarCpfFunction> logger)
 {
 _cpfService = cpfService;
 _logger = logger;
 }

 [Function("ValidarCpf")]
 public async Task<HttpResponseData> Run(
 [HttpTrigger(AuthorizationLevel.Function, "get",
 Route = "cpf/{cpfNumero}")] HttpRequestData req,
 string cpfNumero)
 {
 _logger.LogInformation("Consulta de CPF recebida: {Cpf}",
 cpfNumero?[..Math.Min(3, cpfNumero?.Length ?? 0)] + "***");

 if (string.IsNullOrEmpty(cpfNumero))
 {
 var badRequest = req.CreateResponse(HttpStatusCode.BadRequest);
 await badRequest.WriteAsJsonAsync(new { erro = "CPF e obrigatorio" });
 return badRequest;
 }

 var resultado = await _cpfService.ConsultarAsync(cpfNumero);

 if (!resultado.Valido)
 {
 var statusCode = resultado.Erro?.Contains("nao encontrado") == true
 ? HttpStatusCode.NotFound
 : HttpStatusCode.BadRequest;

 var errorResponse = req.CreateResponse(statusCode);
 await errorResponse.WriteAsJsonAsync(new { erro = resultado.Erro });
 return errorResponse;
 }

 var response = req.CreateResponse(HttpStatusCode.OK);
 await response.WriteAsJsonAsync(new
 {
 valido = true,
 dados = new
 {
 nome = resultado.Nome,
 genero = resultado.Genero,
 dataNascimento = resultado.DataNascimento
 }
 });

 return response;
 }
}
```

---

## Configuração local

O arquivo `local.settings.json` para desenvolvimento:

```json
{
 "IsEncrypted": false,
 "Values": {
 "AzureWebJobsStorage": "UseDevelopmentStorage=true",
 "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
 "CPFHUB_API_KEY": "sua_chave_de_teste"
 }
}
```

---

## Deploy para o Azure

Deploy usando Azure CLI:

```bash
# Criar recursos
az group create --name rg-cpf-validator --location brazilsouth
az storage account create --name stcpfvalidator --location brazilsouth \
 --resource-group rg-cpf-validator --sku Standard_LRS
az functionapp create --resource-group rg-cpf-validator \
 --consumption-plan-location brazilsouth \
 --runtime dotnet-isolated --runtime-version 8 \
 --functions-version 4 --name fn-cpf-validator \
 --storage-account stcpfvalidator

# Deploy do codigo
func azure functionapp publish fn-cpf-validator
```

A regiao `brazilsouth` garante a menor latência para usuários no Brasil.

---

## Monitoramento com Application Insights

As Azure Functions enviam telemetria automaticamente para o Application Insights. Metricas úteis para monitorar:

* **Tempo de resposta** -- Monitore o p95 para garantir que a combinação Function + API CPFHub.io se mantem abaixo de 2 segundos.
* **Taxa de falhas** -- Configure alertas quando a taxa de erros ultrapassar 5%.
* **Dependências** -- O Application Insights rastreia automaticamente chamadas HTTP externas, mostrando a latência da API da CPFHub.io separadamente.
* **Live Metrics** -- Visualize requisições em tempo real durante testes de carga.

---

## Perguntas frequentes

### O que é necessário para integrar validação de CPF em Azure Functions com C#?

A integração requer um projeto .NET com o worker runtime `dotnet-isolated`, o pacote `Microsoft.Azure.Functions.Worker.Extensions.Http` e a chave de API da CPFHub.io configurada via Key Vault ou variável de ambiente. O HTTP trigger recebe o CPF via rota, e o `HttpClient` injetado faz a chamada GET para `https://api.cpfhub.io/cpf/{CPF}` com o header `x-api-key`.

### Qual é a latência esperada ao usar a API CPFHub.io em uma Azure Function?

A API CPFHub.io tem latência média de ~900ms. Somado ao tempo de execução da Function, o tempo total de resposta costuma ficar entre 1 e 2 segundos. Configure o `HttpClient.Timeout` em pelo menos 10 segundos e monitore o p95 no Application Insights para identificar variações fora do esperado.

### A API CPFHub.io retorna erro 429 quando o limite de consultas é atingido?

Não. A API não bloqueia nem retorna 429 ao atingir o limite do plano. Quando o volume mensal é ultrapassado, cada consulta adicional é cobrada a R$0,15. O plano gratuito inclui 50 consultas/mês; o plano Pro oferece 1.000 consultas por R$149/mês.

### Como garantir conformidade com a LGPD ao consultar CPF em uma Azure Function?

Use o CPF apenas para a finalidade declarada ao titular, armazene apenas o necessário (não persista o número cru se um token interno bastar) e implemente controle de acesso aos logs do Application Insights. A [ANPD](https://www.gov.br/anpd) orienta que dados de identificação devem ser tratados com o princípio da necessidade e finalidade.

### Leia também

- [Como validar CPF no frontend com React e API REST](https://cpfhub.io/blog/como-validar-cpf-no-frontend-com-react-e-api-rest)
- [Boas práticas para consumir APIs de CPF de forma segura](https://cpfhub.io/blog/boas-praticas-consumir-apis-cpf-segura)
- [Autenticação em APIs REST: como garantir segurança na consulta de CPF](https://cpfhub.io/blog/autenticacao-apis-rest-seguranca-consulta-cpf)
- [Como integrar validação de CPF em Cloudflare Workers com Fetch API](https://cpfhub.io/blog/como-integrar-validacao-cpf-cloudflare-workers-fetch-api)

---

## Conclusão

Azure Functions com C# oferecem uma plataforma robusta para integrações com a API de CPF da [**CPFHub.io**](https://www.cpfhub.io/)

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/)

