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

# Idempotency

> Learn how to generate valid idempotency keys, safely retry requests, avoid conflicts, and handle interrupted operations on MasterID.

MasterID requires an `Idempotency-Key` header on `POST /verifications` and `POST /collections`. A valid key ensures that retried requests do not create duplicate operations, even if the original call timed out or returned an error.

## When idempotency is required

| Endpoint | Method | Idempotency key required |
| - | - | - |
| `/verifications` | POST | Yes |
| `/collections` | POST | Yes |

`GET` requests are inherently safe and do not need an idempotency key.

## Key format

The `Idempotency-Key` header must satisfy this pattern:

```text theme={null}
^[A-Za-z0-9._:-]{8,100}$
```

* 8 to 100 characters
* Allowed characters: letters, digits, period, underscore, colon, hyphen

> [!WARNING]
>
> Keys outside this range or containing other characters return HTTP 400.

## Safe retry rule

Retry with the **same key** and **identical JSON body**. MasterID returns the saved outcome without starting a second operation.

Never change the request body under a used key. If you need different input, generate a new key.

## Conflicts (409)

If you reuse a key but change the request body, MasterID returns HTTP 409. Resolve this by either:

1. Sending the exact same body again (safe retry), or
2. Generating a new idempotency key (only if the change was intentional)

## Interrupted requests

If a `POST /verifications` or `POST /collections` call is interrupted (network timeout, connection reset), the operation may already be processing. Because the outcome is unknown, do not create a duplicate with a new key. Instead:

* Use the saved session ID or collection reference to poll for the result, or
* Contact support with the request ID if you have it

## Body size limit

The maximum JSON body is 20,000 characters. Requests exceeding this return HTTP 413.

## Generate and persist keys

Generate a unique key for every new operation and store it alongside the returned reference so you can retry safely.

```typescript idempotency.ts theme={null}
import { randomUUID } from "crypto";

function generateIdempotencyKey(): string {
  // UUID v4 is 36 characters and uses only allowed symbols
  return randomUUID();
}

async function submitVerification(payload: object) {
  const key = generateIdempotencyKey();

  // Persist key before calling the API so you can retry after a crash
  await db.save({ key, status: "pending", payload });

  const res = await fetch("https://masterid.me/api/public/v1/verifications", {
    method: "POST",
    headers: {
      "X-API-Key": process.env.MASTERID_API_KEY!,
      "X-API-Secret": process.env.MASTERID_API_SECRET!,
      "Content-Type": "application/json",
      "Idempotency-Key": key,
    },
    body: JSON.stringify(payload),
  });

  const body = await res.json();

  if (res.ok) {
    await db.update(key, {
      status: body.status === 202 ? "processing" : "completed",
      sessionId: body.data?.sessionId,
    });
  }

  return { res, body, key };
}

// Retry later using the same key and body
async function retryVerification(key: string) {
  const record = await db.find(key);
  if (!record) throw new Error("Unknown key");
  return submitVerificationWithKey(record.payload, key);
}

async function submitVerificationWithKey(payload: object, key: string) {
  const res = await fetch("https://masterid.me/api/public/v1/verifications", {
    method: "POST",
    headers: {
      "X-API-Key": process.env.MASTERID_API_KEY!,
      "X-API-Secret": process.env.MASTERID_API_SECRET!,
      "Content-Type": "application/json",
      "Idempotency-Key": key,
    },
    body: JSON.stringify(payload),
  });
  const body = await res.json();
  return { res, body, key };
}
```

```python idempotency.py theme={null}
import os
import uuid
import json
import requests

BASE_URL = "https://masterid.me/api/public/v1"


def generate_idempotency_key() -> str:
    # UUID4 is 36 characters and uses only allowed symbols
    return str(uuid.uuid4())


def submit_verification(payload: dict):
    key = generate_idempotency_key()

    # Persist key before calling the API so you can retry after a crash
    db.save({"key": key, "status": "pending", "payload": payload})

    headers = {
        "X-API-Key": os.environ["MASTERID_API_KEY"],
        "X-API-Secret": os.environ["MASTERID_API_SECRET"],
        "Content-Type": "application/json",
        "Idempotency-Key": key,
    }

    res = requests.post(
        f"{BASE_URL}/verifications",
        headers=headers,
        data=json.dumps(payload),
    )
    body = res.json() if res.text else {}

    if res.ok:
        db.update(
            key,
            {
                "status": "processing" if res.status_code == 202 else "completed",
                "session_id": body.get("data", {}).get("sessionId"),
            },
        )

    return res, body, key


def retry_verification(key: str):
    record = db.find(key)
    if not record:
        raise ValueError("Unknown key")
    return submit_verification_with_key(record["payload"], key)


def submit_verification_with_key(payload: dict, key: str):
    headers = {
        "X-API-Key": os.environ["MASTERID_API_KEY"],
        "X-API-Secret": os.environ["MASTERID_API_SECRET"],
        "Content-Type": "application/json",
        "Idempotency-Key": key,
    }
    res = requests.post(
        f"{BASE_URL}/verifications",
        headers=headers,
        data=json.dumps(payload),
    )
    body = res.json() if res.text else {}
    return res, body, key
```

> [!TIP]
>
> Persist the idempotency key before you send the request. If your server crashes mid-call, you can safely retry with the same key without creating duplicates.


## Related topics

- [Go-live checklist](https://docs.masterid.co.ug/guides/go-live-checklist.md)
- [Errors](https://docs.masterid.co.ug/concepts/errors.md)
- [Run a verification](https://docs.masterid.co.ug/guides/verifications.md)
- [API Overview](https://docs.masterid.co.ug/api-reference/overview.md)
- [POST /verifications](https://docs.masterid.co.ug/api-reference/verifications/create-verification.md)


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