Update an API
PATCH /v1/apis/{api_id} · permission apis:write
Updates an API with a JSON merge patch (RFC 7396, application/merge-patch+json): fields you send change, fields you omit stay. If-Match is required. key and identifier cannot change after creation, and the system API cannot be modified. A patch that changes nothing writes nothing and keeps the version.
Request
| Parameter | In | Description |
|---|---|---|
api_id |
path | The API id. |
If-Match |
header | The ETag from the last read (required). |
Body: any of the writable fields below (all optional). A field cannot be removed with null.
| Field | Type | Required | Description |
|---|---|---|---|
key |
string | no | Stable configuration key, ^[a-z0-9_-]{1,64}$. Immutable. |
identifier |
string | no | Token audience: an https URL (no query or fragment) or urn:<nid>:<nss>; stored in canonical form. Immutable. The urn:idp: namespace is reserved. |
name |
string | no | 1-128 characters. |
access_token_lifetime_s |
integer | no | 60-86400. Default 3600 (600 with mcp_profile). |
token_format |
string | no | jwt (default) or opaque. |
rbac_mode |
string | no | How roles and permissions reach the token: claims (default) adds permissions and org_permissions; off adds neither (org_roles is still added); enforce adds them and also limits the granted scopes to the user's effective permissions. |
allow_offline_access |
boolean | no | Default true. |
require_resource_indicator |
boolean | no | Default false (true with mcp_profile). |
dpop_required |
boolean | no | Default false. |
mcp_profile |
boolean | no | Requires an https identifier and require_resource_indicator: true. |
first_party_access |
string | no | all (default) or granted_only. |
introspection_applications |
array | no | Applications (app_…) that may introspect this API's tokens, at most 50, no duplicates. Only web and m2m applications of the same environment. The list is replaced as a whole; [] empties it, null is refused. |
Introspection applications
The introspection endpoint (POST <issuer>/oauth2/introspect, RFC 7662) answers active: true for an access token only to two callers: the application the token was issued to, or an application in the introspection_applications list of the API named in the token's aud. Every other caller gets active: false, so APIs cannot read each other's tokens. Only confidential applications (web, m2m) of the same environment can be listed; the list is stored as a set and returned in id order. A suspended application stays on the list but cannot introspect. The system API's list cannot be written.
Response
200 OK with the new ETag:
{
"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": "off",
"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"
}
Errors
| HTTP | code | When |
|---|---|---|
| 400 | unknown_field |
The patch contains a read-only or unknown field. |
| 404 | not_found |
No such API in this environment. |
| 409 | conflict |
The API is the system API. |
| 412 | precondition_failed |
If-Match does not match the current version. |
| 415 | unsupported_media_type |
The content type is not application/merge-patch+json. |
| 422 | validation_failed |
A value is invalid, a field was set to null, or key / identifier was changed. |
| 422 | validation_failed |
An introspection_applications item does not exist in this environment (unknown_application), is not confidential (not_confidential), is a duplicate (duplicate) or is not an app_… id (invalid_value); the pointer names the index in the request. |
| 428 | precondition_required |
If-Match is missing. |
Example
curl -X PATCH https://api.eu.keenauth.com/v1/apis/api_01h455vb4pex5vsknk084sn02q \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H "Content-Type: application/merge-patch+json" \
-H 'If-Match: "1"' \
-d '{"access_token_lifetime_s":900}'