Primeros pasos en 5 minutos
Este es el camino completo, de cero a la primera respuesta.
Antes de empezar
Sección titulada «Antes de empezar»- La empresa necesita un plan que incluya la API, a partir del Start.
- Usted necesita ser OWNER o ADMIN de ella. Solo esos dos roles crean claves.
- Tenga a mano su contraseña del panel: el formulario de creación la pide.
1. Crear la clave
Sección titulada «1. Crear la clave»En el panel, abra Configuración, vaya a la pestaña API y haga clic en Nueva clave.
| Campo | Qué completar |
|---|---|
| Nombre | Para reconocer después qué sistema usa esta clave, como “ERP de la tienda” |
| Qué puede hacer esta clave | Marque solo lo que la integración usa. Vea Permisos |
| Vencimiento | No vence, 30 días, 90 días o 1 año |
| IPs permitidas | Opcional. Una por línea, IP o rango. Vacío acepta cualquier IP |
| Contraseña | Su contraseña del panel |
Copie la clave y guárdela en un gestor de secretos o en una variable de entorno de su servidor. Nunca en el código, nunca en un repositorio, nunca en el navegador.
2. Guardar la clave en el entorno
Sección titulada «2. Guardar la clave en el entorno»export FH_API_KEY="fh_live_su_clave"Los ejemplos de abajo leen la clave de esa variable. Así no queda escrita en el archivo que usted versiona.
3. Hacer la primera llamada
Sección titulada «3. Hacer la primera llamada»GET /public/v1/me responde de quién es la clave. Es la llamada correcta para confirmar que todo está en su lugar antes de escribir el resto de la integración.
curl https://api.fatureihoje.com/public/v1/me \ -H "Authorization: Bearer $FH_API_KEY" \ -H "Accept-Language: es"const res = await fetch('https://api.fatureihoje.com/public/v1/me', { headers: { Authorization: `Bearer ${process.env.FH_API_KEY}`, 'Accept-Language': 'es', },});
const body = await res.json();
if (!res.ok) { throw new Error(`${res.status} ${body.error.code}: ${body.error.message}`);}
console.log(body.organization.name, body.key.permissions);Ejecute con node me.mjs. Node.js 18 o más nuevo, que ya trae fetch.
<?php
$ch = curl_init('https://api.fatureihoje.com/public/v1/me');curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('FH_API_KEY'), 'Accept-Language: es', ],]);
$raw = curl_exec($ch);$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$body = json_decode($raw, true);
if ($status !== 200) { throw new RuntimeException($status . ' ' . $body['error']['code'] . ': ' . $body['error']['message']);}
echo $body['organization']['name'], PHP_EOL;Ejecute con php me.php. Necesita las extensiones curl y json, que vienen activadas en la mayoría de las instalaciones.
import jsonimport osimport urllib.errorimport urllib.request
request = urllib.request.Request( "https://api.fatureihoje.com/public/v1/me", headers={ "Authorization": f"Bearer {os.environ['FH_API_KEY']}", "Accept-Language": "es", },)
try: with urllib.request.urlopen(request) as response: body = json.load(response)except urllib.error.HTTPError as failure: error = json.load(failure)["error"] raise SystemExit(f"{failure.code} {error['code']}: {error['message']}")
print(body["organization"]["name"], body["key"]["permissions"])Ejecute con python3 me.py. Solo biblioteca estándar, nada para instalar.
4. La respuesta
Sección titulada «4. La respuesta»{ "object": "api_key_context", "organization": { "id": "0f3a5f1e-9f7a-4f2b-8f4c-2a1d9e6b7c30", "name": "Marcenaria Souza", "timezone": "America/Sao_Paulo", "currency": "BRL" }, "key": { "id": "6d2c8b41-77a3-4a5e-9c10-3b8f0d5e41aa", "name": "ERP de la tienda", "prefix": "fh_live_7Qx4Kd", "permissions": ["clients:read", "leads:create"], "expires_at": null }, "acting_as": { "member_id": "b1d4e2f0-5c69-4a31-9d77-8e2c4f6a0b53", "name": "Ana Souza", "role": "owner" }, "limits": { "requests_per_minute": 60 }}| Campo | Qué es |
|---|---|
organization | La empresa dueña de la clave, con la zona horaria y la moneda que usa |
key.prefix | El comienzo de la clave, el mismo que el panel muestra en la lista. Sirve para saber qué clave está en uso |
key.permissions | Qué puede hacer esta clave, en el formato modulo:accion |
key.expires_at | Fecha de vencimiento en ISO 8601, o null cuando la clave no vence |
acting_as | El miembro de la empresa que la clave representa, y su rol |
limits.requests_per_minute | Llamadas por minuto de la empresa, sumando todas las claves. null significa sin límite |
La Referencia trae esos campos uno por uno, con tipo y formato.
5. Cuando llegue un 401
Sección titulada «5. Cuando llegue un 401»{ "error": { "type": "authentication_error", "code": "api_key_invalid", "message": "Clave de API inválida, revocada o vencida.", "request_id": "0a8c1f2e-3b4d-4c5f-9a6b-7c8d9e0f1a2b", "doc_url": "https://docs.fatureihoje.com/es/errors#api_key_invalid" }}Esa es la respuesta de cualquier rechazo de autenticación, siempre igual. No dice el motivo, a propósito. Revise en este orden:
- El encabezado es
Authorization: Bearer <clave>, con un solo espacio entreBearery la clave. - La clave fue copiada entera, sin espacio ni salto de línea al final.
- La clave no está revocada ni vencida. El panel muestra el estado de cada clave.
- Si la clave tiene lista de IPs, la IP de salida de su servidor está en la lista.
- La dirección es
api.fatureihoje.com. El host del panel no responde/public/v1.
Después, abra Ver uso en el menú de la clave, en el panel. Muestra las llamadas de los últimos 30 días con fecha, método, ruta, estado, duración, IP y request_id, incluidas las rechazadas. Ahí se ve la IP que su servidor usa de verdad.
Guarde el request_id de la respuesta. Es por él que el soporte encuentra la llamada.
Próximo paso
Sección titulada «Próximo paso»- Autenticación: formato de la clave, lista de IPs, rotación y revocación.
- Permisos: por qué una clave con el permiso todavía puede recibir un 403.