API FUNDAMENTALS / LESSON 08
Webhooks.
Receiving real-time notifications

Loading the lesson…
Loading activities…
API FUNDAMENTALS / LESSON 08
Receiving real-time notifications

Loading the lesson…
Loading activities…
So far you've learned how to call APIs. You send a request, you get a response. But sometimes you want it the other way around... you want the server to tell YOU when something happens. That's what webhooks are for.
A webhook is basically a reverse API call. Instead of you asking the server "Did anything happen?", the server tells you on its own, "Something just happened!"
Think about text notifications. You don't sit there asking your phone "Did I get a message?" every ten seconds. Your phone just lets you know when one shows up. Webhooks work the same way.
Without webhooks, you'd have to keep checking for updates over and over.
That's called polling. It burns resources and it misses real-time updates (it's also the toddler-in-the-backseat approach to software).
Here's the webhook version.
WAY better.
First you create a URL on your own server that can receive data. That's your webhook endpoint.
You tell the other service about your endpoint. "When X happens, send data to this URL."
An event happens. Maybe a customer pays, or a user signs up, or a file finishes processing.
The service sends an HTTP POST request to your URL with the details of what happened.
Your endpoint takes that data and does something with it. Maybe it sends an email, updates a database, or kicks off another action.
Here's what happens when a customer pays through Stripe.
checkout.session.completed webhook to your server, shaped like this one (trimmed WAY down, the real thing has a ton more fields)A couple things worth noticing. amount_total is in cents, so 5999 means $59.99. created is a Unix timestamp in seconds. And metadata is stuff YOU attached when you created the checkout (like your own order ID), which Stripe hands right back to you here.
Here's what happens when someone creates an account through a third-party service.
And here's one for when a package changes status.
Here's a simple webhook endpoint in JavaScript (using Node.js with Express) that handles the Stripe payment from above. For now we're skipping the security check so you can see the bones of it. Don't ship it like this, we fix that in the next section.
The main things to notice are pretty simple.
type tells you what happenedmarkOrderAsPaid and sendConfirmationEmail are your own functions)Anybody could try to send fake data to your webhook. So you need to check that a webhook really came from the real service.
Most services sign their webhooks. They include a special header that proves the request is legit, and their SDK gives you a function to check it. Here's the same endpoint with Stripe's check bolted on.
Some services publish a list of IP addresses their webhooks come from. You can check that requests actually come from those IPs.
Here are some events you might end up handling. These names are generic examples. Every service picks its own names, so always check their docs. Stripe for example uses checkout.session.completed, invoice.payment_failed, customer.subscription.deleted and charge.refunded for the payment stuff below.
payment.completed - Customer paid successfullypayment.failed - Payment was declinedsubscription.cancelled - Customer cancelled their subscriptionrefund.created - A refund was processeduser.created - New user signed upuser.updated - User changed their profileuser.deleted - User deleted their accountmessage.received - New message came inmessage.delivered - Your message was deliveredmessage.read - Recipient read your messagefile.uploaded - File upload completedfile.processed - File processing finished (like video encoding)Webhook senders expect a fast answer. Do the bare minimum, then respond with 200. If there's heavy processing to do, save the data and deal with it in a background job.
If your endpoint returns an error (or never answers), most services will retry. Stripe keeps retrying for up to three days in live mode. Your code should be fine getting the same event more than once, and the easy way is to save each event's ID and skip any ID you've already handled.
Keep a record of each webhook's event ID, type, timestamp and processing result. That is usually enough to diagnose a failed or duplicate event. If you must retain a payload, remove sensitive fields, restrict who can read it and delete it after a short retention period. The sample payment event includes a customer's email, so logging the entire body by default would expose personal data.
I learned this one the hard way. A client's Outlook update silently dropped 49 form-fill notifications. Deliverability said "delivered," and NOTHING hit the inbox. When the thing in the middle swears everything's fine, your own logs are the only receipts you've got.
You've learned how to use APIs and receive webhooks. Now it's time to make your own. In the next lesson you'll build a simple API endpoint from scratch...