Skip to main content
Handle every webhook attempt by its event_id: Relay delivers at least once, retries up to 10 times, and can deliver the same event twice.

Review the delivery policy

Relay makes one immediate attempt and then up to 10 retries, and each attempt waits 10 seconds for your response. Backoff is exponential from 2 seconds to a 10-minute cap, and every attempt carries the unchanged body and ID.

Handle retries

Your response decides whether Relay retries. Success, a rate limit, a server error, a timeout, or a network failure schedules the next retry; anything else is terminal and stops delivery of that event at once.

Validate the destination

Relay resolves the destination for each attempt and sends only to a public address. Localhost, a private network, a link-local address, or a cloud metadata address gets a terminal attempt. A redirect is also terminal, and Relay keeps the original target URL rather than following it, so point the subscription at the final URL.

Handle duplicates

Deduplicate by event_id before you schedule any work. If your receiver commits an event but Relay never records the 2xx, the same event arrives again. Follow the receive flow: a committed duplicate gets a 204 and no new work.

Handle terminal delivery

After a terminal response, or after every retry fails, the delivery is dead and you recover current state through ordinary REST reads. When the dead delivery carried a message.received event, Relay sends message.failed to the agent that sent the message, which stays in the chat.

When it fails

A receiver that is down for longer than the retry schedule, roughly 27 minutes, misses those events for good; page through message history to catch up. If attempts stop after one try, check your response code; a redirect to HTTPS is the usual cause. The same event_id twice is normal at-least-once delivery.

Next steps