What you build
1
A policy-backed request
A policy defines what the wallet must prove, such as
age_over_18, identity attributes, EU residency, or a license claim.2
A wallet handoff
Your app sends the user to their wallet through a QR code or mobile deep link. The browser only receives short-lived, browser-safe fields.
3
A trusted server result
Authbound validates the wallet presentation and returns status, webhook events, and signed results your backend can store.
Policies
A policy is the contract for one verification flow. It tells Authbound which wallet credential and claims to request, how to validate them, and what result your backend should expect. For local development, start with a built-in SDK preset or use a custom policy owned by your project. Copy custom policy IDs from the Authbound dashboard or create them with@authbound/server or POST /v1/policies.
SDKs also expose starter presets such as PolicyPresets.AGE_GATE_18, PolicyPresets.AGE_GATE_18_EUDI, PolicyPresets.IDENTITY_BASIC, PolicyPresets.IDENTITY_BASIC_EUDI, PolicyPresets.KYC_BASIC, PolicyPresets.KYC_BASIC_EUDI, and PolicyPresets.PENSION. Use fetchPresetRegistry for cacheable public metadata from /v1/presets, and getPresetPolicyId when you need to resolve a preset key or slug to a concrete pol_* ID.
Use stable, versioned policy IDs in production so changing a policy is an intentional release.
Provider preferences and EUDI options
The browser may send an optionalprovider preference when creating a verification. Advanced EUDI settings such as responseMode and expectedOrigins belong in server-owned creation paths: providerOptions on createVerificationRoute, the Nuxt module config, createVerification from @authbound/nextjs/server, or authbound.verifications.create from @authbound/server. The catch-all createAuthboundHandlers route does not accept providerOptions, and SDK handlers do not trust client-supplied values.
Trust model
The browser flow is for user experience: starting the wallet handoff, showing progress, and moving the user forward when a verification finishes. SDK-managed same-origin session cookies can support route UX after the browser observes verified status. The backend result is what you trust for durable decisions. Store the result from a webhook or signed result lookup before granting access, changing limits, or marking an account as verified.Store only the data you need. Verification results can include personal data depending on the policy. Keep PII on the server and avoid putting it in browser cookies.
API statuses
UI SDKs collapse early API states (
created, awaiting_user, awaiting_provider) into pending. The processing API state maps to UI processing, not pending.Browser SDK UI statuses
UI packages also expose client-side states that are not gateway API values:Time limits
Verifications and theirclientToken expire after 15 minutes by default. Create a new verification when the handoff window has elapsed.
SDK-managed browser sessions also set a short-lived __authbound_pending cookie when a verification is created. This cookie is capped at 10 minutes regardless of your session cookie settings. Session finalization requires the pending cookie to still be present. If the user spends longer than 10 minutes in their wallet, finalize can fail with VERIFICATION_BINDING_REQUIRED even though the verification itself may still be active.
Failure codes
When a verification reachesfailed, the response includes a failure_code. Non-failed responses never include one.
Wallet handoff fields
client_action and verification_url are present only while a verification can still be handed to a wallet. Terminal statuses (verified, failed, canceled, expired) do not include wallet handoff data.
Next steps
Verify a user
Create a verification, return browser-safe fields, and render the wallet handoff.
Webhooks and results
Persist trusted outcomes in your backend before production launch.