16.1.1.10. Token endpoints

The token REST API manages the lifecycle of authentication tokens - enrollment, listing, assignment to users, PIN management, realm membership, tokengroup membership, token info, lost-token handling, bulk import, and admin-only attribute editing.

All endpoints require authentication. Admins may operate on any token that their realm-scoped admin policies permit; regular users may only operate on their own tokens (the request hooks force the user / realm / resolver parameters to the calling user’s identity for non-admin callers). Per-action authorization is enforced by the token-scope policies (enroll<TOKENTYPE>, assign, unassign, revoke, enable, disable, delete, reset, resync, setpin, setrandompin, setdescription, set, tokenrealms, losttoken, getserial, getchallenges, settokeninfo, tokengroups, copytokenpin, copytokenuser, import).

Many endpoints operate on either a single token (via serial) or on a user’s full set of tokens (when user and realm are supplied without a serial); the check_token_action() decorator expands the user-only call to every token the user owns.

See Authentication endpoints for authentication and Policies for the overall policy concept.

POST /token/init

Create or roll over a token. The token type drives both the request shape (each token class accepts its own parameters; see the corresponding TokenClass.update method) and the response shape (each token class returns its own enrollment payload - typically QR codes, otpauth:// URLs, seeds, etc.).

Requires authentication. Authorization is gated by the enroll<TOKENTYPE> policy in the calling principal’s scope (admin or user); a request without an explicit type defaults to HOTP and is therefore checked against enrollHOTP.

For user callers, the user / realm / resolver fields are bound to the calling user before the view runs; a regular user can only enroll tokens for themselves.

JSON Parameters:
  • type – token type (e.g. hotp, totp, push, webauthn, passkey, …). Defaults to hotp when omitted.

  • serial – optional serial; auto-generated when omitted.

  • description – free-form description.

  • pin – the OTP PIN.

  • user – login name of the user to assign the token to.

  • realm – realm of the user; if no user is given, the token is assigned to the realm directly.

  • tokenrealm – additional realms to add the token to.

  • otpkey – the token secret. Either otpkey or genkey is required for OTP token types.

  • genkey – 1 to have the server generate the secret.

  • keysize – byte length of the generated key. The accepted values depend on the token class.

  • otplen – length of the OTP value (typically 6 or 8).

  • hashlib – HMAC hash algorithm - sha1, sha256 or sha512.

  • validity_period_start – start of the validity period.

  • validity_period_end – end of the validity period.

  • 2stepinit – 1 together with genkey=1 to start a two-step enrollment (see Two Step Enrollment).

  • otpkeyformat – alternate encoding for the supplied otpkey (hex or base32check).

  • rollover – 1 or true to roll over a token that is already in the clientwait state.

  • container_serial – optional, attach the new token to this container. Requires the container_add_token policy on the caller; if the policy is missing, the enrollment still succeeds but the token is not added to the container.

Status Codes:
  • 200 OK – True in result.value plus a token-type-specific enrollment payload in detail (QR codes, URLs, seeds, challenge/verify hand-shake info, …).

Depending on the token type there can be additional parameters; see each class’ update method for the full list.

Example response (HOTP token):

HTTP/1.1 200 OK
Content-Type: application/json

{
  "detail": {
    "googleurl": {
      "description": "URL for google Authenticator",
      "img": "<img width=250 src=\"data:image/png;base64,...\"/>",
      "value": "otpauth://hotp/mylabel?secret=GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ&counter=0"
    },
    "oathurl": {
      "description": "URL for OATH token",
      "img": "<img width=250 src=\"data:image/png;base64,...\"/>",
      "value": "oathtoken:///addToken?name=mylabel&lockdown=true&key=3132...3930"
    },
    "otpkey": {
      "description": "OTP seed",
      "img": "<img width=200 src=\"data:image/png;base64,...\"/>",
      "value": "seed://3132...3930"
    },
    "serial": "OATH00096020"
  },
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "status": true,
    "value": true
  },
  "version": "privacyIDEA unknown"
}

The img fields carry inline base64-encoded PNGs (the QR codes shown in the WebUI); they have been abbreviated above for readability.

2 Step Enrollment

Some tokens might need a 2 step initialization process like a smartphone app. This way you can create a shared secret from a part generated by the privacyIDEA server and from a second part generated by the smartphone app/client.

The first API call would be

POST /token/init HTTP/1.1

2stepinit=1

The response would contain the otpkey generated by the server and the serial number of the token. At this point, the token is deactivated and marked as being in an enrollment state. The client would also generated a component of the key and send his component to the privacyIDEA server:

The second API call would be

POST /token/init HTTP/1.1

serial=<serial from the previous response>
otpkey=<key part generated by the client>

Each tokenclass can define its own way to generate the secret key by overwriting the method generate_symmetric_key. The Base Tokenclass contains an extremely simple way by concatenating the two parts. See generate_symmetric_key()

verify enrollment

Some tokens can be configured via enrollment policy so that the user needs to provide some verification that e.g. a QR code was scanned correctly or the token works correctly in general. The specific way depends on the token class. The necessary token class functions are

The first API call to /token/init returns responses in:

{"detail": {"verify": {"message": "Please provide a valid OTP value."},
            "rollout_state": "verify"}}

The second API call then needs to send the serial number and a response

POST /token/init HTTP/1.1

serial=<serial from the previous response>
verify=<e.g. the OTP value>

As long as the token is in state “verify” it can not be used for authentication.

GET /token/challenges/(serial)
GET /token/challenges/

Return the open challenges.

Three filter modes (mutually exclusive):

  • <serial> path component -> challenges for that token (paginated).

  • ?user=<name>[&realm=<realm>] query -> every challenge across all tokens owned by that user. Used by the user-detail view.

  • neither -> all open challenges across the server, paginated.

Requires admin authentication and the policy action getchallenges. Realm-scoping is enforced against the target’s owning user when a serial or user filter is given.

Parameters:
  • serial – optional path component, the token serial.

Query Parameters:
  • user – optional username - switches to user-aggregation mode.

  • realm – optional realm for the user lookup.

  • sortby – sort column, default timestamp (paginated mode only).

  • sortdir – asc (default) or desc.

  • page – 1-indexed page number; values below 1 are treated as 1.

  • pagesize – page size (default 15), capped at 1000.

  • transaction_id – restrict to challenges with this transaction id.

Status Codes:
  • 200 OK – challenge list in result.value.

DELETE /token/challenges/transaction/(transaction_id)

Cancel (delete) a single active challenge by its transaction ID. Removes it from both the Redis cache (when active) and the database.

Parameters:
  • transaction_id – The transaction ID of the challenge to cancel.

Return:

json with deleted count.

DELETE /token/challenges/expired

Remove all expired entries from the challenge table. Useful as a periodic-task target on busy installations.

Requires admin authentication.

Request Headers:
  • PI-Authorization – authentication token.

Status Codes:
  • 200 OK – {"status": True, "deleted": <n>} in result.value, where n is the number of removed rows.

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "status": true,
    "value": {"status": true, "deleted": 42}
  },
  "version": "privacyIDEA unknown"
}
GET /token/

Return tokens, paginated and filtered by the supplied query parameters. Realm-admins are restricted by their policies; user callers always see only their own tokens regardless of the user / realm parameters (the request hooks bind those fields to the calling user).

Requires authentication and the policy action tokenlist. The hide_tokeninfo policy may strip configured token-info keys from the response.

Query Parameters:
  • serial – filter by serial. Substring match via * (e.g. *OATH*); comma-separated list of serials also supported.

  • type – filter by token type. Substring match via * (e.g. *otp* matches hotp and totp).

  • type_list – comma-separated list of token types.

  • user – admin only - filter by this user. Accepts user@realm syntax. If both user and realm are given, realm wins. Ignored for user-role callers.

  • realm – admin only - filter by realm of the assigned user. Without a user parameter, returns every token assigned to any user in this realm. Ignored for user-role callers.

  • resolver – filter by the resolver of the assigned user. Case-insensitive, substring match via *. Only tokens that are assigned to a user can match.

  • userid – filter by the user id of the assigned user. Substring match via *. Only tokens that are assigned to a user can match.

  • tokenrealm – filter to tokens that belong to this realm (independent of the user’s realm). Substring match via *; comma-separated list of realm names also supported, where each entry may contain wildcards (e.g. realm1,realm2,realm3 or staff*,students*).

  • description – filter by description.

  • assigned – True or False to limit to assigned or unassigned tokens.

  • active – True or False to limit to active or inactive tokens.

  • rollout_state – filter by rollout state (e.g. clientwait).

  • infokey – filter by token-info key (combine with infovalue).

  • infovalue – filter by token-info value (combine with infokey).

  • container_serial – filter to tokens attached to the given container; pass an empty string to limit to tokens without any container.

  • hidden_tokeninfo – list of token-info keys to strip from the response. Overridden by the hide_tokeninfo policy if active.

  • sortby – sort column, default serial.

  • sortdir – asc (default) or desc.

  • page – 1-indexed page number, default 1; values below 1 are treated as 1.

  • pagesize – page size, default 15, capped at 1000.

  • outform – csv to return text/csv instead of JSON. Pagination still applies.

Status Codes:
  • 200 OK – paginated token list in result.value (or as a CSV body when outform=csv). Each token carries readonly_info_keys and undeletable_info_keys, the subsets of its info entries that the token info endpoints refuse to change respectively to remove because the token itself maintains them, and settable_info_keys, the subset of those that POST /token/set accepts.

POST /token/assign

Assign a token to a user. The user’s realm is added to the token’s realm list; existing realms are preserved. An optional PIN may be set on the same call.

Requires authentication and the policy action assign. User-role callers can only assign tokens to themselves.

JSON Parameters:
  • serial – token serial (required, must be non-empty).

  • user – login name of the user (required).

  • realm – realm of the user (required if not the default realm).

  • pin – optional OTP PIN to set in the same call.

  • encryptpin – True to store the PIN encrypted (the default behavior is governed by the encrypt_pin policy).

Status Codes:
  • 200 OK – True on success in result.value.

POST /token/unassign

Remove the user assignment from a token. Three call shapes are supported:

  • serial=... (single, or comma-separated list) - operate on these tokens.

  • serials=[...] - operate on this list of tokens.

  • user=...&realm=... (no serial) - operate on every token currently assigned to that user.

Requires authentication and the policy action unassign. Tokens the caller is not authorized to manage are silently skipped and reported back; missing serials are reported in failed.

JSON Parameters:
  • serial – single serial or comma-separated list.

  • serials – list of serials.

  • user – user name (only when serial / serials is omitted; requires realm).

  • realm – realm name (only when serial / serials is omitted; requires user).

Status Codes:
  • 200 OK – for a single-serial call the response is True in result.value; for any multi-serial call (or any case with skipped tokens), the response value is {"count_success": <n>, "failed": [...], "unauthorized": [...]}.

POST /token/revoke/(serial)
POST /token/revoke

Revoke a token. A revoked token is locked and can no longer authenticate; some token types perform additional teardown (e.g. push tokens unsubscribe, certificate tokens revoke their cert).

Without serial and with user set, every token of that user is revoked.

Requires authentication and the policy action revoke.

Parameters:
  • serial – optional path component, the token serial.

JSON Parameters:
  • serial – token serial (alternative to the path component).

  • user – login name (only when no serial is given - revokes every token of the user).

  • realm – realm of the user.

Status Codes:
  • 200 OK – number of revoked tokens in result.value.

POST /token/enable/(serial)
POST /token/enable

Enable a token. Without serial and with user set, every token of that user is enabled.

Requires authentication and the policy action enable. Subject to the per-user token-count limit (check_max_token_user).

Parameters:
  • serial – optional path component, the token serial.

JSON Parameters:
  • serial – token serial (alternative to the path component).

  • user – login name (only when no serial is given - enables every token of the user).

  • realm – realm of the user.

Status Codes:
  • 200 OK – number of enabled tokens in result.value.

POST /token/disable/(serial)
POST /token/disable

Disable a token. Disabled tokens cannot authenticate but can be re-enabled later. Without serial and with user set, every token of that user is disabled.

Requires authentication and the policy action disable.

Parameters:
  • serial – optional path component, the token serial.

JSON Parameters:
  • serial – token serial (alternative to the path component).

  • user – login name (only when no serial is given - disables every token of the user).

  • realm – realm of the user.

Status Codes:
  • 200 OK – number of disabled tokens in result.value.

DELETE /token/(serial)
DELETE /token/

Delete tokens. Three call shapes are supported, mirroring POST /token/unassign:

  • single serial via the <serial> path component, or serial=... (or comma-separated list);

  • serials=[...] list;

  • user=...&realm=... (no serial) - delete every token of that user.

Requires authentication and the policy action delete. Tokens the caller is not authorized to manage are silently skipped and reported back; missing serials are reported in failed.

Parameters:
  • serial – optional path component, the token serial.

JSON Parameters:
  • serial – single serial or comma-separated list.

  • serials – list of serials.

  • user – login name.

  • realm – realm of the user.

Status Codes:
  • 200 OK – for a single-serial call the response is the number of deleted tokens in result.value; for any multi-serial call (or any case with skipped tokens), the response value is {"count_success": <n>, "failed": [...], "unauthorized": [...]}.

POST /token/reset/(serial)
POST /token/reset

Reset the fail counter of a token. Without serial and with user set, every token of that user is reset.

Requires authentication and the policy action reset.

Parameters:
  • serial – optional path component, the token serial.

JSON Parameters:
  • serial – token serial (alternative to the path component).

  • user – login name (only when no serial is given - resets every token of the user).

  • realm – realm of the user.

Status Codes:
  • 200 OK – True on success in result.value.

POST /token/resync/(serial)
POST /token/resync

Resynchronize an OTP token by submitting two consecutive OTP values it produced. Used when an event-based token (HOTP) has drifted out of sync with the server’s counter, or when a time-based token (TOTP) is on a clock the server cannot reach.

Requires authentication and the policy action resync.

Parameters:
  • serial – optional path component, the token serial.

JSON Parameters:
  • serial – token serial (required if not in the path).

  • otp1 – first OTP value (required).

  • otp2 – second OTP value, immediately following otp1 (required).

Status Codes:
  • 200 OK – True if the token resynchronized, False otherwise.

POST /token/setpin/(serial)
POST /token/setpin

Set one or more PINs on a token. Three PIN slots are supported:

  • userpin - the user PIN of a smartcard, also used by mOTP tokens to store the mOTP PIN.

  • sopin - the security-officer PIN of a smartcard.

  • otppin - the regular OTP PIN that gates token use.

Each supplied field is set independently; omitted fields are untouched.

Requires authentication and the policy action setpin.

Parameters:
  • serial – optional path component, the token serial.

JSON Parameters:
  • serial – token serial (required if not in the path).

  • userpin – smartcard user PIN.

  • sopin – smartcard SO PIN.

  • otppin – OTP PIN.

  • encryptpin – True to store the OTP PIN encrypted (default behavior is governed by the encrypt_pin policy).

Status Codes:
  • 200 OK – number of PINs set in result.value.

POST /token/setrandompin/(serial)
POST /token/setrandompin

Generate a random OTP PIN and set it on the token. The PIN length and content rules come from the otp_pin_set_random policy; if that policy is not configured the call fails.

The freshly generated PIN is included in the response under detail.pin so that the calling principal can show or relay it once. Treat the response body accordingly - do not log or persist it past handing it to the user.

Requires authentication and the policy action setrandompin.

Parameters:
  • serial – optional path component, the token serial.

JSON Parameters:
  • serial – token serial (required if not in the path).

  • encryptpin – True to store the PIN encrypted (default behavior is governed by the encrypt_pin policy).

Status Codes:
  • 200 OK – number of PINs set in result.value; the generated PIN is in detail.pin.

POST /token/description/(serial)
POST /token/description

Set the description of a token. May be required by the require_description_on_edit policy.

Requires authentication and the policy action setdescription.

Parameters:
  • serial – optional path component, the token serial.

JSON Parameters:
  • serial – token serial (required if not in the path).

  • description – new description (required).

Status Codes:
  • 200 OK – True on success in result.value.

POST /token/set/(serial)
POST /token/set

Admin-only. Set one or more low-level token attributes on a token (or on every token of a user). Each supplied field is applied independently; omitted fields are untouched.

Requires admin authentication and the policy action set.

Parameters:
  • serial – optional path component, the token serial.

JSON Parameters:
  • serial – token serial (alternative to the path component). Either serial or user is required; with user and no serial, every token of that user is modified.

  • user – login name.

  • realm – realm of the user.

  • description – free-form description.

  • count_window – counter look-ahead window (HOTP).

  • sync_window – synchronization window.

  • count_auth_max – maximum authentication count before the token is locked.

  • count_auth_success_max – maximum number of successful authentications before the token is locked.

  • hashlib – HMAC hash algorithm (sha1, sha256, sha512).

  • max_failcount – maximum allowed failed authentications.

  • validity_period_start – ISO 8601 start of validity (YYYY-MM-DDThh:mm+oooo).

  • validity_period_end – ISO 8601 end of validity.

  • <tokentype>.<key> – a token type specific token-info entry, e.g. remote.user on a remote token. The prefix has to name a known token type and the entry is only written to tokens of that type, so a parameter cannot reach the namespace of another token type. These entries are maintained by the token, so the generic token-info endpoints refuse them.

Status Codes:
  • 200 OK – number of attribute updates applied in result.value.

POST /token/realm/(serial)

Replace the realms a token belongs to. The full set of realms is replaced - realms not listed in the request are removed. For realm-admin callers, the call is restricted to realms the caller’s policies cover.

Requires admin authentication and the policy action tokenrealms. Subject to the per-realm token-count limit (check_max_token_realm).

Parameters:
  • serial – path component, the token serial.

JSON Parameters:
  • realms – comma-separated string or JSON list of realm names (required; empty list removes all realms).

Status Codes:
  • 200 OK – True on success in result.value.

Example request:

POST /token/realm/<serial> HTTP/1.1
Host: example.com
Content-Type: application/json

{"realms": "realm1,realm2"}
POST /token/load/(filename)

Bulk-import tokens from a file. Accepts OATH CSV, Aladdin XML, Yubikey CSV (as exported by the Yubikey initialization tool) and PSKC. PGP-encrypted files (-----BEGIN PGP MESSAGE----- header) are decrypted in-place using the configured GPG keyring before parsing.

The request body must be multipart/form-data with the file in the file field; the path component filename is used only for logging.

Requires admin authentication and the import policy in scope ADMIN. The check honors the supplied tokenrealms: the admin must be allowed to import into every named realm.

Parameters:
  • filename – path component, used as a log/audit label for the imported file.

Request Headers:
Form Parameters:
  • file – the file contents (required).

JSON Parameters:
  • type – file format - aladdin-xml, oathcsv (alias OATH CSV), yubikeycsv (alias Yubikey CSV), or pskc (required).

  • tokenrealms – comma-separated list of realms to assign the imported tokens to.

  • psk – Pre-Shared Key for PSKC import (32 hex characters / 128 bits).

  • password – passphrase for PSKC import when keys are password-derived.

  • pskcValidateMAC – PSKC MAC handling - no_check skips MAC verification, check_fail_soft warns, check_fail_hard (default) rejects on bad MAC.

Status Codes:
  • 200 OK – {"n_imported": <int>, "n_not_imported": <int>} in result.value.

  • 400 Bad Request – empty file, undecodable file, unknown type, or bad pre-shared-key length.

POST /token/copypin

Copy the OTP PIN of one token onto another.

Requires admin authentication and the policy action copytokenpin for both tokens, so an admin restricted to certain realms can only copy between tokens in those realms.

Deprecated since version 3.14: This endpoint is deprecated and will be removed in a future release. It exposes one raw step of the lost-token workflow; use POST /token/lost/(serial), which performs the whole replacement, instead.

JSON Parameters:
  • from – serial of the source token (required).

  • to – serial of the destination token (required).

Status Codes:
  • 200 OK – True on success in result.value.

  • 403 Forbidden – the calling admin is not authorized for one of the two tokens.

POST /token/copyuser

Copy the user assignment of one token onto another. The destination token is unassigned first, and the source token’s realms are copied along with the owner.

Requires admin authentication and the policy action copytokenuser for both tokens, so an admin restricted to certain realms can only copy between tokens in those realms.

Deprecated since version 3.14: This endpoint is deprecated and will be removed in a future release. It exposes one raw step of the lost-token workflow; use POST /token/lost/(serial), which performs the whole replacement, instead.

JSON Parameters:
  • from – serial of the source token (required).

  • to – serial of the destination token (required).

Status Codes:
  • 200 OK – True on success in result.value.

  • 403 Forbidden – the calling admin is not authorized for one of the two tokens.

POST /token/lost/(serial)

Mark a token as lost and issue a temporary replacement. The replacement is a newly created password token carrying a derived serial (lost<original-serial>, with a counted suffix if that serial is already taken), a generated password, the original token’s PIN, and a limited validity period. The original token is disabled.

The PIN is copied as a hash, so the replacement keeps the PIN the user already knows without the calling admin learning it.

Requires admin authentication and the policy action losttoken, which is checked against the realms of the lost token. If a user is passed as well, it has to be the owner of the token.

Parameters:
  • serial – path component, the serial of the lost token.

Status Codes:
  • 200 OK – dict carrying the new serial, the temporary password, and the validity window in result.value.

GET /token/getserial/(otp)

Identify a token by an OTP value. Useful when an admin holds an unlabeled token and wants to know which token (and therefore which user) it belongs to.

Requires admin authentication and the policy action getserial.

Parameters:
  • otp – path component, the observed OTP value.

Query Parameters:
  • type – limit the search to this token type.

  • serial – substring filter against token serials (e.g. OATH).

  • unassigned – 1 to search only unassigned tokens.

  • assigned – 1 to search only assigned tokens.

  • count – 1 to return only the number of tokens that would be searched, without performing the OTP check.

  • window – OTP look-ahead window, default 10.

Status Codes:
  • 200 OK – {"serial": <serial-or-null>, "count": <int>} in result.value.

GET /token/sshkey/(serial)

Return the decrypted public SSH key of an SSH key token.

The public key of an SSH key token is stored encrypted in the database and is therefore not returned in the token list. This endpoint returns the assembled public key (<type> <key> [<comment>]) so that it can be imported into an authorized_keys file.

Before returning, the integrity checksum of the token is verified, so a manipulation of the SSH key data in the database is detected.

Only active tokens are returned. Disabling or revoking an SSH key token stops its key from being handed out here, just like it stops the key from appearing in the authorized keys of a machine.

Requires authentication and the policy action sshkey_read. Admins are restricted by the realms of their policies, users can only read the SSH key of their own tokens.

Parameters:
  • serial – path component, the serial of the SSH key token.

Status Codes:
  • 200 OK – {"sshkey": "<type> <key> <comment>"} in result.value.

POST /token/info/(serial)/(key)

Set a single tokeninfo entry on a token. If an entry with this key already exists, the value is overwritten.

Requires admin authentication and the policy action settokeninfo.

Parameters:
  • serial – path component, the token serial.

  • key – path component, the tokeninfo key.

JSON Parameters:
  • value – tokeninfo value to set (required).

Status Codes:
  • 200 OK – True on success in result.value.

DELETE /token/info/(serial)/(key)

Delete a tokeninfo entry from a token.

Requires admin authentication and the policy action settokeninfo.

Parameters:
  • serial – path component, the token serial.

  • key – path component, the tokeninfo key.

Status Codes:
  • 200 OK – True if a matching token existed (which does not necessarily mean the key was set on it), False otherwise.

POST /token/group/(serial)/(groupname)
POST /token/group/(serial)

Modify the tokengroup membership of a token. The endpoint has two shapes:

  • with the <groupname> path component, the named tokengroup is added to the token (additive, single membership).

  • without the path component, the body must carry groups - the token’s membership is replaced with that list, so any tokengroup not in groups is removed.

Requires admin authentication and the policy action tokengroups.

Parameters:
  • serial – path component, the token serial.

  • groupname – optional path component - if present, add this tokengroup; if absent, replace membership from groups.

JSON Parameters:
  • groups – list (or comma-separated string) of tokengroup names. Required when groupname is omitted; ignored otherwise.

Status Codes:
  • 200 OK – 1 in result.value.

DELETE /token/group/(serial)/(groupname)

Remove a single tokengroup from a token.

Requires admin authentication and the policy action tokengroups.

Parameters:
  • serial – path component, the token serial.

  • groupname – path component, the tokengroup name.

Status Codes:
  • 200 OK – 1 in result.value.