Deze referentie is alleen in het Engels. Naar het Nederlandse REST API-overzicht

Diese Referenz gibt es nur auf Englisch. Zur deutschen REST-API-Übersicht

Cette référence existe uniquement en anglais. Aller à la présentation de l'API REST en français

Esta referencia solo está en inglés. Ir a la introducción de la API REST en español

Idempotency

Idempotency

Send an Idempotency-Key with a POST, so that a retry after a lost response returns the first result instead of writing twice.

View as Markdown

A GET, PATCH or DELETE is safe to retry: the second attempt lands on the same record and repeats the same effect, or answers 404. With If-Match, a retried PATCH or DELETE whose first attempt went through can answer 412, because your own write changed the tag. Re-read the record before you decide it failed.

A POST is not safe to retry. When the response to a POST gets lost and you retry, you can create a second row.

An Idempotency-Key header closes that gap. Every POST accepts one.

In the examples, <your-url> is the address you sign in to plnnrly on, such as acme.plnnrly.com, or your organisation's own domain.

Send a key

Pick a new key for each write you mean to make once: a UUID or a ULID works. Store it with the work you are about to do, before you send the request. A retry must send the same key as the attempt whose answer you never saw, so a key you generate on the retry path protects nothing.

Terminal
curl -X POST "https://<your-url>/api/v2/worklogs" \
  -H "Authorization: Bearer <token>" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3f1c9a52-7d4e-4b8a-9c21-5e6f0a7b8d13" \
  -d '{
    "project_id": 12,
    "date": "2026-10-14",
    "minutes": 90,
    "description": "Pairing on the importer"
  }'

A key is at most 255 characters. Spaces around it are trimmed, and an empty key counts as no key. A longer key is 422 validation-failed, with an error for parameter Idempotency-Key and code max.

What a retry gets back

Retry with the same key and the same body, and you get the first response back: the same status and the same body, with its Content-Type, Location and ETag headers. One header is added:

HTTP
Idempotency-Replayed: true

The first, real write does not carry it. So Idempotency-Replayed tells you "this already happened" without comparing bodies. X-Request-Id is new on every replay, because each attempt is a request of its own.

How long and for whom a key counts

  • A stored response is kept for 24 hours. After that, the same key writes again.
  • Only successes are stored: responses below 400. After a 4xx or 5xx the key is free again, so you can correct the request and retry with the same key.
  • While the first request is still running, a retry with the same key answers 409 idempotency-key-in-flight with Retry-After: 1. That claim lasts at most 120 seconds.
  • A key belongs to one organisation and one token. The same key sent with another token is another key. For an app signed in with OAuth, the key belongs to the app and the user, so it survives a refresh of the access token.
  • A key is bound to the path and the JSON body it was first used with. The order of keys and the whitespace in the body do not matter. The same key with a different body, or on another path, is 409 idempotency-key-reused.

Where a key is required

These operations refuse to run without a key, because a lost 201 retried without one would report a failure, or write twice, for a write that had in fact succeeded:

OperationWhy
POST /worklogsA duplicate worklog counts the same hours twice.
POST /work-items/{work_item}/attachmentsA retry without a key fails on the spent upload ticket, although the file exists.
POST /drive-items/{drive_item}/filesThe same as for attachments.

Without a key, these answer 400 idempotency-key-required. Everywhere else the key is optional, and each operation page says which of the two it is.

When it goes wrong

StatusProblem typeCauseWhat to do
409idempotency-key-reusedThe key was used before with a different body or path.Use a new key for a new write.
409idempotency-key-in-flightThe first request with this key has not finished.Wait for Retry-After, then retry with the same key.
400idempotency-key-requiredThe operation requires a key and you sent none.Send one.

idempotency-key-in-flight means your retry overtook the first attempt, not that anything failed. Retry with the same key. A new key would create the duplicate the key exists to prevent.

Over MCP

Note:

AI clients write through the api_write tool, which neither requires nor honours an Idempotency-Key. A POST /worklogs needs no key there, and repeating a call writes again. See MCP tools.

Idempotency is not concurrency

An idempotency key stops a POST from being applied twice. It does not stop a PATCH from overwriting someone else's change: that is If-Match, a different header with a different failure. See Concurrency and ETags.