
# Update the organization defaults

`PATCH /v1/organization-defaults` · permission `organizations:write`

Updates the environment's organization defaults with a JSON merge patch (`application/merge-patch+json`, RFC 7396). `If-Match` is required: missing gives `428`, a stale version gives `412`. Send only the fields you change. A patch that changes nothing writes nothing and keeps the version.

## Request

| Field | Type | Required | Description |
|---|---|---|---|
| `If-Match` | header | yes | The `ETag` of the defaults as last read. Missing: `428`; stale: `412`. |
| `org_admin_role_id` | string | no | Environment role (`rol_…`) that organization admins get. It must hold the organization management system permissions (`422 permission_reserved`), and no organization may be left without an active admin (`409 last_org_admin`). Cannot be `null`. |
| `default_member_role_id` | string | no | Environment role (`rol_…`) new organization members get. Cannot be `null`. |
| `max_memberships_per_user` | integer | no | Organizations one user can belong to, 1-1000 (default 200). Cannot be `null`. |
| `invitation_ttl_days` | integer | no | Days an invitation stays valid, 1-30 (default 7). Cannot be `null`. |
| `org_self_service_deletion_grace_days` | integer | no | Days a self-service organization deletion waits before it runs, 0-30 (default 14). Cannot be `null`. |
| `on_org_delete_members` | string | no | `detach` (default): members only lose the membership. `delete_exclusive_provisioned`: users who came to this organization through JIT or SCIM and belong to no other organization are queued for deletion. Cannot be `null`. |
| `org_custom_roles_enabled` | boolean | no | Lets organization admins define their own roles (default `false`). Writing organization roles still needs the `org_custom_roles` plan feature. Cannot be `null`. |
| `org_self_delete_enabled` | boolean | no | Lets organization admins delete their organization themselves (default `false`). Cannot be `null`. |

## Behavior

- Role fields must name a role of this environment; an organization role or an unknown role returns `422 validation_failed` with `unknown_role`.
- Changing `on_org_delete_members` applies to organizations deleted after the change.
- Validation errors carry the JSON pointer of the field, for example `/invitation_ttl_days` with code `out_of_range`.
- The change is written to the management audit log as `organization_defaults.updated` with the names of the changed fields, never their values.

## Response

`200 OK` with the updated defaults and the new `ETag`.

```json
{
  "org_admin_role_id": "rol_01j9xs0a2b4c6d8e0f2g4h6j8k",
  "default_member_role_id": "rol_01j9xs0a2b4c6d8e0f2g4h6j8m",
  "max_memberships_per_user": 200,
  "invitation_ttl_days": 9,
  "org_self_service_deletion_grace_days": 14,
  "on_org_delete_members": "delete_exclusive_provisioned",
  "org_custom_roles_enabled": false,
  "org_self_delete_enabled": false,
  "updated_at": "2026-11-03T10:00:00.123456Z",
  "version": 2
}
```

## Errors

| HTTP | code | When |
|---|---|---|
| 400 | `unknown_field` | The patch contains an unknown or read-only field, or is not a JSON object (`malformed_request`). |
| 403 | `insufficient_permissions` | The credential lacks the required permission. |
| 409 | `last_org_admin` | The new admin role would leave an organization without an active admin. |
| 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 (the pointer names the field), or a field was set to `null` (`code: invalid`). |
| 428 | `precondition_required` | `If-Match` is missing. |

## Example

```bash
curl -i -X PATCH "https://api.eu.keenauth.com/v1/organization-defaults" \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/merge-patch+json" \
  -H 'If-Match: "1"' \
  -d '{"on_org_delete_members":"delete_exclusive_provisioned","invitation_ttl_days":9}'
```

```bash
keenauth organization-defaults update --if-match '"1"' \
  --on-org-delete-members delete_exclusive_provisioned --invitation-ttl-days 9
```
