Skip to main content
Flat reference for everything the bridge emits. For per-method documentation, see Auth Methods, Sessions, Backend, and Account.

Payload envelope

Shape of every onClerkEvent callback

Events

Every event name the bridge can emit

Status values

What status strings mean

Error codes

Every error.code and what fires it

Quirks

Bridge behavior worth knowing

Platform support

iOS vs Android, +3 Android divergences

Payload envelope

Every onClerkEvent callback receives an object with this shape:
Always branch on 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 a signIn or signUp event).

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

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.

OAuth providers

Recognized values for method=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.
provider=apple is rejected with use_native_apple. Use method=apple for the native sheet on iOS or Apple OAuth via Chrome Custom Tabs on Android.

Quirks

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

Same clerk:// 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

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.

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 generic CUSTOM 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