Create an Admin Portal link

POST /v1/admin-portal-links · permission admin-portal-links:write

Creates a link that lets the IT administrator of one of your customer organizations set up SSO, directory sync, domain verification and more in the hosted Admin Portal, without your support team. Generate a fresh link each time your administrator clicks "Set up SSO" in your application and redirect them to url right away: the link is valid for 5 minutes and opens one portal session exactly once. url is returned only in this response, once; no endpoint returns it later. The response carries Cache-Control: no-store, and a response replayed for the same Idempotency-Key omits url and carries secret_redacted: true. The portal session lasts 60 minutes idle, 8 hours at most; revoke it with DELETE /v1/admin-portal-links/{link_id}. The creation is audited as admin_portal_link.created (the URL never enters the audit log).

audit_logs needs the Business plan and log_streams the Enterprise plan; the other intents are available on every plan. delivery: email sends an invitation instead: it lives 7 days and is mailed to recipient_email; the response carries no url and no address. When the recipient opens it, a 6-digit code (valid 10 minutes) goes to the same address, and only the verified code opens the portal session. If the invitation mail cannot be sent, the call answers 503 service_unavailable with Retry-After and creates nothing. Revoke an invitation with DELETE /v1/admin-portal-links/{link_id}. The recipient address never appears in a response, a list, the audit log or a log.

Request

Field Type Required Description
organization_id string yes Organization ID (org_…); it must exist in this environment.
intents string[] yes 1–6 of sso, dsync, domain_verification, certificate_renewal, audit_logs (Business), log_streams (Enterprise), none twice.
return_url string yes Absolute https URL of at most 2048 bytes, without user information or fragment. Its origin must be the origin of a redirect_uri of an active application registered in this environment.
delivery string no link (default; 5-minute one-time url in the response) or email (7-day invitation mailed to recipient_email; no url).
recipient_email string no Only with delivery: email, and required there; at most 320 characters. Missing: 422 /recipient_email required; with delivery: link: not_allowed; not a valid address: invalid_value.

Response

201 Created with the link and its one-time url.

{
  "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>"
}

Errors

HTTP code When
403 plan_feature_unavailable An intent needs a higher plan; feature and required_plan name it.
404 not_found The organization does not exist in this environment.
409 organization_disabled The organization is not active (disabled); no link is created.
409 organization_pending_deletion The organization is scheduled for deletion; no link is created.
422 validation_failed A field is missing or invalid; /return_url origin_not_registered when its origin is not a registered application origin; /recipient_email required, not_allowed or invalid_value.
401 unauthenticated The credential is missing, invalid or revoked.
403 insufficient_permissions The credential lacks the required permission.
429 rate_limited The rate limit was exceeded; retry after the Retry-After period.
503 service_unavailable A dependency is temporarily unavailable, or (delivery: email) the invitation mail cannot be sent; nothing is created. Retry after the Retry-After period.

Example

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"}'

Send an invitation by 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; there is no url and no address in the response:

{
  "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"
}

With the 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.