> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.formantai.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.formantai.com/_mcp/server.

# Delivery & Retries

> Understand webhook timeout, retry, and idempotency behavior.

FormantAI retries webhook delivery for transient failures.

## Success criteria

Your endpoint should return any `2xx` response within 10 seconds.

```http
HTTP/1.1 204 No Content
```

## Retry schedule

| Attempt | Timing            |
| ------- | ----------------- |
| 1       | Immediate         |
| 2       | 30 seconds later  |
| 3       | 300 seconds later |

## Retry conditions

FormantAI retries:

* Network errors
* Timeouts
* HTTP `429`
* HTTP `5xx`

FormantAI does not retry most `4xx` responses because they usually mean the request was rejected permanently.

## Timeout

Each delivery attempt has a 10 second timeout. If your workflow needs more time, store the event and process it asynchronously.

## Idempotency

Webhook deliveries can be retried. Your endpoint must be idempotent.

Use `event_id` as the primary dedupe key.

```javascript
app.post("/webhooks/formant", async (req, res) => {
  const event = req.body;
  const inserted = await insertWebhookEventIfNew(event.event_id, event);

  if (!inserted) {
    return res.status(204).send();
  }

  await enqueueWebhookWork(event.event_id);
  res.status(204).send();
});
```

## Delivery metadata

Delivery attempts are stored on the conversation metadata for debugging. Use the Conversations API and `trace_id` when investigating missed downstream updates.

## Receiver checklist

* Verify the HMAC signature.
* Persist the raw event.
* Dedupe by `event_id`.
* Return quickly.
* Process business logic in a queue.
* Monitor failure rates and latency.