Créer un lien Admin Portal
POST /v1/admin-portal-links · permission admin-portal-links:write
Crée un lien qui permet à l'administrateur informatique de l'une de vos organisations clientes de configurer SSO, la synchronisation d'annuaire, la vérification de domaine et plus encore dans le Admin Portal hébergé, sans passer par votre équipe de support. Générez un lien neuf chaque fois que votre administrateur clique sur « Configurer SSO » dans votre application, puis redirigez-le immédiatement vers url : le lien est valable 5 minutes et ouvre une seule session de portail, une seule fois. url n'est renvoyée que dans cette réponse, une seule fois ; aucun point de terminaison ne la renvoie ensuite. La réponse porte Cache-Control: no-store, et une réponse rejouée pour le même Idempotency-Key omet url et porte secret_redacted: true. La session de portail dure 60 minutes d'inactivité, 8 heures au maximum ; révoquez-la avec DELETE /v1/admin-portal-links/{link_id}. La création est auditée sous admin_portal_link.created (l'URL n'entre jamais dans le journal d'audit).
audit_logs nécessite le plan Business et log_streams le plan Enterprise ; les autres intentions sont disponibles sur tous les plans. delivery: email envoie plutôt une invitation : elle reste valable 7 jours et est envoyée par e-mail à recipient_email ; la réponse ne contient ni url ni adresse. Lorsque le destinataire l'ouvre, un code à 6 chiffres (valable 10 minutes) est envoyé à la même adresse, et seul le code vérifié ouvre la session de portail. Si l'e-mail d'invitation ne peut pas être envoyé, l'appel répond 503 service_unavailable avec Retry-After et ne crée rien. Révoquez une invitation avec DELETE /v1/admin-portal-links/{link_id}. L'adresse du destinataire n'apparaît jamais dans une réponse, une liste, le journal d'audit ou un journal.
Requête
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
organization_id |
string | oui | Identifiant de l'organisation (org_…) ; elle doit exister dans cet environnement. |
intents |
string[] | oui | 1 à 6 valeurs parmi sso, dsync, domain_verification, certificate_renewal, audit_logs (Business), log_streams (Enterprise), sans doublon. |
return_url |
string | oui | URL https absolue d'au plus 2048 octets, sans informations utilisateur ni fragment. Son origine doit être celle d'un redirect_uri d'une application active enregistrée dans cet environnement. |
delivery |
string | non | link (par défaut ; url à usage unique valable 5 minutes dans la réponse) ou email (invitation valable 7 jours envoyée à recipient_email ; sans url). |
recipient_email |
string | non | Uniquement avec delivery: email, et obligatoire dans ce cas ; 320 caractères au maximum. Absent : 422 /recipient_email required ; avec delivery: link : not_allowed ; adresse invalide : invalid_value. |
Réponse
201 Created avec le lien et son url à usage unique.
{
"id": "apl_01j9xv2c4d6e8f0g2h4j6k8m0n",
"organization_id": "org_01j9xk3m7q8r2s4t6v8w0y2z4a",
"intents": [
"dsync",
"sso"
],
"delivery": "link",
"return_url": "https://app.example.com/settings/sso",
"expires_at": "2026-10-12T09:36:00.123456Z",
"consumed_at": null,
"revoked_at": null,
"created_at": "2026-10-12T09:31:00.123456Z",
"url": "https://acme.eu.keenauth.app/portal/l/<token>"
}
Erreurs
| HTTP | code | Quand |
|---|---|---|
| 403 | plan_feature_unavailable |
Une intention exige un plan supérieur ; feature et required_plan la désignent. |
| 404 | not_found |
L'organisation n'existe pas dans cet environnement. |
| 409 | organization_disabled |
L'organisation n'est pas active (désactivée) ; aucun lien n'est créé. |
| 409 | organization_pending_deletion |
L'organisation est programmée pour suppression ; aucun lien n'est créé. |
| 422 | validation_failed |
Un champ est absent ou invalide ; /return_url origin_not_registered lorsque son origine n'est pas celle d'une application enregistrée ; /recipient_email required, not_allowed ou invalid_value. |
| 401 | unauthenticated |
L'identifiant est absent, invalide ou révoqué. |
| 403 | insufficient_permissions |
L'identifiant ne dispose pas de la permission requise. |
| 429 | rate_limited |
La limite de débit a été dépassée ; réessayez après le délai Retry-After. |
| 503 | service_unavailable |
Une dépendance est temporairement indisponible, ou (delivery: email) l'e-mail d'invitation ne peut pas être envoyé ; rien n'est créé. Réessayez après le délai Retry-After. |
Exemple
curl -i -X POST "https://api.eu.keenauth.com/v1/admin-portal-links" \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"organization_id":"org_01j9xk3m7q8r2s4t6v8w0y2z4a","intents":["sso","dsync"],"return_url":"https://app.example.com/settings/sso"}'
Envoyer une invitation par e-mail
curl -i -X POST "https://api.eu.keenauth.com/v1/admin-portal-links" \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"organization_id":"org_01j9xk3m7q8r2s4t6v8w0y2z4a","intents":["sso"],"return_url":"https://app.example.com/settings/sso","delivery":"email","recipient_email":"it@customer.example"}'
201 Created ; la réponse ne contient ni url ni adresse :
{
"id": "apl_01j9xv2c4d6e8f0g2h4j6k8m0n",
"organization_id": "org_01j9xk3m7q8r2s4t6v8w0y2z4a",
"intents": [
"sso"
],
"delivery": "email",
"return_url": "https://app.example.com/settings/sso",
"expires_at": "2026-10-19T09:31:00.123456Z",
"consumed_at": null,
"revoked_at": null,
"created_at": "2026-10-12T09:31:00.123456Z"
}
Avec la CLI : keenauth admin-portal-links create --organization-id org_01j9xk3m7q8r2s4t6v8w0y2z4a --intents sso --return-url https://app.example.com/settings/sso --delivery email --recipient-email it@customer.example.