Documentation

API reference

The full typed reference for the step-up model — every field individually: name, type, description.

Step
FieldTypeDefaultDescription
stateStepState—'waiting' | 'approved' | 'rejected' | 'expired' | 'enroll' | 'passkey_required' | 'offline' | 'blocked' | 'frozen' | 'rate_limited'
requestIdstring?—The approval request's id. Pass this to check() and complete().
numberstring?—Number matching: show it on screen — the user picks it on the phone. Present only in the waiting state.
expiresAtstring?—ISO timestamp. Stop polling and show an expired message after this.
detailsArray<{label, value}>?[]The transaction details the phone is showing the user, echoed back so your UI can match it.
enroll{ qrCodeDataUrl, recoveryCodes?, expiresAt? }?—Present only in the enroll state — the user has no linked phone yet. Render qrCodeDataUrl directly as an <img> src.
offline{ challengeId, qrDataUrl?, expiresAt?, totpAvailable?, attemptsLeft? }?—Present only in the offline state — see the Offline Sign guide.
reasonstring?—Present in the blocked/frozen/rate_limited states — why the request was refused.
retryAfternumber?—Seconds. Present alongside frozen/rate_limited.
assurance{ phishingResistant, method }?—Present once approved. Only phishingResistant === true (a passkey was used) should be trusted for high-value actions.

This is the raw JSON returned by start() and check() — identical in every language.

requireTouchque(action, options?)
ParameterTypeDefaultDescription
user(req) => stringreq.user.email/id/usernameWho is approving. For the login step, return whoever just passed your password check.
details(req) => LoginRequestDetails—What the phone shows and the approval is bound to. Build it from server-side state, never from client input.
referenceId(req) => string—Your own transaction id, bound to the approval.
silentSignInboolean | { maxAgeSeconds }falseSilent sign-ins: a request carrying X-Touchque-Browser first asks risk.check; prompt === false runs the handler with no push (assurance.method 'silent'). Also on withTouchque and touchqueRouter.