What is a callback URL? Callback URL vs webhook URL

A callback URL is an address you give to another service so it can call you back later, when something has finished or happened. Instead of you polling for a result, the service sends a request to your callback URL. Depending on the context, that request is a browser redirect (OAuth login, payment checkout) or a server-to-server HTTP call (webhooks, async job results).

https://app.example.com/auth/callback?code=4/0AbCD...&state=xyz123

That's an OAuth callback: the provider sent the user's browser back to your app with an authorization code.

Where callback URLs show up

ContextWho calls itWhat arrives
OAuth / OpenID Connect loginThe user's browser, via a redirectcode and state in the query string
Payment checkout returnThe user's browser, via a redirectAn order or session ID
Async API job (transcription, video, SMS status)The provider's serverA POST with the job result
WebhooksThe provider's serverA POST with an event payload

The name is borrowed from programming, where a callback is a function you pass to code that will call it later. A callback URL is the same idea across the network.

Callback URL vs webhook URL

A webhook URL is a specific kind of callback URL:

  • Registration. A webhook URL is registered once, in a dashboard or by API, and receives every matching event until you remove it. Callback URLs are often passed per request: Twilio's StatusCallback parameter, or the redirect_uri in each OAuth authorization request.
  • Transport. Webhooks are always server-to-server. OAuth and checkout callbacks go through the user's browser.
  • Content. A webhook carries an event payload and usually a signature. An OAuth callback carries a short-lived code that is only useful together with your client secret.

In casual use the two terms overlap. Some providers label the webhook setting "callback URL", so check the docs for whether the provider will redirect a browser or send a request from its servers.

How an OAuth callback URL works

  1. Your app sends the user to the provider with redirect_uri=https://app.example.com/auth/callback and a random state.
  2. The user logs in and approves access.
  3. The provider redirects the browser to your callback URL with ?code=...&state=....
  4. Your server checks that state matches what it issued, then exchanges the code for tokens in a back-channel request.
app.get('/auth/callback', async (req, res) => {
  if (req.query.state !== req.session.oauthState) return res.sendStatus(400)
  const tokens = await exchangeCodeForTokens(req.query.code)
  req.session.user = await fetchProfile(tokens.access_token)
  res.redirect('/dashboard')
})

Common mistakes

  • redirect_uri_mismatch. OAuth providers compare the callback URL exactly: scheme, host, port, path and often the trailing slash. http://localhost:3000/callback and http://localhost:3000/callback/ are different URLs.
  • Skipping the state check. Without it, an attacker can complete a login flow in someone else's session (login CSRF).
  • Using localhost for a server-to-server callback. A browser redirect to localhost:3000 works because the user's own browser follows it. A job-complete callback from a provider's servers can't reach your machine. Use a public URL that forwards to it, through a tunnel or webhook forwarding.
  • Trusting the callback blindly. For server-to-server callbacks, verify the signature or fetch the result from the provider's API before acting on it.
  • Slow handlers. Server-to-server callbacks behave like webhooks: return 2xx quickly or the provider may time out and retry. See webhook retries.

Testing callbacks

For browser-redirect callbacks during development, register a http://localhost redirect URI if the provider allows it. For server-to-server callbacks, point the provider at a Webhook Bin URL to see exactly what it sends, then run relay forward --bucket my-app http://localhost:3000/callbacks to deliver real callbacks to your local code through a permanent public URL.

Frequently asked questions

What is a callback URL?

A callback URL is an address you give to another service so it can call you back when something finishes or happens. The service later sends a request to that URL, either by redirecting the user's browser to it, as in OAuth login, or by making a server-to-server HTTP request, as with webhooks and async job notifications.

What is the difference between a callback URL and a webhook URL?

A webhook URL is one kind of callback URL. Webhook URLs are registered once and receive a server-to-server request for every matching event. Callback URLs are often passed per request or per flow, and in OAuth the callback is a browser redirect that carries an authorization code rather than an event payload.

What is an OAuth callback URL?

It is the redirect URI the authorization server sends the user's browser back to after they log in and grant access. The URL receives an authorization code and a state value in the query string, and your app exchanges the code for tokens. It must exactly match one of the redirect URIs registered with the provider.

Can a callback URL be localhost?

For OAuth browser redirects, often yes, because the user's own browser follows the redirect and can reach localhost. Many providers allow http://localhost redirect URIs for development. For server-to-server callbacks, no: the provider's servers cannot reach localhost, so you need a public URL that forwards to your machine.