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.

  • genkey1 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.

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

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

  • rollover1 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 OKTrue 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. With <serial> only the challenges for that token are returned; without it, all open challenges across the server are returned (paginated).

Requires admin authentication and the policy action getchallenges.

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

Query Parameters:
  • sortby – sort column, default timestamp.

  • sortdirasc (default) or desc.

  • page – 1-indexed page number.

  • pagesize – page size (default 15).

  • transaction_id – restrict to challenges with this transaction id (useful for push or TiQR tokens).

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

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.

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

  • realmadmin 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.

  • tokenrealm – filter to tokens that belong to this realm (independent of the user’s realm).

  • description – filter by description.

  • assignedTrue or False to limit to assigned or unassigned tokens.

  • activeTrue 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.

  • sortdirasc (default) or desc.

  • page – 1-indexed page number, default 1.

  • pagesize – page size, default 15.

  • outformcsv 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).

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.

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

Status Codes:
  • 200 OKTrue 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 OKTrue 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 OKTrue 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.

  • encryptpinTrue 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).

  • encryptpinTrue 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 OKTrue 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.

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 OKTrue 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. Used by helpdesk flows where a replacement token is issued without forcing the user to set a new PIN.

Requires admin authentication and the policy action copytokenpin. The check is global rather than realm-scoped, so an admin holding copytokenpin can copy a PIN between tokens regardless of which realms those tokens belong to.

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

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

Status Codes:
  • 200 OKTrue on success in result.value.

POST /token/copyuser

Copy the user assignment of one token onto another. Used by helpdesk flows where a replacement token must inherit the original token’s owner without re-running the assign workflow.

Requires admin authentication and the policy action copytokenuser. The check is global rather than realm-scoped; see copypin above for the same caveat.

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

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

Status Codes:
  • 200 OKTrue on success in result.value.

POST /token/lost/(serial)

Mark a token as lost and issue a temporary replacement. The replacement carries a derived serial (lost<original-serial>), a generated password, the original token’s PIN, and a limited validity period. The original token is disabled.

Callable by both admins and users; user-role callers may only operate on their own tokens (the view enforces ownership).

Requires authentication and the policy action losttoken.

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).

  • unassigned1 to search only unassigned tokens.

  • assigned1 to search only assigned tokens.

  • count1 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.

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 OKTrue 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 OKTrue 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 OK1 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 OK1 in result.value.