Eridian

Idempotency

Idempotency-Key semantics for mutating inference and governance calls.

Send Idempotency-Key on any request that must not execute twice: inference, key creation, budget writes, webhook registration, template publish, and evidence export. Eridian stores the first successful response for 24 hours per project and key.

POST /v1/inference
Authorization: Bearer eridian_sk_...
Content-Type: application/json
Idempotency-Key: contract-summary-4821-v1
X-Eridian-Project: prj_legal_001

Keys must be 1 to 255 characters from [A-Za-z0-9._-]. Generate them in your application (UUID v4 or a deterministic workflow ID). Do not reuse a key across different request bodies.

Replay Behavior

ConditionResult
Same key, same body, first request in flightSecond caller waits up to 30s then receives the original response
Same key, same body, completeHTTP 200 with original eridian.inference.response and X-Eridian-Idempotent-Replay: true
Same key, different bodyHTTP 409 idempotency_conflict
Key expired (>24h)Treated as a new request

Cached replays do not increment usage, do not re-hit GPT or Gemini, and do not emit a second inference.completed webhook. The original X-Eridian-Request-Id is returned.

Scope

Idempotency is partitioned by project_id and API key ID. Two projects may use the same string without colliding.

Mutating Endpoints

MethodPathIdempotent with header
POST/v1/inferenceYes
POST/v1/keysYes
POST/v1/keys/{id}/rotateYes
PUT/v1/projects/{id}/governanceYes
POST/v1/webhooksYes
POST/v1/templates/{id}/publishYes
POST/v1/audit/exportsYes
GETanyNot required; GET is safe

Conflict Body

{
  "error": {
    "type": "eridian.error",
    "code": "idempotency_conflict",
    "message": "Idempotency-Key contract-summary-4821-v1 was already used with a different body.",
    "request_id": "axm_req_8f3a2b1c"
  }
}

Python

response = client.inference.create(
    model="auto",
    project_id="prj_legal_001",
    messages=[{"role": "user", "content": "Summarize this MSA."}],
    idempotency_key="contract-summary-4821-v1",
)

TypeScript

await client.inference.create({
  model: "auto",
  projectId: "prj_legal_001",
  messages: [{ role: "user", content: "Summarize this MSA." }],
  idempotencyKey: "contract-summary-4821-v1",
});

See Errors and Inference.

Production API credentials are issued with an institution workspace. Contact sales if you need access.