How to receive a webhook and forward it to another URL with Python
Most "connect two tools" jobs start the same way: something sends a
webhook (a form submission, a payment event, a status change) and you need
to catch it and either log it or pass it on somewhere else. Python's
standard library can run a small HTTP server that does exactly that — no
framework, no pip install:
import csv, json, urllib.request
from http.server import BaseHTTPRequestHandler, HTTPServer
FORWARD_TO = "https://example.com/your-target-endpoint"
LOG_FILE = "webhooks.csv"
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
length = int(self.headers.get("Content-Length", 0))
body = self.rfile.read(length)
# log every event received
with open(LOG_FILE, "a", newline="", encoding="utf-8") as f:
csv.writer(f).writerow([self.headers.get("Date", ""), body.decode("utf-8", "replace")])
# forward it on, unchanged
req = urllib.request.Request(FORWARD_TO, data=body,
headers={"Content-Type": self.headers.get("Content-Type", "application/json")})
try:
urllib.request.urlopen(req, timeout=10)
except Exception:
pass # log kept above even if the forward fails
self.send_response(200)
self.end_headers()
if __name__ == "__main__":
HTTPServer(("0.0.0.0", 8000), Handler).serve_forever()
Run python3 bridge.py, point the sender's webhook URL at
http://your-server:8000/, and every call gets logged to
webhooks.csv and relayed to FORWARD_TO.
Where a script like this stops being enough
This one relays the payload as-is. Real bridges usually need to reshape it first — pull specific fields out of the sender's JSON, rename or map them, verify a signature header so random requests can't spoof the webhook, retry on failure instead of dropping it, and often talk to a service that isn't a plain URL at all (a spreadsheet API, a CRM, Slack) which means authentication and that service's own request format. At that point it isn't twenty lines running on a laptop anymore — it needs to run somewhere reliably, and it's worth having someone else write and hand you.
The finished version, free
The receiver above forwards while the sender is still waiting, which is fine until the target is slow or down. hookbridge.py accepts to a queue on disk and answers in about a millisecond, then delivers with backoff — so a restart, or a target that is down for an hour, loses nothing. It also verifies the HMAC signature before parsing the body.
hookbridge.py on GitHub — one file, no dependencies, public domain, tested on Python 3.9 to 3.13. Keep it, change it, ship it in something you sell.
Or skip writing it yourself
Send the two services and what should happen between them — forward form submissions into a spreadsheet, sync records both ways, relay events into Slack — and get back working code, field mapping and signature verification included where the source supports it.
99€ — one-time, fixed, 48h
Buy — Stripe checkout details← See the other two packages (CSV cleanup, website scraping)