# Como integrar validação de CPF em Ionic com Angular e HTTP client

> Aprenda a integrar validação de CPF em apps Ionic com Angular usando HttpClient, interceptors e a API da CPFHub.io.

**Publicado:** 09/07/2026
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/como-integrar-validacao-de-cpf-em-ionic-com-angular-e-http-client

---

Para integrar validação de CPF em um app Ionic com Angular, crie um serviço injetável que usa o `HttpClient` para chamar `GET https://api.cpfhub.io/cpf/{CPF}` com o header `x-api-key`. O Angular oferece interceptors que centralizam a autenticação automaticamente em todas as requisições, e os reactive forms garantem que o CPF seja validado no cliente antes mesmo de a chamada sair do dispositivo. A API da CPFHub.io responde em ~900ms e retorna nome, data de nascimento e gênero do titular — dados suficientes para a maioria dos fluxos de cadastro e verificação de identidade em apps mobile.

---

## 1. Pré-requisitos

* **Node.js 18+** e Ionic CLI: `npm install -g @ionic/cli`.

* Um projeto Ionic/Angular criado: `ionic start cpf-app blank --type=angular`.

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

* Consulte a documentação oficial do Ionic em [ionicframework.com/docs](https://ionicframework.com/docs) para referência dos componentes usados neste guia.

---

## 2. Configure o environment

Adicione as configurações da API nos arquivos de environment do Angular:

```typescript
// src/environments/environment.ts
export const environment = {
 production: false,
 cpfhub: {
 baseUrl: "https://api.cpfhub.io",
 apiKey: "SUA_CHAVE_DE_API",
 timeout: 5000,
 },
};
```

```typescript
// src/environments/environment.prod.ts
export const environment = {
 production: true,
 cpfhub: {
 baseUrl: "https://api.cpfhub.io",
 apiKey: "${CPFHUB_API_KEY}",
 timeout: 5000,
 },
};
```

---

## 3. Crie as interfaces de tipagem

Defina interfaces TypeScript para modelar a resposta da API:

```typescript
// src/app/models/cpf.model.ts
export interface CpfData {
 cpf: string;
 name: string;
 nameUpper: string;
 gender: string;
 birthDate: string;
 day: number;
 month: number;
 year: number;
}

export interface CpfResponse {
 success: boolean;
 data: CpfData;
}

export interface CpfError {
 message: string;
 statusCode: number;
}
```

---

## 4. Crie o serviço de consulta

Implemente o serviço Angular com `HttpClient`:

```typescript
// src/app/services/cpfhub.service.ts
import { Injectable } from "@angular/core";
import { HttpClient, HttpHeaders, HttpErrorResponse } from "@angular/common/http";
import { Observable, throwError, timeout, catchError, map } from "rxjs";
import { environment } from "../../environments/environment";
import { CpfData, CpfResponse } from "../models/cpf.model";

@Injectable({
 providedIn: "root",
})
export class CpfHubService {
 private readonly baseUrl = environment.cpfhub.baseUrl;
 private readonly apiKey = environment.cpfhub.apiKey;
 private readonly timeoutMs = environment.cpfhub.timeout;

 constructor(private http: HttpClient) {}

 consultarCpf(cpf: string): Observable<CpfData> {
 const cpfLimpo = cpf.replace(/\D/g, "");

 if (cpfLimpo.length !== 11) {
 return throwError(() => ({
 message: "CPF deve conter exatamente 11 dígitos",
 statusCode: 400,
 }));
 }

 const url = `${this.baseUrl}/cpf/${cpfLimpo}`;
 const headers = new HttpHeaders({
 "x-api-key": this.apiKey,
 Accept: "application/json",
 });

 return this.http.get<CpfResponse>(url, { headers }).pipe(
 timeout(this.timeoutMs),
 map((response) => {
 if (response.success && response.data) {
 return response.data;
 }
 throw { message: "Resposta inesperada da API", statusCode: 500 };
 }),
 catchError((error) => this.handleError(error))
 );
 }

 private handleError(error: HttpErrorResponse | any): Observable<never> {
 if (error.name === "TimeoutError") {
 return throwError(() => ({
 message: "Timeout na consulta. Tente novamente.",
 statusCode: 504,
 }));
 }

 if (error instanceof HttpErrorResponse) {
 const errorMap: Record<number, string> = {
 400: "CPF com formato inválido",
 401: "Chave de API inválida ou ausente",
 404: "CPF não encontrado na base de dados",
 };

 return throwError(() => ({
 message: errorMap[error.status] || `Erro HTTP ${error.status}`,
 statusCode: error.status,
 }));
 }

 return throwError(() => ({
 message: error.message || "Erro desconhecido",
 statusCode: error.statusCode || 500,
 }));
 }
}
```

---

## 5. Crie o interceptor de autenticação

Use um interceptor para adicionar o header de API key automaticamente:

```typescript
// src/app/interceptors/cpfhub.interceptor.ts
import { Injectable } from "@angular/core";
import {
 HttpInterceptor,
 HttpRequest,
 HttpHandler,
 HttpEvent,
} from "@angular/common/http";
import { Observable } from "rxjs";
import { environment } from "../../environments/environment";

@Injectable()
export class CpfHubInterceptor implements HttpInterceptor {
 intercept(
 req: HttpRequest<any>,
 next: HttpHandler
 ): Observable<HttpEvent<any>> {
 if (req.url.startsWith(environment.cpfhub.baseUrl)) {
 const cloned = req.clone({
 setHeaders: {
 "x-api-key": environment.cpfhub.apiKey,
 Accept: "application/json",
 },
 });
 return next.handle(cloned);
 }
 return next.handle(req);
 }
}
```

Registre o interceptor no módulo:

```typescript
// src/app/app.module.ts
import { HTTP_INTERCEPTORS } from "@angular/common/http";
import { CpfHubInterceptor } from "./interceptors/cpfhub.interceptor";

@NgModule({
 providers: [
 {
 provide: HTTP_INTERCEPTORS,
 useClass: CpfHubInterceptor,
 multi: true,
 },
 ],
})
export class AppModule {}
```

---

## 6. Crie a página de consulta

Implemente a página Ionic com reactive forms:

```typescript
// src/app/pages/consulta/consulta.page.ts
import { Component } from "@angular/core";
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { LoadingController, ToastController } from "@ionic/angular";
import { CpfHubService } from "../../services/cpfhub.service";
import { CpfData } from "../../models/cpf.model";

@Component({
 selector: "app-consulta",
 templateUrl: "./consulta.page.html",
 styleUrls: ["./consulta.page.scss"],
})
export class ConsultaPage {
 cpfForm: FormGroup;
 resultado: CpfData | null = null;
 erro: string | null = null;

 constructor(
 private fb: FormBuilder,
 private cpfService: CpfHubService,
 private loadingCtrl: LoadingController,
 private toastCtrl: ToastController
 ) {
 this.cpfForm = this.fb.group({
 cpf: ["", [Validators.required, Validators.minLength(11)]],
 });
 }

 async consultar(): Promise<void> {
 if (this.cpfForm.invalid) return;

 this.resultado = null;
 this.erro = null;

 const loading = await this.loadingCtrl.create({
 message: "Consultando CPF...",
 duration: 10000,
 });
 await loading.present();

 this.cpfService.consultarCpf(this.cpfForm.value.cpf).subscribe({
 next: async (data) => {
 this.resultado = data;
 await loading.dismiss();
 await this.mostrarToast("CPF encontrado com sucesso!", "success");
 },
 error: async (err) => {
 this.erro = err.message;
 await loading.dismiss();
 await this.mostrarToast(err.message, "danger");
 },
 });
 }

 private async mostrarToast(message: string, color: string): Promise<void> {
 const toast = await this.toastCtrl.create({
 message,
 duration: 3000,
 color,
 position: "bottom",
 });
 await toast.present();
 }

 formatarCpf(event: any): void {
 let value = event.target.value.replace(/\D/g, "").slice(0, 11);
 if (value.length > 9) {
 value = `${value.slice(0, 3)}.${value.slice(3, 6)}.${value.slice(6, 9)}-${value.slice(9)}`;
 } else if (value.length > 6) {
 value = `${value.slice(0, 3)}.${value.slice(3, 6)}.${value.slice(6)}`;
 } else if (value.length > 3) {
 value = `${value.slice(0, 3)}.${value.slice(3)}`;
 }
 this.cpfForm.patchValue({ cpf: value });
 }
}
```

```html
<!-- src/app/pages/consulta/consulta.page.html -->
<ion-header>
 <ion-toolbar color="primary">
 <ion-title>Consulta de CPF</ion-title>
 </ion-toolbar>
</ion-header>

<ion-content class="ion-padding">
 <form [formGroup]="cpfForm" (ngSubmit)="consultar()">
 <ion-item>
 <ion-label position="floating">CPF</ion-label>
 <ion-input
 formControlName="cpf"
 type="text"
 placeholder="000.000.000-00"
 maxlength="14"
 (ionInput)="formatarCpf($event)"
 ></ion-input>
 </ion-item>

 <ion-button
 expand="block"
 type="submit"
 [disabled]="cpfForm.invalid"
 class="ion-margin-top"
 >
 Consultar
 </ion-button>
 </form>

 <ion-card *ngIf="resultado" class="ion-margin-top">
 <ion-card-header>
 <ion-card-title>{{ resultado.name }}</ion-card-title>
 <ion-card-subtitle>CPF: {{ resultado.cpf }}</ion-card-subtitle>
 </ion-card-header>
 <ion-card-content>
 <ion-list>
 <ion-item>
 <ion-label>Genero: {{ resultado.gender }}</ion-label>
 </ion-item>
 <ion-item>
 <ion-label>Nascimento: {{ resultado.birthDate }}</ion-label>
 </ion-item>
 </ion-list>
 </ion-card-content>
 </ion-card>

 <ion-card *ngIf="erro" color="danger" class="ion-margin-top">
 <ion-card-content>{{ erro }}</ion-card-content>
 </ion-card>
</ion-content>
```

---

## 7. Boas práticas

* **HttpClient** -- Use o `HttpClient` do Angular com tipagem genérica para garantir type safety nas respostas da API.

* **Interceptors** -- Centralize a adição de headers em interceptors para evitar repetição em cada chamada.

* **Timeout** -- Configure timeout via operador RxJS `timeout()` para evitar que o app trave aguardando respostas. A latência típica da API é ~900ms; um timeout de 5 segundos é adequado.

* **Reactive Forms** -- Use reactive forms com validadores para garantir que o CPF tenha o formato correto antes da consulta.

* **Ionic Components** -- Aproveite componentes como `LoadingController` e `ToastController` para feedback visual nativo.

* **LGPD** -- A API da CPFHub.io é 100% compatível com a LGPD. Em apps mobile, implemente controles de consentimento e política de privacidade.

---

## Perguntas frequentes

### Como funciona a autenticação na API da CPFHub.io em um app Ionic?

A autenticação usa o header HTTP `x-api-key` em cada requisição. No Angular, a prática recomendada é centralizar isso em um interceptor: o `CpfHubInterceptor` detecta requisições direcionadas ao domínio da API e injeta o header automaticamente, sem repetir código nos serviços. A chave de API é gerada no painel da CPFHub.io após o cadastro.

### Qual o tempo de resposta esperado da API ao consultar um CPF?

A latência típica da API da CPFHub.io é de ~900ms. Configure o timeout do `HttpClient` para pelo menos 5 segundos para absorver variações de rede sem falsos erros. No Angular, use o operador `timeout()` do RxJS diretamente no `pipe()` do observable para controlar isso de forma reativa.

### O que acontece quando o limite de consultas do plano gratuito é atingido?

A API não bloqueia a conta nem retorna erro 429 ao atingir o limite. O plano gratuito inclui 50 consultas por mês; ao superá-las, cada consulta adicional é cobrada a R$0,15, de forma automática. O plano Pro oferece 1.000 consultas por R$149/mês, com o mesmo modelo de cobrança por excedente.

### Como garantir conformidade com a LGPD ao usar uma API de CPF em Ionic?

Use o CPF apenas para a finalidade declarada ao titular, armazene apenas o estritamente necessário e implemente controle de acesso aos logs de consulta no app. A [ANPD](https://www.gov.br/anpd) orienta que dados de identificação devem ser tratados com o princípio da necessidade — documente a base legal para o tratamento antes de colocar o app em produção.

### 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)
- [Como consumir API de CPF em TypeScript com tipagem segura](https://cpfhub.io/blog/como-consumir-api-de-cpf-em-typescript-com-tipagem-segura)
- [Como consumir API de CPF em Capacitor para apps híbridos](https://cpfhub.io/blog/como-consumir-api-de-cpf-em-capacitor-para-apps-hibridos)

---

## Conclusão

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

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

