List the revisions of a connection
GET /v1/connections/{connection_id}/revisions · permission connections:read
Lists the revisions of an enterprise (SAML or OIDC) connection, newest first: the pending draft (at most one) and the revisions published or discarded in the last 90 days.
On an active connection, a security-critical change is not applied directly. It becomes a draft revision and the live configuration stays as it is until you test and publish the draft:
- importing SAML metadata that changes the identity provider's entity ID or SSO URL, or removes a signing pin (Import metadata);
- changing the OIDC
issuerorclient_id(Put the OIDC configuration); - every SP host migration, whatever the connection's status (Migrate the SP host).
Test a draft with Test a connection and its revision_id, then publish it. A new draft discards the previous one (discard_reason: superseded).
A revision shows only the new non-secret values (changes). A new OIDC client secret appears only as client_secret_change (keep, replace or clear); the secret and its last characters are never returned. Who made or decided a revision is recorded in the management audit log (connection.revision_created, connection.revision_published), not here.
Request
| Field | Type | Required | Description |
|---|---|---|---|
connection_id |
path | yes | Enterprise connection ID (conn_…). |
limit |
query | no | Page size, 1–100 (default 20). |
after |
query | no | Cursor from list_metadata.after. A cursor works only for the connection that produced it. |
The list is paged forward only: before and order are not supported (422).
Response
200 OK:
{
"data": [
{
"id": "connrev_01j9xr8c2d4e6f8g0h2j4k6m8n",
"connection_id": "conn_01j9xp6q0r1s5t7v9w1x3y5z7b",
"protocol": "saml",
"kind": "sp_host",
"status": "draft",
"discard_reason": null,
"created_at": "2026-10-28T10:00:00Z",
"decided_at": null,
"purge_after": null,
"superseded_revision_id": null,
"changes": {
"sp_host": "login.example.com",
"idp_entity_id": null,
"idp_sso_url": null,
"idp_slo_url": null,
"certificate_fingerprints": [],
"mfa_authn_context_values": null,
"issuer": null,
"client_id": null,
"client_auth_method": null,
"provider_profile": null,
"client_secret_change": null
},
"latest_test": {
"test_id": "conntest_01j9xr4a6b8c0d2e4f6g8h0j2k",
"status": "passed",
"failure_reason": null,
"started_at": "2026-10-28T10:05:00Z",
"completed_at": "2026-10-28T10:06:00Z"
}
}
],
"list_metadata": { "before": null, "after": null }
}
| Field | Description |
|---|---|
kind |
configuration (identity provider or OIDC client change) or sp_host (SP host migration). |
status |
draft (waiting for test and publication), published or discarded. |
decided_at / purge_after |
When the revision was published or discarded, and when it is deleted (90 days later); null for a draft. |
changes |
The new values. Fields that the revision does not change are null. |
latest_test |
The latest test sign-in of this revision from the last 24 hours, or null. Publication needs a passed one. |
Errors
| HTTP | code | When |
|---|---|---|
| 400 | invalid_cursor |
The cursor is malformed or belongs to another connection or query. |
| 401 | unauthenticated |
The credential is missing, invalid or revoked. |
| 403 | insufficient_permissions |
The credential lacks connections:read. |
| 404 | not_found |
The connection does not exist in this environment or is not an enterprise connection. |
| 422 | validation_failed |
A query parameter is invalid (for example limit above 100, or before). |
| 429 | rate_limited |
The rate limit was exceeded; retry after the Retry-After period. |
| 503 | service_unavailable |
A dependency is temporarily unavailable; retry after the Retry-After period. |
Example
curl "https://api.eu.keenauth.com/v1/connections/conn_01j9xp6q0r1s5t7v9w1x3y5z7b/revisions?limit=20" \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY"
keenauth connections revisions list conn_01j9xp6q0r1s5t7v9w1x3y5z7b --limit 20