Inbound Webhooks
Receive events from GitHub and any system that signs requests with HMAC-SHA256, each request checked against a per-source secret.
Receive events from external systems as they happen. When a commit is pushed to GitHub, or your own service posts a change, the event enters your pipeline with that request.
SaaS connectors poll on a schedule. A webhook source receives each event when the sender posts it.
Create a webhook source
In the console, open Pipeline → Sources → Webhooks and create a webhook source in the environment that should receive the events. Bind it to a route so its events reach your sinks. A source with no active route answers 503 and keeps nothing.
Each source gets its own URL and signing secret:
POST https://api.schemabounce.com/api/v1/ingest/webhook/{workspace_id}/{environment_id}/{webhook_id}
Copy the URL from the source in the console and paste it into the sending system.
Signing requests
Every request must carry an HMAC-SHA256 signature of the raw request body, computed with the source's signing secret and sent as lowercase hex. The header is X-Webhook-Signature unless you set a different header name on the source. A sha256= prefix is accepted.
import hashlib
import hmac
def sign(body: bytes, secret: str) -> str:
return "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
# requests.post(url, data=body, headers={"X-Webhook-Signature": sign(body, secret),
# "Content-Type": "application/json"})
Senders that already sign this way work as they are. GitHub does: set the source's signature header to X-Hub-Signature-256 and use the same secret in GitHub. Senders with a different signing scheme are not verified today. That includes Stripe's timestamped Stripe-Signature, Shopify's base64 HMAC and Slack's v0 signature.
When you rotate a source's secret, the previous secret keeps working until the expiry you set, so senders can switch over without dropped events. A source can also restrict which IP addresses may call it.
What becomes an event
The request body becomes the event's data, unchanged. Send JSON. Up to 10 MB per request.
| Header | Effect |
|---|---|
X-Event-Type | Sets the event type. Without it the event is an insert. |
X-GitHub-Event | Used as the event type when X-Event-Type is absent. |
Stripe-Event-Type | Used as the event type when neither header above is present. |
X-Object-Type | Optional object name carried with the event. |
Each accepted request is one event. A request the sender retries becomes a second event, so put the sender's own ID in the body if your downstream needs to remove repeats.
Response codes
| Code | Meaning |
|---|---|
| 202 | Accepted. The body is {"status": "accepted", "event_id": "..."}. |
| 400 | The URL is malformed or the body could not be read. |
| 401 | The signature is missing or does not match. |
| 403 | The source is not active, the IP address is not allowed, or the URL names another workspace or environment. |
| 404 | No webhook source has this ID. |
| 413 | The body is over 10 MB. |
| 503 | The source has no active pipeline route, or ingest is unavailable. Retry with backoff. |
Good practice
- Retry on 503 with exponential backoff.
- Rotate the signing secret on a schedule, using the overlap window above.
- Keep the secret server-side. Anyone holding it can send events as that source.
Related
- SaaS Connectors: pair webhooks with a scheduled OAuth sync for full record history plus real-time updates.
- Database CDC: the lowest-latency option when the source is your own database.
- Outbox Pattern: a transactional alternative to CDC for databases without log access.
- Connector Reference: the full catalog of connectors, several of which also support webhooks.
- Direct Pull: query-based syncing for managed databases.
- Pipeline overview and how the pipeline works.
- Filters and transforms for shaping webhook events before they reach a sink.
- Troubleshooting if webhook deliveries are failing or delayed.
- Read what CDC is for how push-based webhooks compare to log-based change capture.
- Real-Time CDC Webhooks: Streaming Database Changes to Any Endpoint
Related Documentation
Continue exploring