# Como consumir API de CPF em Xamarin/MAUI para apps cross-platform

> Aprenda a consumir a API de CPF da CPFHub.io em .NET MAUI para criar apps cross-platform com validação de CPF em C#.

**Publicado:** 10/07/2026
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/como-consumir-api-de-cpf-em-xamarin-maui-para-apps-cross-platform

---

Para consumir a API de CPF da CPFHub.io em .NET MAUI, crie um serviço C# que usa `HttpClient` para chamar `GET https://api.cpfhub.io/cpf/{CPF}` com o header `x-api-key`. O MAUI herda a injeção de dependência nativa do .NET, o que permite registrar o `HttpClient` com a chave de API uma única vez no `MauiProgram.cs` e reutilizá-lo em todas as páginas via `IHttpClientFactory`. A API responde em ~900ms e a integração completa — do modelo de dados ao ViewModel com padrão MVVM — fica funcional em menos de 30 minutos. Consulte a [documentação oficial do .NET MAUI](https://learn.microsoft.com/en-us/dotnet/maui) para referência das APIs de plataforma usadas neste guia.

---

## 1. Pré-requisitos

* **Visual Studio 2022+** com workload .NET MAUI instalado.

* **.NET 8.0+** SDK.

* Um projeto MAUI criado: `dotnet new maui -n CpfValidatorApp`.

* Uma conta gratuita na [**CPFHub.io**](https://www.cpfhub.io/)

---

## 2. Crie os modelos de dados

Defina as classes C# para modelar a resposta da API:

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

namespace CpfValidatorApp.Models;

public class CpfResponse
{
 [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; }
}
```

---

## 3. Crie o serviço de consulta

Implemente o serviço com `HttpClient` e tratamento de erros:

```csharp
// Services/CpfHubService.cs
using System.Net.Http.Json;
using System.Text.RegularExpressions;
using CpfValidatorApp.Models;

namespace CpfValidatorApp.Services;

public interface ICpfHubService
{
 Task<CpfData> ConsultarCpfAsync(string cpf);
}

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

 public CpfHubService(HttpClient httpClient)
 {
 _httpClient = httpClient;
 _httpClient.Timeout = TimeSpan.FromSeconds(5);
 _httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
 }

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

 if (cpfLimpo.Length != 11)
 throw new ArgumentException("CPF deve conter exatamente 11 dígitos.");

 var url = $"{BaseUrl}/cpf/{cpfLimpo}";

 try
 {
 var response = await _httpClient.GetAsync(url);

 if (response.IsSuccessStatusCode)
 {
 var resultado = await response.Content.ReadFromJsonAsync<CpfResponse>();
 if (resultado?.Success == true && resultado.Data != null)
 return resultado.Data;

 throw new InvalidOperationException("Resposta inesperada da API.");
 }

 var mensagemErro = response.StatusCode switch
 {
 System.Net.HttpStatusCode.BadRequest => "CPF com formato inválido.",
 System.Net.HttpStatusCode.Unauthorized => "Chave de API inválida ou ausente.",
 System.Net.HttpStatusCode.NotFound => "CPF não encontrado na base de dados.",
 _ => $"Erro HTTP {(int)response.StatusCode}."
 };

 throw new HttpRequestException(mensagemErro);
 }
 catch (TaskCanceledException)
 {
 throw new TimeoutException("Timeout ao consultar a API da CPFHub.");
 }
 catch (HttpRequestException)
 {
 throw;
 }
 catch (Exception ex)
 {
 throw new InvalidOperationException($"Erro na consulta: {ex.Message}", ex);
 }
 }
}
```

---

## 4. Configure a injeção de dependência

Registre o serviço no `MauiProgram.cs`:

```csharp
// MauiProgram.cs
using CpfValidatorApp.Services;
using CpfValidatorApp.ViewModels;

namespace CpfValidatorApp;

public static class MauiProgram
{
 public static MauiApp CreateMauiApp()
 {
 var builder = MauiApp.CreateBuilder();
 builder
 .UseMauiApp<App>()
 .ConfigureFonts(fonts =>
 {
 fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
 });

 // Registrar HttpClient com API key
 builder.Services.AddHttpClient<ICpfHubService, CpfHubService>(client =>
 {
 client.DefaultRequestHeaders.Add("x-api-key", "SUA_CHAVE_DE_API");
 });

 // Registrar ViewModels
 builder.Services.AddTransient<ConsultaViewModel>();
 builder.Services.AddTransient<MainPage>();

 return builder.Build();
 }
}
```

---

## 5. Crie o ViewModel

Implemente o ViewModel seguindo o padrão MVVM com `CommunityToolkit.Mvvm`:

```bash
dotnet add package CommunityToolkit.Mvvm
```

```csharp
// ViewModels/ConsultaViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CpfValidatorApp.Models;
using CpfValidatorApp.Services;

namespace CpfValidatorApp.ViewModels;

public partial class ConsultaViewModel : ObservableObject
{
 private readonly ICpfHubService _cpfService;

 [ObservableProperty]
 private string cpfInput = string.Empty;

 [ObservableProperty]
 private CpfData? resultado;

 [ObservableProperty]
 private string? mensagemErro;

 [ObservableProperty]
 private bool isLoading;

 [ObservableProperty]
 private bool temResultado;

 public ConsultaViewModel(ICpfHubService cpfService)
 {
 _cpfService = cpfService;
 }

 [RelayCommand]
 private async Task ConsultarCpfAsync()
 {
 if (string.IsNullOrWhiteSpace(CpfInput))
 {
 MensagemErro = "Digite um CPF.";
 return;
 }

 IsLoading = true;
 MensagemErro = null;
 Resultado = null;
 TemResultado = false;

 try
 {
 Resultado = await _cpfService.ConsultarCpfAsync(CpfInput);
 TemResultado = true;
 }
 catch (ArgumentException ex)
 {
 MensagemErro = ex.Message;
 }
 catch (TimeoutException ex)
 {
 MensagemErro = ex.Message;
 }
 catch (HttpRequestException ex)
 {
 MensagemErro = ex.Message;
 }
 catch (Exception ex)
 {
 MensagemErro = $"Erro inesperado: {ex.Message}";
 }
 finally
 {
 IsLoading = false;
 }
 }
}
```

---

## 6. Crie a interface XAML

Implemente a página de consulta com XAML:

```xml
<!-- MainPage.xaml -->
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
 xmlns:vm="clr-namespace:CpfValidatorApp.ViewModels"
 x:Class="CpfValidatorApp.MainPage"
 Title="Consulta de CPF">

 <ScrollView Padding="20">
 <VerticalStackLayout Spacing="15">

 <Label Text="Consulta de CPF"
 FontSize="24"
 FontAttributes="Bold"
 HorizontalOptions="Center" />

 <Entry Placeholder="000.000.000-00"
 Text="{Binding CpfInput}"
 Keyboard="Numeric"
 MaxLength="14"
 FontSize="18" />

 <Button Text="Consultar"
 Command="{Binding ConsultarCpfCommand}"
 IsEnabled="{Binding IsLoading, Converter={StaticResource InvertBoolConverter}}"
 FontSize="16" />

 <ActivityIndicator IsRunning="{Binding IsLoading}"
 IsVisible="{Binding IsLoading}"
 Color="{StaticResource Primary}" />

 <Frame IsVisible="{Binding TemResultado}"
 BorderColor="Green"
 Padding="15"
 CornerRadius="8">
 <VerticalStackLayout Spacing="8">
 <Label Text="{Binding Resultado.Name}"
 FontSize="20"
 FontAttributes="Bold" />
 <Label Text="{Binding Resultado.Cpf, StringFormat='CPF: {0}'}" />
 <Label Text="{Binding Resultado.Gender, StringFormat='Genero: {0}'}" />
 <Label Text="{Binding Resultado.BirthDate, StringFormat='Nascimento: {0}'}" />
 </VerticalStackLayout>
 </Frame>

 <Frame IsVisible="{Binding MensagemErro, Converter={StaticResource IsNotNullConverter}}"
 BorderColor="Red"
 BackgroundColor="#FFF0F0"
 Padding="15"
 CornerRadius="8">
 <Label Text="{Binding MensagemErro}"
 TextColor="Red" />
 </Frame>

 </VerticalStackLayout>
 </ScrollView>
</ContentPage>
```

---

## 7. Boas práticas

* **HttpClient** -- Use `IHttpClientFactory` via injeção de dependência para gerenciar o ciclo de vida do `HttpClient` e evitar socket exhaustion.

* **Timeout** -- Configure o timeout do `HttpClient` para 5 segundos, adequado ao tempo de resposta de ~900ms da API.

* **MVVM** -- Separe a lógica de negócios no ViewModel e a apresentação na View para facilitar testes unitários.

* **Segurança** -- Em produção, armazene a chave de API usando `SecureStorage` do MAUI em vez de hardcode.

* **Plataformas** -- Teste em todas as plataformas alvo (Android, iOS, Windows) para garantir compatibilidade.

* **LGPD** -- A API da CPFHub.io é 100% compatível com a LGPD. Implemente controles de consentimento e política de privacidade no app.

---

## Perguntas frequentes

### Como registrar a API key da CPFHub.io com segurança em um app .NET MAUI?

O caminho mais direto para desenvolvimento é registrar a chave no `MauiProgram.cs` via `AddHttpClient`. Em produção, use o `SecureStorage` do MAUI para armazenar a chave após obtê-la de um backend próprio — assim ela não fica exposta no binário do app. Nunca distribua a API key diretamente em builds públicas da loja.

### Qual o tempo de resposta esperado da API da CPFHub.io?

A latência típica é de ~900ms. O timeout padrão do `HttpClient` está configurado para 5 segundos neste guia, o que dá margem suficiente para variações de rede mobile sem impactar a experiência do usuário. Se a requisição ultrapassar o timeout, o `TaskCanceledException` é capturado e convertido em mensagem amigável.

### O que acontece se o limite de consultas for ultrapassado?

A API não bloqueia nem retorna status 429 ao atingir o limite. O plano gratuito inclui 50 consultas por mês; consultas adicionais são cobradas automaticamente a R$0,15 cada. O plano Pro oferece 1.000 consultas por R$149/mês com o mesmo modelo de excedente — sem interrupção de serviço.

### O código funciona tanto para Xamarin.Forms quanto para .NET MAUI?

A estrutura de serviço com `HttpClient` e o padrão MVVM são compatíveis com ambos, mas este guia é otimizado para .NET MAUI com .NET 8. Em projetos Xamarin.Forms mais antigos, substitua `System.Text.Json` por `Newtonsoft.Json` e ajuste o registro de dependências no `App.xaml.cs`. A Microsoft recomenda migrar para MAUI, pois o Xamarin foi descontinuado.

### 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)
- [Como consumir API de CPF em C# com HttpClient e .NET 8](https://cpfhub.io/blog/como-consumir-api-de-cpf-em-csharp-com-httpclient-e-dotnet-8)
- [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)

---

## Conclusão

Consumir a API da [**CPFHub.io**](https://www.cpfhub.io/)

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

