# Como consumir API de CPF em Flutter com Dart e pacote http

> Aprenda a consumir a API de consulta de CPF em Flutter usando Dart e o pacote http. Guia completo com exemplos de código e boas práticas.

**Publicado:** 08/10/2024
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/como-consumir-api-de-cpf-em-flutter-com-dart-e-pacote-http

---


Para consumir a API de CPF da [**CPFHub.io**](https://www.cpfhub.io/) em Flutter, adicione o pacote `http` ao `pubspec.yaml`, crie um serviço Dart que faz `GET https://api.cpfhub.io/cpf/{CPF}` com o header `x-api-key` e modele a resposta JSON em uma classe `CpfData`. O plano gratuito oferece 50 consultas/mês sem cartão, suficiente para desenvolvimento e testes em qualquer plataforma suportada pelo Flutter.

## Introdução

O Flutter se tornou uma das plataformas mais populares para o desenvolvimento de aplicativos multiplataforma, permitindo criar aplicações para Android, iOS, web e desktop a partir de uma única base de código em Dart. Para aplicativos brasileiros que envolvem cadastro de usuários, o CPF é o documento de identificação mais utilizado e sua validação via API garante que os dados coletados sejam confiáveis.

---

## Pré-requisitos

* **Flutter SDK** -- Versão 3.0 ou superior.
* **Dart 3.0+** -- Incluído com o Flutter SDK.
* **Conta na CPFHub.io** -- Para obter a chave de API. O plano gratuito oferece 50 consultas/mês sem cartão de crédito.
* **Pacote http** -- Para realizar requisições HTTP.

### Adicionando a dependência

No arquivo `pubspec.yaml`, adicione o pacote http:

```yaml
dependencies:
 flutter:
 sdk: flutter
 http: ^1.2.0
```

Execute `flutter pub get` para instalar a dependência.

---

## Modelando a resposta da API

Crie um modelo Dart para representar os dados retornados pela API:

```dart
class CpfData {
 final String cpf;
 final String name;
 final String nameUpper;
 final String gender;
 final String birthDate;
 final int day;
 final int month;
 final int year;

 CpfData({
 required this.cpf,
 required this.name,
 required this.nameUpper,
 required this.gender,
 required this.birthDate,
 required this.day,
 required this.month,
 required this.year,
 });

 factory CpfData.fromJson(Map<String, dynamic> json) {
 return CpfData(
 cpf: json['cpf'] as String,
 name: json['name'] as String,
 nameUpper: json['nameUpper'] as String,
 gender: json['gender'] as String,
 birthDate: json['birthDate'] as String,
 day: json['day'] as int,
 month: json['month'] as int,
 year: json['year'] as int,
 );
 }
}
```

A resposta da API tem o seguinte formato:

```json
{
 "success": true,
 "data": {
 "cpf": "12345678900",
 "name": "João da Silva",
 "nameUpper": "JOÃO DA SILVA",
 "gender": "M",
 "birthDate": "15/06/1990",
 "day": 15,
 "month": 6,
 "year": 1990
 }
}
```

---

## Criando o serviço de consulta

Implemente o serviço que encapsula a chamada à API:

```dart
import 'dart:convert';
import 'package:http/http.dart' as http;

class CpfService {
 static const String _baseUrl = 'https://api.cpfhub.io/cpf/';
 final String apiKey;

 CpfService({required this.apiKey});

 Future<CpfData> consultarCpf(String cpf) async {
 final cpfLimpo = cpf.replaceAll(RegExp(r'\D'), '');

 if (cpfLimpo.length != 11) {
 throw Exception('CPF inválido. Informe 11 dígitos numéricos.');
 }

 final url = Uri.parse('$_baseUrl$cpfLimpo');
 final headers = {
 'x-api-key': apiKey,
 'Accept': 'application/json',
 };

 try {
 final response = await http
 .get(url, headers: headers)
 .timeout(const Duration(seconds: 10));

 if (response.statusCode == 200) {
 final body = jsonDecode(response.body) as Map<String, dynamic>;

 if (body['success'] == true && body['data'] != null) {
 return CpfData.fromJson(body['data'] as Map<String, dynamic>);
 } else {
 throw Exception('CPF não encontrado na base de dados.');
 }
 } else {
 throw Exception('Erro HTTP: ${response.statusCode}');
 }
 } on Exception catch (e) {
 if (e.toString().contains('TimeoutException')) {
 throw Exception('A requisição excedeu o tempo limite.');
 }
 rethrow;
 }
 }
}
```

---

## Implementando a tela de consulta

Crie um widget StatefulWidget que permite ao usuário digitar o CPF e visualizar o resultado:

```dart
import 'package:flutter/material.dart';

class ConsultaCpfPage extends StatefulWidget {
 const ConsultaCpfPage({super.key});

 @override
 State<ConsultaCpfPage> createState() => _ConsultaCpfPageState();
}

class _ConsultaCpfPageState extends State<ConsultaCpfPage> {
 final _cpfController = TextEditingController();
 final _service = CpfService(apiKey: 'SUA_CHAVE_DE_API');

 CpfData? _resultado;
 String? _erro;
 bool _carregando = false;

 Future<void> _consultar() async {
 setState(() {
 _resultado = null;
 _erro = null;
 _carregando = true;
 });

 try {
 final dados = await _service.consultarCpf(_cpfController.text);
 setState(() {
 _resultado = dados;
 });
 } catch (e) {
 setState(() {
 _erro = e.toString().replaceFirst('Exception: ', '');
 });
 } finally {
 setState(() {
 _carregando = false;
 });
 }
 }

 @override
 Widget build(BuildContext context) {
 return Scaffold(
 appBar: AppBar(title: const Text('Consulta de CPF')),
 body: Padding(
 padding: const EdgeInsets.all(16.0),
 child: Column(
 crossAxisAlignment: CrossAxisAlignment.stretch,
 children: [
 TextField(
 controller: _cpfController,
 keyboardType: TextInputType.number,
 maxLength: 11,
 decoration: const InputDecoration(
 labelText: 'CPF (somente números)',
 border: OutlineInputBorder(),
 ),
 ),
 const SizedBox(height: 16),
 ElevatedButton(
 onPressed: _carregando ? null : _consultar,
 child: Text(_carregando ? 'Consultando...' : 'Consultar'),
 ),
 const SizedBox(height: 24),
 if (_resultado != null) ...[
 Text('Nome: ${_resultado!.name}',
 style: const TextStyle(fontSize: 16)),
 Text('CPF: ${_resultado!.cpf}'),
 Text('Nascimento: ${_resultado!.birthDate}'),
 Text('Gênero: ${_resultado!.gender}'),
 ],
 if (_erro != null)
 Text(
 _erro!,
 style: const TextStyle(color: Colors.red, fontSize: 14),
 ),
 ],
 ),
 ),
 );
 }

 @override
 void dispose() {
 _cpfController.dispose();
 super.dispose();
 }
}
```

---

## Validação sintática local

Para economizar consultas à API, valide os dígitos verificadores do CPF localmente antes de enviar a requisição:

```dart
bool validarCpfLocal(String cpf) {
 final cpfLimpo = cpf.replaceAll(RegExp(r'\D'), '');

 if (cpfLimpo.length != 11) return false;
 if (RegExp(r'^(\d)\1{10}$').hasMatch(cpfLimpo)) return false;

 int soma = 0;
 for (int i = 0; i < 9; i++) {
 soma += int.parse(cpfLimpo[i]) * (10 - i);
 }
 int resto = (soma * 10) % 11;
 if (resto == 10) resto = 0;
 if (resto != int.parse(cpfLimpo[9])) return false;

 soma = 0;
 for (int i = 0; i < 10; i++) {
 soma += int.parse(cpfLimpo[i]) * (11 - i);
 }
 resto = (soma * 10) % 11;
 if (resto == 10) resto = 0;
 if (resto != int.parse(cpfLimpo[10])) return false;

 return true;
}
```

---

## Testando com cURL

Para confirmar o funcionamento da API antes de integrar no Flutter:

```bash
curl -X GET https://api.cpfhub.io/cpf/12345678900 \
 -H "x-api-key: SUA_CHAVE_DE_API" \
 -H "Accept: application/json" \
 --max-time 10
```

---

## Boas práticas para Flutter

* **Chave de API segura** -- Não inclua a chave diretamente no código em produção. Utilize variáveis de ambiente com `--dart-define` ou um back-end intermediário.

* **Timeout** -- Sempre inclua `.timeout()` nas requisições HTTP para evitar travamentos.

* **Gerenciamento de estado** -- Para projetos maiores, considere usar Provider, Riverpod ou Bloc para gerenciar o estado da consulta.

* **Volume de consultas** -- No plano gratuito, o limite é de 50 consultas/mês. Ao atingir o limite, consultas adicionais são cobradas a R$0,15 cada — sem bloqueio do serviço. O plano Pro oferece 1.000 consultas por R$149/mês.

* **Multiplataforma** -- O mesmo código funciona em Android, iOS, web e desktop, maximizando o reúso.

---

## Perguntas frequentes

### Como proteger a chave de API da CPFHub.io em um app Flutter?

Em Flutter, evite incluir a chave de API diretamente no código-fonte. A abordagem mais segura para produção é intermediar as chamadas por um back-end próprio — o app Flutter chama seu servidor, que por sua vez chama a API da CPFHub.io com a chave armazenada em variável de ambiente. Para desenvolvimento, use `--dart-define=API_KEY=...` ao rodar o app. Consulte as [diretrizes de segurança do Flutter](https://docs.flutter.dev/security) para mais detalhes.

### O pacote `http` é a melhor opção para requisições HTTP em Flutter?

O pacote `http` é simples, mantido pela equipe do Dart e adequado para a maioria dos casos. Para projetos maiores que precisam de interceptadores, cancelamento de requisições, transformações de resposta e retry automático, o pacote `dio` é uma alternativa popular. Para a integração com a API CPFHub.io, o pacote `http` com `.timeout()` cobre todos os cenários descritos neste guia.

### Como tratar o estado de carregamento durante a consulta de CPF no Flutter?

Use um `StatefulWidget` com uma variável booleana `_carregando` que é definida como `true` antes da chamada à API e `false` no bloco `finally`. Durante o carregamento, desabilite o botão de consulta e exiba um `CircularProgressIndicator` ou texto informativo. Isso evita chamadas duplicadas e mantém o usuário informado sobre o progresso da verificação.

### É possível usar a API CPFHub.io em apps Flutter para web?

Sim. O mesmo código Dart funciona em Flutter web sem alterações. A única consideração é que chamadas diretas à API a partir do front-end (incluindo Flutter web) expõem a chave de API ao cliente. Para produção, sempre intermedie as chamadas por um back-end — independentemente da plataforma. Em desenvolvimento local, o Flutter web pode requerer configuração de CORS no servidor de testes.

### 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)
- [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)
- [10 erros mais comuns ao integrar uma API de CPF e como evitá-los](https://cpfhub.io/blog/10-erros-mais-comuns-ao-integrar-uma-api-de-cpf)

---

## Conclusão

Consumir a API de consulta de CPF da [**CPFHub.io**](https://www.cpfhub.io/) em Flutter é direto: adicione o pacote `http`, crie um serviço tipado com `CpfService`, valide o CPF localmente antes de chamar a API e trate cada estado — carregando, sucesso e erro — no widget de forma explícita.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) — 50 consultas mensais gratuitas, sem cartão de crédito — e integre a validação de CPF no seu app Flutter hoje mesmo.

