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.updatemethod) 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 explicittypedefaults toHOTPand is therefore checked againstenrollHOTP.For user callers, the
user/realm/resolverfields 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 tohotpwhen 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
useris given, the token is assigned to the realm directly.tokenrealm – additional realms to add the token to.
otpkey – the token secret. Either
otpkeyorgenkeyis required for OTP token types.genkey –
1to 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
6or8).hashlib – HMAC hash algorithm —
sha1,sha256orsha512.validity_period_start – start of the validity period.
validity_period_end – end of the validity period.
2stepinit –
1together withgenkey=1to start a two-step enrollment (see Two Step Enrollment).otpkeyformat – alternate encoding for the supplied
otpkey(hexorbase32check).rollover –
1ortrueto roll over a token that is already in theclientwaitstate.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 –
Trueinresult.valueplus a token-type-specific enrollment payload indetail(QR codes, URLs, seeds, challenge/verify hand-shake info, …).
Depending on the token type there can be additional parameters; see each class’
updatemethod 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
imgfields 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. Seegenerate_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.sortdir –
asc(default) ordesc.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>}inresult.value, wherenis 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/realmparameters (the request hooks bind those fields to the calling user).Requires authentication and the policy action
tokenlist. Thehide_tokeninfopolicy 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@realmsyntax. If bothuserandrealmare given,realmwins. Ignored for user-role callers.realm – admin only — filter by realm of the assigned user. Without a
userparameter, 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.
assigned –
TrueorFalseto limit to assigned or unassigned tokens.active –
TrueorFalseto 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_tokeninfopolicy if active.sortby – sort column, default
serial.sortdir –
asc(default) ordesc.page – 1-indexed page number, default
1.pagesize – page size, default
15.outform –
csvto returntext/csvinstead of JSON. Pagination still applies.
- Status Codes:
200 OK – paginated token list in
result.value(or as a CSV body whenoutform=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.
encryptpin –
Trueto store the PIN encrypted (the default behavior is governed by theencrypt_pinpolicy).
- Status Codes:
200 OK –
Trueon success inresult.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 infailed.- JSON Parameters:
serial – single serial or comma-separated list.
serials – list of serials.
user – user name (only when
serial/serialsis omitted; requiresrealm).realm – realm name (only when
serial/serialsis omitted; requiresuser).
- Status Codes:
200 OK – for a single-serial call the response is
Trueinresult.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
serialand withuserset, 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
serialand withuserset, 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
serialand withuserset, 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, orserial=...(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 infailed.- 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
serialand withuserset, 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 –
Trueon success inresult.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 –
Trueif the token resynchronized,Falseotherwise.
- 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 –
Trueto store the OTP PIN encrypted (default behavior is governed by theencrypt_pinpolicy).
- 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_randompolicy; if that policy is not configured the call fails.The freshly generated PIN is included in the response under
detail.pinso 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 –
Trueto store the PIN encrypted (default behavior is governed by theencrypt_pinpolicy).
- Status Codes:
200 OK – number of PINs set in
result.value; the generated PIN is indetail.pin.
- POST /token/description/(serial)¶
- POST /token/description¶
Set the description of a token. May be required by the
require_description_on_editpolicy.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 –
Trueon success inresult.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
serialoruseris required; withuserand 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 OK –
Trueon success inresult.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-datawith the file in thefilefield; the path componentfilenameis 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:
Content-Type –
multipart/form-data(required).
- Form Parameters:
file – the file contents (required).
- JSON Parameters:
type – file format —
aladdin-xml,oathcsv(aliasOATH CSV),yubikeycsv(aliasYubikey CSV), orpskc(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_checkskips MAC verification,check_fail_softwarns,check_fail_hard(default) rejects on bad MAC.
- Status Codes:
200 OK –
{"n_imported": <int>, "n_not_imported": <int>}inresult.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
copytokenpincan 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 OK –
Trueon success inresult.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
copypinabove for the same caveat.- JSON Parameters:
from – serial of the source token (required).
to – serial of the destination token (required).
- Status Codes:
200 OK –
Trueon success inresult.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).unassigned –
1to search only unassigned tokens.assigned –
1to search only assigned tokens.count –
1to 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>}inresult.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 –
Trueon success inresult.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 –
Trueif a matching token existed (which does not necessarily mean the key was set on it),Falseotherwise.
- 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 ingroupsis 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
groupnameis omitted; ignored otherwise.
- Status Codes:
200 OK –
1inresult.value.