Docs

Idempotency

Last updated: 2026-10-033 min read

The network sometimes drops a request and you cannot tell whether it arrived. To retry a POST without running (and paying for) the work twice, send an Idempotency-Key header - a unique value per logical operation. A UUID works well.

curl -X POST https://developers.grem.capital/api/v1/valuation/express \
  -H "Authorization: Bearer gsk_live_xxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3f1c8a90-1e2b-4c77-9a10-2b6d0f9e4a11" \
  -d '{"propertyCategory":"apartment","addressText":"Torstraße 12, Berlin","totalArea":64}'

How it works

  • The first request with a key runs normally; its successful response is stored.
  • A retry with the same key returns the stored response: the tool does not run again and is not charged again.
  • While the first request is still running, a second request with the same key gets 409 with title: idempotency_conflict. Wait and retry with the same key.
  • If the first request failed, the key is released - a retry with it runs anew. A request that never reached the service (connection refused) releases the key too.
  • After a timeout (502 provider_error) of a tool, a listing create or a lead create the key stays reserved for 15 minutes, so a retry cannot run the work twice. Check the result before repeating: GET /works for tools, GET /objects and GET /leads for creates. Photo enhancement, site and draft results are not kept in GET /works - check them in the cabinet or among your listings. A repeat after the 15 minutes runs the work (and its charge) again.
  • The express valuation is the exception: after a timeout the key is released - repeat it with the same key at once, a finished valuation is returned free of charge: neither the valuation nor the API call is charged again.
  • A key is remembered for 24 hours and belongs to your API key and the operation - the method plus the actual path: equal values under different API keys, the same key on another tool, or POST /objects/property and POST /objects/rental are different requests.

The retry body is not compared with the first request. Send a different request with an already used key and you get the answer to the first one. Use a new key for every new operation.

Where it applies

Request
POST /valuation/express and every tool (POST /valuation/report, POST /content/generate, POST /flyer/create and so on)yes
POST /objects/{kind} - create a listingyes
POST /leads - create a leadyes
POST /match/leads/{id}/events - a Swipe Match eventyes; the key must match ^[A-Za-z0-9_.:-]{8,128}$, otherwise it is ignored
POST /uploads, POST /chat/messages, POST /valuation/review/jobs/{id}/confirmno (chat uses clientMessageId for this)

In the SDK the key is the last argument of a method.

Was this article helpful?