Flat reference for everything the bridge emits. For per-method documentation, see Auth Methods, Sessions, Backend, and Account.Documentation Index
Fetch the complete documentation index at: https://setup.despia.com/llms.txt
Use this file to discover all available pages before exploring further.
Payload envelope
Shape of every
onClerkEvent callbackEvents
Every event name the bridge can emit
Status values
What
status strings meanError codes
Every
error.code and what fires itQuirks
Bridge behavior worth knowing
Platform support
iOS vs Android, +3 Android divergences
Payload envelope
EveryonClerkEvent callback receives an object with this shape:
ok first.
Events
Every command emits at least one event. Some routes emit only error envelopes, their success transfers into a different event (for example, OAuth success becomes asignIn or signUp event).
| Event | Emitted by | Reference |
|---|---|---|
ready | Configure | Configure |
state | State snapshot | Session State |
token | JWT refresh | Force a refresh |
signIn | Any sign-in reaching a session | Auth Methods |
signUp | Any sign-up reaching a session | Auth Methods |
emailCode | Email OTP flow | Email Code |
phoneCode | SMS OTP flow | Phone Code |
secondFactor | MFA continuation | MFA |
resetPassword | Password reset flow | Reset Password |
passkey | Passkey registration | Passkeys |
authview | Auth Sheet close | Auth Sheet |
userprofile | User Profile sheet close | User Profile |
signOut | Sign Out | Sign Out |
attribution | Attribution toggle | Attribution Sync |
ssr | SSR toggle | Backend |
enterpriseSSO | Enterprise SSO errors | Success transfers to signIn/signUp |
ticket | Magic Link Ticket errors | Success emits signIn |
configure, manual, oauth, apple | Error envelopes only | Success of each transfers to a different event |
unknown | Unrecognized clerk:// host | Returns unknown_command |
Status values
status on signIn, signUp, emailCode, phoneCode, secondFactor, and resetPassword is the raw Clerk SDK status, passed through verbatim. Match complete explicitly and treat anything else as “needs another step.”
- Sign-in / sign-up
- Lifecycle
| Status | Meaning |
|---|---|
complete | Session established. Payload carries userId and (if present) emailAddress. JWT refresher starts. |
needs_identifier | Sign-in missing the identifier |
needs_first_factor | Password or other first factor required |
needs_second_factor | MFA required, continue with method=second_factor |
needs_new_password | Password reset required |
needs_client_trust | Trusted-device challenge required |
missing_requirements | Sign-up missing email/phone verification |
abandoned | Sign-up timed out |
Error codes
Every error envelope follows{ ok: false, event, error: { code, message } }. error.message is human-readable (Clerk’s own text for SDK errors, the bridge’s text for guard errors). Error codes are grouped by the route that emits them.
Configure and lifecycle
Configure and lifecycle
| Code | Triggered by | Meaning |
|---|---|---|
invalid_key | configure | Key missing or does not start with pk_ |
reconfigure_in_progress | configure | Previous tenant switch still running |
reconfigure_failed | configure | SDK reconfigure threw |
not_configured | Any non-configure route | clerk://configure not called yet |
signout_failed | signout | Network error during server-side revoke |
token_fetch_failed | token | Refresh failed, window.clerkJWT keeps last value |
Build and runtime guards
Build and runtime guards
| Code | Triggered by | Meaning |
|---|---|---|
unsupported_os | All routes | Below the Clerk SDK runtime minimum (iOS 17+, clerk-android’s minimum API level) |
sdk_not_linked | All routes | Clerk SDK or prebuilt UI not in the build |
unknown_command | Unknown host | For example, clerk://foo |
unknown_method | manual | method= not recognized |
unknown_action | OTP, reset password, passkey | action= not recognized for the route |
missing_params | Manual flows | Required field absent |
missing_state | OTP verify, reset password steps, MFA continuation | A later step called before its prerequisite (shared state, one multi-step flow at a time) |
Password, OAuth, Apple
Password, OAuth, Apple
| Code | Triggered by | Meaning |
|---|---|---|
auth_failed | password | Wrong credentials, account locked, etc. Clerk’s message in error.message |
oauth_failed | oauth | User cancelled, network error, or provider denied |
use_native_apple | oauth&provider=apple | Use method=apple instead |
apple_failed | apple | User cancelled Sign in with Apple |
OTP and code flows
OTP and code flows
| Code | Triggered by | Meaning |
|---|---|---|
email_code_failed | email_code | Code wrong or expired |
phone_code_failed | phone_code | Code wrong, expired, or SMS send failed |
second_factor_failed | second_factor | Wrong code, expired, or strategy error |
prepare_not_needed | second_factor&action=prepare | Strategy does not require a prepare step (TOTP, backup codes) |
reset_password_failed | reset_password | Wrong code, expired, password policy rejected, etc. |
SSO, ticket, passkey
SSO, ticket, passkey
| Code | Triggered by | Meaning |
|---|---|---|
enterprise_sso_failed | enterprise_sso | User cancelled, no SSO connection for the domain, or provider error |
ticket_failed | ticket | Ticket invalid, expired, or already used |
passkey_failed | passkey | User cancelled or no credential |
not_signed_in | passkey&action=register | Cannot register a passkey without a signed-in user |
OAuth providers
Recognized values formethod=oauth. Anything else routes to Clerk’s custom provider handler.
google, github, microsoft, gitlab, discord, twitter (alias x), twitch, linkedin, linkedin_oidc, facebook, tiktok, dropbox, atlassian, bitbucket, notion, line, instagram, coinbase, spotify, xero, box, slack, linear, hubspot, huggingface, vercel.
Quirks
Invocation and event delivery
Invocation and event delivery
despia() calls for clerk:// routes are fire-and-forget. Results arrive through window.onClerkEvent.Events are not buffered. A handler attached after a command was issued misses the result. Wire window.onClerkEvent before any clerk:// call.fetch() and XMLHttpRequest cannot trigger clerk:// URLs. Use despia() to invoke the bridge.JWT timing on completion
JWT timing on completion
window.clerkJWT populates a tick after sign-in completion, not synchronously. After configure or any flow reaching status: "complete", the JWT refresher starts and window.clerkJWT is written on the next event loop tick.Read window.clerkJWT on your next API call, or force a synchronous refresh with clerk://token if you need the token immediately in the same handler.Debug logging
Debug logging
Every inbound URL and every outbound event is printed to the platform console with a
[Clerk] prefix (Xcode console on iOS, Logcat on Android). The JWT value itself is never logged. Grep for [Clerk] while debugging to trace exactly what the bridge received and what it emitted.Toggle off with ClerkBridge.LOG = false on Android or loggingEnabled = false on iOS.If window.onClerkEvent is not defined as a function when the bridge tries to emit, the bridge logs a console warning identifying which event was dropped. The most common integration mistake is not defining the handler before the first clerk:// call.Lenient query parsing
Lenient query parsing
The bridge splits the query string at known-key boundaries, so an unencoded
&, #, or = inside a password survives intact.Recognized keys: method, type, identifier, password, newPassword, email, emailAddress, firstName, lastName, username, phoneNumber, phone, code, action, provider, ephemeral, mode, dismissable, key, ticket, enabled, header, domains.Values are percent-decoded once. Unrecognized parameter names are folded into the previous value and silently ignored.Parameter value formats
Parameter value formats
Boolean parameters accept
true, false, 1, 0, yes, no (case-insensitive).Mode values are lowercase: signin, signup, signinorup (aliases signin_or_up, default).Status values pass through verbatim from the Clerk SDK. Match complete explicitly and treat anything else as “needs more steps.”Phone numbers are normalized to E.164 natively. +1 (555) 123-4567, %2B15551234567, and +15551234567 all reach Clerk as +15551234567.Server-side trust
Server-side trust
On the server, trust only the verified
sub claim from the JWT. Never accept a client-reported userId as proof of identity. The JWT is verifiable against Clerk’s JWKS, but client-supplied IDs are not.See Backend for verification patterns.Platform support
Sameclerk:// URLs, event names, status strings, error codes, and payload shapes work identically on iOS and Android. Implementation differences happen under the hood, the JS contract is the same.
Under-the-hood differences
| Concern | iOS | Android |
|---|---|---|
| Secure session storage | Keychain | Android Keystore |
| Apple Sign In | Native ASAuthorizationController | Apple OAuth via Chrome Custom Tabs |
| OAuth provider flow | ASWebAuthenticationSession | Chrome Custom Tabs |
| Sheet container | View controller (page sheet) | Activity (bottom sheet dialog) |
| Passkey provider | iCloud Keychain | Google Password Manager (Credential Manager, API 28+) |
| Runtime minimum | iOS 17+ | clerk-android’s minimum supported API level |
apple_failed exists on Android too, even though the underlying flow is OAuth rather than the native sheet.
Input-inert on Android
Three optional parameters are accepted on both platforms for schema parity but currently have no native effect on Android due to clerk-android SDK limitations. Passing them on Android is a no-op rather than an error.| Parameter | iOS behavior | Android behavior |
|---|---|---|
clerk://authview?mode=... | Opens the requested screen (signin, signup, or signinorup) | Always opens the combined sign-in-or-up screen. clerk-android-ui’s AuthView() does not expose a mode parameter |
method=oauth&ephemeral=true | Skips shared browser cookies via ASWebAuthenticationSession | Inert. Chrome Custom Tab has no ephemeral session option |
method=enterprise_sso&ephemeral=true | Skips shared browser cookies | Inert. Same SDK limitation as OAuth |
Custom OAuth providers
All 26 named providers in the OAuth providers list resolve identically on both platforms. An unrecognized provider value (a custom Clerk OAuth provider configured in your dashboard) runs as Clerk’s genericCUSTOM strategy on Android, the bridge cannot carry the specific provider key. On iOS the exact custom provider key is preserved end-to-end. In both cases the flow runs rather than failing.
Resources
NPM Package
despia-native