Simulate SCIM provisioning

POST /v1/directories/{directory_id}:simulate · permission directories:write · development and staging only

Runs one SCIM simulator scenario against the directory's real SCIM endpoint. For the run only, KeenAuth mints a real SCIM token, uses it, and then revokes it. Token checks, rate limits, the mass deprovision circuit breaker and the provisioning log all run exactly as they do for your identity provider. The users are a fixed fictional set: 25 people at example.test in 5 groups. They contain no real personal data.

The simulator is a development tool and changes the directory. The users and groups it writes stay in the directory like any other provisioned records. Use a directory you created for testing.

Scenario What it does
seed Creates the 25 users and the 5 groups with their memberships. In a directory that already holds them, the first user gets a SCIM 409 and the run is failed.
bulk_deactivate Sends active=false for 60% of the users (15 of 25). The circuit breaker trips only when the directory's mass_deprovision_guard.absolute_min is 15 or lower. With the default of 25 it does not trip.
group_churn Moves a user from one group to another.
attribute_update Changes every user's display name and family name.
conflict_email Creates a user with an existing userName and expects a SCIM 409 uniqueness.

When the directory is empty, every scenario except seed runs seed first.

The simulation token is never listed and does not count toward the 2 valid tokens. Using it does not start the rotation of your identity provider's token. Only one run per directory can be in progress at a time. The run is audited as directory.simulation_started and directory.simulation_finished.

Request

Field Type Required Description
directory_id path yes SCIM directory ID (dir_…).
scenario body, string yes seed, bulk_deactivate, group_churn, attribute_update or conflict_email.
Idempotency-Key header no Replays the first response for a retried request; the scenario does not run again.
{"scenario": "bulk_deactivate"}

Response

200 OK with the run's result. A SCIM error answer does not fail the request. It makes the run failed, fills failure and leaves the counts at what succeeded before the error. The result has counts and states only: no user, no SCIM ID and no token.

{
  "directory_id": "dir_01j9xm2n4p6q8r0s2t4v6w8y0z",
  "scenario": "bulk_deactivate",
  "status": "completed",
  "users_created": 0,
  "groups_created": 0,
  "users_updated": 0,
  "groups_updated": 0,
  "users_deactivated": 15,
  "conflicts": 0,
  "circuit_breaker_tripped": true,
  "deprovision_hold": {"id": "0191e9b2-6f3a-7c4d-8e5f-0a1b2c3d4e5f", "pending_count": 6},
  "failure": null,
  "started_at": "2026-10-28T09:31:00.123456Z",
  "completed_at": "2026-10-28T09:31:01.654321Z"
}
Field Description
status completed, or failed when the endpoint answered with a SCIM error, the run took too long, or an answer was not what the scenario expected.
users_updated User PATCHes other than deactivations.
users_deactivated active=false PATCHes the endpoint accepted, held ones included.
conflicts Expected 409 uniqueness answers (conflict_email).
circuit_breaker_tripped A mass deprovision hold was opened during the run.
deprovision_hold The directory's open hold after the run, or null. Approve or reject it with the deprovision-holds endpoints.
failure null when completed. Otherwise reason (scim_error, timeout or unexpected_response), and for scim_error also scim_status (HTTP status) and scim_type (SCIM scimType, or null).

Errors

HTTP code When
400 unknown_field The body contains a field other than scenario.
403 test_feature_not_in_production The environment is a production environment.
404 not_found The directory does not exist in this environment.
409 conflict Another run of this directory is in progress, or the directory is deactivated or being deleted.
422 validation_failed scenario is missing or unknown (/scenario).
422 idempotency_key_reuse The Idempotency-Key was used for a different request.
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 Directory sync or the simulator is temporarily unavailable or not configured in this deployment; retry after the Retry-After period.

Example

curl -X POST "https://api.eu.keenauth.com/v1/directories/dir_01j9xm2n4p6q8r0s2t4v6w8y0z:simulate" \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"scenario": "seed"}'
keenauth directories simulate dir_01j9xm2n4p6q8r0s2t4v6w8y0z --scenario bulk_deactivate