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

# Idempotency-Key conventions

Creating a project with `POST /api/public/v1/projects` is an idempotent operation. Because connectors retry on network failures, timeouts and rate limits, the endpoint requires an `Idempotency-Key` header so a retried request cannot create a duplicate project.

## Sending the key

Send a fresh **UUID** in the `Idempotency-Key` header for each logical create. Reuse the **same** key when retrying that same create.

```bash
curl -X POST https://api.adaptria.locaria.com/api/public/v1/projects \
  -H "Api-key: lla_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Idempotency-Key: 3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Content-Type: application/json" \
  -d '{ "externalId": "crowdin-order-12345", "companyId": "...", "projectName": "...", "...": "..." }'
```

The header is **required** for this endpoint. A missing key returns `400` (`IDEMPOTENCY_KEY_REQUIRED`); a key that is not a valid UUID returns `400` (`IDEMPOTENCY_KEY_INVALID`).

## How retries behave

| Situation                            | Result                                                                                          |
| ------------------------------------ | ----------------------------------------------------------------------------------------------- |
| Same key, same request body          | The original response is replayed; no second project is created.                                |
| Same key, **different** request body | `409 Conflict` (`IDEMPOTENCY_KEY_CONFLICT`): the key is already in use for a different payload. |
| New key                              | Treated as a new create.                                                                        |

{% hint style="info" %}
The cached response is retained for a limited retention window, after which the key is forgotten. Reusing a UUID after that window will be treated as a new create, so always generate a fresh UUID per logical operation and only reuse it for retries of that same operation.
{% endhint %}

## Relationship to `externalId`

The create request body also carries an `externalId`, your own stable identifier (for example, a Crowdin order ID or ticket ID). This is unique per company: submitting a duplicate `externalId` for the same company returns `409 Conflict`. Use `externalId` as your business-level deduplication key and `Idempotency-Key` as your transport-level retry-safety key; together they ensure one external order maps to exactly one Adaptria project.
