> For the complete documentation index, see [llms.txt](https://docs.insurgrid.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.insurgrid.com/guides/idempotency.md).

# Idempotency keys

Networks are unreliable. If a request to create or publish a form times out, you don't actually know whether it succeeded on InsurGrid's side before the connection dropped — so the safe move, retrying, risks doing the same operation twice. An idempotency key is how you retry safely: it tells InsurGrid "if you've already done this exact operation, just give me the same result again — don't do it a second time."

> **New term — idempotency key:** a unique value you generate and attach to a single write request. If InsurGrid sees the same key again, it returns the result of the original request instead of repeating the operation.

This is the write-side counterpart to [Delivery & de-duplication](/guides/delivery-dedup.md), which covers the same problem from the other direction — duplicate webhook *deliveries* landing on your server.

## When to send one

Send an `Idempotency-Key` header on every write call: creating a form, publishing it, archiving it — anything that changes state. Reads (`GET`) don't need one; they don't have a "did this already happen" problem.

## What the value should be

A **UUIDv4** — a randomly generated 128-bit identifier, formatted as a string. It just needs to be unique per operation; you don't need to coordinate it with InsurGrid ahead of time, and you don't need to store a registry of used keys — you generate a fresh one right before each write.

> **New term — UUIDv4:** a universally unique identifier built from random bits (version 4 of the UUID spec), typically written as 32 hex characters split by dashes, e.g. `3f1a9c7e-2b44-4e8a-9f21-6c0b8d5e4a12`. The chance of two independently generated UUIDv4s colliding is negligible, so it's a safe default for "give me something unique."

## Using it · *server*

**Node:**

```js
const { randomUUID } = require("crypto");

async function createForm(payload) {
  const res = await fetch("https://api.insurgrid.com/v2/forms", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.INSURGRID_API_TOKEN}`,
      "Content-Type": "application/json",
      "Idempotency-Key": randomUUID(),   // fresh key for this operation
    },
    body: JSON.stringify(payload),
  });
  return res.json();
}
```

**Python:**

```python
import os, uuid, requests

def create_form(payload: dict) -> dict:
    res = requests.post(
        "https://api.insurgrid.com/v2/forms",
        headers={
            "Authorization": f"Bearer {os.environ['INSURGRID_API_TOKEN']}",
            "Idempotency-Key": str(uuid.uuid4()),   # fresh key for this operation
        },
        json=payload,
    )
    return res.json()
```

## What happens on retry

| Situation                                                                      | What InsurGrid does                                              |
| ------------------------------------------------------------------------------ | ---------------------------------------------------------------- |
| First request with a given key                                                 | Performs the operation normally, returns the result.             |
| Same key sent again, same operation (e.g. your client retried after a timeout) | Returns the **original** result — the operation is not repeated. |
| A **new** key on a distinct operation (e.g. creating a second, different form) | Performs it as a new operation.                                  |

## The 24-hour window

A key is honored for **24 hours** from the original request. Retry with the same key within that window and you get the original result back safely. After 24 hours, the key is no longer recognized, and a request using it is treated as new.

## One key per operation

Generate a **fresh key for every distinct write** — don't reuse one key across unrelated create/publish/archive calls, or InsurGrid will treat the second one as a retry of the first and hand you back the first result instead of doing the second operation. Reuse the *same* key only when you're genuinely retrying the *same* attempt (your original request failed or timed out and you're trying again with identical payload).

A simple rule of thumb: generate the key at the same point in your code where you build the request, immediately before sending it — never earlier, and never share one across a loop of otherwise-different calls.

## Related

* [Delivery & de-duplication](/guides/delivery-dedup.md)
* [Authentication & tokens](/guides/authentication.md)
* [Register your endpoint & choose an auth type](/guides/register-endpoint-auth-types.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.insurgrid.com/guides/idempotency.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
