Update a connection

PATCH /v1/connections/{connection_id} · permission connections:write

Updates a connection with a JSON merge patch (application/merge-patch+json, RFC 7396). If-Match is required. key, type, strategy and org_id cannot be changed. A patch that changes nothing writes nothing and keeps the version. Settings must not contain secrets.

Request

Field Type Required Description
connection_id string yes Connection identifier (conn_…).
If-Match header yes The ETag of the connection as last read. Missing: 428; stale: 412.
key string no Cannot change; the same value is accepted.
type string no Cannot change.
strategy string no Cannot change.
name string no 1-128 characters.
display_name string | null no null clears it.
status string no active or inactive.
org_id string | null no Cannot change; the same value is accepted.
allowed_email_domains array of strings | null no Replaces the list; null or [] clears it. Same rules as on create; on an organization connection only newly added domains are checked against the organization's verified domains.
allow_external_domains boolean no enterprise only.
jit_mode string no create, create_and_update or off. enterprise only.
email_trust boolean no enterprise only. Turning it on for an organization connection needs a non-empty allowed_email_domains in which every domain is a verified domain of the organization.
default_role_ids array of strings | null no Replaces the list; null or [] clears it. Same rules as on create; only newly added roles are checked, so a role already in the list that was deleted later does not block the update (it is skipped at sign-in).
trust_idp_mfa boolean no enterprise only.
settings object | null no Merged recursively (RFC 7396); a null member deletes that key; null clears all settings. No secrets.

Response

200 OK with the updated connection and the new ETag.

{
  "id": "conn_0k3v8m1q2x9dz4h7s5t6w0y1ab",
  "key": "google",
  "type": "social",
  "strategy": "google",
  "name": "Google",
  "display_name": "Sign in with Google",
  "status": "active",
  "org_id": null,
  "allowed_email_domains": [],
  "allow_external_domains": false,
  "jit_mode": null,
  "email_trust": null,
  "default_role_ids": [],
  "trust_idp_mfa": null,
  "allow_idp_initiated": null,
  "idp_initiated_default_application_id": null,
  "idp_initiated_allowed_application_ids": [],
  "settings": {},
  "created_at": "2026-10-05T09:30:00.123456Z",
  "updated_at": "2026-10-05T09:30:00.123456Z"
}

Passkey settings

For type: "passkey" the settings object accepts only the keys below. Any other key, a wrong type or an out-of-range value is rejected with 422 validation_failed and an errors[].pointer such as /settings/max_credentials_per_user. A null value means the default. Shape errors are reported before plan errors.

Key Type Notes
rp_id string Absent, null or empty: each sign-in host is its own rpId. Otherwise the host name of an active custom domain of the environment (lower-case, IDNA A-label); any other value is 422 validation_failed (/settings/rp_id). Once the environment has passkeys, change it with Change the passkey rpId.
rp_name string Up to 128 characters.
passkey_first_factor_enabled, security_key_second_factor_enabled boolean Default true.
user_verification string preferred (default) or required.
max_credentials_per_user integer 1-20, default 20; fractions are rejected.
require_device_bound_passkeys boolean Plan-gated: true needs Startup.
attestation_required boolean Plan-gated: true needs Enterprise.
aaguid_allowlist, aaguid_blocklist array of UUID strings At most 500 unique entries each (errors point at /settings/<key>/<index>). Plan-gated: a non-empty list needs Enterprise.
related_origins array of strings https://host[:port] origins. Plan-gated: a non-empty list needs Enterprise.
passkey_enrollment_prompt string off or after_login (default).

Writing a non-default value of a plan-gated key fails with 403 plan_feature_unavailable and the members feature and required_plan. Until plan entitlements are available, these keys cannot be set in any environment; writing a default value (false, [], null) or removing the key is always allowed. When the feature is available, every related_origins entry must be an active verified custom domain of the environment, otherwise the request fails with 422 related_origin_not_verified. The settings are validated after the merge patch is applied, only when settings is part of the patch.

Errors

HTTP code When
400 unknown_field The patch contains an unknown or read-only field.
404 not_found The connection does not exist or belongs to another environment.
409 connection_test_required The patch sets an enterprise connection to active, or adds a domain to allowed_email_domains of an active one, without a successful test of the resulting configuration in the last 24 hours (see Activate a connection); nothing is written. Removing domains is not checked.
409 rp_id_change_requires_migration The patch changes settings.rp_id of a passkey connection while the environment has passkeys that would stop working; use Change the passkey rpId. Nothing is written.
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 or an immutable field changed (code: immutable).
422 related_origin_not_verified A related origin is not a verified custom domain of the environment.
403 plan_feature_unavailable The plan does not include a setting you set (feature, required_plan members), for example attestation_required.
428 precondition_required The If-Match header is missing.
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 (for example, the passkey check of an rp_id change could not run, so nothing is written); retry after the Retry-After period.

Example

curl -X PATCH https://api.eu.keenauth.com/v1/connections/conn_0k3v8m1q2x9dz4h7s5t6w0y1ab \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/merge-patch+json" \
  -H 'If-Match: "1"' \
  -d '{"display_name":"Sign in with Google"}'