MeetOne retries failed webhook deliveries automatically, so your endpoint needs to handle both retries and the occasional duplicate delivery.

Expected response

Respond within the 30-second timeout with a 2xx status code to acknowledge a delivery.

Response Result
2xx Delivery marked as delivered. Not retried.
4xx Delivery marked as failed. Not retried — use this to permanently reject invalid requests.
5xx Delivery marked as failed. Retried with backoff.
Timeout (30s) Delivery marked as failed. Retried with backoff.
Network error (DNS failure, connection refused, etc.) Delivery marked as failed. Retried with backoff.
TLS error (e.g. expired certificate) Delivery marked as failed. Retried with backoff — the issue may resolve within the retry window.
Refused destination URL (private/loopback address, or a non-http(s) scheme) Delivery marked as failed. Not retried.

Retry policy

Failed deliveries are retried up to 10 times with exponential backoff and jitter. Each retry is scheduled roughly (attempt ** 5) seconds + jitter (30s–10m) after the previous attempt, so retries span from seconds after the first failure up to several hours later for the final attempts. After the 10th failed attempt, the delivery is recorded as permanently failed and is not retried further.

Because retries can span hours, don't assume a delivery you haven't received yet has been abandoned — check the delivery's status in the admin under Webhook Events before concluding it failed for good.

What's never retried

Two categories of failure are treated as permanent and are not retried:

  • 4xx responses. MeetOne assumes you deliberately rejected the request (bad signature, unrecognized payload, etc.) and won't keep sending it.
  • Refused destination URLs. If your endpoint's hostname resolves to a private, loopback, link-local, or otherwise non-public address, or the URL isn't http(s), the delivery is rejected outright as unsafe and not attempted again. This is re-checked at delivery time, not just when you save the endpoint, so a hostname that starts pointing at a private address after the fact will also be blocked.

If you want MeetOne to stop retrying an event you can't process, return a 4xx rather than ignoring the request or timing out.

Using X-Request-ID as an idempotency key

Every delivery carries an X-Request-ID header — a UUID generated once, the first time MeetOne records that delivery. The value stays the same across every retry of that delivery, so it's safe to use as an idempotency key: store the IDs you've already processed, and skip any delivery whose ID you've seen before.

X-Request-ID: 8f14e45f-ceea-467e-b0fd-d0b3f1e6f39c

Duplicate deliveries of the same event can also occur under rare conditions, independent of retries. If you need stronger guarantees than X-Request-ID alone provides, also key off a natural identifier in the payload (e.g. a room token plus event type).

Respond quickly, process asynchronously

Your endpoint should acknowledge a delivery as fast as possible. Do the expensive part of your integration — database writes, calls to other services, notifications — after responding, not before. A handler that blocks on downstream calls risks hitting the 30-second timeout, which MeetOne treats as a failure and retries.

A typical pattern:

  1. Verify the signature (see Verifying webhook signatures).
  2. Check X-Request-ID against deliveries you've already processed; skip if seen.
  3. Enqueue the payload for background processing.
  4. Return 200 immediately.

Questions? Contact us at support@meetone.io.