# hookstream — Full Documentation > The modern event gateway for developers who need webhooks that just work. Ingest, transform, route, and deliver webhooks with retries, DLQ, real-time streaming, and full observability. ## Agent API Reference Source: https://docs.hookstream.io/ai/agent-api The Agent API exposes hookstream's webhook testing infrastructure with agent-friendly aliases under . It's the same surface as — same rate limits, same lifetime, same features — but named and documented for programmatic use by AI agents. No authentication required. Rate limited to 10 sessions per IP per hour. Sessions live for 14 days or 2,000 requests, whichever comes first. Sessions can be graduated into a full hookstream account later — no data is lost. If your agent needs higher limits, longer retention, or access to the full platform (connections, destinations, transforms, metrics), create a free hookstream account and use an API key with the regular REST API. The Agent API is designed for zero-friction prototyping and ephemeral workflows. Base URL The same endpoints are also mounted at — use whichever feels clearer in your code. Typical agent workflow returns a and a live webhook . to set a custom status code, content type, and body returned to webhook senders. Give the returned to a provider like Stripe, GitHub, or Shopify — or send test requests yourself. returns session metadata plus the most recent events. Supports filters and cursor pagination. Read method, headers, body, and timing from each event. Optionally to relay to your local app in real time. dumps NDJSON or CSV. removes the session early. Endpoints Create a session POST Creates a new ephemeral webhook endpoint. No body required, no auth. Response List events for a session GET Returns session metadata and received events. Supports filtering and pagination. Filter by HTTP method (e.g. , ). Filter by response status range: , , or . Full-text search in headers and body. Results per page. Max 100, default 50. Pagination cursor from a previous response. Response Configure custom response PATCH Set what hookstream returns to webhook senders that hit this endpoint. HTTP status code between 200 and 599. Default . Response content type. Default . Response body. Max 4KB. Example request Configure forwarding PATCH Real-time relay of incoming webhooks to another URL. Runs in , so it doesn't block ingest. Target URL (http or https). Pass to disable forwarding. Example request Export events GET Dumps all session events. (default) or . Delete a session DELETE Removes the session and all its events. Idempotent. Full example: agent creates a session, sends a webhook, and checks events Full-account access for agents If your agent needs the full platform — connections, transforms, destinations, metrics, real-time streaming — create a free account and issue an API key. Then the agent can hit the full REST API at with an header. API keys are plain HTTP headers, so they work with every agent framework — LangChain tool specs, OpenAI function calls, Anthropic tool use, MCP servers, and bespoke agents alike. No SDK required. Rate limits and lifetime - 10 sessions per IP per hour on session creation - 2,000 requests per session — after that, new webhooks are rejected - 14-day TTL — sessions expire automatically; data is cleaned up by a Cron job - Early deletion via - Graduation — calling with an authenticated session moves the session and all its events into the user's organization. The webhook URL keeps working. Session graduation An ephemeral session can become a persistent source. When a user signs up and authenticates, calling attaches the session to their org. The stays identical, all received events come with it, and it shows up as a regular source in the dashboard. This is useful when an agent prototype graduates into production. Related - AI & LLM Integration - Skills & IDE Integration - Webhook Testing guide --- ## AI & LLM Integration Source: https://docs.hookstream.io/ai/overview hookstream is built to be AI-friendly from the ground up. Every documentation page is available as clean markdown, the full docs are bundled into a single file for LLMs, the REST API is OpenAPI 3.1 with AI-friendly extensions, and the test sessions API doubles as a zero-auth Agent API that any model can drive. Whether you're pasting docs into Claude, asking Cursor to write a webhook handler, or building an autonomous agent that spins up ephemeral endpoints and monitors deliveries — hookstream has a surface for it. Install the hookstream Claude Code skill and wire up Cursor, Windsurf, and Copilot CLI with full API context. Zero-auth programmatic endpoints designed for AI agents to create, inspect, and forward webhooks. What hookstream provides for AI - discovery at hookstream.io/llms.txt — summary with categorized doc links, following the llms.txt standard - Full docs bundle at hookstream.io/llms-full.txt and hookstream.io/docs.md — the entire documentation concatenated into a single ~180KB file - Per-page markdown exports — append to any URL to get clean markdown (e.g. ) - OpenAPI 3.1 spec at with , , and extensions - hookstream Claude Code skill at hookstream.io/hookstream.skills.md — teaches Claude Code how to bootstrap webhook projects, generate sources/destinations, and apply retry/filter patterns - AI plugin manifest at [](https://hookstream.io/.well-known/ai-plugin.json) for OpenAI-compatible tool discovery - Agent API at — no-auth ephemeral webhook endpoints for agent workflows Point your agent at for a single-file version of the entire documentation bundle (~180KB). It's the fastest way to give a model complete, accurate context about hookstream in one paste. Copy any page as markdown Every documentation page has a Copy as Markdown button in the AI bar at the top — ready to paste into Claude, ChatGPT, or any other AI chat. You can also fetch the same content programmatically by appending to any URL: The markdown output includes all sections, API endpoint tables, code examples, and related page links — no HTML cruft. Expose these docs to your IDE HolyDocs ships an MCP server at that exposes all pages as searchable tools. Add it to Claude Code, Cursor, or any MCP-capable client and your assistant will query docs on demand instead of consuming context on every prompt. For IDEs without MCP support, use the or bundle as a custom context file — Cursor's Custom Instructions, Windsurf's rules, and Copilot CLI's system prompt all accept raw markdown. Where to go next - Skills & IDE Integration — install the hookstream skill in Claude Code, Cursor, Windsurf, and Copilot CLI - Agent API Reference — zero-auth endpoints for ephemeral webhook endpoints - Webhook Testing — the product surface the Agent API is built on --- ## Skills & IDE Integration Source: https://docs.hookstream.io/ai/skills Skills files teach AI coding assistants about specific APIs and tools. Once the hookstream skill is installed, your assistant can create sources and destinations, configure connections with filters and transforms, send test webhooks, debug delivery failures, and tune retry strategies — all by calling the hookstream API directly from your editor. The skill file lives at hookstream.io/hookstream.skills.md and covers the full API surface, CLI commands, all 8 destination provider types, and common patterns (signature verification, retry strategies, DLQ, circuit breakers). What the skill enables Once installed, you can ask your assistant things like: Create a hookstream source for Stripe webhooks with signature verification, then wire it to an HTTP destination pointing at my staging API. Set up a connection that only routes paymentintent.succeeded events and transforms the payload to flatten data.object into top-level fields. Why are my deliveries failing? Check the circuit breaker status and the last 10 delivery attempts for destination dstxxx. Create a DLQ alert that fires when more than 5 events land in the dead letter queue in a 10-minute window, and notify my Slack channel. The assistant will use the hookstream API (or the CLI) to carry out each request, including creating resources, reading logs, and diagnosing failures. Install the skill From your project root: The skill is auto-loaded by Claude Code on next launch — no manual registration. Install and log in once so the skill can drive the CLI non-interactively: This saves an API key to . Claude Code will then be able to run commands like without further auth prompts. Ask Claude Code: "Create a test webhook session and send a sample order.created event to it." The assistant should call , then POST to the returned URL. Cursor doesn't have a native skills format yet, so feed it the docs as custom context. Go to Settings → Rules for AI (or AI → Custom Instructions, depending on version). Add this as a rule or linked context URL: That single file (~180KB) contains the entire hookstream documentation bundle. For the most compact, task-focused context, paste the contents of hookstream.skills.md directly into your rules. It's tighter than the full docs bundle and tuned for code generation. Windsurf uses at the project root. Windsurf picks up on next prompt. Test with: "List the hookstream destination provider types I can use." GitHub Copilot CLI accepts a system prompt via . Alternative: point at the docs bundle For any tool that accepts a URL or raw markdown as context, use one of: - — short summary (~5KB) with links to all doc pages - — full docs bundle (~180KB), quickstart first - — task-focused skill, tighter than full docs - — any single page as clean markdown These URLs all return and are safe to fetch from any AI tool. If you're iterating quickly, use the "Copy as context" button on any in these docs. It copies a clean, AI-ready markdown snippet for that specific endpoint — perfect for dropping into a chat without flooding the context window. Related - AI & LLM Integration - Agent API Reference - Quickstart --- ## Alert Rules Source: https://docs.hookstream.io/api/alert-rules Alert rules define conditions that trigger notifications. hookstream evaluates alert rules every 5 minutes via a Cron trigger. When a rule's threshold is exceeded, notifications are sent to configured channels. Rules auto-resolve after 30 minutes if the condition clears. Five alert types are supported: , , , , and . List Alert Rules GET List all alert rules. Authentication: API key or session cookie. Create Alert Rule POST Create a new alert rule. Authentication: API key or session cookie. Body Parameters Display name for the rule. Alert type: , , , , or . Type-specific configuration: - : (decimal, e.g., for 10%) - : - : - : Array of notification channel IDs to send alerts to. Minimum minutes between alert triggers. Retrieve Alert Rule GET Get a single alert rule with its trigger history. Authentication: API key or session cookie. Update Alert Rule PATCH Update an alert rule. Authentication: API key or session cookie. Delete Alert Rule DELETE Delete an alert rule. Authentication: API key or session cookie. --- ## API Keys Source: https://docs.hookstream.io/api/api-keys API keys provide programmatic access to the hookstream API. Keys are shown in plaintext only once at creation time — hookstream stores a SHA-256 hash internally and cannot recover a key after creation. API key management endpoints require session authentication (you must be logged in to the dashboard). You cannot create or revoke API keys using another API key. Create API Key POST Create a new API key. The plaintext key is returned only in this response. Authentication: Session cookie. Body Parameters A human-readable label for the key (e.g., "Production Backend"). Save the value immediately. hookstream stores only the SHA-256 hash and cannot retrieve it later. List API Keys GET List all API keys for the authenticated user. Keys are masked — only the prefix is shown. Authentication: Session cookie. Response Fields Array of API key objects. First 12 characters of the plaintext key for identification. Number of requests made with this key. if the key has been revoked, otherwise . Revoke API Key DELETE Revoke an API key. The key is immediately invalidated and cannot be recovered. Authentication: Session cookie. Related How API keys and session cookies work. Log in the CLI with your API key. --- ## Authentication Source: https://docs.hookstream.io/api/authentication hookstream supports two authentication methods: API keys for programmatic access and session cookies for browser-based dashboard use. Most API endpoints use combined auth, accepting whichever succeeds first. Authentication methods API key authentication Send your API key in the header. hookstream hashes the key with SHA-256 and looks up the hash in D1. Keys use the format for production or for test mode. Create and manage API keys on the API Keys page. Session authentication The hookstream dashboard uses cookie-based sessions via Better Auth. When you sign in through the web UI (email/password or Google/GitHub OAuth), a session cookie is set automatically. All subsequent API requests from the browser include this cookie. On first login, hookstream auto-provisions an organization and a default project for the user. Combined auth Most endpoints use middleware, which tries API key authentication first. If no header is present or the key is invalid, it falls back to session cookie verification. This allows both programmatic access and browser access on the same endpoint. Frontend code uses on calls. There are no Bearer tokens — all auth is cookie-based in the browser and header-based from server code. Public endpoints Some endpoints require no authentication and use IP-based rate limiting instead: - — public webhook ingestion - — ephemeral test sessions - — free developer tools - — service health check - — test session WebSocket Related Create, list, and revoke API keys. Standard error responses and status codes. --- ## Billing Source: https://docs.hookstream.io/api/billing The Billing API lets you check your plan's usage, create Stripe Checkout sessions to upgrade, open the Stripe Customer Portal to manage your subscription, view current subscription details, and list invoices. All billing endpoints require authentication. Plan limits Each plan includes specific resource limits: | Plan | Events/mo | Sources | Destinations | Retention | | --- | --- | --- | --- | --- | | Free | 50,000 | 10 | 5 | 7 days | | Pro | 1,000,000 | unlimited | unlimited | 30 days | | Enterprise | 10,000,000 | unlimited | unlimited | 90 days | Paid plans have a soft limit — events are accepted up to 120% of the monthly quota before returning 429. The Free plan has a hard cutoff at 100%. Get Usage GET Get current usage vs plan limits for the authenticated organization. Authentication: API key or session cookie. Create Checkout Session POST Create a Stripe Checkout session. Returns a URL to redirect the user to. Authentication: API key or session cookie. Body Parameters Plan to subscribe to: or . Billing interval: or . Stripe coupon ID to apply. Open Customer Portal POST Create a Stripe Customer Portal session for subscription management. Redirect the user to to update payment methods, cancel, or view invoices. Authentication: API key or session cookie. Get Subscription GET Get current subscription details. Authentication: API key or session cookie. List Invoices GET List recent invoices from Stripe (up to 12). Invoices are fetched from the Stripe API on demand rather than cached in D1, so there's no sync lag. Authentication: API key or session cookie. --- ## Collections Source: https://docs.hookstream.io/api/collections Collections are part of hookstream's Instant Database feature. A collection automatically syncs events from a source into a queryable table using a for upsert (last-write-wins). Collections support schema inference from record samples, full-text search, NDJSON/CSV export, and batch backfill from existing events. List Collections GET List all collections. Authentication: API key or session cookie. Create Collection POST Create a new collection linked to a source. Authentication: API key or session cookie. Body Parameters Display name for the collection. URL-safe slug for the collection (e.g., ). Source to sync events from. Dot-notation path to the primary key field in the event body (e.g., ). Retrieve Collection GET Get a single collection by ID. Authentication: API key or session cookie. Update Collection PATCH Update a collection's name or description. Authentication: API key or session cookie. Delete Collection DELETE Delete a collection and all its synced records. Authentication: API key or session cookie. List Records GET List records in a collection with optional search and pagination. Authentication: API key or session cookie. Query Parameters Cursor for pagination. Number of results to return (max 100). Full-text search across record data. Retrieve Record GET Get a single record by its record key. Authentication: API key or session cookie. Record Changelog GET Get the change history for a specific record. Authentication: API key or session cookie. Query Parameters Number of changelog entries to return (max 100). Collection Stats GET Get collection statistics (record count, size, last sync). Authentication: API key or session cookie. Infer Schema GET Infer JSON schema from a sample of up to 200 records in the collection. Authentication: API key or session cookie. Schema inference runs on-demand against a rolling sample — there is no stored schema. Sampling 200 records is fast (tens of milliseconds) and avoids stale schemas as your data shape evolves. Export Records GET Export all collection records as NDJSON or CSV. Authentication: API key or session cookie. Query Parameters Export format: (NDJSON) or . Start Backfill POST Start a backfill job to sync existing events into the collection. Authentication: API key or session cookie. Check Backfill Status GET Check the status and progress of a backfill job. Authentication: API key or session cookie. --- ## Connections Source: https://docs.hookstream.io/api/connections Connections link a source to a destination. When an event arrives at a source, hookstream evaluates all connections for that source. If the event passes the connection's filters, it is optionally transformed via a JSONata expression and then delivered to the destination. Filters & transforms Content-based filters use 9 operators: , , , , , , , , . Filters reference event fields using dot-notation paths (e.g., , , ). All filters must match for the event to be routed (AND logic). JSONata transforms are expressions applied to the event payload before delivery. Use transforms to reshape data, extract fields, add computed values, or convert formats. The transform receives the full event body and must return a valid JSON object. List Connections GET List all connections for the authenticated organization. Authentication: API key or session cookie. Query Parameters Filter connections by source. Filter connections by destination. Cursor for pagination. Number of results to return (max 100). Create Connection POST Create a connection between a source and a destination. Authentication: API key or session cookie. Body Parameters The source to receive events from. The destination to deliver events to. Array of filter rule objects: . Operators: , , , , , , , , . JSONata expression to transform the event payload before delivery. Whether to apply the transform expression. Retrieve Connection GET Get a single connection by ID. Authentication: API key or session cookie. Update Connection PATCH Update a connection's filters or transform. Authentication: API key or session cookie. Delete Connection DELETE Delete a connection. Events already in the pipeline are still delivered. Authentication: API key or session cookie. --- ## Delivery Attempts Source: https://docs.hookstream.io/api/delivery-attempts Delivery attempts track each attempt to deliver an event to a destination. Each attempt records the HTTP status code, response body, latency, and whether it was an initial delivery or a retry. Failed attempts are automatically retried according to the destination's retry policy. List Delivery Attempts GET List delivery attempts with optional filters for event, destination, and status. Authentication: API key or session cookie. Query Parameters Filter by event ID. Filter by connection ID. Filter by destination ID. Filter by attempt status (e.g., , , ). Set to to only return dead-letter queue attempts. Number of results to return (max 100). Offset for pagination. Retrieve Delivery Attempt GET Get full detail for a delivery attempt including the response body. Authentication: API key or session cookie. Retry Delivery Attempt POST Retry a specific failed delivery attempt immediately. Authentication: API key or session cookie. --- ## Destinations Source: https://docs.hookstream.io/api/destinations Destinations define where events are delivered. hookstream supports 8 destination types: HTTP/Webhook, AWS SQS, AWS S3, AWS EventBridge, GCP Pub/Sub, Kafka (Confluent REST Proxy), RabbitMQ (HTTP Management API), and WebSocket. Each destination has its own retry policy, circuit breaker state, and dead letter queue. Each destination has an automatic circuit breaker. When consecutive failures exceed the threshold, the circuit opens and deliveries pause. After a cooldown, a single test delivery is attempted (half-open). You can inspect and reset circuit state via the API below. List Destinations GET List all destinations for the authenticated organization. Authentication: API key or session cookie. Query Parameters Cursor for pagination. Number of results to return (max 100). Create Destination POST Create a new destination with delivery configuration and retry policy. Authentication: API key or session cookie. Body Parameters Display name for the destination. URL-safe slug for the destination. Provider type: , , , , , , , or . Destination URL (required for HTTP destinations). HTTP method to use for delivery. Custom headers to include with deliveries. Provider-specific configuration. For SQS: . For S3: . Maximum retry attempts (1-10). Retry backoff strategy: , , or . Array of retry delay intervals in seconds. Default: . Retrieve Destination GET Get a single destination by ID with its configuration. Authentication: API key or session cookie. Update Destination PATCH Update a destination. All fields are optional. Authentication: API key or session cookie. Delete Destination DELETE Delete a destination and stop all pending deliveries. Authentication: API key or session cookie. List Destination Templates GET List pre-configured destination templates (Slack, Discord, PagerDuty, etc.). Authentication: API key or session cookie. Get Circuit Breaker Status GET Get the circuit breaker status for a destination (, , or ). Authentication: API key or session cookie. Reset Circuit Breaker POST Manually reset the circuit breaker to closed state, allowing deliveries to resume. Authentication: API key or session cookie. --- ## Errors Source: https://docs.hookstream.io/api/errors All hookstream API errors return a consistent JSON format with an error message, HTTP status code, and a unique for debugging. Provide the to hookstream support when investigating issues. Error response format Every error response includes three fields: Human-readable error message. HTTP status code. Unique identifier for the request. Provide this to support. Status codes | Status | Meaning | Common causes | | --- | --- | --- | | | Bad Request | Invalid body, missing fields, malformed parameters. | | | Unauthorized | Missing or invalid API key / session cookie. | | | Forbidden | Valid auth but insufficient permissions, or IP blocked. | | | Not Found | Resource doesn't exist or belongs to a different org. | | | Conflict | Duplicate resource, or event deduplicated at ingest. | | | Too Many Requests | Rate limit or plan quota exceeded. | | | Internal Server Error | Unexpected server error. | Common errors The request body was invalid. Check that all required fields are present, types match, and JSON is well-formed. The field will describe which field failed validation. Your API key is missing, invalid, or the session cookie has expired. Check that you are sending or that your session is valid. The authenticated user does not have permission to access the resource, or a source's IP allowlist/denylist has blocked the request. The resource does not exist, or it belongs to a different organization/project. Verify the ID and that you are using the correct API key for the right project. For ingestion, this means the event was deduplicated — the same payload hash or dedup key was already seen. For resource creation, a resource with the same slug or unique field already exists. You've exceeded a rate limit or your plan's monthly quota. Check the response headers and retry after the reset time. Paid plans have a soft limit — events are accepted up to 120% before returning 429. The Free plan hard-caps at 100%. An unexpected error occurred on the server. Retry the request with exponential backoff. If the error persists, contact support with the so we can investigate. Related Troubleshoot 401 errors. Handle 429 errors. --- ## Events Source: https://docs.hookstream.io/api/events Events represent individual webhook payloads received at a source's ingestion URL. Each event stores the HTTP method, headers, body, and metadata. Events support cursor pagination, full-text search, time range filters, and status filtering. You can retry delivery for individual events or in bulk. List Events GET List events with optional filters for source, status, time range, and search. Authentication: API key or session cookie. Query Parameters Filter by source ID. Filter by event status (e.g., , ). Cursor for pagination (base64 encoded). Number of results to return (max 100). ISO 8601 lower bound for time range filter. ISO 8601 upper bound for time range filter. Search by event ID prefix or payload content. Retrieve Event GET Get full event detail including body, headers, and delivery attempts. Authentication: API key or session cookie. Retry Event POST Retry delivery for a specific event across all connected destinations. Authentication: API key or session cookie. --- ## Ingest Source: https://docs.hookstream.io/api/ingest The ingest endpoint is the public URL where external services send webhook events. Each source gets a unique ingestion URL at . The endpoint accepts any HTTP method (GET, POST, PUT, PATCH, DELETE) and stores the request method, headers, and body as an event. No authentication is required — security is handled through optional signature verification, deduplication, and IP filtering configured on the source. Ingest Event ANY Receive a webhook event at the source's ingestion URL. Accepts any HTTP method. Authentication: None (verification configured per source). Signature verification If the source has a configured, hookstream validates the request signature before accepting the event. Supported methods: | Method | Used by | Header | | --- | --- | --- | | | Stripe, GitHub, Shopify, etc. | Provider-specific | | | Legacy providers | Provider-specific | | | standardwebhooks.com spec | | Failed verification returns 401 Unauthorized. Configure the secret on the source via . Deduplication hookstream supports three dedup strategies to avoid processing the same event twice: hookstream computes a SHA-256 hash of the request body and uses it as the dedup key. Identical payloads sent within the dedup window return 200 but are not processed further. Uses a specific header as the dedup key (e.g., , ). Configure the header name on the source. Uses a specific JSON body field as the dedup key (e.g., ). Configure the field path on the source. Duplicate events return 200 OK so senders don't retry. hookstream still records the duplicate for audit visibility but does not route it to destinations. IP filtering Sources can define IP allow/deny lists using individual addresses or CIDR ranges. Requests from blocked IPs receive 403 Forbidden. Response codes | Status | Meaning | | --- | --- | | | Event accepted and queued for delivery (or deduplicated). | | | Signature verification failed. | | | IP address blocked by source's deny list. | | | Source does not exist. | | | Rate limit or plan quota exceeded. | | | Unexpected server error. | Related Create and configure source endpoints. Browse and retry ingested events. --- ## Issues Source: https://docs.hookstream.io/api/issues Issues are automatically created when delivery attempts fail. hookstream groups related failures into a single issue per destination and error type. Issues track occurrence counts, first/last seen timestamps, and resolution status. Issues auto-resolve after 30 minutes without new occurrences. List Issues GET List issues with optional status filter. Authentication: API key or session cookie. Query Parameters Filter by status: , , , or . Filter by destination ID. Number of results to return (max 100). Offset for pagination. Issue Summary GET Get issue counts by status. Authentication: API key or session cookie. Retrieve Issue GET Get full issue detail including recent failed delivery attempt IDs. Authentication: API key or session cookie. Update Issue PATCH Update an issue's status or snooze it until a specific time. Authentication: API key or session cookie. Body Parameters New status: , , or . ISO 8601 datetime to snooze the issue until, or to unsnooze. Bulk Retry Issue POST Bulk retry all failed events associated with this issue. Authentication: API key or session cookie. --- ## Metrics Source: https://docs.hookstream.io/api/metrics The metrics API provides aggregated analytics for your webhook traffic. It uses a hybrid approach: queries within the last 48 hours run against raw event data for instant accuracy, while older queries use Cron-driven pre-aggregated hourly and daily rollups for bounded performance. Metrics can be aggregated by or granularity. The and parameters accept ISO 8601 timestamps. If omitted, most endpoints default to the last 24 hours with hourly intervals. Overview GET Get summary stats: today's events, deliveries, success rate, and active resource counts. Authentication: API key or session cookie. Volume GET Get event volume over time grouped by granularity. Authentication: API key or session cookie. Query Parameters ISO 8601 start time. ISO 8601 end time. Filter by source ID. Aggregation granularity: or . Deliveries GET Get delivery success/failure breakdown over time. Authentication: API key or session cookie. Query Parameters ISO 8601 start time. ISO 8601 end time. Filter by destination ID. Aggregation granularity: or . Latency GET Get delivery latency percentiles (p50, p95, p99) over time. Authentication: API key or session cookie. Query Parameters ISO 8601 start time. ISO 8601 end time. Filter by destination ID. --- ## Notification Channels Source: https://docs.hookstream.io/api/notification-channels Notification channels define where alerts are delivered. hookstream supports four channel types: webhook (with optional HMAC signing), Slack, Discord, and email. When an alert rule triggers, hookstream sends a notification to each configured channel with the alert details. List Channels GET List all notification channels. Authentication: API key or session cookie. Create Channel POST Create a new notification channel. Authentication: API key or session cookie. Body Parameters Display name for the channel. Channel type: , , , or . Channel configuration. For webhook: . If is provided, requests are signed with HMAC-SHA256. Retrieve Channel GET Get a single notification channel by ID. Authentication: API key or session cookie. Update Channel PATCH Update a notification channel. Authentication: API key or session cookie. Delete Channel DELETE Delete a notification channel. Alert rules referencing it must be updated first. Authentication: API key or session cookie. Test Channel POST Send a test notification to verify the channel is working. Authentication: API key or session cookie. --- ## Pagination & Rate Limits Source: https://docs.hookstream.io/api/pagination-rate-limits hookstream uses cursor-based pagination for all list endpoints and applies rate limiting to protect the platform. Understanding these patterns helps you build robust integrations that handle large datasets and respect rate limits. Cursor-based pagination All list endpoints return paginated results. Each endpoint uses a named wrapper key matching the resource type (e.g., , , , ). To fetch the next page, pass the cursor value as a query parameter. Cursors are opaque strings — do not parse or construct them. They remain stable across pages even when new records are inserted. Example Query Parameters Opaque cursor from a previous response. Omit for the first page. Number of results per page. Maximum . Results are ordered by creation time (newest first) unless otherwise specified on the endpoint. Always check before fetching the next page — do not assume fixed page sizes. Some endpoints (events, delivery-attempts) use different defaults and wrapper shapes; always read the actual response. Rate limiting Authenticated endpoints are rate-limited per organization. Unauthenticated endpoints (ingest, test sessions, tools) are rate-limited per IP address. When you exceed the rate limit, the API returns 429 Too Many Requests. Rate limit headers Every response includes IETF standard response headers: | Header | Meaning | | --- | --- | | | Maximum requests allowed in the current window. | | | Requests remaining in the current window. | | | Seconds until the window resets. | Example: When reaches , wait until seconds have elapsed before making additional requests. Best practices Always check to decide whether to fetch another page — some endpoints return on the last page, others don't. Implement exponential backoff when receiving 429 responses. Read for the minimum wait. Use the parameter to control page size based on your processing capacity. Larger pages = fewer round trips but more latency per request. For high-volume integrations, use WebSocket streaming instead of polling list endpoints. --- ## Replay Source: https://docs.hookstream.io/api/replay Event replay lets you re-deliver historical events to a destination. Useful for backfilling a new destination, recovering from outages, or testing. Replay jobs are rate-limited and tracked in KV with auto-expiry. You specify a , , and time range, and hookstream re-delivers each matching event through the normal delivery pipeline. Create Replay Job POST Create a replay job to re-deliver events from a time range. Authentication: API key or session cookie. Body Parameters Destination to deliver replayed events to. Filter to events from a specific source. ISO 8601 start time for the replay window. ISO 8601 end time for the replay window. Maximum events per second (max 100). Maximum events to replay (max 10000). Get Replay Status GET Get the status and progress of a replay job. Authentication: API key or session cookie. Response Fields Job status: , , or . Number of events processed so far. Number of events successfully delivered. Number of events that failed delivery. --- ## Sources Source: https://docs.hookstream.io/api/sources Sources are your webhook ingestion endpoints. Each source gets a unique URL at where external services send webhooks. Sources support optional HMAC signature verification, deduplication strategies, and IP allow/deny lists. hookstream ships with 15 pre-configured source templates for popular providers (Stripe, GitHub, Shopify, Twilio, etc.). Use the templates endpoint to pre-fill verification settings. List Sources GET List all sources for the authenticated organization in the current project. Authentication: API key or session cookie. Query Parameters Cursor for pagination. Pass the value from the previous response. Number of results to return (max 100). Create Source POST Create a new source. Returns the source with its ingestion URL. Authentication: API key or session cookie. Body Parameters Display name for the source. URL-safe slug for the source (e.g., ). Signature verification method: , , , or . Secret used for signature verification. Required if is set. Deduplication strategy: , , , or . Array of allowed IP addresses or CIDR ranges. Array of denied IP addresses or CIDR ranges. Retrieve Source GET Get a single source by ID. Authentication: API key or session cookie. Update Source PATCH Update a source. All fields are optional. Authentication: API key or session cookie. Body Parameters Updated display name. Updated verification method. Updated verification secret. Delete Source DELETE Delete a source. Events and connections referencing this source are not deleted. Authentication: API key or session cookie. List Source Templates GET List pre-configured source templates for popular webhook providers. Authentication: API key or session cookie. Related Send webhooks to a source's public URL. Link sources to destinations. --- ## Test Sessions Source: https://docs.hookstream.io/api/test-sessions Test sessions provide ephemeral webhook endpoints for testing and debugging. Sessions are created without authentication and last for 14 days or 2000 requests (whichever comes first). Each session gets a unique ingestion URL and a real-time WebSocket feed. Sessions support custom response configuration, webhook forwarding, event notes, and NDJSON/CSV export. Authenticated users can claim sessions to make them permanent. Most test session endpoints require no authentication — they're designed for quick, frictionless testing. Only the claim endpoint requires auth. Sessions are rate-limited by IP address. Create Session POST Create a new ephemeral test session. Returns the session with its ingestion URL. Authentication: None (IP rate-limited). Retrieve Session GET Get a test session with its received events. Authentication: None. Claim Session POST Claim a test session, converting it from ephemeral to permanent and associating it with your organization. Authentication: API key or session cookie. Delete Session DELETE Delete a test session and all its events. Authentication: None. Retrieve Event GET Get full details for a specific event in a test session, including the resolved payload. Authentication: None. Configure Custom Response PATCH Configure the custom response returned when webhooks hit this session's ingestion URL. Authentication: None. Body Parameters HTTP status code to return (200-599). Response content type. Custom response body (max 4KB). Configure Forwarding PATCH Configure webhook forwarding — incoming webhooks are forwarded to the target URL in addition to being recorded. Authentication: None. Body Parameters Target URL to forward webhooks to. Set to to disable. Set Event Note PUT Add or update a note on a specific event in a test session. Authentication: None. Body Parameters Note text to attach to the event. Export Events GET Export all events from a test session as NDJSON or CSV. Authentication: None. Query Parameters Export format: or . --- ## Tools API Source: https://docs.hookstream.io/api/tools-api The Tools API powers hookstream's free developer tools at hookstream.io/tools. These endpoints require no authentication but are IP rate-limited. They provide utility functions for webhook development: checking endpoint health, scheduling future webhook deliveries, and testing idempotency behavior. Health Check POST Check the health of a webhook endpoint by sending a test request and measuring the response. Authentication: None (IP rate-limited). Body Parameters The endpoint URL to check ( or ). Schedule Webhook POST Schedule a webhook to be sent at a future time. Authentication: None (IP rate-limited). Body Parameters Destination URL for the scheduled webhook. Delay in seconds before sending (1-86400). HTTP method to use. Custom headers to include. Request body to send. Get Schedule Status GET Check the status of a scheduled webhook. Authentication: None. Idempotency Test POST Send duplicate requests to test a webhook endpoint's idempotency behavior. Authentication: None (IP rate-limited). Body Parameters The endpoint URL to test. Header name to use for idempotency (e.g., ). Value for the idempotency header. Number of requests to send (2-10). HTTP method. Additional headers to include. Request body to send. Delay between requests in milliseconds (0-5000). --- ## Topics Source: https://docs.hookstream.io/api/topics Topics enable pub/sub-style fan-out delivery. Create a topic with a unique slug, subscribe destinations to it with optional per-subscription filters and transforms, then publish events to the topic. hookstream delivers the event to all matching subscribers. Topics run alongside the connection-based pipeline, not replacing it. You can mix both patterns in the same project — use connections for direct 1-to-1 routing and topics for fan-out. List Topics GET List all topics. Authentication: API key or session cookie. Create Topic POST Create a new topic. Authentication: API key or session cookie. Body Parameters Display name for the topic. URL-safe slug for the publish endpoint (e.g., ). Optional description of the topic. Retrieve Topic GET Get a single topic by ID with its subscriptions. Authentication: API key or session cookie. Update Topic PATCH Update a topic's name or description. Authentication: API key or session cookie. Delete Topic DELETE Delete a topic and all its subscriptions. Authentication: API key or session cookie. Subscribe Destination POST Subscribe a destination to a topic. Authentication: API key or session cookie. Body Parameters The destination to receive events. Per-subscription content-based filter rules. Per-subscription JSONata transform expression. Update Subscription PATCH Update a subscription's filter rules or transform expression. Authentication: API key or session cookie. Body Parameters Updated content-based filter rules. Updated JSONata transform expression. Unsubscribe DELETE Remove a subscription from a topic. Authentication: API key or session cookie. Publish Event POST Publish an event to a topic by slug. The event is delivered to all matching subscribers. Authentication: API key or session cookie. --- ## WebSockets Source: https://docs.hookstream.io/api/websockets hookstream provides three WebSocket endpoints for real-time communication. All connections use Cloudflare Durable Objects with the Hibernatable WebSocket API — efficient, stateful connections that survive idle periods without cost. WebSocket upgrades cannot use custom request headers in browsers, so API keys are passed via the query parameter instead of . Browser clients signed in to the dashboard use session cookies automatically. Dashboard Stream GET Upgrade to authenticated WebSocket for real-time organization-wide event streaming. After connecting, you receive real-time events for your organization across all sources and destinations. Messages are JSON with a field for filtering (e.g., , , ). Authentication: API key via query param, or session cookie. Query Parameters API key for authentication. Browser clients with an active session cookie can omit this. See [](/cli/commands) for filtering and formatting options. Test Session Stream GET Upgrade to unauthenticated WebSocket for a test session's real-time event feed. Used by the browser-based test inspector. Authentication: None. Validates the source is an ephemeral test session. Inbound WebSocket Source GET Upgrade to authenticated WebSocket for inbound event ingestion. Instead of receiving HTTP webhooks, you can send events over a persistent WebSocket connection. Each message sent on this connection is ingested as an event and routed through the normal delivery pipeline. Useful for high-throughput or bidirectional scenarios. Authentication: API key via query param. Query Parameters API key for authentication. Message format All WebSocket messages are JSON objects with a field indicating the message kind. Server → client: | Type | Meaning | | --- | --- | | | New event received at a source. | | | Delivery attempt completed. | | | Issue created or updated. | | | Database collection record synced. | | | Heartbeat — respond with . | Client → server: | Type | Meaning | | --- | --- | | | Subscribe to a specific channel. | | | Heartbeat response. | Related Ephemeral testing endpoints. Browse past events via REST. --- ## CLI Authentication Source: https://docs.hookstream.io/cli/authentication The hookstream CLI authenticates with an API key. You can either grab a key through the browser device flow (recommended for humans) or pass one directly via a flag, env var, or config file (recommended for scripts and CI). Browser login (recommended) starts a device flow against https://hookstream.io/dashboard/cli-auth. A short, readable code is shown in your terminal and pre-filled in the browser — you approve once and the CLI picks up the key automatically. The CLI prints an 8-character code (like ) and opens your browser to . Confirm the code matches, then approve. The code alphabet excludes to avoid ambiguity. Codes expire after 15 minutes. The CLI polls the auth endpoint every 5 seconds and saves the key to once you approve. No copy-pasting. If you have no sources yet, the CLI asks whether you want to create one. It runs a 2-question wizard (name + provider template) and prints your ingest URL plus a ready-to-run command. Skip with . Login flags Don't auto-open the browser. Prints the code and URL so you can open it manually — useful on remote servers or over SSH. Skip the first-run onboarding wizard after login. Prompt for an API key in the terminal instead of using the browser flow. Falls back to this automatically if the device-auth endpoint is unreachable. " type="string"> Skip the flow entirely and save a key you already have. " type="string"> Authenticate against a non-default hookstream instance (staging, self-hosted). API key auth You can bypass the login flow entirely and pass an API key directly. This is how you'd use the CLI in CI/CD. Precedence The CLI checks sources in this order, highest wins: | Priority | Source | Use case | |---|---|---| | 1 | flag | Per-command override | | 2 | env var | CI/CD, scripts, session override | | 3 | | Persistent default from | Per-command flag Override the stored key for a single command: Environment variable Ideal for CI. Set the var once, run many commands: Key format hookstream API keys follow this format: - Live: - Test: The plaintext key is shown once at creation. hookstream stores only the SHA-256 hash for verification — you cannot recover a lost key. Create and rotate keys in the dashboard at Settings → API Keys, or read more about the key model on the API authentication page. Logout Clear the stored API key and base URL: This removes from . The file itself stays behind. whoami Verify which user, org, and project your current key resolves to: Scripting tips Add to any command for clean, machine-readable output you can pipe into : Troubleshooting No API key was found in any source. Run , or set , or pass . The key is malformed or was revoked. Verify the format ( or + 64 hex chars), then create a new key in the dashboard at Settings → API Keys. You didn't approve the device code within 15 minutes, or the browser tab never opened. Run again — or if you're on a headless machine and need to copy the URL manually. Your key is probably bound to a different project than you expect. Run to confirm, and create a project-scoped key in the dashboard if needed. The CLI polls every 5 seconds. Wait up to 10 seconds after approving. If it still hangs, the local clock may be wrong (affects TLS) or a corporate proxy may be blocking the poll — try and verify the URL in the terminal matches what's in the browser. Related How the server verifies API keys and sessions. Create, list, and revoke keys via API. --- ## Commands Source: https://docs.hookstream.io/cli/commands The hookstream CLI exposes 19 command groups and 50+ subcommands. Every command supports the global flags below, and every list/get command supports for machine-readable output. Run at any time to see options for a specific command. Global flags Available on every command. Global flags must come before the subcommand: . " type="string"> Use a specific API key for this command. Overrides and the config file. " type="string" default="https://hookstream.io"> Override the API base URL — useful for staging or self-hosted instances. Output JSON instead of formatted text. Every command supports this. Designed to pipe into . Show help for any command or subcommand. Print the CLI version. Commands Manage CLI authentication. See CLI Authentication for the full device-flow walkthrough. Interactive onboarding. Asks for a name and provider template, creates a source, and prints the ingest URL with a ready-to-run command. Runs automatically after if you have zero sources. Skip with . Manage inbound webhook sources — the endpoints that receive events. Manage where events are delivered. Supports 8 destination types including HTTP, AWS SQS/S3/EventBridge, GCP Pub/Sub, Kafka, RabbitMQ, and WebSocket broadcast. Route events from a source to a destination. Supports content-based filters (9 operators) and JSONata transforms. Inspect received events with headers, payload, and full delivery history. Each delivery attempt (initial + retries) is tracked individually. View aggregated metrics — hybrid query (real-time raw for the last 48h, pre-aggregated for longer windows). Send test events and stream webhooks live to your terminal. connects over WebSocket to the EventStream Durable Object and prints each event as it arrives. Pair it with in another terminal for end-to-end local dev. Topics let one event fan out to multiple destinations via subscriptions. Each subscription supports its own filters and transforms. Replay events from a time window to any destination, with optional rate limiting. Jobs are stored in KV with auto-expiry. See Event replay for background. Issues are auto-created when deliveries fail consistently. Use them to triage, mute, or bulk-retry. Alert rules fire on delivery failures, high latency, volume spikes, and more. Every rule targets a notification channel. Notification channels receive alert events. Supports webhook (Slack, PagerDuty, Discord, etc.) and email. Collections turn inbound webhooks into queryable tables via last-write-wins upsert. Applications group outbound endpoints for your customers (Standard Webhooks). View current plan and monthly usage counters. Related Browser device flow, API keys, env vars, and config precedence. Every CLI command maps to an HTTP endpoint — drop down to the API when you need it. --- ## Installation Source: https://docs.hookstream.io/cli/installation The hookstream CLI ships as a single ESM binary on npm. It runs on Node.js 18+ and works on macOS, Linux, and Windows. Install The binary installs as . Run to see all command groups. Run without installing Use (or the pnpm/bun equivalent) for one-off commands — handy in CI: Verify use a specific API key\n --base-url override API base URL\n --json output machine-readable JSON\n -h, --help display help" } ]} /> Configuration Config file The CLI stores its config in an XDG-compliant location: - macOS / Linux: - Windows: The file is created automatically on and looks like: Environment variables All config can be overridden by environment variables, which is what you'll want in CI: Your API key. Overrides the value in . API base URL. Override when pointing at a self-hosted or staging instance. Precedence API key resolution order, highest to lowest: 1. CLI flag — per-command override 2. environment variable — session or CI 3. — persistent default from This lets you keep a default key in config while overriding per-command for ad-hoc work. Build from source Clone the monorepo and build the CLI locally — useful for contributing or running against a local Worker: Point it at a local Worker with or . Next Log in with your browser or an API key. Every command, option, and example. --- ## CLI Overview Source: https://docs.hookstream.io/cli/overview The CLI (/cli) is a command-line tool for managing your webhook infrastructure. It does everything the dashboard does — plus things the dashboard cannot, like streaming events to your terminal in real time and piping results through . What you can do streams events from any source to your terminal over WebSocket — perfect for local development. Manage sources, destinations, connections, topics, alerts, and channels without leaving the terminal. Device-flow authentication — no copy-pasting API keys. Also supports and for CI. Every command supports for clean, machine-readable output ready to pipe into or other tools. When to reach for the CLI - Local webhook development — run to receive live webhooks on your laptop. - CI/CD pipelines — create sources, destinations, and connections as part of your deploy scripts. - Quick ops — triage a failed delivery, reset a circuit breaker, or check metrics without opening the dashboard. - Bulk operations — replay events, retry failed deliveries, or export collections. - Debugging — shows full headers and payload inline. Command groups The CLI has 19 command groups and 50+ subcommands. The most common ones: | Group | Purpose | |---|---| | , , | Authentication | | | First-run onboarding wizard | | , | Send test events and stream webhooks live | | , , | Core pipeline resources | | , | Inspect event history and delivery attempts | | | Usage and latency stats | | , | Pub/sub fan-out and historical replay | | , , | Observability and notifications | | | Instant Database | | | Outbound webhooks | | | Plan and usage | See the full command reference for every command and option. Quick example Send a test event to a source and watch it arrive in real time — two terminals: The CLI reads your API key from after . You can also pass per command or set — see Authentication. Next steps npm, pnpm, yarn, or bun. Browser flow or API key. Full reference. --- ## Connections Source: https://docs.hookstream.io/concepts/connections Connections are the routing layer of hookstream. Each connection links a source to a destination and optionally applies a content-based filter and a JSONata transform before delivery. What is a Connection? A connection is a route: source → destination, optionally gated by filters and reshaped by a transform. When an event arrives at a source, hookstream evaluates every connection for that source. If the event matches a connection's filters, it's transformed (if configured) and dispatched to the destination's DO. Fan-Out A single source can own any number of connections, each pointing at a different destination. One inbound webhook can trigger deliveries to many endpoints — and because every connection has its own filter, you can cleanly route different event types to different destinations. Example: one Stripe source, three connections — events go to your billing service, events go to your CRM, and everything else goes to an S3 archive. Content-Based Filters Connections support filters with 9 operators that evaluate against the event's method, headers, content type, source IP, or payload: - / — exact match / inverse match - — substring match (strings only) - / / / — numeric comparisons - — field is present () or absent () - — value is within an array of allowed values Filters use dot-notation paths like to reach nested fields. Multiple filters are AND-combined — all must match for the event to pass. See Filters & Transforms for the complete operator reference. JSONata Transforms Connections can reshape the event payload before delivery using a JSONata expression. Use it to flatten nested structures, strip sensitive fields, compute derived values, or convert between formats. Transforms run after filters, before the event is handed to the destination's DO. JSONata runs in a sandboxed interpreter — no , no filesystem, no network. It's safe to let users author their own transforms. Processing Order When an event arrives at a source: 1. All connections for the source are loaded from D1. 2. Content-based filters are evaluated for each connection. 3. Matching connections apply their JSONata transforms. 4. Each transformed payload is dispatched to the destination's DO via . Connections are evaluated in parallel — there's no ordering guarantee between them. If you need strict ordering, put the ordering logic on the receiving side. Next Steps All 9 operators plus JSONata transform patterns. Create and manage connections via the API. Where events come from. Where events go. --- ## Delivery Pipeline Source: https://docs.hookstream.io/concepts/delivery-pipeline The delivery pipeline is what hookstream does with an event once it arrives: verify it, route it through matching connections, transform the payload, deliver to each destination, retry on failure, and dead-letter anything that never makes it through. Pipeline Overview Events flow through six stages: ingest, route, transform, deliver, retry, DLQ. Ingest Stage The ingest endpoint () accepts any HTTP method. Each request runs through: 1. Signature verification — HMAC-SHA256, HMAC-SHA1, or Standard Webhooks. 2. IP filter — allow/deny by IP or CIDR. 3. Dedup check — KV lookup by payload hash, header, or body field. 4. Event storage — D1 for metadata, D1 or R2 for the payload. 5. Real-time broadcast — pushed to the per-org DO for dashboards and the CLI command. 6. Pipeline dispatch — delivery is scheduled via so ingestion returns immediately. The whole ingest path is designed to return as fast as possible — everything downstream happens after the response is sent. Delivery Stage Every destination owns a dedicated Durable Object. When an event is dispatched: 1. The DO checks the circuit breaker state. 2. If closed or half-open, it attempts delivery via the configured provider. 3. On success — the attempt is recorded and a event is broadcast. 4. On failure — a retry alarm is scheduled and the circuit breaker's failure count is incremented. 5. On final failure — the event moves to the DLQ and an issue is created or updated. Because every destination has its own DO, failures on one destination never slow down deliveries to another. Retry Logic Retries are alarm-driven inside the DO. The retry policy is configurable: - Exponential backoff (default) — each attempt uses the next interval in the array: . - Linear backoff — base interval × attempt number. - Fixed backoff — the first interval, every time. Default intervals: seconds. See the retry strategies guide for tuning advice. Circuit Breaker The circuit breaker protects destinations from cascading failures: - Closed (normal) — deliveries proceed; consecutive failures are tracked. - Open (tripped) — after 5 consecutive failures, deliveries are paused and new events are queued. A cooldown alarm is set. - Half-Open (testing) — after cooldown, one probe delivery is sent. Success closes the circuit and flushes the queue. Failure re-opens it. Circuit state is visible in the dashboard and queryable via . See the circuit breaker guide for more. While the circuit is open, events are queued in the DO — they aren't lost. When the circuit closes, the queue flushes in order. But if traffic is heavy and the destination stays down, the queue can grow quickly. Monitor your issues page. Dead Letter Queue Events that exhaust every retry are moved to the DLQ. They're still visible in the dashboard and API, and can be manually retried individually or in bulk. An issue is created automatically for each DLQ event, with severity based on failure count. See the DLQ guide for replay patterns. Next Steps Tune backoff, intervals, and max retries. How the breaker trips, cools down, and recovers. Inspect and replay DLQ events. Route and reshape events in-pipeline. --- ## Destinations Source: https://docs.hookstream.io/concepts/destinations A destination is where hookstream sends events. Every destination runs inside its own Durable Object — a per-destination state machine that handles delivery, retries, circuit breaking, and dead-letter queue management. What is a Destination? Each destination owns a dedicated Durable Object, keyed by destination ID. The DO holds circuit breaker state, schedules retry alarms, and serializes delivery so your downstream service sees a predictable load profile. You never provision or manage these DOs — they exist the moment you create a destination. Provider Types hookstream supports 8 destination provider types. Each has its own auth model and payload shape, but connections, filters, and transforms work the same way across all of them. | Type | Description | Auth | |---|---|---| | | Deliver to any HTTP endpoint | Bearer, Basic, API key, or custom headers | | | Push to an SQS queue | AWS SigV4 (crypto.subtle) | | | Write objects to an S3 bucket | AWS SigV4 | | | Publish to an EventBridge bus | AWS SigV4 | | | Publish to a Pub/Sub topic | Service account JWT | | | Produce via Confluent REST Proxy | Basic / API key | | | Publish via the HTTP Management API | Basic auth | | | Broadcast to connected clients | — | Kafka and RabbitMQ use HTTP-based APIs (Confluent REST Proxy and the RabbitMQ HTTP Management API) because Cloudflare Workers can't speak the native wire protocols. See the provider reference for detailed configuration per type. Retry Policy Every destination has a configurable retry policy: - — maximum retry attempts (default: ) - — , , or - — array of retry delays in seconds (default: — 30s, 5m, 30m, 2h, 24h) For exponential backoff, each attempt uses the next interval in the array. Linear multiplies the base interval by the attempt number. Fixed uses the first interval every time. Retries are alarm-driven inside the DO — no external queue, no cron polling. Circuit Breaker Each destination runs a circuit breaker to protect failing endpoints from being hammered: - Closed — normal operation. Deliveries proceed and consecutive failures are tracked. - Open — after 5 consecutive failures, deliveries are paused and new events are queued. A cooldown alarm is set. - Half-Open — after the cooldown, one probe request is sent. If it succeeds the circuit closes and the queue flushes. If it fails, the circuit re-opens. Circuit state is visible in the dashboard and queryable via API. You can also manually reset the circuit via . Destination Templates hookstream includes templates for popular destination services with prefilled URLs, headers, and payload shapes: - Slack — incoming webhooks - Discord — webhooks - PagerDuty — Events API v2 - Datadog — HTTP intake - Zapier — webhooks - Linear — webhooks Outbound Signing HTTP destinations can sign outbound requests using HMAC-SHA256 or HMAC-SHA1 so your receiving endpoint can verify authenticity. The signature is injected into a configurable header (default: ). Pair it with a timestamp header to prevent replay attacks. Next Steps Configure HTTP destinations with auth, headers, and timeouts. How events flow from source to destination. Manage destinations programmatically. Route events from sources into destinations. --- ## Events Source: https://docs.hookstream.io/concepts/events Every webhook hookstream receives becomes an event — an immutable record of the HTTP request with its own lifecycle, storage strategy, and retry semantics. What is an Event? An event represents a single webhook request captured by a source. Each event stores the complete HTTP request: method, headers, body, query parameters, source IP, and content type — plus a unique ID and timestamp. Events are immutable; retries create new delivery attempts but never mutate the original event. Event Lifecycle Events move through four states: 1. — webhook captured and stored in D1. 2. — running through the pipeline (filter → transform → deliver). 3. — successfully delivered to every matched destination. 4. — delivery failed after all retries were exhausted. Events with no matching connections stay in the state indefinitely. That's not a bug — it just means nothing was routed to process them yet. You can wire up a connection later and replay them. Storage hookstream picks storage based on payload size: - Inline in D1 for bodies under 10KB — fast, cheap, and queryable. - R2 object storage for larger payloads, with the R2 key referenced in D1. - Metadata in D1 always — headers, method, query params, and timestamps. Events older than 30 days are archived to R2 as NDJSON, partitioned by org and date. Your dashboard queries stay fast and you still have access to the historical record when you need it. Free plans retain events for 7 days, Pro for 30 days, and Enterprise for 90 days. Archived events remain accessible via R2 even after they age out of D1. Searching & Filtering The Events API and dashboard both support: - Source filter — show events from a specific source - Status filter — , , - Time range — filter by start and end timestamp - Search — full-text search across event bodies - Cursor pagination — efficient forward/backward traversal Retrying Events Failed events can be retried individually or in bulk: - Individual — re-runs a single event through the pipeline. - Bulk — retries every event tied to an issue. Retries always create new delivery attempts while preserving the original event. You can retry the same event as many times as you want without losing the original record or the audit trail. Next Steps List, search, and retry events programmatically. Per-attempt records with status codes and latencies. Replay historical events against new destinations. How events move from ingestion to delivery. --- ## Filters & Transforms Source: https://docs.hookstream.io/concepts/filters-transforms Filters decide which events a connection or subscription receives. Transforms reshape the payload before delivery. Together they let you route precisely and deliver exactly the shape your downstream system expects. Content-Based Filters Filters let you selectively route events based on their content. Each filter has three parts: a field path (dot-notation), an operator, and a value. Multiple filters on the same connection are AND-combined — every rule must match for the event to pass. Filter Operators hookstream supports 9 operators: | Operator | Description | Types | |---|---|---| | | Exact match | string, number, bool | | | Inverse of | string, number, bool | | | Substring match | string only | | | Greater than | number | | | Greater than or equal | number | | | Less than | number | | | Less than or equal | number | | | Field is present () or absent () | any | | | Value is in an array of allowed values | any | Numeric comparisons (, , , ) return when either the field value or the rule value isn't a number — they don't coerce strings. Field Paths Field paths use dot-notation to reach values in the event: - — top-level body field - — nested body field - — request header (case-insensitive) - — HTTP method - — request content type - — client IP address Paths are case-sensitive except for headers. Missing paths resolve to — pair them with the operator to branch on presence. Filter Example This connection only matches public GitHub push/PR events delivered via POST. JSONata Transforms Transforms reshape event payloads using JSONata — a lightweight query and transformation language built specifically for JSON. Transforms run after filters and before the event is handed to the destination. Transform Examples JSONata runs in a sandboxed interpreter — no , no filesystem, no network. It's safe to let end users author their own transforms. Schema Validation Sources can validate incoming payloads against a JSON Schema — a complementary feature that runs before filters. Two modes: - — invalid payloads return and aren't stored. - — invalid payloads are stored with a validation warning flag. Schema validation uses [](https://github.com/cfworker/cfworker), a Workers-native validator. See the schema validation guide for details. Next Steps Where filters and transforms live. Manage connection filters and transforms via the API. Validate incoming payloads against a JSON Schema. Per-subscription filters and transforms for fan-out. --- ## Instant Database Source: https://docs.hookstream.io/concepts/instant-database Instant Database turns a webhook stream into a queryable table. Point a collection at a source, pick a primary key, and hookstream upserts every matching event into a record — ready to query, export, and analyze. What is Instant Database? Instant Database lets you sync webhook events to queryable collections. Each collection is like a table: define a primary key field, and hookstream upserts events as records using a last-write-wins strategy. You get structured, queryable webhook data without running a database or writing ETL code. Collections A collection is a container for records. Create one with: - — human-readable label - — which source to sync from - — dot-notation path to the unique identifier (e.g. ) Every event from that source is automatically upserted as a record, keyed by the primary key. Use one collection per logical entity — customers, orders, subscriptions, whatever your webhooks represent. Upsert Engine The upsert engine uses last-write-wins semantics based on the timestamp. When an event arrives: 1. Extract the primary key from the payload using . 2. Check whether a record already exists. 3. If new — insert the record. 4. If existing and newer — update the record. 5. If existing and older — skip (out-of-order protection). This handles out-of-order webhook delivery without CRDTs or vector clocks. If Stripe sends then in the wrong order, you still end up with the latest state. Last-write-wins means the most recent wins — not the time hookstream received it. This preserves the sender's intended ordering even when the network reorders things. Schema Inference hookstream infers the JSON schema of a collection by sampling up to 200 records. The inferred schema surfaces field names, types, and nesting — useful for building dashboards or writing typed clients against your webhook data. Schema is computed on-demand**, not stored. If your payload shape changes, the next inference call picks up the new shape automatically. No migrations, no staleness. Data Export Export collection records as NDJSON or CSV: CSV export uses json-flatten to convert nested JSON into dot-notation columns (e.g. ). Large exports stream so you don't have to hold the whole thing in memory. Backfill Backfill re-processes historical events into a collection — useful when you create a collection after events have already been received. The backfill engine processes events in batches using , and the frontend re-triggers batches until the job completes. Progress is visible in the dashboard. Next Steps Create collections, query records, and run exports. Shape payloads before they hit your collections. Replay historical events to backfill a collection. How events flow into the upsert engine. --- ## Sources Source: https://docs.hookstream.io/concepts/sources A source is a webhook ingestion endpoint. Every source gets a unique URL that accepts any HTTP method — hookstream captures the full request, stores it as an event, and hands it off to the pipeline. What is a Source? A source is a single ingestion endpoint. When a request hits it, hookstream records the method, headers, body, query parameters, and source IP as an immutable event, then runs it through the delivery pipeline. Sources don't care what's inside the body — they'll accept anything and let connections decide what to do with it. Source URL Every source has a dedicated ingestion URL: This URL accepts , , , , and . The complete request is captured — nothing is stripped, so you can always go back and inspect exactly what the sender delivered. Source Templates hookstream ships with templates for 15+ common webhook providers. Each template preconfigures signature verification, expected headers, and documentation links — just pick one and paste your signing secret. | Provider | Template | Signature Scheme | |---|---|---| | Stripe | | HMAC-SHA256 | | GitHub | | HMAC-SHA256 | | Shopify | | HMAC-SHA256 | | Slack | | HMAC-SHA256 | | Twilio | | HMAC-SHA1 | | SendGrid | | HMAC-SHA256 | | Intercom | | HMAC-SHA1 | | Linear | | HMAC-SHA256 | | Clerk | | Standard Webhooks | | Svix | | Standard Webhooks | | Paddle | | HMAC-SHA256 | | Resend | | Standard Webhooks | | Postmark | | — | | Typeform | | HMAC-SHA256 | | Custom | | Configurable | Preconfigured for Stripe, GitHub, Shopify, and 12 more providers — just pick a template and paste your signing secret. Signature Verification Sources can verify incoming webhook signatures so you only accept requests from who you expect. hookstream supports three schemes: - HMAC-SHA256 — used by Stripe, GitHub, Shopify, and most modern providers - HMAC-SHA1 — legacy providers like Twilio and Intercom - Standard Webhooks — the standardwebhooks.com spec used by Svix, Clerk, and Resend Configure a signing secret on the source and hookstream verifies every incoming request. Invalid signatures are rejected with before the event is stored. See the Signature Verification guide for the full walkthrough. Deduplication Sources can dedupe events so a retried webhook doesn't trigger double-processing. Pick one of three strategies: - — SHA-256 of the request body (default) - — use a specific header (e.g. ) as the dedup key - — use a JSON body field (e.g. ) as the dedup key Dedup uses Cloudflare KV with a configurable window (default: 5 minutes). Duplicates return but skip the pipeline entirely — your destinations never see them. IP Filtering Sources can restrict which IPs are allowed to send webhooks using an allowlist or denylist of addresses or CIDR ranges. Requests from blocked IPs are rejected with before any processing. Pair this with signature verification for defense in depth. See the IP filtering guide for details. WebSocket Sources Beyond HTTP ingestion, sources can accept inbound WebSocket connections. A per-source Durable Object manages each connection, enabling bidirectional communication and real-time event streaming from connected clients. Useful for browser-facing event streams or IoT fleets. Next Steps Deep dive into HMAC-SHA256, SHA-1, and Standard Webhooks. Lock down sources to trusted IP ranges and CIDRs. Create and manage sources programmatically. Where events go once they've been ingested. --- ## Topics & Pub/Sub Source: https://docs.hookstream.io/concepts/topics-pubsub Topics add a publish-subscribe messaging pattern on top of hookstream. Your application publishes events to a named topic, and every subscribed destination receives them — with optional per-subscription filters and transforms. What are Topics? A topic is a named channel that destinations can subscribe to. When you publish an event, hookstream fans it out to every subscribed destination, applying each subscription's filter and transform along the way. Topics run alongside the connection-based pipeline, not replacing it. Use connections for external webhook routing; use topics for application-initiated fan-out. Creating Topics Topics have a name and a URL-safe slug. Create one via the API: The slug shows up in the publish URL: . Subscriptions Subscribe a destination to a topic: Subscriptions support the same 9 filter operators as connections plus optional JSONata transforms — so different subscribers can receive different slices of the same topic, reshaped however they need. See Filters & Transforms for the operator reference. Publishing Publish an event to a topic and hookstream fans it out to every matching subscription: Each subscription's filter runs against the published event, matching subscriptions apply their transform, and the result is handed to the destination's DO. Topics vs. Connections Both move events to destinations, but they solve different problems: - Connections are source-to-destination routes. External webhooks come in through a source and get routed out. Use them for ingesting third-party webhooks. - Topics are a pub/sub overlay. Your application publishes directly to a topic and subscribers receive it. Use them for internal events you want to fan out to many destinations. You can combine them: route webhooks through connections into your app, then have your app re-publish to a topic after enrichment — giving downstream systems a cleaner, normalized stream. Next Steps Create topics, manage subscriptions, publish events. The source-to-destination routing layer. Where subscribed events end up. Operator reference for subscription filters. --- ## Key Concepts Source: https://docs.hookstream.io/getting-started/concepts A quick reference for the objects you'll touch in the dashboard, API, and CLI. Organization An organization (org) is the top-level container for all your hookstream resources. When you sign up, an org is auto-provisioned. Sources, destinations, connections, events, metrics, and team members all belong to an org. - ID format: - Management: invite teammates and manage roles from Settings > Team in the dashboard. Project Each org has one or more projects (e.g. , ). Projects provide data isolation — sources, destinations, connections, and events are all scoped to a project, and API keys are issued per project. - ID format: - Switch the active project from the sidebar dropdown in the dashboard. The API and database still use the legacy name (for example , response fields). The dashboard and docs call them projects — it's a UI rename, not a schema change. Source A source is a webhook ingestion endpoint. Each source has a unique URL: Sources accept any HTTP method and can be configured with signature verification (HMAC-SHA256, SHA-1, Standard Webhooks), IP allowlisting, and deduplication. Pick from 15+ provider templates (Stripe, GitHub, Shopify, and more) for one-click setup. Destination A destination is where events get delivered. hookstream supports 8 provider types: - HTTP / Webhook — any endpoint that accepts JSON - AWS SQS — via SigV4 and - AWS S3 — object storage delivery - AWS EventBridge — event buses - GCP Pub/Sub — with service account JWT auth - Kafka — via Confluent REST Proxy - RabbitMQ — via HTTP Management API - WebSocket — broadcast to connected clients Each destination has its own retry policy, circuit breaker, and dead letter queue. See Destinations for the full matrix. Connection A connection routes events from a source to a destination. Connections can have: - Content-based filters — selectively route events based on payload fields. - JSONata transforms — reshape payloads before delivery. - Schema validation — reject or warn on malformed events. Multiple connections can reference the same source, enabling fan-out. Event An event is a single webhook request received by a source. Events store the full HTTP method, headers, body, query parameters, and metadata (source IP, content length, etc). Events follow a simple lifecycle: Delivery Attempt A delivery attempt is a single try to send an event to a destination. Each attempt records: - HTTP status code - Response body (truncated) - Latency in milliseconds - Error message (if any) Failed attempts trigger retries according to the destination's retry policy. See Delivery Attempts for the state machine. API Key API keys authenticate machine clients to the hookstream API. Keys are scoped to a project and look like: The plaintext key is shown once at creation — only the SHA-256 hash is stored. If you lose it, create a new key and rotate. Next Steps Deep dive on source configuration and verification. Provider matrix and retry policies. Routing with filters and transforms. Event lifecycle and inspection. --- ## Dashboard Tour Source: https://docs.hookstream.io/getting-started/dashboard-tour A quick tour of the pages you'll use most. Every list and detail view updates in real time via WebSocket — no manual refresh required. Overview The Overview page (hookstream.io/dashboard) is your home base. It shows your org's key stats at a glance: - Total events - Delivery success rate - Active sources - Active destinations A volume chart displays event traffic over time and stat cards animate as new events flow in. Sources The Sources page lists every webhook ingestion endpoint in your project. Each row shows the name, ingestion URL, event count, and verification status. Click a source to open its detail view with configuration, recent events, and a connection graph. Use source templates for one-click setup with Stripe, GitHub, Shopify, and a dozen more providers. Templates preconfigure signature verification and common filters for you. Destinations The Destinations page shows all delivery targets. Each row displays the type (HTTP, SQS, S3, etc.), URL or ARN, delivery stats, and circuit breaker status. Click a destination to see its retry policy, recent delivery attempts, and circuit breaker history. Connections The Connections page shows source-to-destination routes. Each row lists the source name, destination name, filter rules, and transform status. Click into a connection to edit filters, tweak its JSONata transform, or browse events that matched the route. Events The Events page is a searchable, filterable log of every received webhook. You can filter by source, status, or date range — or search by body content. Click an event to inspect: - Headers - Body (raw and parsed) - Delivery attempts per destination - Retry history Metrics The Metrics page has four charts: - Event volume over time - Delivery success rate - Latency percentiles (p50, p95, p99) - Error breakdown by type Time ranges run from 1 hour to 30 days. Data is queried live for the last 48 hours and served from pre-aggregated hourly rollups beyond that. Issues & Alerts The Issues page lists auto-detected problems: delivery failures, circuit breaker opens, high error rates. Issues are created and resolved automatically. Configure alert rules to get notified via webhook, email, or any notification channel when thresholds are breached. Topics, Replay & Databases Pub/sub overlay on top of connections. Create a topic, attach subscriber destinations, and publish via the topic endpoint for fan-out delivery with per-subscription filters and transforms. Replay historical events to any destination with built-in rate limiting. Useful for backfills, testing new destinations, or recovering after an outage. Sync webhook events into queryable collections with auto-inferred schema, last-write-wins upsert, backfill, and CSV/NDJSON export. No ORM, no migrations — just point a connection at a collection. Next Steps The five-step flow to your first delivered webhook. Event lifecycle, inspection, and retry semantics. Pull volume, latency, and error stats programmatically. --- ## Your First Webhook Source: https://docs.hookstream.io/getting-started/first-webhook In this tutorial you'll create a source, send a webhook from your terminal, watch it appear in the dashboard in real time, and (optionally) wire up a destination for delivery. Total time: about three minutes. Using the Dashboard Log in to the hookstream dashboard and go to Sources. Click Create Source. - Name: - Verification: None (for this tutorial) Click Create. You'll see your source's ingestion URL: Copy it — you'll need it in the next step. Open your terminal and send a POST request: You should get a response with an in the JSON body. Head to Events in the dashboard. You'll see your event listed with the method, source, and timestamp. Click it to drill into: - Full request headers - Parsed JSON body - Query parameters - Metadata (source IP, content length, etc.) If the dashboard is already open when you send the request, the event appears in real time via WebSocket push — no refresh needed. To actually deliver events somewhere: 1. Go to Destinations > Create Destination 2. Choose HTTP/Webhook and enter your endpoint URL 3. Go to Connections > Create Connection 4. Select your source and destination 5. Send another webhook — watch it get delivered Check the Events page to see delivery attempts with status codes and latency. If your endpoint is unreachable, hookstream will retry automatically with exponential backoff. Using the CLI You can do the entire flow from your terminal with the hookstream CLI: opens your browser for a one-time device auth flow. If you're on a headless box, pass to get the device code in the terminal instead. You can also tail events live with — it opens a WebSocket and prints events as they arrive. Next Steps The condensed version of this flow in five steps. Add signature verification, IP filtering, and dedup to harden your source. The public ingestion endpoint reference. --- ## How It Works Source: https://docs.hookstream.io/getting-started/how-it-works hookstream is an event gateway that sits between webhook senders and your applications. It receives webhooks (via Sources), routes them (via Connections), and delivers them (to Destinations) — with retries, circuit breakers, and real-time monitoring built in. Ingest When a webhook arrives at a source URL, hookstream runs it through the ingest pipeline: 1. Verify the signature (if configured) using HMAC-SHA256, SHA-1, or the Standard Webhooks spec. 2. Check IP allowlist/denylist against the request's source IP. 3. Deduplicate against a sliding KV-backed window so retried sends from the provider don't double-process. 4. Persist the event in D1 with the full method, headers, body, query params, and metadata. 5. Offload large payloads (over 10 KB) to R2 object storage; small payloads stay inline in D1. See Sources for configuration details and 15+ provider templates for one-click setup. Routing Each connection defines a source-to-destination route with optional: - Content-based filters — 9 operators (, , , , , , , , ) with dot-notation field paths. - JSONata transforms — reshape the payload before delivery without leaving the sandbox. - JSON Schema validation — reject or warn on malformed events. An event can match multiple connections, enabling fan-out to many destinations from a single source. Delivery Each destination gets its own Durable Object () that owns: - Immediate delivery via the configured provider (HTTP, SQS, S3, EventBridge, Pub/Sub, Kafka, RabbitMQ, or WebSocket). - Retries on failure with exponential, linear, or fixed backoff. - Circuit breaker — opens after 5 consecutive failures, probes with a half-open request, auto-closes on success. - Dead letter queue for events that exhaust every retry. Every attempt is recorded with status code, latency, and error message — visible in the dashboard and via the delivery-attempts API. Monitoring hookstream gives you real-time visibility through: - WebSocket push to the dashboard via a per-org Durable Object (Hibernatable WebSockets — no idle cost). - Metrics for event volume, delivery success rate, latency percentiles, and error breakdown. - Issues auto-created on delivery failure with severity and affected resources. - Alert rules — 5 types: failure rate, latency, volume drop, DLQ growth, issue opened. - Notification channels — HMAC-signed webhooks or email via Resend. Architecture The happy path for a single event: All backend logic runs on Cloudflare Workers with Durable Objects for stateful operations. Data lives in D1 (SQLite), KV (cache, dedup, rate limits), and R2 (large payloads). Auth is Better Auth — session cookies for the dashboard, API keys for machine clients. Next Steps Ingestion endpoints with verification, filtering, and dedup. Eight provider types with retries and circuit breakers. Route events with filters and JSONata transforms. Durable Objects, retries, circuit breakers, and DLQ. --- ## Quickstart Source: https://docs.hookstream.io/getting-started/quickstart Create a source, send a webhook, and watch it get delivered — end to end in about five minutes. No local setup required. Prerequisites You'll need a hookstream account (sign up at hookstream.io — free for small projects) and a way to send HTTP requests: cURL, Postman, or your own application. Walkthrough A source is your webhook ingestion endpoint. In the dashboard go to Sources and click Create Source. Name it something like . hookstream generates a unique ingestion URL for you: Any HTTP request sent to this URL becomes an event in hookstream. See Sources for configuration options like signature verification and IP filtering. A destination is where events get delivered. Go to Destinations > Create Destination, choose HTTP/Webhook, and enter your application's webhook handler URL. hookstream supports 8 destination types: HTTP, AWS SQS, AWS S3, AWS EventBridge, GCP Pub/Sub, Kafka, RabbitMQ, and WebSocket. See Destinations for the full list. A connection links a source to a destination. Go to Connections > Create Connection and pick the source and destination you just created. Optionally add content-based filters (e.g. only route events where equals ) or a JSONata transform to reshape the payload before delivery. Fire a POST request at your source URL: hookstream receives the event, runs it through every matching connection, and delivers it to each destination. Open Events in the dashboard to see your event. Click into the detail view for delivery attempts, status codes, and latency. If delivery fails, hookstream retries automatically with exponential backoff. After five consecutive failures the circuit breaker opens and events are routed to the dead letter queue. Next Steps You now have a working webhook pipeline. Secure your source with signature verification, tighten routing with filters, and keep an eye on metrics. A longer walkthrough that includes CLI setup and event inspection. The architecture behind the pipeline — ingest, routing, delivery, monitoring. Use API keys to manage sources, destinations, and connections programmatically. --- ## Billing & Plans Source: https://docs.hookstream.io/guides/billing Hookstream has three plans. All three include the full product — webhook testing, signature verification, retries, DLQ, real-time streaming, observability, the CLI, and every destination type. The tiers only gate usage and retention. Plans | Plan | Price | Events / month | Sources | Destinations | Retention | | --- | --- | --- | --- | --- | --- | | Free | $0 | 50,000 | 10 | 5 | 7 days | | Pro | $19 / month (or $190 / year) | 1,000,000 | Unlimited | Unlimited | 30 days | | Enterprise | $99 / month (or $990 / year) | 10,000,000 | Unlimited | Unlimited | 90 days | Annual billing saves about 17%. Upgrade or downgrade any time. Usage tracking Event usage is counted per organization per calendar month (UTC). The counter resets at 00:00 UTC on the 1st. Counters live in KV, which means increments happen on the ingest hot path without a database round trip. Check your current usage from any of three places: When you cross 80% of your monthly event limit, an amber warning banner appears in the dashboard. Treat it as your first-stage page — there's still headroom, but it's time to think about the next move. Limit enforcement Hookstream enforces plan limits at two boundaries: on ingest (per event) and on resource creation (per source/destination). Event limits - Free — hard cutoff. The ingest endpoint returns the moment you hit 100% of your monthly event limit. No grace period. - Pro / Enterprise — soft limit. Events keep flowing up to 120% of the limit, then hookstream returns . That 20% burst covers unexpected spikes without paging you at 2am. Resource limits Source and destination limits are checked when you create new resources. If you're at your plan's cap, the API returns . Existing resources are never auto-deleted — if you downgrade, everything you already built keeps running. Upgrade your plan Both flows land on Stripe Checkout. Hookstream uses Stripe Checkout (redirect-based) for PCI-safe card handling — you're briefly redirected to and back. No card data touches hookstream's infrastructure. New limits apply as soon as Stripe fires the webhook. The dashboard updates within seconds. Manage your subscription All subscription management happens through the Stripe Customer Portal. Open it from Settings → Billing → Manage Subscription and you can: - Update your payment method - Switch between monthly and annual billing - Apply or review coupons - Download invoices - Cancel the subscription Downgrade and cancellation Cancelling leaves your paid plan active until the end of the current billing period. After that, you revert to Free. Your existing sources, destinations, and connections are preserved across a downgrade. If you're over the Free plan's resource limits afterward, you can't create new resources until you're back under the cap — but everything you had before keeps working. Events beyond Free's 50,000 / month still hit the cap though, so plan accordingly. Coupons Hookstream supports Stripe promotion codes. Enter them on the Stripe Checkout page — percentage and fixed-amount discounts are both supported, and codes can be scoped to specific plans or time ranges. Next Steps Endpoints for usage, checkout, portal, subscription, and invoices. Full CLI reference, including . --- ## Circuit Breaker Source: https://docs.hookstream.io/guides/circuit-breaker Every HTTP destination has a per-destination circuit breaker managed by its DeliveryScheduler Durable Object. When an endpoint starts failing hard, the breaker trips and pauses deliveries so hookstream doesn't turn a bad day into a worse one. The three states Deliveries flow through as usual. The DO counts consecutive failures. A single success resets the counter. After 5 consecutive failures the breaker opens. New deliveries are queued (not dropped) and a cooldown alarm is scheduled for 60 seconds out. When the cooldown alarm fires, the DO releases a single probe delivery. If it succeeds, the breaker closes and any queued events flush in order. If it fails, the breaker returns to open and the cooldown restarts. Default thresholds | Setting | Value | | --- | --- | | Failure threshold | 5 consecutive failures | | Cooldown period | 60 seconds | | Success threshold | 1 successful probe | These are per-destination and enforced by the DeliveryScheduler DO. Monitor the breaker The circuit breaker surfaces in a few places so you notice when it trips: - Dashboard — the destination detail page shows , , or live. - API — returns state, failure count, and the last transition timestamp. - Issues — an issue is auto-created when the breaker opens, so it shows up on your Issues page. - Alerts — the alert type fires on the same event. See Monitoring & Alerts. Pair the breaker with a notification channel so you find out before customers do. What happens to queued events When the breaker is open, new deliveries are stored in the DO's queue. Once it closes — via a successful probe or a manual reset — the queued events drain in order. Events are never dropped here. But if an event sits queued long enough to blow past its retry window, it still moves to the DLQ. Manually reset a breaker Whatever was returning 500s — fix that first. A reset without a fix just re-trips the breaker. Click Reset circuit on the destination detail page, or call: This closes the breaker immediately, zeroes the failure counter, and flushes queued events. The next event delivered will either succeed (you're done) or re-open the breaker within a few failures (back to step 1). Resetting a breaker while the destination is still failing just wastes retry attempts. If you're not sure it's recovered, wait for the 60-second probe to do its job automatically. Next Steps Where the circuit breaker sits in the delivery flow. How retries interact with the breaker state. --- ## Dead Letter Queue Source: https://docs.hookstream.io/guides/dead-letter-queue The dead letter queue holds events that exhausted every retry attempt. Instead of silently dropping them, hookstream flags them as permanently failed so you can inspect and retry on your own schedule. How an event reaches the DLQ A delivery attempt returns a non-2xx status or throws a network error. The DeliveryScheduler schedules the next attempt based on the destination's retry policy. Once the attempt count reaches , the delivery is marked as DLQ: and is stamped. Hookstream opens or updates an issue grouping the failure with similar ones so you can triage in batches. Inspect DLQ events Filter failed events anywhere you can filter events: You can also open the Events page in the dashboard and set Status = Failed, or jump straight to the Issues page where related failures are already grouped. Every failed event keeps its full history — status codes, latency, response headers, and error messages for each attempt. Retry DLQ events Retries create new delivery attempts. The originals are preserved for audit, so your history stays intact. Check the destination's circuit breaker before mass retrying. If the endpoint is still down, every retry just fails again and re-opens the breaker. Best practices - Alert on DLQ growth. Create a alert rule so you notice before your customers do. - Use the Issues page for bulk work. One handles every event in a group. - Look at error breakdown in Metrics. Clusters of identical errors usually point at one fix that clears the whole queue. - Tune retries for flaky destinations. If a destination reliably recovers within hours, extend so retries outlive transient outages. Next Steps Control how long an event retries before hitting the DLQ. Programmatic access to events and delivery attempts. --- ## Deduplication Source: https://docs.hookstream.io/guides/deduplication Providers occasionally send the same webhook twice — during their own retry loops, failovers, or race conditions. Without deduplication you might double-charge a customer, fire the same notification twice, or corrupt a sync. Hookstream dedupes at ingest using a KV-backed window so each unique event only fans out to your connections once. Three dedup strategies Pick the one that matches how your provider guarantees uniqueness. Hookstream computes a SHA-256 hash of the raw request body and checks KV for a match. Perfect when the entire payload is identical on retry (most providers). Zero configuration beyond enabling it. Uses a specific header — typically an idempotency key like or — as the dedup key. Best when the provider supplies an explicit unique id. Extracts a value from the JSON body using dot-notation (, , etc.). Useful when the idempotency id lives inside the payload instead of a header. Duplicate events are still stored (with ) so you can see them in the dashboard — they just don't get delivered to your destinations. That makes debugging much easier than silently dropping them. The dedup window The window controls how long a key is remembered. Default is 300 seconds (5 minutes), which covers most providers' retry windows. Pick a window longer than your provider's maximum retry interval: - Stripe: 3 days max retry → a window of 1–7 days if you're truly paranoid, but in practice 15 minutes catches almost everything. - GitHub: retries within an hour → 1 hour window. - Most SaaS: retries within 1–5 minutes → the default 5 minutes is fine. Configure dedup Use if the provider sends an idempotency header — it's the cheapest and most correct. Fall back to if they don't. Patch the source with , optionally , and a window: Replay a real webhook (or send the same request twice via ). The second event shows up in the dashboard with a badge and no delivery attempts. Implementation notes - Dedup keys live in Cloudflare KV with a TTL equal to the dedup window. Storage cleans itself up — no maintenance. - Header lookup is case-insensitive. - If or can't extract a value (missing header, invalid JSON), hookstream falls back to so the event still gets deduped. Next Steps Full source schema, including every dedup field. Combine dedup with a network-level allowlist. --- ## Event Replay Source: https://docs.hookstream.io/guides/event-replay Event replay re-delivers historical events to any destination on demand. Use it after fixing a bug, backfilling a new destination, testing against real production traffic, or recovering from an outage. What a replay job does A replay job takes a time range, an optional source filter, and a destination. Hookstream walks through matching events in chronological order and delivers them to the target destination at a rate you control. Jobs run in the background and their progress is stored in KV with a 24-hour auto-expiry. Replayed events use — if an individual delivery fails, the failure is logged but hookstream does not retry it. This prevents a long replay from turning into an out-of-control retry storm. Rerun the replay with a tighter range if you need to retry. Create a replay job Use the Events page or the Events API to find the range that needs replaying. Start narrow — even a few minutes is often enough to test. , , and are required. is optional. defaults to 10 events/second (max 100). defaults to 1000 (max 10000). Use the returned from the create call: Response fields: ( or ), , , , , , . Rate limiting Replay delivers up to events, pauses for a second, then continues. This lets you run large replays without blowing past a destination's quota or tripping its circuit breaker. Pick based on the destination's own limits. If your API allows 100 req/s but you share the quota with production traffic, set to something like 10 or 20 so there's headroom. Best practices Create a throwaway HTTP destination that points at a service you control (or a test session). Replay there first to confirm the payloads look right. Replay an hour before replaying a day, and a day before replaying a month. Keep the destination detail page open. If the breaker trips during replay, stop and investigate — your rate limit is probably too high. Replay walks the events table by , oldest first. Downstream consumers should tolerate a delayed-but-in-order stream. Next Steps Full job schema and endpoints. How hookstream routes events from source to destination. --- ## IP Filtering Source: https://docs.hookstream.io/guides/ip-filtering IP filtering adds a network-level gate in front of every source. Use an allowlist to only accept requests from known provider IPs, or a denylist to block specific bad actors. Blocked requests return before anything else in the pipeline runs. Allowlist vs denylist - Allowlist — "only these IPs are allowed." Best when your provider publishes a fixed IP list (Stripe, Twilio, GitHub webhooks from GitHub.com). - Denylist — "everyone except these IPs." Best for blocking known abusers while keeping the source open otherwise. You can set both. The denylist is checked first, then the allowlist. CIDR notation Both lists accept single IPs or CIDR ranges for IPv4: - Single IP: - /24 subnet: (256 addresses) - /16 subnet: (65,536 addresses) IPv6 CIDR matching is not currently supported. If you need to allow IPv6 traffic, leave the allowlist empty for now or reach out. Configure a source Grab the current IP list from your provider's documentation. For Stripe, that's stripe.com/docs/ips; for GitHub, it's the section of api.github.com/meta. The allowlist is stored as a JSON array. Update the source via API: Or open the source in the dashboard and paste comma-separated entries into the IP Filtering section — the UI serializes them for you. Send a webhook from a known-good IP. A rejected request returns with reason or . Pipeline evaluation order IP filtering runs at the very front of the ingest pipeline, before any other check: 1. IP filter — 403 if the client IP is blocked. Client IP is read from , falling back to . 2. Signature verification — 401 if the signature doesn't match. 3. Deduplication — stored as if the dedup window says so. 4. Schema validation — 422 if reject mode and the payload fails. 5. Storage and fan-out — the event is persisted and pushed into connections. Running IP filtering first means banned IPs never cost you a hash or a database round trip. Provider IP lists change. Set a calendar reminder (or a cron job) to re-sync them every quarter so legitimate traffic doesn't start getting 403s. Next Steps Verify cryptographic signatures on top of the IP allowlist. Full source schema, including and . --- ## Monitoring & Alerts Source: https://docs.hookstream.io/guides/monitoring-alerts Hookstream turns delivery problems into actionable signal through three connected pieces: issues (auto-detected problems), alert rules (configurable triggers over metrics), and notification channels (where alerts go). A cron runs every 5 minutes evaluating every rule and sending notifications. Issues: auto-detected problems Issues are created automatically when something breaks: - A delivery fails after all retries are exhausted. - A destination's circuit breaker opens. - Error rate crosses an internal threshold. Each issue tracks severity, affected source/destination, failure count, and a timeline of related attempts. Issues auto-resolve after 30 minutes of no new matching failures — or you can manually resolve them with . Alert rule types Hookstream supports five alert types. Each takes a with thresholds specific to the type. | Type | Triggers when | | | --- | --- | --- | | | Delivery failure rate exceeds a percentage over the evaluation window. | | | | p95 delivery latency exceeds a millisecond threshold. | | | | Event volume drops below a threshold vs the previous window. | | | | DLQ event count exceeds a number. | | | | A new issue is created. | | Create an alert rule Hookstream supports two channel types: webhook (HTTP POST to a URL, optionally HMAC-signed) and email (delivered via Resend). Webhook notifications include an header (HMAC-SHA256) when is set. Test any channel with . Link one or more channels to the rule and set a cooldown so you don't get paged 50 times in a row: The cron runs every 5 minutes. For testing, tripping the rule intentionally (post some failing deliveries) and waiting a cycle is the fastest way to confirm it works end to end. Auto-resolve Open issues and fired alerts auto-resolve after 30 minutes without a matching event. The same 5-minute cron that evaluates rules also closes stable issues. If you need immediate resolution, with . Troubleshooting Rules are gated by — if it fired recently, it won't fire again until the cooldown expires. Also check is lower than current actual values, and that the rule is . If you set , you need to verify the header on your side. See Outbound Signing for a receiver verification snippet — the algorithm is the same. Each rule dedupes via its cooldown, but multiple rules can fire on the same underlying event (e.g. both and ). That's intentional — if you want one-signal-per-incident, pick a single rule and disable the rest. Next Steps Full schema for rule types and configs. Channel schema and the test endpoint. --- ## Outbound Signing Source: https://docs.hookstream.io/guides/outbound-signing Outbound signing mirrors inbound signature verification but from the other side: hookstream signs every outbound delivery so your receivers can verify it came from you, not from an attacker who guessed the URL. How it works Stored in on the destination. For every outbound request, using the configured algorithm (SHA-256 or SHA-1). Default header is with a prefix. If the signatures match (constant-time compare), the request is verified. Configure outbound signing Set on an HTTP destination: Fields | Field | Default | Notes | | --- | --- | --- | | | — | Required. The shared secret. | | | | (recommended) or . | | | | Header the signature lands in. | | | | Prepended to the hex digest. Set to send raw hex. | | | | When true, the signing payload becomes (dot-separated) and the timestamp is also sent in . | | | | Only used when is true. | The verification examples below assume . If you enable timestamps, the receiver must read , reconstruct the signing payload as `${timestamp}.${rawBody}rawBodycrypto.timingSafeEqualhmac.comparedigesthmac.Equal==signingconfig`. The inbound side — verifying signatures on the events you receive. --- ## Real-Time Streaming Source: https://docs.hookstream.io/guides/real-time-streaming Hookstream pushes updates to connected clients in real-time over WebSockets. Under the hood, a per-org Durable Object manages every connection using Cloudflare's Hibernatable WebSocket API — so idle connections cost you nothing. Connect to the stream Generate one from Settings → API Keys or via the CLI: The endpoint is . In the browser, session cookies also work automatically. On connect, hookstream sends a welcome message with your . Send for every channel you want to receive. Available channels - — every new event, across all sources in the org. - — events from a single source. - — completed delivery attempts across all destinations. - — delivery attempts for a single destination. - — issue created, updated, or resolved. - — Instant Database sync events. Subscribe to as many as you like — the DO uses Cloudflare's native tag-based filtering so you only receive messages for channels you asked for. Message format Every message is JSON with a and a : The field is the complete resource — the same shape you'd get from the REST API. Reconnect automatically The dashboard's hook handles reconnection with exponential backoff (1s → 2s → 4s → capped at 30s) and re-sends channel subscriptions after reconnecting. If you're writing your own client, mirror that behavior. Polling fallback Every dashboard page also polls the REST API on an interval, just in case the WebSocket drops. When connected, polling slows down to 30 seconds. When disconnected, it speeds up to 5 seconds so the UI stays fresh. The hook in the frontend manages this automatically. If you're building your own client, the same pattern works — treat the WebSocket as the fast path and the REST API as the safety net. Next Steps WebSocket endpoints, authentication, and channel semantics. The test inspector uses the same WebSocket infrastructure. --- ## Retry Strategies Source: https://docs.hookstream.io/guides/retry-strategies When a delivery returns a non-2xx status or throws a network error, hookstream schedules a retry on the destination's DeliveryScheduler Durable Object. Retries are alarm-driven, which means they survive Worker restarts and always run once the alarm fires. Compare the three strategies | Strategy | When to use | Default intervals | | --- | --- | --- | | | Default choice. Gives a failing endpoint room to recover while keeping the total retry window bounded. | seconds (30s → 24h) | | | Predictable, evenly-growing delays. Good for monitoring dashboards where you want retries spaced by a fixed cadence. | | | | Idempotent endpoints that just need the same nudge every N seconds. | every time | All three read from the same array on the destination. Exponential uses the whole array as a lookup table; linear and fixed only read . How the math works Attempt N uses . With the default array, retries fire at 30s, 5m, 30m, 2h, and 24h. If exceeds the array length, the final interval is reused. Delay = . Default base is 30 seconds, so retries fire at 30s, 60s, 90s, 120s, 150s. Delay = on every attempt. Default is 30 seconds. Delays are deterministic — there is no built-in jitter. If your destination cannot tolerate a thundering herd, stagger delivery with per-connection filters or spread destinations across retry schedules. Configure retries Start with exponential unless you have a strong reason not to. The default intervals are a good balance for most APIs. Set , , and on the destination: Each delivery attempt is logged individually on the Events and Delivery Attempts pages, with status code, latency, and the retry number. When all attempts are exhausted the event moves to the dead letter queue. Troubleshooting Check the destination's circuit breaker state — if it is open, new deliveries are queued until the cooldown probe succeeds. Also confirm is greater than 0 and that the delivery actually failed (2xx responses are considered successful). Exponential uses the array directly — edit it to change the schedule. Linear and fixed only read the first element, so adjust . Either increase the intervals so retries spread out, or switch to backoff with a delay that matches your destination's rate limit window. Next Steps How ingest, filters, transforms, and delivery attempts fit together. What happens after the last retry is exhausted. --- ## Schema Validation Source: https://docs.hookstream.io/guides/schema-validation Schema validation checks every incoming webhook against a JSON Schema you attach to the source. Catch malformed payloads before they hit your destinations — either by rejecting them outright, or by flagging them and letting them through. Hookstream uses [](https://github.com/cfworker/cfworker/tree/main/packages/json-schema), a Workers-native validator with support for Draft 4, 6, and 7 (including , , , , , and ). Two modes Reject mode Invalid payloads return HTTP with a array in the response. The event is not stored or delivered. Use this when bad data must never reach your destinations — for example, a billing event that must have a . Warn mode Invalid payloads are accepted and stored, but tagged with so you can spot them in the dashboard. Delivery still happens. Use this during migrations or when you want visibility without blocking production traffic. Attach a schema Any JSON Schema Draft 7 document works. Start with the shape you expect and add constraints as you learn more. Enable validation and set the action: Send a valid event (should deliver normally) and an invalid one (should return 422 in reject mode, or arrive with in warn mode). Start in warn mode, leave it for a few days, then audit the events in the dashboard. Once you're confident the schema matches real traffic, flip to reject mode. Don't have a schema yet? Infer one. Hookstream's Instant Database can reverse-engineer a schema from live events: A collection auto-ingests events through a connection and stores them as records. Schema inference samples up to 200 records to build its types, so the more you send, the more accurate the inferred schema. Call . Copy the result into on the source. Next Steps Schema validation fields on the source schema. Use filter expressions to narrow what reaches each destination. --- ## Signature Verification Source: https://docs.hookstream.io/guides/signature-verification Signatures prove a webhook came from the expected sender and not an attacker. The provider hashes the request body with a shared secret; hookstream recomputes the hash and compares with constant-time equality. Mismatch means 401. Hookstream ships preconfigured signature verification for 15+ providers — Stripe, GitHub, Shopify, Clerk, Svix, Linear, and more. Use a source template and the secret is the only field you need to set. Supported algorithms | Algorithm | | Used by | | --- | --- | --- | | HMAC-SHA256 | | Stripe, GitHub, Shopify, Slack, most modern providers | | HMAC-SHA1 | | Legacy providers (pre-2020 GitHub, some CI systems) | | Standard Webhooks | | Svix, Clerk, Resend, and other Standard Webhooks adopters | HMAC-SHA256 is the default recommendation. SHA-1 is still supported for legacy integrations but should not be chosen for new work. How each algorithm works HMAC-SHA256 The sender computes and puts the hex digest in a header (for example or ). Hookstream: 1. Reads the signature header you configured on the source. 2. Recomputes the HMAC over the raw request body. 3. Compares using constant-time equality. A common prefix like is stripped automatically before comparison. HMAC-SHA1 Same flow, but the hash function is SHA-1. Configure with . Standard Webhooks Standard Webhooks is an open spec built on HMAC-SHA256 with a fixed set of headers: - — unique event id - — Unix timestamp - — (multiple versions allowed, comma separated) The signed string is and the secret is base64-encoded. Configure with . Configure verification In the provider's dashboard, create or view the webhook endpoint and copy the signing secret. For Stripe this is ; for GitHub it's whatever you typed into the "Secret" field when creating the hook. Either use a template from or post the fields directly: Copy the URL from the source detail page — it looks like — and paste it into the provider's webhook settings. Send a test event from the provider (or use the Signature Validator to simulate one). Successful requests land in your Events page with . Signature verification runs on the raw request body. If something upstream (a proxy, a transform) modifies the body before hookstream sees it, every signature will fail. Hookstream handles this correctly because it reads the body exactly once. Test and debug Two free tools help when a signature keeps failing: - Signature Validator — paste the secret, headers, and body to see step-by-step verification output. - HMAC Calculator — compute an HMAC over arbitrary input to cross-check what your sender should be producing. Events that fail verification are still stored (with ) so you can inspect the headers and body in the dashboard and figure out what went wrong. Next Steps Full source schema, including every verification field. Add a network-layer allowlist on top of signature verification. --- ## Webhook Testing Source: https://docs.hookstream.io/guides/webhook-testing Hookstream gives you a free, no-signup webhook testing tool at hookstream.io/test. Open the page, get a unique URL, and inspect every request in real-time. When you're ready, graduate the session to a full account without losing any data. No account required. No credit card. No install. Open the page and you have a working webhook URL in under a second. Create a test session A session is auto-created on page load. You get: - A unique ingest URL: - A two-panel inspector (events list on the left, event detail on the right) - 14-day TTL or 2,000 requests, whichever comes first Paste the ingest URL into any webhook provider, or hit it with curl: New events stream into the inspector via WebSocket — no refresh needed. Click an event to see headers, pretty-printed JSON body, query parameters, source IP, and metadata. Hookstream also auto-detects common providers (Stripe, GitHub, Shopify, Clerk, Svix, etc.) and shows a provider badge so you know what you're looking at. Prefer the terminal? Use the CLI. creates a session and opens the inspector URL. creates a session and streams events into your terminal in real-time over WebSocket — headers, body, status, the lot. Customize the response By default the ingest URL returns . You can override that per session to simulate odd behavior (5xx, redirects, custom bodies): Forward to localhost (or anywhere) Tunnel your live test session to your dev server without setting up ngrok: Use ngrok, Cloudflare Tunnel, or a local URL your laptop can reach from the internet. Forwarding runs via , so it never blocks the provider's response — hookstream replies instantly and forwards in the background. The forwarding response shows up in the event detail so you can see what your server said. Everything else you can do - Search and filter across received events. - Copy as code — hookstream generates ready-to-paste snippets in cURL, JavaScript, Python, and Go for any captured request. - Add notes to events () — handy for documenting what each test was for. - Export as NDJSON or CSV: . - Configure a custom response body to simulate provider-side quirks. Graduate to your account Sign up and hookstream offers to "graduate" your test session: the ingest URL stays exactly the same, but the source and all its events move into your org with full pipeline support — destinations, retries, alerts, collections, everything. You don't need to update anything on the provider side — the URL keeps working. Next Steps Full endpoints for sessions, responses, forwarding, and export. The same WebSocket infrastructure used by the inspector. --- ## hookstream Source: https://docs.hookstream.io/index hookstream is an event gateway that sits between your webhook senders and your infrastructure. It ingests events, applies filters and transforms, delivers them to 8 destination types with automatic retries, and gives you end-to-end observability. Built on Cloudflare Workers and Durable Objects, it's fast at the edge and cheap to run. Send your first webhook in under 5 minutes. Create a source, a destination, connect them, and watch events flow. The architecture: sources, connections, destinations, and the delivery pipeline with retries and circuit breakers. Every endpoint, parameter, and response. Authenticate with API keys or session cookies. Manage everything from the terminal. streams events locally for debugging. What you can build Stripe, Shopify, GitHub, Twilio — 15+ templates with signature verification preconfigured. HTTP, AWS (SQS, S3, EventBridge), GCP Pub/Sub, Kafka, RabbitMQ, WebSocket. Content-based filters with 9 operators. JSONata transforms for reshaping payloads. Fan out events to many subscribers, each with their own filters and transforms. Sync events into queryable collections with automatic schema inference. Ephemeral test sessions with a live inspector — no signup needed. Core primitives A source is a webhook endpoint. Each source gets a unique URL like that accepts any HTTP method. Optional signature verification, IP filtering, deduplication. A destination is where events get delivered. Every destination runs on its own DeliveryScheduler Durable Object with retries, circuit breaker, and DLQ. A connection links a source to a destination. Add content-based filters and JSONata transforms to shape what gets delivered where. Every incoming request becomes an event — immutable, searchable, replayable. See live delivery attempts in the dashboard or via WebSocket. Try it right now No signup required — open the test inspector, copy the temporary URL, and send it a POST. You'll see the event land live in the two-panel inspector with headers, body, and a custom response configurator. You don't need to run a server to receive webhooks. Use webhook testing to spin up an instant public URL and inspect requests in real time. Most-read guides HMAC-SHA256, SHA1, and Standard Webhooks. Preconfigured for Stripe, GitHub, Shopify, and more. Exponential, linear, fixed. Configure per-destination backoff and max attempts. How hookstream protects failing endpoints and when it probes recovery. Issue auto-creation, 5 alert rule types, webhook + email notification channels. --- ## AWS EventBridge Source: https://docs.hookstream.io/providers/aws-eventbridge The provider publishes events to an EventBridge event bus via the API. Once on the bus, EventBridge rules can route events to Lambda, Step Functions, SQS, SNS, Kinesis, or any other supported target. When to use this: you already use EventBridge as your serverless event router and want webhooks to land on the same bus. SigV4 signing runs on — no AWS SDK bundled into the Worker. Configuration ARN of the target event bus, or for the account's default bus. AWS region the bus lives in. Value used for the EventBridge field on every published event, e.g. or . Value used for the EventBridge field, e.g. . IAM access key ID with permission. IAM secret access key. Stored encrypted, masked in responses. Event Shape hookstream calls with the webhook body serialized into the field: Write EventBridge rules against the , , or inner fields to fan out to downstream targets. Authentication Create an IAM user with on your target bus ARN: Example Gotchas EventBridge enforces a 256 KB limit on the field. For larger payloads, use AWS S3 and trigger rules from object creation events instead. Next Steps Push to SQS directly if you don't need rule-based routing. Archive events as S3 objects. The GCP equivalent for fan-out messaging. Full API reference. --- ## AWS S3 Source: https://docs.hookstream.io/providers/aws-s3 The provider writes each event to an S3 bucket as a separate JSON object, partitioned by date. Use it for webhook archiving, data lake ingestion, or triggering S3 event notifications into Lambda or Step Functions. When to use this: you want durable long-term storage of raw events, or you're building a pipeline that reads from S3 downstream. SigV4 signing runs on — no AWS SDK. Object keys follow the pattern , so date-based lifecycle policies work out of the box. Configuration S3 bucket name. AWS region the bucket lives in, e.g. . Optional key prefix prepended to every object, e.g. . A trailing is added automatically if missing. When omitted, objects land at the bucket root under . IAM access key ID with permission on the bucket. IAM secret access key. Stored encrypted, masked in responses. Object format. (default) writes . writes with the raw event body. Object Layout Object keys are composed as: For example, . Each object contains the full event: Authentication Create an IAM user with an inline policy granting on your bucket: Generate an access key and paste both values into the config. Example Gotchas hookstream never deletes S3 objects. Set an S3 lifecycle rule on the bucket to expire archived events after N days, or transition them to Glacier. Without the trailing , keys end up like instead of . Always include the separator. Next Steps Queue events for async processing instead of archiving. Route events through EventBridge rules. Learn how hookstream archives old events to R2 automatically. Full API reference. --- ## AWS SQS Source: https://docs.hookstream.io/providers/aws-sqs The provider pushes events into an Amazon SQS queue. Each event becomes an SQS message whose body is the event payload — standard and FIFO queues are both supported. When to use this: you want queued, at-least-once processing downstream (Lambda consumers, ECS workers, Step Functions), or you need FIFO ordering on a per-key basis. SigV4 signing runs entirely on — no AWS SDK is bundled into the Worker. This keeps the delivery path fast and deploy artifacts small. Configuration Full SQS queue URL, e.g. . AWS region, e.g. . Must match the queue's region. IAM access key ID with permission. IAM secret access key. Stored encrypted and masked in responses (only the last 4 characters are shown). For FIFO queues only. Sets on every message and auto-generates from the event ID. Authentication Create an IAM user with an inline policy granting on the target queue ARN, generate an access key, and paste both values into the config. Cloudflare Workers can't natively assume AWS roles. If you need role-based auth, run a short-lived process that assumes the role via STS and rotate the resulting access key into hookstream on a schedule. Example Gotchas SQS rejects messages to FIFO queues without a . Set in the config, and hookstream will auto-generate deduplication IDs from event IDs. Create a dedicated IAM user scoped only to on the target queue ARN. Don't reuse broader credentials. SQS caps message size at 256 KB. Larger events will fail delivery — use the AWS S3 provider for heavy payloads, or trim with a JSONata transform on the connection. Next Steps Archive events as JSON objects instead of queuing them. Route through EventBridge for rule-based fan-out. Configure exponential, linear, or fixed retries per destination. Full API reference. --- ## GCP Pub/Sub Source: https://docs.hookstream.io/providers/gcp-pubsub The provider publishes events to a Google Cloud Pub/Sub topic. hookstream signs short-lived JWTs with your service account private key and exchanges them for access tokens on the fly — no GCP SDK needed. When to use this: you're on GCP and want hookstream events to flow into Pub/Sub subscribers (Dataflow, Cloud Functions, Cloud Run, BigQuery via Dataflow). JWT signing uses (). The resulting access token is used as a header on the Pub/Sub publish call. Configuration GCP project ID hosting the topic. Pub/Sub topic name (just the short name — not the full resource path). Full service account key JSON as a string. Must contain , , and . Stored encrypted and masked in responses. Authentication 1. Create a service account in the GCP console. 2. Grant it the role on the target topic: 3. Download the service account key JSON. 4. Paste the entire file contents into the field. Under the hood, hookstream extracts and , signs a JWT with , exchanges it at , and caches the bearer token for the publish call. Message Format The webhook body is base64-encoded and sent as the Pub/Sub message field. Message attributes include and so subscribers can filter without decoding the payload. Example Gotchas The field contains literal escape sequences. Pass the service account JSON exactly as downloaded — don't try to pretty-print or unescape it. hookstream does not create topics. Create it ahead of time with . Service account keys never expire on their own. Rotate them via Terraform or on a cadence and update the destination config. Next Steps Produce to Kafka topics via Confluent REST Proxy. The AWS equivalent for rule-based fan-out. How hookstream's topic overlay fans out to subscribers. Full API reference. --- ## HTTP / Webhook Source: https://docs.hookstream.io/providers/http The provider posts events to any HTTP endpoint. This is the most common destination type — use it for your own APIs, Slack, Discord, PagerDuty, Zapier, Linear, Datadog, or anything that accepts an HTTP webhook. When to use this: you control (or subscribe to) an HTTPS endpoint that can accept JSON POSTs. If you need AMQP, Kafka, Pub/Sub, or cloud queues, use one of the dedicated providers. All destinations share the same retry, circuit breaker, and DLQ behavior. See Delivery Pipeline for details. Configuration destinations use the top-level , , , and columns on the destination row — there's no nested object required. The destination URL. HTTPS in production. HTTP method. , , or . Key-value map of custom headers merged into every request. Use this for auth tokens, content types, and provider-specific headers. Request timeout in seconds. Requests exceeding this are aborted and retried per the destination's retry policy. Outbound HMAC signing is configured separately on the destination's object, not inside the HTTP config. See Outbound Signing. Authentication HTTP destinations don't have a dedicated auth field — you set credentials via the map. Base64-encode and set the header manually: Skip auth headers entirely and verify signatures on the receiver using Outbound Signing. hookstream signs every payload with HMAC-SHA256 when configured. Delivery Headers hookstream adds these headers to every HTTP delivery on top of your map: - — the originating event ID - — the attempt number (, , ...) - — ISO 8601 delivery timestamp If a JSONata transform is configured on the connection, the transformed body is sent instead of the raw event. Example Enable outbound signing so your receiver can verify that requests actually came from hookstream — it's a one-line config change and gets you replay protection. Destination Templates hookstream ships with prefilled templates for common services. Pass when creating a destination: - Slack — incoming webhook URL, - Discord — webhook URL with the suffix for Slack-compatible payloads - PagerDuty — Events API v2 with routing key - Datadog — HTTP intake with header - Zapier — webhook trigger URL - Linear — webhook URL with API key header Next Steps How destinations, retries, and circuit breakers fit together. Sign outbound requests so your receiver can verify them. Full API reference for creating and managing destinations. Push to queues instead of HTTP endpoints. --- ## Kafka Source: https://docs.hookstream.io/providers/kafka The provider produces events to Kafka topics via the Confluent REST Proxy v3. Events become JSON messages, keyed and headered with the hookstream event metadata. When to use this: you're already running Confluent Cloud (or self-hosted Confluent Platform) and want hookstream events to land as Kafka records. Cloudflare Workers can't speak the native Kafka wire protocol — it needs raw TCP sockets. hookstream produces over the Confluent REST Proxy v3 HTTP API instead. Your cluster must have the REST Proxy enabled (it's on by default in Confluent Cloud). Configuration Confluent bootstrap server, e.g. . The REST endpoint is derived from this by switching to HTTPS on port 443. Confluent cluster ID, e.g. . Found in the Confluent Cloud console under cluster settings. Target Kafka topic name. The topic must already exist. Confluent API key with produce permissions on the topic. Confluent API secret. Stored encrypted and masked in responses. The full REST URL hookstream hits is: Authentication 1. In the Confluent Cloud console, open your cluster and create a new API key. 2. Grant it on the target topic (or if you're setting up quickly). 3. Paste and into the destination config. hookstream uses HTTP Basic auth () on every produce request. Message Format Each produce request is a single record: Headers are base64-encoded per the REST Proxy v3 contract. The full webhook body lives in . Example Gotchas hookstream cannot connect via bootstrap servers directly. Confluent Cloud clusters expose REST Proxy by default; self-hosted clusters need the Confluent REST Proxy running in front of them. hookstream does not create topics. Create it via the Confluent UI, Terraform, or . If you're running your own REST Proxy, set to the proxy host:port (HTTPS on 443). The auth model still expects / in Basic auth headers. Next Steps Publish via RabbitMQ's HTTP Management API. Managed pub/sub without the Kafka overhead. Simple queue-based delivery. Full API reference. --- ## RabbitMQ Source: https://docs.hookstream.io/providers/rabbitmq The provider publishes events to a RabbitMQ exchange via the HTTP Management API's endpoint. When to use this: you already run RabbitMQ and want webhooks to fan out through your existing exchanges and queues. Cloudflare Workers can't speak AMQP — it needs raw TCP sockets. hookstream publishes via the RabbitMQ HTTP Management API instead, which means you must enable the management plugin and expose it over HTTPS. This is fine for most setups, but it's not the AMQP fast path you might be used to. Configuration RabbitMQ Management API base URL (usually port ), e.g. . No trailing slash required. Virtual host to publish into. URL-encoded automatically — use for the default vhost. Exchange name to publish to. The exchange must already exist. Routing key applied to every published message. RabbitMQ username with publish permissions. RabbitMQ password. Stored encrypted and masked in responses. Authentication hookstream uses HTTP Basic auth () on every publish request. Create a dedicated RabbitMQ user with only publish permissions on the target exchange: (The three regex args are configure/write/read — the example above allows writing only to the exchange.) Message Format Each publish call looks like: Success requires both a response and a response body of . A with is treated as a delivery failure so an unbound exchange won't silently swallow events. Example Gotchas The Management API ships with RabbitMQ but isn't always enabled: The API listens on port by default. Don't put the Management API on the public internet without TLS. Use a reverse proxy (nginx, Caddy, Cloudflare Tunnel) or whitelist Cloudflare egress IPs at the firewall. If your exchange has no matching binding, RabbitMQ returns . hookstream treats this as a failure so it'll retry and eventually raise an issue — bind at least one queue before publishing. Next Steps Produce to Kafka topics via Confluent REST Proxy. Deliver straight to an HTTP endpoint instead. How hookstream protects failing exchanges from being hammered. Full API reference. --- ## WebSocket Source: https://docs.hookstream.io/providers/websocket The provider broadcasts delivered events to any WebSocket client subscribed to a named channel. Under the hood it uses hookstream's Durable Object (one per org, Hibernatable WebSockets), so there's no extra infrastructure to manage. When to use this: you're building a live dashboard, a developer tool that streams webhooks to the browser, or a multi-client broadcast fan-out where many viewers need the same events. Unlike the other providers, WebSocket doesn't make an outbound HTTP call — it hands the event to the per-org DO, which fans it out to every connected subscriber on the configured channel. Configuration Channel identifier to broadcast on. Alphanumeric with dots, underscores, or hyphens (). Clients subscribe to this exact name. Authentication The destination itself has no auth — it just publishes into your org's DO. Access control happens on the client side when subscribing. Clients connect to with an API key and subscribe to the channel: After the upgrade, send a subscribe frame: Message Format Broadcasts are sent as JSON frames with : The field is the raw event body as a string (so it matches exactly what would've been POSTed to an HTTP destination). Example Browser client: Gotchas If no client is connected when an event is delivered, the broadcast is dropped. Use WebSocket alongside another destination (HTTP, SQS, S3) if you need durability. One DO per org handles all channels, so subscribers on different channels inside the same org share the same hibernating DO. This is cheap — Hibernatable WebSockets incur no idle cost. Next Steps Deliver to traditional HTTP endpoints. How destinations, retries, and circuit breakers work together. Full pipeline from ingest to delivery. Full API reference. --- ## Health check Source: https://docs.hookstream.io/api-reference/health-check --- ## List API keys Source: https://docs.hookstream.io/api-reference/list-api-keys --- ## Create API key Source: https://docs.hookstream.io/api-reference/create-api-key --- ## Revoke API key Source: https://docs.hookstream.io/api-reference/revoke-api-key --- ## List source templates Source: https://docs.hookstream.io/api-reference/list-source-templates --- ## List sources Source: https://docs.hookstream.io/api-reference/list-sources --- ## Create a source Source: https://docs.hookstream.io/api-reference/create-a-source --- ## Get a source Source: https://docs.hookstream.io/api-reference/get-a-source --- ## Update a source Source: https://docs.hookstream.io/api-reference/update-a-source --- ## Delete a source Source: https://docs.hookstream.io/api-reference/delete-a-source --- ## List events Source: https://docs.hookstream.io/api-reference/list-events --- ## Get event detail Source: https://docs.hookstream.io/api-reference/get-event-detail --- ## Retry failed deliveries for an event Source: https://docs.hookstream.io/api-reference/retry-failed-deliveries-for-an-event --- ## List destination templates Source: https://docs.hookstream.io/api-reference/list-destination-templates --- ## List destinations Source: https://docs.hookstream.io/api-reference/list-destinations --- ## Create a destination Source: https://docs.hookstream.io/api-reference/create-a-destination --- ## Get destination by ID Source: https://docs.hookstream.io/api-reference/get-destination-by-id --- ## Update a destination Source: https://docs.hookstream.io/api-reference/update-a-destination --- ## Delete a destination Source: https://docs.hookstream.io/api-reference/delete-a-destination --- ## Get circuit breaker status Source: https://docs.hookstream.io/api-reference/get-circuit-breaker-status --- ## Reset circuit breaker Source: https://docs.hookstream.io/api-reference/reset-circuit-breaker --- ## List connections Source: https://docs.hookstream.io/api-reference/list-connections --- ## Create a connection Source: https://docs.hookstream.io/api-reference/create-a-connection --- ## Get a connection Source: https://docs.hookstream.io/api-reference/get-a-connection --- ## Update a connection Source: https://docs.hookstream.io/api-reference/update-a-connection --- ## Delete a connection Source: https://docs.hookstream.io/api-reference/delete-a-connection --- ## List delivery attempts Source: https://docs.hookstream.io/api-reference/list-delivery-attempts --- ## Get a delivery attempt Source: https://docs.hookstream.io/api-reference/get-a-delivery-attempt --- ## Retry a delivery attempt Source: https://docs.hookstream.io/api-reference/retry-a-delivery-attempt --- ## Get overview metrics Source: https://docs.hookstream.io/api-reference/get-overview-metrics --- ## Get event volume time series Source: https://docs.hookstream.io/api-reference/get-event-volume-time-series --- ## Get delivery metrics time series Source: https://docs.hookstream.io/api-reference/get-delivery-metrics-time-series --- ## Get latency percentiles time series Source: https://docs.hookstream.io/api-reference/get-latency-percentiles-time-series --- ## List issues with filters Source: https://docs.hookstream.io/api-reference/list-issues-with-filters --- ## Get issue summary counts Source: https://docs.hookstream.io/api-reference/get-issue-summary-counts --- ## Get issue by ID Source: https://docs.hookstream.io/api-reference/get-issue-by-id --- ## Update issue status Source: https://docs.hookstream.io/api-reference/update-issue-status --- ## Retry failed deliveries for an issue Source: https://docs.hookstream.io/api-reference/retry-failed-deliveries-for-an-issue --- ## List notification channels Source: https://docs.hookstream.io/api-reference/list-notification-channels --- ## Create a notification channel Source: https://docs.hookstream.io/api-reference/create-a-notification-channel --- ## Get notification channel by ID Source: https://docs.hookstream.io/api-reference/get-notification-channel-by-id --- ## Update a notification channel Source: https://docs.hookstream.io/api-reference/update-a-notification-channel --- ## Delete a notification channel Source: https://docs.hookstream.io/api-reference/delete-a-notification-channel --- ## Test a notification channel Source: https://docs.hookstream.io/api-reference/test-a-notification-channel --- ## List alert rules Source: https://docs.hookstream.io/api-reference/list-alert-rules --- ## Create alert rule Source: https://docs.hookstream.io/api-reference/create-alert-rule --- ## Get alert rule Source: https://docs.hookstream.io/api-reference/get-alert-rule --- ## Update alert rule Source: https://docs.hookstream.io/api-reference/update-alert-rule --- ## Delete alert rule Source: https://docs.hookstream.io/api-reference/delete-alert-rule --- ## List collections Source: https://docs.hookstream.io/api-reference/list-collections --- ## Create collection Source: https://docs.hookstream.io/api-reference/create-collection --- ## Get collection Source: https://docs.hookstream.io/api-reference/get-collection --- ## Update collection Source: https://docs.hookstream.io/api-reference/update-collection --- ## Delete collection Source: https://docs.hookstream.io/api-reference/delete-collection --- ## Get collection stats Source: https://docs.hookstream.io/api-reference/get-collection-stats --- ## List records Source: https://docs.hookstream.io/api-reference/list-records --- ## Get record by key Source: https://docs.hookstream.io/api-reference/get-record-by-key --- ## Get record changelog Source: https://docs.hookstream.io/api-reference/get-record-changelog --- ## Infer schema Source: https://docs.hookstream.io/api-reference/infer-schema --- ## Get backfill progress Source: https://docs.hookstream.io/api-reference/get-backfill-progress --- ## Start backfill Source: https://docs.hookstream.io/api-reference/start-backfill --- ## List topics Source: https://docs.hookstream.io/api-reference/list-topics --- ## Create topic Source: https://docs.hookstream.io/api-reference/create-topic --- ## Get topic Source: https://docs.hookstream.io/api-reference/get-topic --- ## Update topic Source: https://docs.hookstream.io/api-reference/update-topic --- ## Delete topic Source: https://docs.hookstream.io/api-reference/delete-topic --- ## Create subscription Source: https://docs.hookstream.io/api-reference/create-subscription --- ## Update subscription Source: https://docs.hookstream.io/api-reference/update-subscription --- ## Delete subscription Source: https://docs.hookstream.io/api-reference/delete-subscription --- ## Publish to topic Source: https://docs.hookstream.io/api-reference/publish-to-topic --- ## Create replay job Source: https://docs.hookstream.io/api-reference/create-replay-job --- ## Get replay job status Source: https://docs.hookstream.io/api-reference/get-replay-job-status --- ## Get current usage Source: https://docs.hookstream.io/api-reference/get-current-usage --- ## Create checkout session Source: https://docs.hookstream.io/api-reference/create-checkout-session --- ## Create customer portal session Source: https://docs.hookstream.io/api-reference/create-customer-portal-session --- ## Get current subscription Source: https://docs.hookstream.io/api-reference/get-current-subscription --- ## List recent invoices Source: https://docs.hookstream.io/api-reference/list-recent-invoices --- ## List applications Source: https://docs.hookstream.io/api-reference/list-applications --- ## Create application Source: https://docs.hookstream.io/api-reference/create-application --- ## Get application Source: https://docs.hookstream.io/api-reference/get-application --- ## Update application Source: https://docs.hookstream.io/api-reference/update-application --- ## Delete application Source: https://docs.hookstream.io/api-reference/delete-application --- ## List endpoints Source: https://docs.hookstream.io/api-reference/list-endpoints --- ## Create endpoint Source: https://docs.hookstream.io/api-reference/create-endpoint --- ## Get endpoint Source: https://docs.hookstream.io/api-reference/get-endpoint --- ## Update endpoint Source: https://docs.hookstream.io/api-reference/update-endpoint --- ## Delete endpoint Source: https://docs.hookstream.io/api-reference/delete-endpoint --- ## Rotate signing secret Source: https://docs.hookstream.io/api-reference/rotate-signing-secret --- ## List messages Source: https://docs.hookstream.io/api-reference/list-messages --- ## Send message Source: https://docs.hookstream.io/api-reference/send-message --- ## Get message with attempts Source: https://docs.hookstream.io/api-reference/get-message-with-attempts --- ## Retry message delivery Source: https://docs.hookstream.io/api-reference/retry-message-delivery --- ## Generate portal access Source: https://docs.hookstream.io/api-reference/generate-portal-access --- ## List event types Source: https://docs.hookstream.io/api-reference/list-event-types --- ## Create event type Source: https://docs.hookstream.io/api-reference/create-event-type --- ## Get event type Source: https://docs.hookstream.io/api-reference/get-event-type --- ## Update event type Source: https://docs.hookstream.io/api-reference/update-event-type --- ## Delete event type Source: https://docs.hookstream.io/api-reference/delete-event-type --- ## List audit log entries Source: https://docs.hookstream.io/api-reference/list-audit-log-entries --- ## List environments Source: https://docs.hookstream.io/api-reference/list-environments --- ## Create environment Source: https://docs.hookstream.io/api-reference/create-environment --- ## Update environment Source: https://docs.hookstream.io/api-reference/update-environment --- ## Delete environment Source: https://docs.hookstream.io/api-reference/delete-environment --- ## Activate environment Source: https://docs.hookstream.io/api-reference/activate-environment --- ## Changelog Source: https://docs.hookstream.io/changelog Improvement Documentation Updates and Configuration Improvements April 13, 2026 · Improvement Updated documentation with hardcoded URLs and improved S3 configuration options for better clarity and usability. Read more Feature CLI Authentication and Onboarding Improvements April 12, 2026 · Feature Enhanced device authentication flow and added first-run onboarding wizard to improve CLI setup experience. Read more --- ## Documentation Updates and Configuration Improvements Source: https://docs.hookstream.io/changelog/documentation-updates-and-configuration-improvements April 13, 2026 · Improvement We've made several improvements to make hookstream easier to use and understand. Documentation Enhancements All API URLs in the documentation are now hardcoded for better clarity. Instead of placeholder variables, you'll see the actual URLs you need to use, making it easier to copy and paste examples directly into your code. S3 Configuration Updates The AWS S3 provider configuration has been improved: - The parameter is now optional - when omitted, events are automatically organized by date - Trailing slashes are added automatically to prefixes for cleaner file organization - Better default behavior for object storage structure Back to Changelog. --- ## CLI Authentication and Onboarding Improvements Source: https://docs.hookstream.io/changelog/cli-authentication-and-onboarding-improvements April 12, 2026 · Feature We've improved the CLI experience with better authentication and guided setup. Enhanced Authentication - Polished device authentication flow for smoother login - Improved error handling and user feedback during setup New Onboarding Wizard - Added first-run wizard to guide new users through initial CLI configuration - Streamlined setup process with step-by-step guidance Back to Changelog. ---