Crear una API
POST /v1/apis · permiso apis:write
Crea una API en el entorno. key, identifier y name son requeridos; los campos opcionales omitidos toman sus valores por defecto. El identificador es único en el entorno (una API eliminada mantiene su identificador reservado durante 90 días). La respuesta incluye un ETag con la versión actual. Envía un encabezado Idempotency-Key para hacer los reintentos seguros.
Solicitud
Cuerpo application/json. Los campos desconocidos son rechazados.
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
key |
string | sí | Clave de configuración estable, ^[a-z0-9_-]{1,64}$. Inmutable. |
identifier |
string | sí | Audiencia de token: una URL https (sin consulta ni fragmento) o urn:<nid>:<nss>; almacenada en forma canónica. Inmutable. El espacio de nombres urn:idp: está reservado. |
name |
string | sí | 1-128 caracteres. |
access_token_lifetime_s |
integer | no | 60-86400. Por defecto 3600 (600 con mcp_profile). |
token_format |
string | no | jwt (por defecto) u opaque. |
rbac_mode |
string | no | Cómo llegan los roles y permisos al token: claims (por defecto) añade permissions y org_permissions; off no añade ninguno (org_roles se sigue añadiendo); enforce los añade y además limita los scopes concedidos a los permisos efectivos del usuario. |
allow_offline_access |
boolean | no | Por defecto true. |
require_resource_indicator |
boolean | no | Por defecto false (true con mcp_profile). |
dpop_required |
boolean | no | Por defecto false. |
mcp_profile |
boolean | no | Requiere un identifier https y require_resource_indicator: true. |
first_party_access |
string | no | all (por defecto) u granted_only. |
introspection_applications |
array | no | Aplicaciones (app_…) que pueden introspeccionar los tokens de esta API, máximo 50, sin duplicados. Solo aplicaciones web y m2m del mismo entorno. Vacío por defecto. |
Aplicaciones de introspeción
El punto de conexión de introspeción (POST <issuer>/oauth2/introspect, RFC 7662) responde con active: true para un token de acceso solo a dos llamadores: la aplicación a la que se emitió el token, o una aplicación en la lista introspection_applications de la API nombrada en el aud del token. Todos los demás llamadores reciben active: false, por lo que las API no pueden leer los tokens entre sí. Solo las aplicaciones confidenciales (web, m2m) del mismo entorno pueden listarse; la lista se almacena como un conjunto y se devuelve en orden de ID. Una aplicación suspendida permanece en la lista pero no puede introspeccionar. La lista de la API del sistema no se puede escribir.
Respuesta
201 Created con un encabezado ETag y la API:
{
"id": "api_01h455vb4pex5vsknk084sn02q",
"key": "orders",
"identifier": "https://api.example.com/orders",
"name": "Orders API",
"is_system": false,
"access_token_lifetime_s": 3600,
"token_format": "jwt",
"rbac_mode": "claims",
"allow_offline_access": true,
"require_resource_indicator": false,
"dpop_required": false,
"mcp_profile": false,
"first_party_access": "all",
"introspection_applications": ["app_01h455vb4pex5vsknk084sn02r"],
"created_at": "2026-10-05T12:00:00Z",
"updated_at": "2026-10-05T12:00:00Z"
}
Errores
| HTTP | código | Cuándo |
|---|---|---|
| 400 | unknown_field |
El cuerpo contiene un campo que no está listado arriba (por ejemplo id o is_system). |
| 409 | conflict |
Una API con esta key o identifier ya existe. |
| 415 | unsupported_media_type |
El tipo de contenido no es application/json. |
| 422 | validation_failed |
Un campo está faltando o es inválido (errors[].pointer, por ejemplo /identifier). |
| 422 | validation_failed |
Un elemento introspection_applications no existe en este entorno (unknown_application), no es confidencial (not_confidential), es un duplicado (duplicate) o no es un ID app_… (invalid_value); el puntero nombra el índice en la solicitud. |
| 403 | quota_exceeded |
El entorno alcanzó su límite técnico de API. |
| 403 | insufficient_permissions |
La credencial carece de apis:write. |
Ejemplo
curl -X POST https://api.eu.keenauth.com/v1/apis \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"key":"orders","identifier":"https://api.example.com/orders","name":"Orders API"}'