Webhook Guides

Webhook Request Example

A webhook request example gives engineers a concrete request shape before they connect a real provider. It shows the URL, method, headers, JSON payload, optional query parameters, idempotency key, and the request record you should expect to see after FastHook captures it.

Use this example for onboarding docs, staging smoke tests, CI fixtures, partner integration docs, and debugging conversations where everyone needs the same payload and headers.

Complete webhook request anatomy

A webhook request is just HTTP, but production debugging depends on preserving each part of that HTTP request. FastHook stores request data so you can inspect the method, path, query, headers, body, accepted or rejected status, and routed events.

Webhook request anatomy showing method, source URL, query, headers, signature or idempotency fields, JSON body, and response.
A useful webhook example names every HTTP boundary: method, URL, query, headers, body, and response. That makes it reusable for docs, tests, and debugging.

Endpoint URL

Send test traffic to a FastHook source URL. The optional path and query are captured with the request and can be used later for debugging, filtering, or transformations.

Endpoint URL
https://hook-xxxxxx.fasthook.io/

Sample request examples

Sample request with cURL

Sample cURL
curl -X POST "https://hook-xxxxxx.fasthook.io/webhook?env=staging" \
  -H "Content-Type: application/json" \
  -H "X-Event-Type: test.run" \
  -H "X-Request-Id: req_4f9d" \
  -H "X-Idempotency-Key: evt_test_42" \
  -d '{
    "id": "evt_test_42",
    "type": "test.run",
    "timestamp": "2026-05-31T10:00:00Z",
    "data": {
      "ok": true,
      "source": "custom-provider",
      "customer_id": "cus_88"
    }
  }'

Same request as raw HTTP

Raw HTTP
POST /webhook?env=staging HTTP/1.1
Host: hook-xxxxxx.fasthook.io
Content-Type: application/json
X-Event-Type: test.run
X-Request-Id: req_4f9d
X-Idempotency-Key: evt_test_42

{
  "id": "evt_test_42",
  "type": "test.run",
  "timestamp": "2026-05-31T10:00:00Z",
  "data": {
    "ok": true,
    "source": "custom-provider",
    "customer_id": "cus_88"
  }
}

Same request with Node.js fetch

Node.js fetch
const response = await fetch("https://hook-xxxxxx.fasthook.io/webhook?env=staging", {
  method: "POST",
  headers: {
    "content-type": "application/json",
    "x-event-type": "test.run",
    "x-request-id": "req_4f9d",
    "x-idempotency-key": "evt_test_42"
  },
  body: JSON.stringify({
    id: "evt_test_42",
    type: "test.run",
    timestamp: "2026-05-31T10:00:00Z",
    data: {
      ok: true,
      source: "custom-provider"
    }
  })
});

if (!response.ok) {
  throw new Error(`Webhook request failed with ${response.status}`);
}

Sample headers

Headers JSON
{
  "content-type": "application/json",
  "x-event-type": "test.run",
  "x-request-id": "req_4f9d",
  "x-idempotency-key": "evt_test_42",
  "user-agent": "CustomProvider-Webhooks/1.0"
}

Sample payload

Payload JSON
{
  "id": "evt_test_42",
  "type": "test.run",
  "timestamp": "2026-05-31T10:00:00Z",
  "data": {
    "ok": true,
    "source": "custom-provider",
    "customer_id": "cus_88"
  }
}

How FastHook records the request

The request list returns a compact model by default. Add include=data when you need the stored request body, headers, parsed query, path, and method. Request status is derived from rejection_cause: no rejection cause means accepted, and any rejection cause means rejected.

FastHook request record flow from inbound HTTP request to accepted or rejected request record, routed event, destination attempt, and replay.
FastHook request history is the first debugging checkpoint. Accepted requests can create routed events; rejected requests preserve ingress evidence without normal destination delivery.

Create a test source

Create test source
curl -X POST "https://api.fasthook.io/v1/sources" \
  -H "Authorization: Bearer fhp_xxx" \
  -H "x-team-id: tm_3b5335b627084a838b" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Generic request example",
    "type": "WEBHOOK",
    "status": "enabled",
    "config": {
      "auth_type": null,
      "allowed_http_methods": ["POST"]
    }
  }'

Inspect accepted requests with stored data

Inspect accepted requests
curl "https://api.fasthook.io/v1/requests?source_id=src_q6z62b6py5o79b&from=now-24h&to=now&status=accepted&limit=20&include=data" \
  -H "Authorization: Bearer fhp_xxx" \
  -H "x-team-id: tm_3b5335b627084a838b"

Retrieve one request by id

Retrieve request
curl "https://api.fasthook.io/v1/requests/req_01jv8c3m7b2p4q9x6r5t1n0k8s" \
  -H "Authorization: Bearer fhp_xxx" \
  -H "x-team-id: tm_3b5335b627084a838b"

Inspect events created from one request

Inspect request events
curl "https://api.fasthook.io/v1/requests/req_01jv8c3m7b2p4q9x6r5t1n0k8s/events?limit=20" \
  -H "Authorization: Bearer fhp_xxx" \
  -H "x-team-id: tm_3b5335b627084a838b"

Accepted request record example

Accepted request JSON
{
  "id": "req_01jv8c3m7b2p4q9x6r5t1n0k8s",
  "team_id": "tm_3b5335b627084a838b",
  "status": "accepted",
  "verified": false,
  "rejection_cause": null,
  "source_id": "src_q6z62b6py5o79b",
  "events_count": 1,
  "ignored_count": 0,
  "ingested_at": "2026-05-31T10:00:00.000Z",
  "data": {
    "body": {
      "id": "evt_test_42",
      "type": "test.run",
      "data": {
        "ok": true,
        "source": "custom-provider"
      }
    },
    "headers": {
      "content-type": "application/json",
      "x-event-type": "test.run",
      "x-request-id": "req_4f9d"
    },
    "parsed_query": {
      "env": "staging"
    },
    "path": "/webhook",
    "method": "POST",
    "query": "env=staging"
  }
}

Inspect rejected requests

Inspect rejected requests
curl "https://api.fasthook.io/v1/requests?source_id=src_q6z62b6py5o79b&from=now-24h&to=now&status=rejected&limit=20&include=data" \
  -H "Authorization: Bearer fhp_xxx" \
  -H "x-team-id: tm_3b5335b627084a838b"

Rejected request record example

Rejected request JSON
{
  "id": "req_01jv8d9p4c6n2m0x5t7q3r1s8a",
  "status": "rejected",
  "verified": false,
  "source_id": "src_q6z62b6py5o79b",
  "rejection_cause": "SOURCE_METHOD_NOT_ALLOWED",
  "events_count": 0,
  "ignored_count": 0,
  "data": {
    "body": null,
    "headers": {
      "content-type": "application/json",
      "x-debug": "yes"
    },
    "path": "/",
    "method": "GET",
    "query": ""
  }
}

When to use this example

  • Smoke-test a FastHook source before registering a production provider.
  • Share a copyable webhook fixture in partner docs, README files, or support tickets.
  • Validate that headers, query parameters, and JSON body are captured the way your route expects.
  • Build receiver idempotency tests around the same event id or idempotency key.
  • Confirm rejected request behavior before relying on source authentication or method restrictions.

Implementation checklist

  • Use Content-Type: application/json for JSON payloads.
  • Include an event id or delivery id that can be used for idempotency.
  • Include an event type header or payload field so routing rules can branch safely.
  • Use source authentication before exposing production provider URLs.
  • Inspect the stored request before debugging destination attempts.
  • Query rejected requests when a provider reports delivery but no routed event appears.

Webhook request example FAQ

What should a webhook request include?

A webhook request should include a stable endpoint URL, HTTP method, content type, event type, delivery or request id, optional signature headers, and a JSON payload with an event id, event type, timestamp, and data object.

What is the most important header in a webhook request?

The content-type header is required for payload parsing, while event type, delivery id, and signature headers are usually the most useful for routing, idempotency, and security.

How does FastHook store webhook request data?

FastHook stores a request model with accepted or rejected status, source id, verification state, timestamps, event counts, and optional request data when you query with include=data. Request data includes parsed body, headers, query, path, and method when available.

What is the difference between an accepted and rejected webhook request?

An accepted request has no rejection cause and can create routed events. A rejected request has a rejection cause such as SOURCE_AUTH_FAILED, SOURCE_METHOD_NOT_ALLOWED, or SOURCE_DISABLED and does not proceed as a normal accepted delivery.

Try FastHook

Create a FastHook source, send this request example, inspect the stored request with include=data, then follow the routed events and destination attempts from the same request id.

Related guides