Skip to content
Back to site

Migrate to Railhook

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 base64 HMAC-SHA256 over {id}.{timestamp}.{body}. A receiver using 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 receivers can move 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. Verification code for each SDK language is in Signatures.

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 no direct equivalent was found in that vendor’s documentation, not that the capability is missing.

Two differences matter:

  • 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, so the retry count is exact.
  • 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.

Receivers can verify both signature schemes, so the old platform and Railhook can run side by side.

  1. Recreate the shape. Create projects, endpoints and subscriptions through the API. See Endpoints and subscriptions.
  2. Give each receiver its new secret in whsec_ form. It now accepts signatures from both platforms.
  3. Send every event to both platforms until you are confident. A receiver that deduplicates on webhook-id handles each Railhook delivery once.
  4. Compare delivery_oldest_pending_age_seconds and failed messages in Railhook with the old platform’s numbers. See Observability.
  5. Stop sending to the old platform. There is no cutover moment.

How Railhook compares lists what Railhook does not have, such as SSO and non-HTTP destinations.