> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rangler.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Retries and Duplicate Delivery

> Make Rangler integrations safe when API requests are retried or webhook events are delivered more than once.

API request idempotency and webhook duplicate handling solve different problems. Do not use the terms or identifiers interchangeably.

## Webhook duplicate delivery

Rangler webhook delivery is **at least once**. An event can arrive more than once after a timeout, a non-`2xx` response, or a manual redelivery.

Use the payload's top-level event `id` as the stable deduplication key for the logical Rangler event. `Webhook-Id` is a signed transport header; do not substitute it for the payload event `id` in business-processing records.

Your receiver should:

1. Verify the signature and timestamp against the raw request body.
2. Insert the payload event `id` into durable storage with a uniqueness constraint.
3. Persist the event payload as durable inbox work in the same transaction.
4. Return `2xx` after the event has been durably accepted.
5. Let a background worker process pending inbox records.

If the unique insert conflicts, acknowledge the delivery without repeating its business effects.

<Warning>
  An in-memory set or SDK in-memory store is suitable only for local examples and single-process tests. It loses state on restart and cannot coordinate multiple receiver instances. Use a database-backed inbox or another shared, durable store in production.
</Warning>

Do not mark an event complete before its business transaction succeeds. Track receipt and processing state separately so a worker can safely retry failed work.

## Check for missed events

Event feeds use the same event format as webhooks. Store each event `id` and skip it if you receive it again. This lets a scheduled check recover a missed webhook without applying the event twice.

## Write-request idempotency

Rangler supports `Idempotency-Key` only on endpoints that document it. Do not assume that sending the header makes every `POST` replay-safe.

### Connect link tokens

`POST /v1/connect/link-tokens` accepts an `Idempotency-Key` of up to 180 characters. Generate a unique value for one logical link-token request and reuse that value only when retrying the same request body.

Rangler scopes the key to the organization, API key, and environment:

* the same key and equivalent request return the original unexpired, unused link token
* the same key with a different request returns `409` with `idempotency_key_conflict`
* the same key after its link token expires or is used returns `409` with `idempotency_key_expired`

Do not use a permanent identifier such as a user ID as the key. A new logical link-token operation needs a new key.

### Other writes

When an endpoint does not document `Idempotency-Key` support:

* keep a stable operation ID in your own system
* after a timeout or transport failure, read the affected resource to determine whether the write completed
* treat a `409 Conflict` as a resource or state conflict unless the endpoint documentation says otherwise
* do not automatically repeat a non-idempotent create request when its outcome is unknown

## Identifier reference

| Identifier | Scope | Purpose |
| - | - | - |
| Payload `id` | Logical Rangler event | Durable webhook and event-feed deduplication |
| `Webhook-Id` | Signed webhook transport | Signature verification and delivery diagnostics |
| Your operation ID | Your application | Correlating and reconciling write attempts |
| `Idempotency-Key` | One documented write operation | Endpoint-specific request replay protection |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.