Apariencia
Autenticación
La API pública v1 utiliza tokens de API. Cada llamada debe llevar el token en el header Authorization.
Generar un token
Los tokens se generan desde el backoffice, en Configuración → Tokens de API (requiere rol Administrador). Al crear el token se pide:
- Nombre descriptivo (ej.
"CRM principal — producción"). - Permisos (abilities): subset de la lista de permisos descrita más abajo. Conviene asignar el mínimo necesario.
- Fecha de expiración opcional. Si no se configura, el token no expira hasta ser revocado.
El valor en plano del token se muestra una sola vez al momento de generarlo. El sistema sólo guarda un hash SHA-256: si se pierde el valor, no se puede recuperar — hay que generar uno nuevo.
Buenas prácticas
- Un token distinto por cada integración. Si una queda comprometida, la revocación afecta sólo a ese sistema.
- Almacená el token en un secret manager (Vault, AWS Secrets Manager, GCP Secret Manager). Nunca lo incluyas en el repositorio de código fuente.
- Revisá periódicamente la columna Último uso del listado para detectar tokens que ya no se usan y revocarlos.
Cómo enviarlo
El token se envía en el header HTTP Authorization con el esquema Bearer:
http
GET /api/v1/accounts HTTP/1.1
Host: compliance.quantian.ar
Authorization: Bearer qtn_live_a7c3...d4e9
Accept: application/jsonNo uses el token en query string
Nunca incluyas el token en la URL (?token=...) ni en parámetros de consulta. Las URLs quedan registradas en proxies, balanceadores, el historial del navegador y los referers — el header Authorization es el único lugar seguro.
Permisos (abilities)
Los permisos son granulares y se combinan al crear el token:
| Ability | Qué habilita |
|---|---|
accounts:read | Listar legajos, leer detalle, leer checklist, listar documentos, consultar catálogos globales. |
accounts:write | Crear y actualizar legajos (incluyendo el bulk POST), subir y borrar documentos, generar magic-links de hosted flow. |
Si su token no tiene la ability requerida por un endpoint, la API responde 403 Forbidden con el campo required indicando qué permiso falta:
jsonc
{
"message": "Token lacks required ability.",
"required": ["accounts:write"]
}Esto es independiente del estado del token: un token activo sin la ability correcta sigue devolviendo 403, no 401.
Estados del token
| Estado | Comportamiento |
|---|---|
| Activo | Las llamadas pasan. last_used_at se actualiza periódicamente, no en cada request. |
| Revocado | El administrador presionó "Revocar". Toda llamada responde 401 Unauthorized de forma inmediata. La revocación es irreversible: hay que generar un token nuevo. |
| Expirado | Pasó la fecha de expiración configurada al crearlo. Mismo comportamiento que revocado: 401 Unauthorized. |
La API distingue entre token ausente y token presente pero rechazado:
http
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{ "message": "Missing API token." }http
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{ "message": "Invalid or expired API token." }Por seguridad, no se diferencia entre "el token no existe" y "el token existe pero fue revocado / expiró".
Identidad y auditoría
Cada llamada que muta estado (POST/DELETE) deja una entrada en el módulo de Auditoría del backoffice con:
- La operación realizada (descripción en español, evento técnico, recurso afectado).
- El diff Antes / Después de los campos modificados, cuando aplica.
- La dirección IP de origen y el
User-Agent.
La columna Quién queda vacía para llamadas de la API pública: las operaciones no tienen un usuario humano identificable detrás, sólo el token. Para investigar actividad de un token específico:
- Usá la pantalla Configuración → Tokens de API para ver el
Último usode cada token y a quién pertenece la integración. - Cruzá las entradas de auditoría por categoría (
onboarding,authentication,document), IP y rango horario para reconstruir la actividad asociada a una integración.
Para emisiones de magic-link, la entrada de auditoría incluye en su payload el magic_link_id y el email destinatario, lo que permite correlacionar la actividad del token con el cierre del legajo por parte del consumidor.