Skip to main content
Every Portal-managed sign-in ends the same way: Portal redirects the user to a URL you control, with a single-use token appended. That URL is your redirect URL, and it has to be allow-listed for the auth environment before any sign-in will start. This page is the source of truth for how redirect URLs are matched and what Portal appends to them. For the SDK calls that consume the redirect, see the Web Client Auth guide.

Two different redirects

Two URLs in this flow are both called a redirect, and they are not the same thing. The provider redirect URI is how Google or Apple hands the user back to Portal, and it is covered in Google OAuth and Apple OAuth. Everything below is about the second one.

Supported forms

An App Link or Universal Link is not a separate kind of allow-list entry. To Portal it is an ordinary HTTPS URL; what routes it to your app instead of a browser is the association file you host on that domain (assetlinks.json on Android, apple-app-site-association on iOS). Portal appends its parameters the same way either way.
Custom schemes are valid allow-list entries. If you are integrating a mobile app, register the same custom scheme URL you will pass to the SDK — you do not need to host a web page to complete a sign-in.

How matching works

Portal compares your redirect URL against the allow list by exact string comparison. There are no wildcards and no path prefixes. A request whose redirectUrl is not on the list is rejected with a 401. This is what stops someone who has your Auth Environment ID from sending your users, and their sign-in tokens, to a site they control. On the OAuth path the check runs twice: once when the sign-in starts and again when the provider calls back.
The Portal SDKs compare redirect URLs more loosely than the backend does. Locally they lowercase the scheme and authority, strip trailing slashes, and ignore the query string and fragment, so an SDK can accept a URL that the API then refuses with a 401. Never treat a successful local match as proof the value is allow-listed — use the exact string in every place below.

Use one string everywhere

The same redirect URL has to appear, byte for byte, in up to three places.
  1. The dashboard. The Redirect URLs allow list under Authentication > Configure. See Enable authentication.
  2. Your SDK configuration. redirectUrl in the Web SDK’s clientAuth option, or the equivalent for whichever client you are using.
  3. Your native app registration. On mobile only: the URL scheme in Info.plist and the intent filter in AndroidManifest.xml.
Each mismatch fails differently, which is worth knowing when you are debugging:
  • Dashboard and SDK disagree — the sign-in never starts. You get a 401 from the call that begins the flow.
  • SDK and native registration disagree — the sign-in completes, but the redirect never reaches your app. Nothing throws; the user is left in the browser.

What Portal appends

Portal appends its parameters to your redirect URL, using ? or & depending on whether your URL already has a query string.
If your redirect URL already carries a parameter named token, the SDKs read the last occurrence, which is always the one Portal appended.

Grants are single use

The token parameter is a grant: proof that a sign-in completed. It is short-lived and single use, and it is spent the moment the backend sees it. Once a grant has been exchanged or has expired, the user has to sign in again. There is no way to refresh one.

When a sign-in fails

The two methods fail differently, and your app has to handle both. OAuth returns the user to your redirect URL with error=oauth_failed and no token. The value is deliberately generic — it covers a cancelled consent screen, a disabled method, and a rejected state nonce alike. Treat it as “the user did not complete the sign-in” and offer to start again. Magic links have no error redirect. An expired or already-used link still arrives at your redirect URL carrying a token, and the failure only surfaces when your app exchanges it. So a redirect that looks valid can still fail a moment later. Your app needs an error path on the exchange, not just on the URL.

A redirect can arrive twice

Operating systems re-deliver deep links, and a browser can reload a callback page. Because a grant is spent on first use, a second delivery of the same redirect cannot produce a second session. Route every redirect through exactly one handler in your app. If two code paths both consume the same URL, the second one fails on an already-spent grant, which looks like a genuine authentication error to your user.

Register the redirect in your app

Add a route at the exact URL on your allow list. It has to be reachable by a full-page navigation, because the provider redirects the browser to it.
The page reads its own URL and hands it to the SDK. See Client Auth for the callback route.
Client Auth is available in the Portal Web SDK. If you are integrating on another platform, you can drive the same flow against the Authentication API directly.

Next steps

Web Client Auth

Build a callback route and complete a sign-in in a web app.