Documentation

Everything you need to set up and manage webhook relaying with Webhook Stream.

Getting Started

1. Create an account

Sign up for a free account at webhookstream.com. Authentication is handled through WorkOS, supporting email, Google, GitHub, and Microsoft sign-in methods. No credit card is required for the Free plan.

2. Create your first endpoint

Navigate to Endpoints and click Create Endpoint. Give your endpoint a name and you'll receive a unique ingest URL like:

https://webhookstream.com/ingest/your-endpoint-slug-abc123

Use this URL as the webhook URL in your provider's settings (Stripe, GitHub, Shopify, etc.).

3. Add a destination

On your endpoint's detail page, click Add Destination. Enter the URL where you want webhooks forwarded. You can configure:

  • Destination URL — where the webhook payload will be sent
  • Timeout — how long to wait for a response (default: 30 seconds)
  • Retry attempts — how many times to retry on failure (default: 3)

4. Send a test webhook

You can send a test request using cURL:

$ curl -X POST https://webhookstream.com/ingest/your-endpoint-slug-abc123 \
  -H "Content-Type: application/json" \
  -d '{"event": "test", "data": {"message": "Hello from Webhook Stream"}}'

Check the Logs page to see the incoming request and its delivery status.

Endpoints & Destinations

Endpoint limits

The number of endpoints and destinations you can create depends on your plan:

Plan Endpoints Destinations / Endpoint Requests / Day Log Retention
Free 2 1 100 3 days
Pro 25 10 10,000 30 days
Enterprise Unlimited Unlimited Unlimited 90 days

Multiple destinations

Each endpoint can forward webhooks to multiple destinations simultaneously. When a webhook arrives, it is delivered to all active destinations in parallel. Each destination tracks its own delivery status and retry count independently.

Retry logic

When a destination returns a non-2xx status code or times out, the delivery is retried with exponential backoff. You can configure the maximum number of retry attempts per destination (up to 5). The retry schedule is:

  • Attempt 1: immediate
  • Attempt 2: after 30 seconds
  • Attempt 3: after 2 minutes
  • Attempt 4: after 10 minutes
  • Attempt 5: after 30 minutes

Endpoint Subscriptions (Enterprise)

Overview

Endpoint subscriptions allow developers to programmatically subscribe to any endpoint via the API. When a webhook arrives at that endpoint, the payload is automatically forwarded to all active subscribers in addition to the configured destinations. This is ideal for development and testing workflows where engineers need to receive webhooks without configuring destinations through the UI.

How it works

  1. A developer creates a subscription by calling POST /api/v1/endpoints/{id}/subscriptions with their callback URL
  2. When a webhook arrives at the endpoint, it is forwarded to all configured destinations and all active subscribers
  3. Subscriber forwarding is best-effort (single attempt, no retries) to minimize latency
  4. When finished testing, the developer deletes their subscription via the API

Subscribing via the API

$ curl -X POST https://webhookstream.com/api/v1/endpoints/{endpoint_id}/subscriptions \
  -H "Authorization: Bearer your-api-token" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-local-server.dev/webhook-listener",
    "description": "Local dev testing",
    "secret": "optional-signing-secret",
    "expires_at": "2026-03-01T00:00:00Z"
  }'
PS> Invoke-RestMethod -Uri "https://webhookstream.com/api/v1/endpoints/{endpoint_id}/subscriptions" `
  -Method Post `
  -Headers @{ Authorization = "Bearer your-api-token" } `
  -ContentType "application/json" `
  -Body '{
    "url": "https://your-local-server.dev/webhook-listener",
    "description": "Local dev testing",
    "secret": "optional-signing-secret",
    "expires_at": "2026-03-01T00:00:00Z"
  }'

Subscription options

  • url (required) — the callback URL where webhooks will be forwarded
  • description (optional) — a label to identify the subscription (e.g. "local dev", "staging test")
  • secret (optional) — an HMAC signing secret. When set, forwarded requests include a signature header so your listener can verify authenticity
  • expires_at (optional) — ISO 8601 timestamp for automatic expiration. Expired subscriptions stop receiving webhooks

Managing subscriptions in the UI

Team admins and editors can view, toggle, and remove active subscriptions from the Subscriptions tab on any endpoint's detail page. The tab shows each subscriber's URL, status, creator, and last notification time.

Security

Inbound signature validation

On Pro and Enterprise plans, you can configure signature validation to verify that incoming webhooks are authentic. Webhook Stream supports common signing schemes:

  • HMAC-SHA256 — used by Stripe, Shopify, and many others
  • HMAC-SHA1 — used by GitHub

Configure the signing secret and header name in your endpoint settings. Requests with invalid signatures will be rejected with a 401 response.

Outbound request signing

When forwarding webhooks to your destinations, you can enable outbound signing. Webhook Stream will add an HMAC signature header to forwarded requests so your destination can verify the request came through Webhook Stream.

IP allowlisting

On Pro and Enterprise plans, you can restrict which IP addresses are allowed to send webhooks to your endpoints. Requests from unlisted IPs will be rejected with a 403 response. This is useful when your webhook provider publishes a known list of IP addresses.

SSO & SCIM (Enterprise)

Enterprise plans include single sign-on (SSO) and SCIM directory sync through WorkOS. This allows you to:

  • Enforce SSO for all team members
  • Automatically provision and deprovision users from your identity provider
  • Support SAML 2.0 and OIDC protocols

Configure SSO and SCIM from your team Settings page.

Alerts

Creating alert rules

On Pro and Enterprise plans, you can create alert rules that trigger when specific conditions are met. Navigate to Alerts and click Create Alert Rule. Each rule consists of:

  • Name — a descriptive label for the rule
  • Endpoint — apply to a specific endpoint or all endpoints
  • Logic operator — AND (all conditions must match) or OR (any condition matches)
  • Conditions — one or more conditions based on status code, response time, header values, or payload content

Notification channels

When an alert rule is triggered, notifications are sent to the configured channels. Supported channels include email, Slack, and webhook (POST to a URL of your choice).

Logging & Export

Webhook logs

Every webhook received by your endpoints is logged with the following details:

  • Timestamp, HTTP method, source IP, and content type
  • Full request headers and payload
  • Signature validation result
  • Per-destination delivery status, HTTP response code, duration, and error details

Use the Logs page to search, filter, and inspect webhook requests.

CSV export

On Pro and Enterprise plans, you can export your webhook logs to CSV. The export includes all log fields plus full delivery attempt details. Each delivery attempt is exported as a separate row for easy analysis.

Export is available from the Logs page using the Export CSV button. Filters applied on the page are reflected in the export.

Teams & Members

Roles

Each team member has one of three roles:

  • Owner — full access, manages billing and can delete the team
  • Admin — can manage endpoints, members, settings, and alerts
  • Member — can view endpoints, logs, and alerts but cannot modify settings

Inviting members

Navigate to Settings > Team Members and click Invite Members. You can invite multiple members at once, each with a specific role. Invitations are sent via email and expire after 7 days.

Groups

Endpoints can be organized into groups for better visibility. Team members can be assigned to specific groups to control which endpoints they see. A "General" group is created automatically for every team.

API Reference

Authentication

API requests are authenticated using bearer tokens. Generate API tokens from Settings > API Tokens. Include the token in the Authorization header:

Authorization: Bearer your-api-token

Pro plans include up to 5 API tokens. Enterprise plans have unlimited tokens.

Base URL

https://webhookstream.com/api/v1

Endpoints

GET /endpoints

List all endpoints for the current team.

POST /endpoints

Create a new endpoint. Required fields: name.

GET /endpoints/{id}

Retrieve a specific endpoint with its destinations.

PUT /endpoints/{id}

Update an endpoint's name, group, or settings.

DELETE /endpoints/{id}

Delete an endpoint and all its destinations.

Destinations

POST /endpoints/{id}/destinations

Add a destination. Required: url. Optional: timeout, retry_attempts.

DELETE /endpoints/{id}/destinations/{destinationId}

Remove a destination from an endpoint.

Subscriptions (Enterprise)

Programmatically subscribe to an endpoint to receive forwarded webhooks. Requires an Enterprise plan.

GET /endpoints/{id}/subscriptions

List all subscriptions for an endpoint.

POST /endpoints/{id}/subscriptions

Subscribe to an endpoint. Required: url. Optional: description, secret, expires_at.

GET /endpoints/{id}/subscriptions/{subscriptionId}

Retrieve a specific subscription's details.

PUT /endpoints/{id}/subscriptions/{subscriptionId}

Update a subscription's URL, secret, active state, or expiration.

DELETE /endpoints/{id}/subscriptions/{subscriptionId}

Remove a subscription (unsubscribe).

Logs

GET /logs

List webhook logs. Supports query params: endpoint_id, status, from, to, page.

GET /logs/{id}

Retrieve a single log entry with full headers, payload, and delivery attempts.

Rate limits

API requests are rate-limited to 60 requests per minute per token. Rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining) are included in every response.

Errors

The API returns standard HTTP status codes. Error responses include a JSON body:

{
  "error": "validation_error",
  "message": "The name field is required."
}
Status Meaning
200Success
201Created
400Bad request / validation error
401Unauthorized / invalid token
403Forbidden / insufficient permissions
404Resource not found
429Rate limit exceeded
500Internal server error