Crear Clave de API
Generar una nueva clave de API con permisos acotados para acceso programático.
POST /api/api-keys
Crea una nueva clave de API para el usuario autenticado en el tenant activo. La clave en texto plano se devuelve solo una vez en la respuesta — guárdala de forma segura.
Auth: Requerida — permiso api-key:manage
Cuerpo de la Solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
name | string | Sí | Etiqueta legible para la clave (máximo 255 caracteres) |
permissions | string[] | Sí | Lista de nombres de permisos a conceder (mínimo 1). Debe ser un subconjunto de tus permisos vigentes; api-key:manage no se puede asignar. Editable después con PUT /api/api-keys/:id/permissions |
expiresAt | string | No | Fecha de expiración en formato ISO 8601. La clave es rechazada automáticamente después de esta fecha |
scope | string | Sí | Alcance de la clave: project o tenant (ver abajo) |
projectId | UUID | null | Condicional | Proyecto al que pertenece la clave. Obligatorio con scope: "project"; no se admite con scope: "tenant" (se acepta null) |
Alcance de la clave
El alcance se elige al crear la clave y decide cómo la clave obtiene el proyecto en el que trabaja:
| Alcance | Clave | Proyecto de cada solicitud |
|---|---|---|
project | Clave de proyecto | Siempre el proyecto de la clave. La clave no necesita el header x-project-id; un header que nombre otro proyecto responde 403 en los endpoints project-scoped y project-optional |
tenant | Clave de tenant | Cualquier proyecto del tenant: se declara con el header x-project-id en los endpoints project-scoped, igual que un usuario. En los endpoints project-optional el header es opcional y acota la solicitud a ese proyecto |
En ambos casos el tenant sale de la clave. Ver Integración → Autenticación para el uso de cada clave.
Ejemplo
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": "CI/CD Pipeline Key",
"permissions": ["commerce:manage", "activity:view"],
"expiresAt": "2026-12-31T23:59:59Z",
"scope": "project",
"projectId": "3f6c2b1a-8d4e-4f7a-9b2c-5e1d0a7f6c34"
}'const response = await fetch("https://api.reten.ai/api/api-keys", {
method: "POST",
headers: {
"Authorization": "Bearer <token>",
"x-tenant-id": "<tenant-id>",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "CI/CD Pipeline Key",
permissions: ["commerce:manage", "activity:view"],
expiresAt: "2026-12-31T23:59:59Z",
scope: "project",
projectId: "3f6c2b1a-8d4e-4f7a-9b2c-5e1d0a7f6c34",
}),
});
const data = await response.json();
const plaintextKey = data.plaintextKey; // Guárdala de forma segura — solo se devuelve una vezimport requests
response = requests.post(
"https://api.reten.ai/api/api-keys",
headers={
"Authorization": "Bearer <token>",
"x-tenant-id": "<tenant-id>",
},
json={
"name": "CI/CD Pipeline Key",
"permissions": ["commerce:manage", "activity:view"],
"expiresAt": "2026-12-31T23:59:59Z",
"scope": "project",
"projectId": "3f6c2b1a-8d4e-4f7a-9b2c-5e1d0a7f6c34",
},
)
data = response.json()
plaintext_key = data["plaintextKey"] # Guárdala de forma segura — solo se devuelve una vezRespuesta 201 Created
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"name": "CI/CD Pipeline Key",
"keyPrefix": "rtn_sk_a1b2c3d4",
"plaintextKey": "rtn_sk_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4",
"userId": "550e8400-e29b-41d4-a716-446655440000",
"tenantId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"projectId": "3f6c2b1a-8d4e-4f7a-9b2c-5e1d0a7f6c34",
"isActive": true,
"permissions": ["commerce:manage", "activity:view"],
"expiresAt": "2026-12-31T23:59:59.000Z",
"lastUsedAt": null,
"createdAt": "2026-02-26T14:30:00.000Z",
"revokedAt": null
}El campo plaintextKey solo se incluye en la respuesta de creación. No puede recuperarse nuevamente — si se pierde, revoca la clave y crea una nueva.
La respuesta no incluye scope: el alcance de la clave se lee de projectId — el UUID del proyecto para una clave de proyecto, null para una clave de tenant. Lo mismo vale para Listar Claves de API.
Respuestas de Error
| Estado | Descripción |
|---|---|
400 | Error de validación — campos faltantes, array de permisos vacío o con duplicados, o nombres de permisos inválidos |
400 | scope faltante, o distinto de tenant / project |
400 | scope: "project" sin un projectId válido — Una key de alcance project requiere el projectId (UUID) de un proyecto del tenant. |
400 | scope: "tenant" con un projectId — Una key de alcance tenant no lleva projectId. |
401 | Token de autenticación faltante o inválido |
403 | El conjunto solicitado incluye un permiso que no tienes vigente — Cannot assign permissions you do not have: … |
403 | El conjunto solicitado incluye api-key:manage — Cannot assign api-key:manage to an API key |
404 | projectId no es un proyecto del tenant — El proyecto no existe. |