Skip to main content
Webhooks turn Reader into an event source for your own systems. The typical shape: you start a job, Reader runs it, your endpoint gets a POST when it’s done, and you trigger whatever comes next: write to a database, enqueue a reranking job, notify a user, invalidate a cache.

The end-to-end pattern

The key insight: your job creator and your job consumer can be different services, or even the same service across different process lifetimes. As long as the webhook has somewhere to land, the work gets done.

Creating the webhook

Do this once, ahead of time. Webhooks persist until you delete them.

Kicking off a job

You track the job ID in your own database so when the webhook fires, you know which piece of work to resume.

Receiving the webhook

What to do in handleJobComplete

Don’t do slow work inside the webhook handler. Reader retries if you don’t respond within 10 seconds. Instead, enqueue the slow work and return 200 immediately.
The background worker fetches the full results via GET /v1/jobs/{id} (paginated, so don’t miss pages beyond the first one) and does whatever your pipeline needs: index into a vector store, run LLM extraction, persist to a database.

Idempotency is non-negotiable

Reader may deliver the same event twice. If your endpoint times out but Reader eventually succeeds, it will retry, and the original delivery might still have been received. Always dedupe by X-Reader-Delivery, which is a unique UUID per delivery attempt.

Next