Créer une API
POST /v1/apis · permission apis:write
Crée une API dans l'environnement. key, identifier et name sont obligatoires ; les champs optionnels omis prennent leurs valeurs par défaut. L'identifiant est unique dans l'environnement (une API supprimée conserve son identifiant réservé pendant 90 jours). La réponse porte une entête ETag avec la version actuelle. Envoyez une entête Idempotency-Key pour rendre les retentatives sûres.
Demande
Corps application/json. Les champs inconnus sont rejetés.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
key |
string | oui | Clé de configuration stable, ^[a-z0-9_-]{1,64}$. Immuable. |
identifier |
string | oui | Public cible du jeton : une URL https (sans requête ni fragment) ou urn:<nid>:<nss> ; stockée sous forme canonique. Immuable. L'espace de noms urn:idp: est réservé. |
name |
string | oui | 1-128 caractères. |
access_token_lifetime_s |
integer | non | 60-86400. Par défaut 3600 (600 avec mcp_profile). |
token_format |
string | non | jwt (par défaut) ou opaque. |
rbac_mode |
string | non | Mode par lequel les rôles et permissions atteignent le jeton : claims (par défaut) ajoute permissions et org_permissions ; off n'ajoute aucun des deux (org_roles est toujours ajouté) ; enforce les ajoute et limite en plus les scopes accordés aux permissions effectives de l'utilisateur. |
allow_offline_access |
boolean | non | Par défaut true. |
require_resource_indicator |
boolean | non | Par défaut false (true avec mcp_profile). |
dpop_required |
boolean | non | Par défaut false. |
mcp_profile |
boolean | non | Nécessite un identifier https et require_resource_indicator: true. |
first_party_access |
string | non | all (par défaut) ou granted_only. |
introspection_applications |
array | non | Applications (app_…) pouvant introspect les jetons de cette API, au maximum 50, pas de doublons. Uniquement des applications web et m2m du même environnement. Vide par défaut. |
Applications d'introspection
Le point de terminaison d'introspection (POST <issuer>/oauth2/introspect, RFC 7662) répond active: true pour un jeton d'accès uniquement à deux appelants : l'application à laquelle le jeton a été émis, ou une application dans la liste introspection_applications de l'API nommée dans le aud du jeton. Tous les autres appelants reçoivent active: false, de sorte que les API ne peuvent pas lire les jetons les uns des autres. Seules les applications confidentielles (web, m2m) du même environnement peuvent être répertoriées ; la liste est stockée sous forme d'ensemble et renvoyée dans l'ordre des identifiants. Une application suspendue reste sur la liste mais ne peut pas introspect. La liste de l'API système ne peut pas être écrite.
Réponse
201 Created avec une entête ETag et l'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"
}
Erreurs
| HTTP | code | Quand |
|---|---|---|
| 400 | unknown_field |
Le corps contient un champ qui n'est pas listé ci-dessus (par exemple id ou is_system). |
| 409 | conflict |
Une API avec cette key ou cet identifier existe déjà. |
| 415 | unsupported_media_type |
Le type de contenu n'est pas application/json. |
| 422 | validation_failed |
Un champ manque ou est invalide (errors[].pointer, par exemple /identifier). |
| 422 | validation_failed |
Un élément introspection_applications n'existe pas dans cet environnement (unknown_application), n'est pas confidentiel (not_confidential), est un doublon (duplicate) ou n'est pas un identifiant app_… (invalid_value) ; le pointeur nomme l'index dans la demande. |
| 403 | quota_exceeded |
L'environnement a atteint sa limite technique d'API. |
| 403 | insufficient_permissions |
Le credential manque apis:write. |
Exemple
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"}'