# Como consumir API de CPF em Godot com GDScript para gamificação

> Aprenda a consumir a API de CPF da CPFHub.io em Godot usando GDScript e HTTPRequest para aplicações gamificadas com validação de identidade.

**Publicado:** 13/07/2026
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/como-consumir-api-de-cpf-em-godot-com-gdscript-para-gamificacao

---


Para consumir a API de CPF da CPFHub.io no Godot, use o nó `HTTPRequest` nativo do engine com GDScript: configure a URL `https://api.cpfhub.io/cpf/{CPF}`, adicione o header `x-api-key` com sua chave e conecte o sinal `request_completed` para processar a resposta JSON. A latência média da API é de ~300ms, bem dentro do timeout padrão de 5 segundos recomendado para o `HTTPRequest`. Em cenários de gamificação corporativa, essa integração permite validar a identidade do participante antes de conceder recompensas ou pontos.

---

## 1. Pré-requisitos

* **Godot 4.2+** instalado.

* Conhecimento básico de GDScript e a árvore de nós do Godot.

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

---

## 2. Configure a cena

Crie a seguinte estrutura de nós no Godot:

```
CpfValidator (Control)
├── VBoxContainer
│ ├── TitleLabel (Label)
│ ├── CpfInput (LineEdit)
│ ├── ConsultarButton (Button)
│ ├── LoadingLabel (Label)
│ ├── ResultadoPanel (PanelContainer)
│ │ └── ResultadoLabel (RichTextLabel)
│ └── ErroLabel (Label)
└── HTTPRequest
```

---

## 3. Crie o script de configuração

Crie um recurso personalizado para armazenar as configurações da API:

```gdscript
# cpfhub_config.gd
class_name CpfHubConfig
extends Resource

@export var api_key: String = "SUA_CHAVE_DE_API"
@export var base_url: String = "https://api.cpfhub.io"
@export var timeout_seconds: float = 5.0
```

Salve como recurso `.tres` no Godot Editor para reutilizar em diferentes cenas.

---

## 4. Implemente o serviço de consulta

Crie o script principal de consulta de CPF:

```gdscript
# cpf_hub_service.gd
class_name CpfHubService
extends Node

signal cpf_consultado(dados: Dictionary)
signal cpf_erro(mensagem: String, status_code: int)

@export var config: CpfHubConfig

var _http_request: HTTPRequest

func _ready() -> void:
 _http_request = HTTPRequest.new()
 _http_request.timeout = config.timeout_seconds
 _http_request.request_completed.connect(_on_request_completed)
 add_child(_http_request)

func consultar_cpf(cpf: String) -> void:
 var cpf_limpo := _limpar_cpf(cpf)

 if cpf_limpo.length() != 11:
 cpf_erro.emit("CPF deve conter exatamente 11 digitos.", 400)
 return

 var url := "%s/cpf/%s" % [config.base_url, cpf_limpo]
 var headers := PackedStringArray([
 "x-api-key: %s" % config.api_key,
 "Accept: application/json",
 ])

 print("[CpfHub] Consultando CPF: %s" % cpf_limpo)

 var error := _http_request.request(url, headers, HTTPClient.METHOD_GET)
 if error != OK:
 cpf_erro.emit("Erro ao iniciar requisicao HTTP.", 500)

func _on_request_completed(
 result: int,
 response_code: int,
 headers: PackedStringArray,
 body: PackedByteArray
) -> void:
 if result == HTTPRequest.RESULT_TIMEOUT:
 cpf_erro.emit("Timeout ao consultar a API.", 504)
 return

 if result != HTTPRequest.RESULT_SUCCESS:
 cpf_erro.emit("Erro de conexao com a API.", 502)
 return

 if response_code != 200:
 var mensagem := _mapear_erro(response_code)
 cpf_erro.emit(mensagem, response_code)
 return

 var json_string := body.get_string_from_utf8()
 var json := JSON.new()
 var parse_result := json.parse(json_string)

 if parse_result != OK:
 cpf_erro.emit("Erro ao processar resposta da API.", 500)
 return

 var response: Dictionary = json.data

 if response.get("success", false) and response.has("data"):
 print("[CpfHub] CPF encontrado: %s" % response.data.name)
 cpf_consultado.emit(response.data)
 else:
 cpf_erro.emit("Resposta inesperada da API.", 500)

func _limpar_cpf(cpf: String) -> String:
 var regex := RegEx.new()
 regex.compile("\\D")
 return regex.sub(cpf, "", true)

func _mapear_erro(status_code: int) -> String:
 match status_code:
 400: return "CPF com formato invalido."
 401: return "Chave de API invalida ou ausente."
 404: return "CPF nao encontrado na base de dados."
 _: return "Erro HTTP %d." % status_code
```

---

## 5. Crie o controlador de UI

Implemente o script que conecta a UI ao serviço:

```gdscript
# cpf_validator_ui.gd
extends Control

@onready var cpf_input: LineEdit = $VBoxContainer/CpfInput
@onready var consultar_button: Button = $VBoxContainer/ConsultarButton
@onready var loading_label: Label = $VBoxContainer/LoadingLabel
@onready var resultado_panel: PanelContainer = $VBoxContainer/ResultadoPanel
@onready var resultado_label: RichTextLabel = $VBoxContainer/ResultadoPanel/ResultadoLabel
@onready var erro_label: Label = $VBoxContainer/ErroLabel
@onready var cpf_service: CpfHubService = $CpfHubService

func _ready() -> void:
 loading_label.visible = false
 resultado_panel.visible = false
 erro_label.visible = false

 consultar_button.pressed.connect(_on_consultar_pressed)
 cpf_input.text_changed.connect(_on_cpf_changed)
 cpf_service.cpf_consultado.connect(_on_cpf_consultado)
 cpf_service.cpf_erro.connect(_on_cpf_erro)

func _on_consultar_pressed() -> void:
 var cpf := cpf_input.text.strip_edges()
 if cpf.is_empty():
 _mostrar_erro("Digite um CPF.")
 return

 consultar_button.disabled = true
 loading_label.visible = true
 resultado_panel.visible = false
 erro_label.visible = false

 cpf_service.consultar_cpf(cpf)

func _on_cpf_consultado(dados: Dictionary) -> void:
 loading_label.visible = false
 consultar_button.disabled = false
 resultado_panel.visible = true

 resultado_label.text = ""
 resultado_label.append_text("[b]Nome:[/b] %s\n" % dados.get("name", "N/A"))
 resultado_label.append_text("[b]CPF:[/b] %s\n" % dados.get("cpf", "N/A"))
 resultado_label.append_text("[b]Genero:[/b] %s\n" % dados.get("gender", "N/A"))
 resultado_label.append_text("[b]Nascimento:[/b] %s" % dados.get("birthDate", "N/A"))

func _on_cpf_erro(mensagem: String, _status_code: int) -> void:
 loading_label.visible = false
 consultar_button.disabled = false
 _mostrar_erro(mensagem)

func _mostrar_erro(mensagem: String) -> void:
 resultado_panel.visible = false
 erro_label.visible = true
 erro_label.text = mensagem

func _on_cpf_changed(new_text: String) -> void:
 var regex := RegEx.new()
 regex.compile("\\D")
 var numeros := regex.sub(new_text, "", true)
 if numeros.length() > 11:
 numeros = numeros.substr(0, 11)

 var formatado := numeros
 if numeros.length() > 9:
 formatado = "%s.%s.%s-%s" % [numeros.substr(0, 3), numeros.substr(3, 3), numeros.substr(6, 3), numeros.substr(9)]
 elif numeros.length() > 6:
 formatado = "%s.%s.%s" % [numeros.substr(0, 3), numeros.substr(3, 3), numeros.substr(6)]
 elif numeros.length() > 3:
 formatado = "%s.%s" % [numeros.substr(0, 3), numeros.substr(3)]

 cpf_input.text = formatado
 cpf_input.caret_column = formatado.length()
```

---

## 6. Integração com sistema de gamificação

Exemplo de como integrar a validação de CPF com um sistema de pontos:

```gdscript
# gamification_manager.gd
extends Node

signal pontos_atualizados(total: int)

var pontos_totais: int = 0
var cpfs_validados: Array[String] = []

@onready var cpf_service: CpfHubService = $CpfHubService

func _ready() -> void:
 cpf_service.cpf_consultado.connect(_on_cpf_validado)

func validar_para_recompensa(cpf: String) -> void:
 var cpf_limpo := cpf.replace(".", "").replace("-", "")
 if cpf_limpo in cpfs_validados:
 print("CPF ja validado anteriormente.")
 return

 cpf_service.consultar_cpf(cpf)

func _on_cpf_validado(dados: Dictionary) -> void:
 var cpf: String = dados.get("cpf", "")
 if cpf.is_empty() or cpf in cpfs_validados:
 return

 cpfs_validados.append(cpf)
 pontos_totais += 100
 pontos_atualizados.emit(pontos_totais)
 print("CPF validado! +100 pontos. Total: %d" % pontos_totais)
```

---

## 7. Boas práticas

* **HTTPRequest** -- Use o nó `HTTPRequest` nativo do Godot para requisições HTTP. Ele funciona em todas as plataformas suportadas. Consulte a [documentação oficial do Godot](https://docs.godotengine.org) para detalhes de configuração por plataforma.

* **Timeout** -- Configure o timeout do `HTTPRequest` para 5 segundos, folgado para o tempo de resposta de ~300ms da API.

* **Signals** -- Use sinais (signals) do Godot para desacoplar o serviço da UI, seguindo o padrão observer.

* **Segurança** -- Em projetos exportados, a chave de API fica no binário. Para maior segurança, use um backend intermediário.

* **Export** -- Ao exportar para web (HTML5), verifique se as configurações de CORS permitem a comunicação com a API.

* **LGPD** -- A API da CPFHub.io é 100% compatível com a LGPD. Em aplicações gamificadas, informe os participantes sobre a coleta e o uso de dados pessoais.

---

## Perguntas frequentes

### O nó HTTPRequest do Godot suporta chamadas HTTPS para APIs externas?

Sim. O nó `HTTPRequest` do Godot 4 suporta HTTPS nativamente em todas as plataformas de desktop. Para exportações Web (HTML5), o Godot usa `XMLHttpRequest` do navegador, então as políticas de CORS do servidor de destino precisam permitir a origem do seu domínio. Em builds mobile (Android/iOS), o suporte a TLS também está disponível por padrão.

### Como proteger a chave de API da CPFHub.io em um projeto Godot exportado?

Em projetos exportados, strings hardcoded ficam acessíveis no binário com ferramentas de descompilação. A abordagem mais segura é criar um backend intermediário (Node.js, Python, etc.) que receba a requisição do Godot, adicione a `x-api-key` no servidor e repasse o resultado. Assim a chave nunca sai do servidor. Para projetos internos ou protótipos de baixo risco, usar uma chave com cota limitada já reduz o impacto de um vazamento.

### O plano gratuito da CPFHub.io é suficiente para desenvolvimento e testes no Godot?

O plano gratuito oferece 50 consultas por mês sem cartão de crédito, o que é suficiente para desenvolver e testar a integração completa. A API não bloqueia ao atingir o limite: consultas adicionais são cobradas a R$0,15 cada. Para producão com volume real, o plano Pro (R$149/mês) inclui 1.000 consultas mensais.

### Como lidar com a latência da API em uma cena interativa do Godot?

A melhor prática é desabilitar o botão de consulta assim que o usuário clica, exibir um indicador de carregamento (`LoadingLabel`) e reabilitar os controles apenas no sinal `request_completed`. A CPFHub.io responde em ~300ms na média, mas o sinal assíncrono do Godot garante que a UI permaneça responsiva independentemente do tempo de rede. Evite fazer a requisição em `_process()` ou em loops de física.

### Leia também

- [Diferença entre validação de CPF e consulta de CPF: quando usar cada uma](https://cpfhub.io/blog/diferenca-entre-validacao-de-cpf-e-consulta-de-cpf-quando-usar-cada-uma)
- [API de CPF grátis para desenvolvedores: como começar em 5 minutos](https://cpfhub.io/blog/api-cpf-gratis-desenvolvedores-comecar-5-minutos)
- [Onboarding digital em fintechs: como validar CPF em menos de 30 segundos](https://cpfhub.io/blog/onboarding-digital-em-fintechs-como-validar-cpf-em-menos-de-30-segundos)
- [KYC no Brasil: quais setores são obrigados a validar CPF por lei](https://cpfhub.io/blog/kyc-no-brasil-quais-setores-sao-obrigados-a-validar-cpf-por-lei)

---

## Conclusão

Consumir a API da [**CPFHub.io**](https://www.cpfhub.io/) no Godot é direto: o nó `HTTPRequest` nativo, combinado com o sistema de sinais do engine, entrega uma integração robusta sem dependências externas. Com ~300ms de latência e plano gratuito de 50 consultas mensais, você pode desenvolver e testar a integração completa antes de qualquer custo.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) e comece a validar CPFs no seu jogo ou aplicação Godot em menos de 30 minutos.

