Delete own account
curl --request POST \ --url http://localhost:9090/api/v1/account/deletion \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "password": "example", "otpCode": "example", "recoveryCode": "example" }'Deletes the authenticated user’s account, at once. This can’t be undone. Requires the
user’s password and, while two-factor authentication is on, a current code from the
authenticator (otpCode) or one of the user’s recovery codes (recoveryCode), not both.
The deletion removes the user’s profile, password, authenticator, recovery codes, picture, groups, permissions, attributes and consents, and every session they have, so their refresh tokens are revoked and their access tokens are refused from then on. The user is emailed that their account was deleted, when SMTP is configured and their address is verified.
Only a token issued to the admin console’s own client may call this. Any other client’s
token is refused with 403 (CLIENT_NOT_ALLOWED), whatever its scopes, and the
WWW-Authenticate header says error="insufficient_scope". When an administrator has
turned off Let users delete their own account, the request is refused with 403
(ACCOUNT_DELETION_DISABLED).
The last enabled user holding authserver:manage can’t delete their account: the request is
refused with 409 (LAST_ADMINISTRATOR).
A wrong or blank password is refused with 400 (AUTHENTICATION_FAILED). With two-factor
authentication on, no code is refused with 400 (OTP_CODE_REQUIRED), a wrong or already
used authenticator code with 400 (INVALID_OTP_CODE), the authenticator’s next code, which
only a device whose clock runs ahead shows, with 400 (OTP_CLOCK_AHEAD), and a wrong or
already used recovery code with 400 (INVALID_RECOVERY_CODE). Both codes at once are
refused with 400 (VALIDATION_ERROR). A refused deletion spends no recovery code.
A wrong password, authenticator code or recovery code counts against the account_password
rate limit, shared with the account’s password, two-factor and email changes and new sets
of recovery codes.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
The user’s current password.
A current 6-digit code from the user’s authenticator. Required while two-factor authentication is on, unless recoveryCode is sent instead.
One of the user’s unused recovery codes, in place of otpCode. Send one or the other, not both.
Example generated
{ "password": "example", "otpCode": "example", "recoveryCode": "example"}Responses
Section titled “Responses”The account was deleted
object
Example generated
{ "success": true}Invalid request body or parameters
Admin/account API error envelope. Routing by HTTP status code: 4xx is a client-correctable failure (validation, not found, permission denied, rate limited); 5xx is a server-side problem. The body provides a stable error_code and an error_description for people to read. Protocol endpoints (/auth/token, /auth/authorize, /connect/register, /userinfo) use their RFC-defined error envelopes instead of this one.
object
Stable identifier for the failure. UPPER_SNAKE for legacy codes (e.g. VALIDATION_ERROR), dotted lowercase for codes named after the sentence’s catalog key (e.g. validator.email.required). Never translated, whatever the request’s language.
A sentence for people to read: in the request’s language, from the ui_locales query parameter or else the Accept-Language header, when the server has the sentence in that language, and in English otherwise. Route on error_code, not on this text.
Example generated
{ "error_code": "example", "error_description": "example"}Headers
Section titled “Headers”Bearer challenge when token transport is malformed; ordinary validation errors omit it.
Missing or invalid access token (ACCESS_TOKEN_REQUIRED, INVALID_TOKEN), or a refused DPoP proof (INVALID_DPOP_PROOF)
Admin/account API error envelope. Routing by HTTP status code: 4xx is a client-correctable failure (validation, not found, permission denied, rate limited); 5xx is a server-side problem. The body provides a stable error_code and an error_description for people to read. Protocol endpoints (/auth/token, /auth/authorize, /connect/register, /userinfo) use their RFC-defined error envelopes instead of this one.
object
Stable identifier for the failure. UPPER_SNAKE for legacy codes (e.g. VALIDATION_ERROR), dotted lowercase for codes named after the sentence’s catalog key (e.g. validator.email.required). Never translated, whatever the request’s language.
A sentence for people to read: in the request’s language, from the ui_locales query parameter or else the Accept-Language header, when the server has the sentence in that language, and in English otherwise. Route on error_code, not on this text.
Example generated
{ "error_code": "example", "error_description": "example"}Headers
Section titled “Headers”A Bearer challenge, then a DPoP challenge naming the accepted proof algorithms, on
token refusals, the error in the challenge of the scheme the token was sent with:
Bearer realm="goiabada", error="invalid_token", error_description="...", DPoP realm="goiabada", algs="ES256 ...". An operation may also return a handler-level
401 without this header.
The token is valid but does not authorise this request. A caller tells the refusals apart by error_code.
INSUFFICIENT_SCOPE comes from the route’s authorisation middleware,
before the handler runs: an Admin operation needs one of the scopes
its route names, and an Account operation needs
authserver:manage-account.
USER_CONTEXT_REQUIRED comes from the same middleware on the Account operations, which also require the token to have been issued for a user: one obtained through the client credentials grant carries no auth_time claim and is refused here.
FORBIDDEN comes from the handler, on the account endpoints that resolve a resource by id and then check it belongs to the caller, so a valid token for the wrong user reaches this rather than a 404.
CLIENT_NOT_ALLOWED comes from the route on the two Account
operations only the admin console’s own client may call,
deleteAccount and exportAccount. ACCOUNT_DELETION_DISABLED comes
from deleteAccount while an administrator has turned off Let
users delete their own account.
MANAGE_SCOPE_REQUIRED comes from the handler, on the Admin operations
the administrative policy guards. Only authserver:manage creates an
administrator, changes one, or changes what reaches one, so no
granular scope will ever be enough: the remedy is a token holding
authserver:manage, not requesting the route’s scope as for
INSUFFICIENT_SCOPE. An administrator is a user, group or client
holding any of the six administrative permissions (manage,
admin-read, manage-users, manage-clients, manage-settings,
browser-sessions), a user directly or through any of its groups,
the admin console’s own client whatever it holds, and a client
allowed to request the administrative scopes. A granular scope is
refused here when it:
- grants or revokes an administrative permission, directly or by moving a user into or out of a group that holds one, or deletes such a group;
- writes to an administrator user (profile, credentials, enabled, sessions, consents, attributes, memberships, permissions, deletion), an administrative group (settings, attributes, members, permissions, deletion), or an administrator client (settings, authentication, flows, redirect URIs, sign-out redirect URIs, back-channel logout, DPoP, web origins, token settings, permissions, introspection resources, logo, deletion);
- switches whether a client may request the administrative scopes, on or off, on any client;
- adds the
authserverresource to a client’s introspection resources; - reads an administrator client’s secret, or reads or sets the
secret of a client listed for the
authserverresource among its introspection resources; - sets or changes a client’s back-channel logout URI;
- changes the email or the audit-log settings;
- changes an administrative permission’s description.
Granular scopes still read administrators. The refusal is answered
after the request’s 400 and 404, writes nothing, carries the insufficient_scope challenge of
the scheme the token was sent with, such as
WWW-Authenticate: Bearer realm="goiabada", error="insufficient_scope", error_description="...", scope="authserver:manage", and leaves anadministrator_change_refusedaudit record.
Admin/account API error envelope. Routing by HTTP status code: 4xx is a client-correctable failure (validation, not found, permission denied, rate limited); 5xx is a server-side problem. The body provides a stable error_code and an error_description for people to read. Protocol endpoints (/auth/token, /auth/authorize, /connect/register, /userinfo) use their RFC-defined error envelopes instead of this one.
object
Stable identifier for the failure. UPPER_SNAKE for legacy codes (e.g. VALIDATION_ERROR), dotted lowercase for codes named after the sentence’s catalog key (e.g. validator.email.required). Never translated, whatever the request’s language.
A sentence for people to read: in the request’s language, from the ui_locales query parameter or else the Accept-Language header, when the server has the sentence in that language, and in English otherwise. Route on error_code, not on this text.
Example generated
{ "error_code": "example", "error_description": "example"}Headers
Section titled “Headers”An insufficient_scope challenge in the scheme the token was sent with, Bearer or DPoP, on every refusal but FORBIDDEN and ACCOUNT_DELETION_DISABLED, which omit it.
Resource not found
Admin/account API error envelope. Routing by HTTP status code: 4xx is a client-correctable failure (validation, not found, permission denied, rate limited); 5xx is a server-side problem. The body provides a stable error_code and an error_description for people to read. Protocol endpoints (/auth/token, /auth/authorize, /connect/register, /userinfo) use their RFC-defined error envelopes instead of this one.
object
Stable identifier for the failure. UPPER_SNAKE for legacy codes (e.g. VALIDATION_ERROR), dotted lowercase for codes named after the sentence’s catalog key (e.g. validator.email.required). Never translated, whatever the request’s language.
A sentence for people to read: in the request’s language, from the ui_locales query parameter or else the Accept-Language header, when the server has the sentence in that language, and in English otherwise. Route on error_code, not on this text.
Example generated
{ "error_code": "example", "error_description": "example"}The user is the last enabled user holding authserver:manage. error_code is LAST_ADMINISTRATOR; nothing was deleted. Grant authserver:manage to another user first.
Admin/account API error envelope. Routing by HTTP status code: 4xx is a client-correctable failure (validation, not found, permission denied, rate limited); 5xx is a server-side problem. The body provides a stable error_code and an error_description for people to read. Protocol endpoints (/auth/token, /auth/authorize, /connect/register, /userinfo) use their RFC-defined error envelopes instead of this one.
object
Stable identifier for the failure. UPPER_SNAKE for legacy codes (e.g. VALIDATION_ERROR), dotted lowercase for codes named after the sentence’s catalog key (e.g. validator.email.required). Never translated, whatever the request’s language.
A sentence for people to read: in the request’s language, from the ui_locales query parameter or else the Accept-Language header, when the server has the sentence in that language, and in English otherwise. Route on error_code, not on this text.
Example generated
{ "error_code": "example", "error_description": "example"}Rate limit reached. Every limit on the account API is counted by the token’s user and applies whether or not the rate limiter (GOIABADA_AUTHSERVER_RATELIMITER_ENABLED) is on. error_code is TOO_MANY_REQUESTS and a Retry-After header carries the window length in seconds.
Admin/account API error envelope. Routing by HTTP status code: 4xx is a client-correctable failure (validation, not found, permission denied, rate limited); 5xx is a server-side problem. The body provides a stable error_code and an error_description for people to read. Protocol endpoints (/auth/token, /auth/authorize, /connect/register, /userinfo) use their RFC-defined error envelopes instead of this one.
object
Stable identifier for the failure. UPPER_SNAKE for legacy codes (e.g. VALIDATION_ERROR), dotted lowercase for codes named after the sentence’s catalog key (e.g. validator.email.required). Never translated, whatever the request’s language.
A sentence for people to read: in the request’s language, from the ui_locales query parameter or else the Accept-Language header, when the server has the sentence in that language, and in English otherwise. Route on error_code, not on this text.
Example generated
{ "error_code": "example", "error_description": "example"}Headers
Section titled “Headers”Seconds to wait before retrying
The request failed inside the server, most often a storage error. error_code is INTERNAL_SERVER_ERROR: no detail about the failure, only the request id an operator can find the log line by, and retrying is reasonable. Key rotation’s 500 also answers KEY_SET_INCOMPLETE, which names its cause and no retry clears.
Admin/account API error envelope. Routing by HTTP status code: 4xx is a client-correctable failure (validation, not found, permission denied, rate limited); 5xx is a server-side problem. The body provides a stable error_code and an error_description for people to read. Protocol endpoints (/auth/token, /auth/authorize, /connect/register, /userinfo) use their RFC-defined error envelopes instead of this one.
object
Stable identifier for the failure. UPPER_SNAKE for legacy codes (e.g. VALIDATION_ERROR), dotted lowercase for codes named after the sentence’s catalog key (e.g. validator.email.required). Never translated, whatever the request’s language.
A sentence for people to read: in the request’s language, from the ui_locales query parameter or else the Accept-Language header, when the server has the sentence in that language, and in English otherwise. Route on error_code, not on this text.
Example generated
{ "error_code": "example", "error_description": "example"}