Redirect URIs: the two callbacks

There are two different callback URLs in a social sign-in. Mixing them up is the #1 setup mistake. Here's exactly which is which.

Updated September 19, 2026

A brokered social sign-in has two redirect hops, and therefore two callback URLs registered in two different places. Almost every setup problem comes from confusing them.

The flow, step by step

1. user clicks "Sign in with LinkedIn" in your app
2. → AuthRobo  (start)
3. → LinkedIn  (user approves)
4. → AuthRobo  /api/v1/auth/linkedin/callback     ← callback #1
5. → your app  https://yourapp.com/auth/callback  ← callback #2  (+ AuthRobo code)
6. your app calls exchange() → tokens

Callback #1 — provider → AuthRobo

Registered inside your LinkedIn/Google/GitHub app. It must be AuthRobo's endpoint:

https://authrobo.com/api/v1/auth/<provider>/callback

This is where the provider hands its code to AuthRobo, which holds the secret and does the token exchange. It is the same value whether you use a shared or bring-your-own app.

Callback #2 — AuthRobo → your app

Registered in the AuthRobo dashboard, in your app's allowed redirect URIs. This is *your* URL:

https://yourapp.com/auth/callback

This is where AuthRobo sends its own one-time code after the provider dance finishes. Your backend exchanges that code for tokens.

Callback #2 is per environment

Each environment (production, staging, sandbox, development) is its own set of credentials with its own allowed redirect URIs, edited on its own tab under Environments → Callback URLs. A new environment starts from production's list, and diverges the moment you edit it — changing staging's callbacks never touches production's.

production   https://mycv.com/auth/callback
staging      https://staging.mycv.com/auth/callback
development  http://localhost:3000/auth/callback

A callback must be https, in every environment — an authorization code delivered over plaintext is a code anyone on the network can steal. The one exception is loopback: http://localhost and http://127.0.0.1 are accepted anywhere, because a loopback callback can't be intercepted remotely and it's how native and CLI clients sign in. Development is simply where loopback is expected rather than unusual.

Side by side

Callback #1Callback #2
Registered inYour provider app (LinkedIn, …)AuthRobo dashboard
Valuehttps://authrobo.com/api/v1/auth/<provider>/callbackhttps://yourapp.com/…
Who receives the codeAuthRoboYour app
Which secret exchanges itProvider secret (AuthRobo holds)Your client_secret

Worked example: MYCV

You're adding LinkedIn to MYCV with your own LinkedIn credentials:

  • In the LinkedIn app, set the authorized redirect URL to https://authrobo.com/api/v1/auth/linkedin/callback (callback #1). Not a MYCV URL.
  • In the AuthRobo dashboard, add https://mycv.com/auth/callback to MYCV's allowed redirect URIs (callback #2).

If you instead point the LinkedIn app at https://mycv.com/…, LinkedIn hands its code straight to MYCV, AuthRobo is bypassed, and none of the broker's benefits (uniform tokens, user records, Stripe linkage) apply.

Want a MYCV-branded callback #1? That requires a white-label auth domain (e.g. auth.mycv.com as a CNAME to AuthRobo). The code is still served by AuthRobo — only the hostname changes.
Ready to build? Create your app → or browse the API reference.