Autenticación
FactuLink ofrece dos métodos de autenticación para acceder a la API. Elige el que mejor se adapte a tu caso de uso.
| Método | Ideal para | Expiración |
|---|---|---|
| API Keys | Server-to-server, backends, integraciones | Sin expiración |
| JWT | Frontend, aplicaciones de usuario, SPAs | access: 24h, refresh: 7d |
API Keys (recomendado para server-to-server)
Las API Keys son la forma más sencilla de autenticarte. Son ideales para backends e integraciones donde no hay un usuario interactivo.
Formato de las keys
sk_live_— Producción (timbrado real contra el SAT)sk_test_— Sandbox (timbrado simulado, sin envío al SAT)
El prefijo determina automáticamente el ambiente. No necesitas configurar nada adicional.
Crear una API Key
Para crear una API Key necesitas un JWT con rol ADMIN:
POST/api/v1/api-keys
/api/v1/api-keys201{
"name": "Backend de facturación",
"scopes": ["cfdis:read", "cfdis:write", "clients:read"],
"environment": "test"
}{
"id": "key_01J5K...",
"name": "Backend de facturación",
"prefix": "sk_test_",
"key": "sk_test_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"scopes": ["cfdis:read", "cfdis:write", "clients:read"],
"environment": "test",
"created_at": "2026-04-05T10:30:00Z"
}Importante: La key completa se muestra una sola vez al momento de crearla. Guárdala en un lugar seguro. Después solo verás el prefijo.
Uso en peticiones
Envía la API Key en el header Authorization con el esquema Bearer:
curl -X GET https://api.factulink.com.mx/api/v1/cfdis \
-H "Authorization: Bearer sk_test_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6" \
-H "Content-Type: application/json"JWT (para frontend / browser)
Si estás construyendo una aplicación con usuarios interactivos, usa JWT. El flujo es: login con email/password, obtener tokens, y usarlos para autenticar peticiones.
Login
POST/api/v1/auth/login
/api/v1/auth/login200{
"email": "admin@empresa.com",
"password": "tu-password-seguro"
}{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 86400,
"user": {
"id": "usr_01J5K...",
"email": "admin@empresa.com",
"role": "ADMIN",
"organization_id": "org_01J5K..."
}
}Refresh Token
Cuando el access_token expire (24 horas), usa el refresh_token para obtener uno nuevo sin pedir credenciales de nuevo:
/api/v1/auth/refresh
/api/v1/auth/refresh200{
"refresh_token": "eyJhbGciOiJIUzI1NiIs..."
}{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 86400
}Duración de tokens
| Token | Duración |
|---|---|
access_token | 24 horas |
refresh_token | 7 días |
Si el refresh_token también expira, el usuario debe iniciar sesión de nuevo.
Scopes (permisos por API Key)
Cada API Key puede tener un conjunto de scopes que limitan qué operaciones puede realizar. Usa siempre los scopes mínimos necesarios.
| Scope | Descripción |
|---|---|
cfdis:read | Leer y listar CFDIs |
cfdis:write | Crear y timbrar CFDIs |
cfdis:cancel | Cancelar CFDIs ante el SAT |
clients:read | Leer y listar clientes (receptores) |
clients:write | Crear y actualizar clientes |
certificates:read | Ver certificados CSD cargados |
certificates:write | Subir y administrar certificados CSD |
catalogs:read | Consultar catálogos del SAT |
series:read | Leer series de folio |
series:write | Crear y administrar series de folio |
webhooks:manage | Crear, leer, actualizar y eliminar webhooks |
ai:invoke | Usar endpoints de facturación asistida por IA |
stats:read | Leer estadísticas y reportes |
billing:read | Consultar información de facturación de la cuenta |
Buenas prácticas
- Nunca expongas API Keys en código frontend. Las keys
sk_live_ysk_test_son secretas. Úsalas solo en backends. - Usa variables de entorno. Almacena las keys en
FC_API_KEYo equivalente, nunca las hardcodees en el código. - Rota keys periódicamente. Puedes tener múltiples keys activas para facilitar la rotación sin downtime.
- Usa los scopes mínimos necesarios. Si tu integración solo lee CFDIs, no le des
cfdis:writenicfdis:cancel. - Maneja la expiración de JWT. Implementa lógica de refresh automático en tu cliente para evitar interrupciones.