Network requests can fail anywhere — connection reset, timeout, gateway 502, ambiguous 5xx. To make retries safe on write endpoints without creating duplicate resources, send anDocumentation Index
Fetch the complete documentation index at: https://docs.lasscyber.com/llms.txt
Use this file to discover all available pages before exploring further.
Idempotency-Key
header on the original request and on every retry.
How it works
When the API receives a request with anIdempotency-Key:
- First time with that key + tenant: process the request normally
and cache the response keyed off
(tenant_id, idempotency_key, body_hash)for 24 hours. - Same key + same body: return the cached response. The request is not processed again.
- Same key + different body: return
idempotency_conflict(HTTP 409) so you know the key was reused with mismatched intent.
Where to use it
UseIdempotency-Key on every write call:
POST /api/v1/policies/POST /api/v1/yara-rules/POST /api/v1/yara-policies/POST /api/v1/sdp/policies/POST /api/v1/safety-policies/POST /api/v1/api-keys/POST /api/v1/tenants/POST /api/v1/billing/portal-sessionPOST /api/v1/billing/create-checkout-sessionPOST /api/v1/support/tickets
GET) are naturally idempotent and ignore the header.
The hero POST /api/v1/analyze/ deliberately does not dedupe on
Idempotency-Key. Each analysis is a fresh decision; you almost never
want a cached one. If you need dedupe at your application layer
(e.g. retrying the same prompt should not run analyzers twice in 100
ms), do it in your own caller.
Generating a key
A UUID v4 is the simplest choice. Both SDKs accept any string; pick something with enough entropy that you will not accidentally collide with another caller in your tenant.SDK helpers
Python
The Python SDK auto-generates an idempotency key on every retried write when you do not pass one explicitly. To control it yourself:TypeScript
Conflicts
If you reuse a key with a different body, the API returns:Cache lifetime
- 24 hours from the first request. After that the key is forgotten and a new request with the same key is treated as a fresh write.
- Cache entries are not visible across tenants.
- Cache entries survive Cloud Run autoscale events (the cache is Postgres-backed).
Common pitfalls
- Generating the key inside the retry loop. A fresh key per retry is a different request as far as Agnes is concerned. Generate the key once outside the retry loop.
- Using the same key for different operations. A key scopes to the
full request body, so different operations naturally have different
bodies — but using
"create-policy-1"for both a policy create and a rule create is asking for confusion. Prefer UUIDs. - Sending an empty key. The API ignores empty / whitespace-only values. To use idempotency, send a real value.
Next
- Errors →
idempotency_conflict - Rate limits — the other reason a retry might come back differently.