Skip to main content
Off the Hook delivers webhooks as HTTP POST requests with JSON bodies to the destination URL you configure on a subscription. Your endpoint must be publicly reachable over HTTPS — Off the Hook validates the URL at subscription creation time and rejects any address that resolves to a private IP range.

Responding correctly

Return an HTTP 2xx status code within the timeout window. If your endpoint returns 5xx, 408, 429, or the connection fails entirely, Off the Hook treats the delivery as failed and queues a retry.

Retry schedule

Off the Hook retries a failed delivery up to 7 times with the following delays between attempts: After all 7 attempts are exhausted, the event status moves to failed. You can manually re-queue it using the retry endpoint.

Deduplication

Because retried deliveries re-send the same webhook-id header, you should treat that value as an idempotency key. Store the IDs of events you have already processed and skip any delivery that arrives with a duplicate ID.
Return 2xx even for duplicates — returning an error causes another retry.

SSRF protection

Off the Hook validates your destination URL when you create or update a subscription. URLs that resolve to private IP ranges — including 10.x.x.x, 172.16.x.x172.31.x.x, 192.168.x.x, and 127.x.x.x — are rejected with an ssrf_blocked error. The same check runs at delivery time to defend against DNS rebinding.
Use https://webhook.site to get a free public HTTPS URL during development. It displays every incoming request in real time, making it easy to inspect headers and payloads without running a local server.

Handler examples

The examples below show minimal handlers that verify the signature and deduplicate events. See Verify Webhook Signatures for the full signature verification guide.