What is a webhook URL? Definition and how to get one

A webhook URL is the public HTTPS address that a service sends webhook requests to. You register it with a provider such as Stripe, GitHub or Shopify, and whenever a subscribed event happens, the provider sends an HTTP POST with the event data to that address. The code that handles those requests is the webhook endpoint.

https://api.example.com/webhooks/stripe
https://hooks.slack.com/services/T0000000/B0000000/XXXXXXXXXXXXXXXXXXXXXXXX
https://discord.com/api/webhooks/123456789012345678/abcDEF...

The first is a URL you host to receive events. The other two are generated by Slack and Discord so that you can send messages into them.

Two kinds of webhook URL

People say "webhook URL" for two opposite things, and it helps to know which one a guide means.

Receiving webhook URLIncoming webhook URL
Who hosts itYouThe destination app (Slack, Discord, Teams)
Who sends to itA provider like Stripe or GitHubYou, your script or another service
What it's forBeing notified of eventsPosting a message into a channel
How you secure itSignature verificationKeep the URL secret, since it is the credential

How to get a webhook URL

To receive webhooks from a provider:

  1. Create a route in your app that accepts POST requests, for example /webhooks/stripe.
  2. Deploy it somewhere publicly reachable over HTTPS. The full address, including the path, is your webhook URL.
  3. Paste it into the provider's webhook settings and pick the events you want.
  4. Copy the webhook secret the provider shows you, and use it to verify each request.

To test before you have a server: open Webhook Bin and you get a public URL straight away. Point the provider at it and you'll see every request it sends, with headers and the full payload.

To receive webhooks on your own machine: providers can't reach localhost, so you need a public URL that forwards to it. With the relay CLI:

relay forward --bucket my-app http://localhost:3000/webhooks

The command prints a permanent public URL. Give that to the provider, and every request is delivered to your local server. See receiving webhooks on localhost and webhook forwarding.

To post into Slack or Discord: the app generates the URL for you. Follow the step-by-step guides for getting a Slack webhook URL and getting a Discord webhook URL.

What a good webhook URL looks like

  • HTTPS with a valid certificate. Many providers refuse plain HTTP, and self-signed certificates fail with errors like ERR_CERT_AUTHORITY_INVALID.
  • Stable. If the URL changes every time you restart a tool, you have to update the provider's settings each time and you lose events sent in between.
  • One path per provider. /webhooks/stripe and /webhooks/github keep signature checks and parsing separate.
  • No secrets in the query string. Query strings end up in logs. Use a signature instead.

Common mistakes

  • Using localhost or a private IP. The provider's servers can't reach it, and deliveries fail or time out.
  • A temporary tunnel URL that changes. Free tunnel tools often give a new random hostname on each restart, so the URL in the provider's settings quietly goes stale.
  • A redirect. Many senders don't follow 301 or 308 redirects for POST, so a missing trailing slash or an HTTP-to-HTTPS redirect can break delivery. Register the final URL.
  • Pointing at the wrong environment. Keep separate URLs and secrets for production, staging and local development.
  • Leaking an incoming webhook URL. A Slack or Discord webhook URL committed to a public repository lets anyone post into your channel. Rotate it if that happens.

If you need one URL that several services receive, or a URL in front of an endpoint that is sometimes down, put a webhook gateway in front: it accepts the request, stores it, and fans it out with retries.

Frequently asked questions

What is a webhook URL?

A webhook URL is the public HTTPS address that a service sends webhook requests to. You paste it into the provider's settings, and every time a subscribed event happens the provider sends an HTTP POST with the event data to that address.

How do I get a webhook URL?

If you are receiving webhooks, the URL is the public address of a route on your own server, for example https://api.example.com/webhooks/stripe. For quick testing, a free request bin such as Webhook Bin gives you a public URL instantly. If you want to post messages into Slack or Discord, those apps generate an incoming webhook URL for you in their settings.

Is a webhook URL the same as a webhook endpoint?

In practice, yes. The webhook URL is the address you give the provider, and the webhook endpoint is the code on your server that handles requests sent to it. Most documentation uses the two terms interchangeably.

Can I use a localhost URL as a webhook URL?

No. The provider sends requests from its own servers over the internet and cannot reach localhost or a private IP address. Use a forwarding tool that gives you a public URL and delivers the requests to your local server over an outbound connection.

Should I keep my webhook URL secret?

Treat it as semi-private. For incoming webhook URLs such as Slack and Discord, the URL itself is the credential, so anyone who has it can post messages. For URLs you host, verify the webhook signature on every request rather than relying on the URL being hard to guess.