Event Replay
Replay historical events to any destination with rate limiting and progress tracking.
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 retryEnabled: false — 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
Identify the time window
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.
POST to /v1/replay
bashcurl -X POST https://hookstream.io/v1/replay \ -H "X-API-Key: $HOOKSTREAM_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "destination_id": "dest_xyz", "from": "2026-03-01T00:00:00Z", "to": "2026-03-02T00:00:00Z", "source_id": "src_abc", "rate_limit": 10, "max_events": 1000 }'
destination_id, from, and to are required. source_id is optional. rate_limit defaults to 10 events/second (max 100). max_events defaults to 1000 (max 10000).
Poll for progress
Use the job_id returned from the create call:
bashcurl https://hookstream.io/v1/replay/job_abc \ -H "X-API-Key: $HOOKSTREAM_API_KEY"
Response fields: status (running or completed), total, processed, succeeded, failed, started_at, completed_at.
Rate limiting
Replay delivers up to rate_limit 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 rate_limit based on the destination's own limits. If your API allows 100 req/s but you share the quota with production traffic, set rate_limit to something like 10 or 20 so there's headroom.
Best practices
Dry-run to a test destination
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.
Start with a small window
Replay an hour before replaying a day, and a day before replaying a month.
Watch the circuit breaker
Keep the destination detail page open. If the breaker trips during replay, stop and investigate — your rate limit is probably too high.
Expect events in chronological order
Replay walks the events table by received_at, oldest first. Downstream consumers should tolerate a delayed-but-in-order stream.