Pushrail Docs
Open app
Guides · Destinations

Webhooks

Configure generic REST webhook destinations with signed bodies and custom headers.

Webhooks

Webhooks are the most common destination type, any HTTPS endpoint that accepts JSON over POST can receive Pushrail events. Pushrail signs every body so the receiver can prove the request came from you, retries transient failures with backoff, and exposes the full request and response on every attempt in the delivery log.

When to use

Reach for a webhook when your customer (or your own product) already has an HTTP endpoint that consumes events: a request handler in a Rails app, a Cloud Function, an internal service. Webhooks are the lowest-friction destination, no schema setup, no warehouse credentials, just a URL.

If the receiver is a long-running consumer that needs ordering, durability, or high throughput, prefer a queue destination (SQS, SNS, Kafka, Pub/Sub, Kinesis) over a webhook. Webhooks scale, but a queue gives the receiver control over consumption rate.

Auth options

Webhook destinations support several auth schemes, configurable in the destination's auth section:

  • None, for development and dev-tunnel destinations. Never use this in production.
  • Bearer token, Pushrail sends Authorization: Bearer <token>.
  • Basic auth, Pushrail sends Authorization: Basic <base64(user:pass)>.
  • Custom header, for receivers that expect a single API-key-style header (X-API-Key: ...).
  • OAuth2 client credentials, Pushrail mints and refreshes access tokens against a configured token endpoint.

In all cases the secret is encrypted at rest and masked in the dashboard after creation. Rotate secrets from Destination → Settings → Rotate; the previous secret stays valid for 24 hours so the receiver can update without a delivery gap.

Config reference

Generic REST

The only required field is the URL. Optional settings:

  • HTTP method, POST (default), PUT, PATCH.
  • Custom headers, arbitrary key/value pairs sent on every request.
  • Signing scheme, pushrail_v1 (default, timestamped HMAC-SHA256), github_v1 (GitHub-compatible), or none. See Verifying webhook signatures.
  • Timeout, per-request timeout, default 30s, max 60s.
  • Body envelope, wrap the canonical event in a custom JSON shape using a declarative transform.
{
  "type": "webhook",
  "url": "https://api.acme.example/pushrail/events",
  "method": "POST",
  "auth": { "type": "bearer", "token": "{{secret}}" },
  "signing": { "scheme": "pushrail_v1" },
  "timeoutMs": 30000
}

Common patterns

Per-customer URLs: scope the destination to a customerExternalId so each of your customers can configure their own URL via the embedded portal. The dashboard or portal user enters the URL; you do not store URLs in your application code.

Event-type filtering: add a routing rule that matches only the event types this receiver cares about. A webhook receiver should never see events it does not understand.

Receiver-side dedup: the canonical event's id is stable across retries. Receivers should treat (eventType, id) as the dedup key and skip events they have already processed.

Verifying delivery

Open Observability → Deliveries, filter by the destination. Each delivery shows the request body sent, the request headers (including the signature), the response status and body, and the latency. Failed deliveries show the retry schedule and the classifier's verdict (transient or permanent).

The destination card on the dashboard surfaces per-destination health, success rate, p50/p99 latency, and the most recent failure reason. When the success rate drops, that is the page you want to look at first.