Migrate to Railhook
Two things decide how hard a move is: whether your receivers have to change, and whether your concepts carry over. This page covers both, then gives a migration you can run with both platforms live.
Your receivers usually keep working
Section titled “Your receivers usually keep working”Railhook signs outgoing deliveries with the Standard Webhooks headers:
webhook-id: <the delivery id, unchanged across retries>webhook-timestamp: <unix seconds>webhook-signature: v1,<base64>The signature is HMAC-SHA256 over {id}.{timestamp}.{body}, base64-encoded. A receiver that already verifies with a Svix or Standard Webhooks library keeps working once it has the new secret.
New endpoints also receive Railhook’s own header by default:
X-Signature: t=<unix milliseconds>,v1=<hex HMAC-SHA256 of "{t}.{body}">A receiver verifies the header it knows and ignores the other, so you can move receivers one at a time, or never.
| Your receiver verifies with | What to change |
|---|---|
| A Svix or Standard Webhooks library | The secret and the URL. Nothing else. |
| Another platform’s own signature header | Switch to a Standard Webhooks library, or verify X-Signature. Both are sent. |
A hand-written t=…,v1=… parser |
Check the units: t in X-Signature is in milliseconds, not seconds. |
Receivers should deduplicate on webhook-id. Delivery is at-least-once, and the id stays the same across retries.
See Signatures for verification code in each SDK language.
How the concepts map
Section titled “How the concepts map”| Railhook | Svix | Hookdeck | Convoy |
|---|---|---|---|
| Organization | — | — | Organisation |
| Project | Application | — | Project |
| Endpoint | Endpoint | Destination (Outpost) | Endpoint |
| Subscription (an endpoint and an event type) | Event types on an endpoint | — | Subscription |
| Event | Message | Event | Event |
| Delivery (one event to one endpoint) | — | — | Event delivery |
| Attempt (one HTTP request) | Attempt | Attempt | — |
| Source (a provider you receive from) | Source (Ingest) | Source (Event Gateway) | Source |
| Destination (where a received webhook goes) | Destination (Ingest) | Destination (Event Gateway) | — |
| Time Machine (replay) | Replay | — | — |
A dash means we found no direct equivalent in that vendor’s documentation, not that the vendor lacks the capability.
Two differences matter when you move:
- Delivery and attempt are separate. A delivery is the obligation to get one event to one endpoint; an attempt is one HTTP request towards it. “How many times was this retried” has an exact answer.
- Replay is not a retry. A retry is the next attempt on the same delivery. A replay builds a new delivery from a stored event and leaves the original as it was. See Replay.
Migrate without a maintenance window
Section titled “Migrate without a maintenance window”Because receivers can verify both signature schemes, the old platform and Railhook can run side by side.
- Recreate the shape. Create projects, endpoints and subscriptions through the API. See Endpoints and subscriptions.
- Give each receiver its new secret in
whsec_form. It now accepts signatures from both platforms. - Send every event to both platforms for as long as you need confidence. A receiver that deduplicates on
webhook-idhandles each Railhook delivery once. - Compare. Watch
delivery_oldest_pending_age_secondsand failed messages in Railhook against the old platform’s numbers. See Observability. - Stop sending to the old platform. There is no cutover moment.
Before you commit
Section titled “Before you commit”Check How Railhook compares for what Railhook does not have yet, such as a customer-facing portal, SSO and non-HTTP destinations.