POST /api/v1/admin/users/{id}/actions
Operation: adminUserAction.
User management command (Admin+step-up); typed reason, expected version, audit event
One of five commands. Every one requires an admin session with an enrolled TOTP factor, a fresh admin-sensitive step-up grant, an Idempotency-Key, a typed reason and the expected_version read from GET /api/v1/admin/users/{id}. A stale version is 409 STALE_VERSION and writes nothing. There is no balance action here and there must never be one.
set_role and set_suspension are refused with 409 CONFLICT when they would leave the system with zero admins; the check locks the admin set inside the transaction, so two demotions racing cannot both succeed.
set_suspension blocks sign-in and every API key on the next request and stops new admissions for the account, but never cancels a running rental: it keeps metering and billing to funded expiry or stop. reset_mfa clears the enrolment and every session so the user must re-enrol; it never reveals or sets a secret.
Endpoint
Section titled “Endpoint”POST https://amplerun-api.spiry.org/api/v1/admin/users/{id}/actions
Authentication
Section titled “Authentication”Admin interactive session. API keys do not authorize administrative operations. Sensitive writes also require the stated fresh step-up proof; account MFA is configurable.
Parameters
Section titled “Parameters”| Name | Location | Presence | Type | Description |
|---|---|---|---|---|
id | path | Required | string | |
Idempotency-Key | header | Required | UUID | UUID scoped to authenticated principal, route and canonical request hash. |
Request body
Section titled “Request body”Required body.
application/json
Section titled “application/json”{ "oneOf": [ { "type": "object", "additionalProperties": false, "required": [ "action", "role", "reason", "expected_version" ], "properties": { "action": { "type": "string", "enum": [ "set_role" ] }, "role": { "type": "string", "enum": [ "renter", "host", "admin" ] }, "reason": { "type": "string", "minLength": 5, "maxLength": 2000 }, "expected_version": { "type": "string", "minLength": 1 } } }, { "type": "object", "additionalProperties": false, "required": [ "action", "enabled", "reason", "expected_version" ], "properties": { "action": { "type": "string", "enum": [ "set_host_capability" ] }, "enabled": { "type": "boolean" }, "reason": { "type": "string", "minLength": 5, "maxLength": 2000 }, "expected_version": { "type": "string", "minLength": 1 } } }, { "type": "object", "additionalProperties": false, "required": [ "action", "suspended", "reason", "expected_version" ], "properties": { "action": { "type": "string", "enum": [ "set_suspension" ] }, "suspended": { "type": "boolean" }, "reason": { "type": "string", "minLength": 5, "maxLength": 2000 }, "expected_version": { "type": "string", "minLength": 1 } } }, { "type": "object", "additionalProperties": false, "required": [ "action", "reason", "expected_version" ], "properties": { "action": { "type": "string", "enum": [ "revoke_sessions", "reset_mfa" ] }, "reason": { "type": "string", "minLength": 5, "maxLength": 2000 }, "expected_version": { "type": "string", "minLength": 1 } } } ]}Responses
Section titled “Responses”Applied. Returns the new version, what changed and the stated consequence.
Error envelope. 401 unauthenticated, 403/404 forbidden, 409 conflict, 422 invalid input, 429 rate limited (code UNAVAILABLE, retryable:true, no Retry-After header), 503 unavailable money/provider state with retryable:true.
application/json
| Field | Type | Presence | Description |
|---|---|---|---|
error | object | Required |
{ "$ref": "#/components/schemas/ErrorEnvelope"}default
Section titled “default”Error envelope. 401 unauthenticated, 403/404 forbidden, 409 conflict, 422 invalid input, 429 rate limited (code UNAVAILABLE, retryable:true, no Retry-After header), 503 unavailable money/provider state with retryable:true.
application/json
| Field | Type | Presence | Description |
|---|---|---|---|
error | object | Required |
{ "$ref": "#/components/schemas/ErrorEnvelope"}Static request outline
Section titled “Static request outline”Replace path/query placeholders and provide the required JSON body, headers and credential from the sections above. This is a request outline, not a command that chooses an amount or starts a rental for you.
curl --request POST 'https://amplerun-api.spiry.org/api/v1/admin/users/{id}/actions'Schema definitions · Download OpenAPI · Authentication · Errors and recovery
Official AmpleRun documentation · Contract v3 · Generated from the API contract · Revision 52fe29de · Open AmpleRun · View Markdown · For agents