Create an application

POST /v1/applications · permission applications:write

Creates an application (an OAuth/OIDC client) in the environment of the calling key. key, name, app_type and party are required; every other field gets a safe default derived from the application type. The response carries an ETag that you send as If-Match when updating or deleting. This operation does not create a client secret; secrets and keys are managed through the application credential endpoints.

Request

Body (application/json). Unknown fields are rejected. Only key, name, app_type and party are required.

Field Type Required Description
key string yes Stable configuration key, ^[a-z0-9_-]{1,64}$, unique per environment. Required on create; cannot change afterwards.
name string yes Display name, 1-100 characters.
app_type string yes web, spa, native, m2m, device or management. Required on create; cannot change afterwards.
party string yes first_party or third_party. Required on create; can only change from first_party to third_party.
owner_org_id string or null no org_… id of the owning organization; only for m2m applications; cannot change.
status string no active or suspended. A suspended application cannot get new tokens.
allowed_web_origins string[] no Allowed CORS origins (https://host[:port]), at most 20, no wildcards.
organization_usage string no deny, allow or require. Governs the organization authorization parameter (an org_… id or the organization's slug): deny refuses it, allow makes it optional, require makes it mandatory. The token carries org_id only after the user's membership is verified.
org_access_mode string no Organization sign-in access: all_organizations (default; every member of every organization), enabled_organizations (only organizations where the application is enabled) or assigned_only (additionally only assigned memberships or directory groups). See organization applications.
registration_mode string or null no open, invite_only or closed; empty inherits the environment setting.
registration_source string no dashboard or management_api on create (default management_api); cannot change. Responses may also show dcr or cimd.
verification_status string no verified or unverified.
security_profile string no baseline (the only writable profile today).
token_endpoint_auth_method string no private_key_jwt, client_secret_basic, client_secret_post or none; must be allowed for the app_type.
grant_types string[] no Allowed grant types; a subset of what the app_type permits.
default_api_id string or null no api_… id of the API used when a request has no resource.
require_par boolean no Require pushed authorization requests.
require_state boolean no Require state.
require_nonce boolean no Require nonce.
pkce_required boolean no Require PKCE; can be disabled only for a confidential web application. Without PKCE, nonce is the only defense against authorization code injection, so require_nonce must stay on outside development environments (otherwise validation_failed on /require_nonce).
skip_consent boolean no Skip the consent screen; first-party applications only.
token_binding_policy string no none or dpop_required.
login_host string or null no One of the environment's login hosts (lower-case DNS name).
default_max_age_s integer or null no Default max_age in seconds.
min_acr string or null no Minimum authentication assurance: urn:idp:acr:1fa, urn:idp:acr:mfa or urn:idp:acr:phr.
access_token_lifetime_s integer or null no Access token lifetime, 60-86400 seconds.
refresh_idle_s integer or null no Refresh token idle lifetime in seconds; not above refresh_absolute_s.
refresh_absolute_s integer or null no Refresh token absolute lifetime in seconds.
refresh_reuse_interval_s integer no Refresh token reuse window, 0-30 seconds (default 5).
backchannel_logout_uri string or null no Back-channel logout URI (https).
frontchannel_logout_uri string or null no Front-channel logout URI (https).
frontchannel_logout_session_required boolean no Adds iss and sid to the front-channel logout URI. Setting it to true while the environment's front-channel logout setting is off returns 422. Default false.
initiate_login_uri string no OIDC login initiation URI (OpenID Connect Core 1.0 §4): after an IdP-initiated SAML sign-in the browser is sent here with iss, and the application starts its own authorization code flow with state and PKCE. Absolute https URL with a lower-case DNS host, no fragment or user information, at most 2048 bytes; not allowed for m2m and management applications. Only an application with this URI can be an IdP-initiated target.
id_token_org_claims boolean no When true (default), the ID token of an organization sign-in carries org_id, org_slug and org_roles; when false, the ID token carries no organization claims. Access tokens are not affected, and ID tokens never carry permissions.
policy_uri string or null no Privacy policy URI (https), shown on the consent screen.
tos_uri string or null no Terms of service URI (https).
client_uri string or null no Application home page URI (https).
jwks object or null no Inline JWK Set ({"keys":[…]}): 1-5 public keys, at most 16 KiB; private key members are rejected. Mutually exclusive with jwks_uri.
jwks_uri string or null no Remote JWK Set URI (https); mutually exclusive with jwks.
software_id string or null no DCR applications only.
software_version string or null no DCR applications only.
m2m_token_lifetime_s integer or null no Token lifetime for m2m applications, 60-86400 seconds.
redirect_uris string[] no Allowed redirect URIs, at most 50; must be empty for m2m and management.
post_logout_redirect_uris string[] no Allowed post-logout redirect URIs, at most 50.
connection_ids string[] no Connections enabled on the application (conn_…), ordered; the order is the button order. At most 100.
allowed_first_factors string[] no First factors allowed on the application: values from password, passkey, email_otp, magic_link, sms_otp, social, enterprise, no duplicates; returned in this order. An empty list (the default) means the application adds no restriction. The set is intersected with the environment's allowed_first_factors; if no method is left, 422 policy_conflict.
allowed_response_modes string[] no The response_mode values the application may use in authorization and pushed authorization requests: query, form_post (one or both, no duplicates); returned in this order. Default ["query"]: an application that receives the authorization response by form post adds form_post explicitly. An authorization request whose response_mode is not in the list is rejected; a request without response_mode uses query. An empty list returns 422. JARM modes (jwt, query.jwt, fragment.jwt, form_post.jwt) are not supported yet. Applications registered through dynamic client registration or a client ID metadata document get ["query"].

Response

201 Created with the application and an ETag header.

{
  "id": "app_6f8d0cjgbmf0gtn2rg6pscp3cg",
  "client_id": "app_6f8d0cjgbmf0gtn2rg6pscp3cg",
  "version": 1,
  "created_at": "2026-10-05T10:00:01Z",
  "updated_at": "2026-10-05T10:00:01Z",
  "key": "portal",
  "name": "Portal",
  "app_type": "web",
  "party": "first_party",
  "status": "active",
  "redirect_uris": ["https://portal.example.com/cb"],
  "...": "all other fields from the field reference"
}

Errors

HTTP code When
401 unauthenticated The key is missing, invalid or revoked.
403 insufficient_permissions The key lacks the required permission.
409 conflict An application with this key already exists.
422 validation_failed A field is invalid; errors[].pointer names it (for example /redirect_uris/0).
422 policy_conflict allowed_first_factors has no method in common with the environment's first-factor set.
400 unknown_field The body has a field that is not part of the schema.
403 quota_exceeded The plan limit for applications is reached.

Example

curl -X POST https://api.eu.keenauth.com/v1/applications \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"key":"portal","name":"Portal","app_type":"web","party":"first_party","redirect_uris":["https://portal.example.com/cb"]}'

Response fields

id and client_id are the application id (app_…); version is also returned as ETag; created_at, updated_at, last_token_issued_at and last_token_asn are read-only. Every writable field above is returned. Client secrets are never part of this resource.