Consultar CPF con Ruby on Rails
Consulta un CPF (el número de identificación fiscal de personas físicas en Brasil) con Ruby on Rails usando un service object con Net::HTTP, llamado desde un controller. La clave de API queda en las credentials de Rails.
¿Usas Cursor, Lovable, v0 u otra IA? Copia el prompt de la Consulta Simple y pégalo en tu asistente.
Antes de empezar
- Crea una cuenta gratis en app.cpfhub.io: el plan Gratis incluye 50 créditos y no pide tarjeta.
- Copia tu clave de API en app.cpfhub.io/api-keys.
- Guarda la clave en una variable de entorno, nunca en el código:
export CPFHUB_API_KEY="sua_api_key"Ejemplo
Guarda la clave en las credentials (bin/rails credentials:edit) como cpfhub_api_key, o en la variable de entorno CPFHUB_API_KEY.
# app/services/cpfhub_client.rb
require 'net/http'
class CpfhubClient
class Error < StandardError; end
# Devuelve el hash "data", o nil cuando el CPF no está en la base (404).
def self.lookup(cpf)
uri = URI("https://api.cpfhub.io/cpf/#{cpf}")
req = Net::HTTP::Get.new(uri)
req['x-api-key'] = Rails.application.credentials.cpfhub_api_key || ENV.fetch('CPFHUB_API_KEY')
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true, open_timeout: 5, read_timeout: 10) do |http|
http.request(req)
end
body = JSON.parse(res.body)
case res.code.to_i
when 200 then body['data']
when 404 then nil
else
# error viene como texto ("...") o como objeto ({ "message" => "..." })
error = body['error']
raise Error, "#{res.code}: #{error.is_a?(Hash) ? error['message'] : error}"
end
end
end# app/controllers/cpfs_controller.rb
class CpfsController < ApplicationController
def show
cpf = params[:id].to_s.gsub(/\D/, '')
return render(json: { error: 'El CPF debe tener 11 dígitos' }, status: :bad_request) unless cpf.length == 11
datos = CpfhubClient.lookup(cpf)
if datos
render json: datos
else
render json: { error: 'CPF no encontrado' }, status: :not_found
end
rescue CpfhubClient::Error => e
# 401, 403, 422, 429 y 5xx: regístralo y no expongas detalles al cliente
Rails.logger.error("CPFHub.io #{e.message}")
render json: { error: 'Consulta de CPF no disponible en este momento' }, status: :service_unavailable
end
endAgrega la ruta resources :cpfs, only: :show en config/routes.rb y pruébalo con curl http://localhost:3000/cpfs/12345678909.
Respuesta
CPF encontrado (200, consume 1 crédito):
{
"success": true,
"data": {
"cpf": "12345678909",
"name": "Fulano de Tal",
"nameUpper": "FULANO DE TAL",
"gender": "M",
"birthDate": "15/06/1990",
"day": 15,
"month": 6,
"year": 1990
}
}CPF no encontrado (404, no consume crédito):
{
"success": false,
"data": null,
"error": { "message": "CPF não encontrado na base de dados" }
}El CPF 12345678909 es ficticio, usado solo en los ejemplos. gender puede venir null. El texto de error.message llega de la API en portugués ("CPF no encontrado en la base de datos").
Errores
| Status | Qué significa | Qué hacer |
|---|---|---|
404 | El CPF no está en la base | Trátalo como "no encontrado". No consume crédito. |
400 / 422 | El CPF no tiene 11 dígitos o tiene un dígito verificador inválido | Corrige la entrada. No consume crédito. |
401 | Clave de API ausente o inválida | Revisa la variable CPFHUB_API_KEY. |
403 | Créditos agotados o cuenta inactiva | Consulta el saldo con GET /quota o recarga en el dashboard. |
429 | Límite de solicitudes por minuto | Espera los segundos del header Retry-After y vuelve a intentar. |
5xx | Falla temporal | Vuelve a intentar después de unos segundos. |
El campo error puede venir como texto ("error": "...") o como objeto ("error": { "message": "..." }), según el status. Los ejemplos de arriba manejan los dos formatos. Lista completa en Códigos de Error.