Autenticación
Autentícate con la API de Reten usando API keys o tokens JWT.
Todos los endpoints requieren autenticación a menos que estén marcados como Públicos. Reten soporta dos métodos de autenticación.
API Keys (Recomendado para Integraciones)
Las API keys proporcionan autenticación sin estado, ideal para integraciones, pipelines CI/CD y comunicación entre servicios.
Características Principales
- Permisos acotados — cada key tiene una lista explícita de permisos elegida por su dueño (subconjunto de los permisos vigentes del dueño, editable por el dueño en cualquier momento); en cada solicitud, los permisos efectivos son la intersección de esa lista con los permisos vigentes del dueño
- Vinculada a un tenant — cada key está asociada a un tenant específico (no se necesita el header
x-tenant-id); su alcance decide si además queda atada a un proyecto (ver Contexto de Proyecto) - Almacenamiento seguro — solo se almacena un hash SHA-256; la key en texto plano se muestra una sola vez al crearla
- Expiración opcional — las keys pueden tener una fecha de expiración tras la cual se rechazan automáticamente
Crear una API Key
Crea una API key vía POST /api/api-keys con los permisos deseados. La key en texto plano se devuelve una sola vez y debe almacenarse de forma segura.
Solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
name | string | Sí | Nombre legible para la key |
permissions | string[] | Sí | Permisos a otorgar (subconjunto de tus permisos vigentes; editables después con PUT /api/api-keys/:id/permissions) |
expiresAt | ISO 8601 | No | Fecha de expiración |
scope | string | Sí | project (la key queda atada a un proyecto) o tenant (la key sirve para todos los proyectos del tenant y envía x-project-id donde el endpoint lo exige o para acotar una solicitud a un proyecto) — ver Crear Clave de API |
projectId | UUID | Con scope: "project" | Proyecto al que pertenece la key |
curl -X POST https://api.reten.ai/api/api-keys \
-H "Authorization: Bearer <token>" \
-H "x-tenant-id: <tenant-id>" \
-H "Content-Type: application/json" \
-d '{
"name": "Integration Key",
"permissions": ["activity:view", "activity:create"],
"scope": "project",
"projectId": "<project-id>"
}'import axios from 'axios';
const response = await axios.post(
'https://api.reten.ai/api/api-keys',
{
name: 'Integration Key',
permissions: ['activity:view', 'activity:create'],
scope: 'project',
projectId: '<project-id>',
},
{
headers: {
Authorization: 'Bearer <token>',
'x-tenant-id': '<tenant-id>',
},
}
);
// Guarda esta key de forma segura — solo se muestra una vez
const apiKey = response.data.plaintextKey; // rtn_sk_...Usar una API Key
Incluye la key en el header x-api-key en todas las solicitudes:
x-api-key: rtn_sk_<key>Al usar una API key, el tenant se resuelve a partir de la key — no se necesita el header x-tenant-id. Que la key envíe además x-project-id depende de su alcance — ver Contexto de Proyecto.
Email + Contraseña (JWT)
Los tokens JWT se usan para sesiones interactivas de usuario. El flujo implica una solicitud de login que devuelve un access token y establece un refresh token como cookie.
Flujo de Autenticación
- Llama a
POST /api/auth/logincon email y contraseña - Recibe un access token en el cuerpo de la respuesta; un refresh token se establece como cookie HTTP-only
- Incluye el access token en todas las solicitudes posteriores vía el header
Authorization - Cuando el access token expire (15 min), llama a
POST /api/auth/refresh— el servidor valida la cookie de refresh y emite un nuevo access token - Al cerrar sesión, se limpia la cookie de refresh
Tiempo de Vida de Tokens
| Token | Duración | Transporte |
|---|---|---|
| Access token | 15 minutos | Header Authorization: Bearer |
| Refresh token | 7 días | Cookie HTTP-only |
Solicitud de Login
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
identifier | string | Sí | Nombre de usuario o dirección de email |
password | string | Sí | Contraseña del usuario (mín. 8 caracteres) |
curl -X POST https://api.reten.ai/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"identifier": "admin@example.com",
"password": "SecurePass123!"
}'import axios from 'axios';
const response = await axios.post(
'https://api.reten.ai/api/auth/login',
{
identifier: 'admin@example.com',
password: 'SecurePass123!',
}
);
const { accessToken, user } = response.data;Respuesta 201 Created
{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "jdoe",
"email": "jdoe@example.com",
"firstName": "Jane",
"lastName": "Doe",
"roles": ["viewer"],
"permissions": [
"project:view",
"user:view",
"activity:view",
"commerce-lifecycle-snapshot:view"
],
"tenantIds": ["660e8400-e29b-41d4-a716-446655440000"]
}
}Usar JWT con Contexto de Tenant
Al autenticar con JWT, la mayoría de los endpoints requieren un contexto de tenant vía el header x-tenant-id:
Authorization: Bearer <access_token>
x-tenant-id: <tenant_uuid>Puedes obtener la lista de tenants a los que pertenece tu usuario vía GET /api/tenant/mine.
Los endpoints project-scoped necesitan además el header x-project-id, y los endpoints project-optional lo aceptan — ver Contexto de Proyecto.
Contexto de Proyecto
Los datos de un tenant se dividen en proyectos. Los endpoints project-scoped trabajan en exactamente un proyecto por solicitud: el proyecto activo. Los endpoints tenant-level no miran el proyecto.
Los endpoints project-optional aceptan x-project-id pero no lo exigen. Si se envía, acota la solicitud a ese proyecto y se valida igual que en un endpoint project-scoped. Sin él, una lectura abarca todo el tenant y un resultado toma el proyecto de su actividad; un resultado sin activity_id no tiene actividad de la que tomar el proyecto, así que necesita el header — sin él la API responde 400. Una clave de proyecto siempre trabaja en su propio proyecto: no necesita el header, y un resultado sin activity_id va al proyecto de la clave.
El proyecto activo sale de:
| Credencial | Proyecto activo |
|---|---|
| JWT | El header x-project-id; en un endpoint project-optional sin él, no hay proyecto activo |
| Clave de tenant | El header x-project-id; en un endpoint project-optional sin él, no hay proyecto activo |
| Clave de proyecto | El proyecto de la propia clave — no se necesita el header x-project-id |
Envía el header junto a x-tenant-id. Los IDs de proyecto se obtienen con GET /api/projects:
Authorization: Bearer <access_token>
x-tenant-id: <tenant_uuid>
x-project-id: <project_uuid>Los endpoints tenant-level ignoran el header: enviarlo o no, no cambia la respuesta. Con una clave de API el tenant sigue saliendo de la clave; sólo el proyecto depende del alcance de la clave — ver Integración → Autenticación.
Endpoints project-scoped, project-optional y tenant-level
| Endpoints | Alcance |
|---|---|
Actividades — /api/activities/*, incluidos GET /api/activities/tasks, GET /api/activities/tasks/:id y POST /api/activities/tasks/:id/dispatch | Project-scoped |
Resultados de actividad — POST /api/activity-results/tasks, PATCH /api/activity-results/tasks/:id | Project-scoped |
Activity Generation Configs — /api/activity-generation-configs/* | Project-scoped |
Audiencias — /api/audience-criterias/*, incluido el catálogo (tables, tables/:tableName/columns) | Project-scoped |
Filtros de eventos — /api/event-criterias/* | Project-scoped |
Pilares de ciclo de vida — /api/activation-configs/*, /api/engagement-configs/*, /api/resurrection-configs/* | Project-scoped |
Integración — GET /api/integration/activities/tasks, POST /api/integration/activity-results/tasks | Project-optional |
Todos los demás endpoints: proyectos, API keys, auth, usuarios, tenants, comercios, commerce lifecycle snapshots, operadores, rutas, supervisores, configuraciones y proveedores de despacho, catálogos de activity config, lifecycle defaults; en la API de integración, GET /api/integration/task-result-type-configs y los endpoints batch-upsert | Tenant-level |
GET /api/activity-results/tasks/sync es tenant-level: ignora x-project-id y devuelve los resultados de todos los proyectos del tenant.
Errores de proyecto
En un endpoint project-scoped, y en un endpoint project-optional que recibe el header, la API valida el proyecto antes que los permisos y el cuerpo de la solicitud. La excepción es el 400 de un resultado sin activity_id en un endpoint project-optional, que llega después de validar el cuerpo de la solicitud:
| Estado | Cuándo | message |
|---|---|---|
403 | Una clave de proyecto envía un x-project-id que nombra otro proyecto | La API key pertenece a un proyecto distinto del que declara el header x-project-id. |
400 | Falta el header en un endpoint project-scoped (JWT o clave de tenant) | Falta el header obligatorio x-project-id. |
400 | Se envía un resultado sin activity_id a un endpoint project-optional sin proyecto (JWT o clave de tenant sin el header) | Falta el header obligatorio x-project-id: un resultado sin activity_id necesita proyecto. |
400 | El header no es un UUID válido (JWT o clave de tenant) | El header x-project-id debe ser un UUID válido. |
404 | El proyecto no existe o pertenece a otro tenant | El proyecto no existe. |