Skip to content

Idempotency

Send an Idempotency-Key header with a POST so that a retry after a timeout or a dropped connection does not create a second questionnaire or start a second run. Use a new random value (a UUID is fine) for each logical operation, and the same value for its retries.

  • The key is 1–255 visible ASCII characters.
  • It is kept for 24 hours, per organization, caller and operation.
  • Same key, same request: Tradecraft does not run it again. It answers with the stored response and Idempotent-Replayed: true.
  • Same key, different request (another body, file or query): 409 IDEMPOTENCY_CONFLICT.
  • Same key while the first request is still running: 409 IDEMPOTENCY_CONFLICT; retry after a second.
  • Only successful responses are stored. If the request failed, the key is released and you can retry with it.
Terminal window
curl -s -H "Authorization: Bearer $TOKEN" -H "Idempotency-Key: $(uuidgen)" \
-F file=@questionnaire.xlsx -F customerName="Acme Corp" \
https://api.tradecrafthub.ai/v1/assessments
import { readFile } from "node:fs/promises"
const key = crypto.randomUUID() // keep it for the retries of this upload
const form = new FormData()
form.set("file", new Blob([await readFile("questionnaire.xlsx")]), "questionnaire.xlsx")
form.set("customerName", "Acme Corp")
for (let attempt = 1; attempt <= 3; attempt++) {
const res = await fetch("https://api.tradecrafthub.ai/v1/assessments", {
method: "POST",
headers: { Authorization: `Bearer ${token}`, "Idempotency-Key": key },
body: form,
})
if (res.status === 201) {
const { data } = (await res.json()) as { data: { id: string; status: string } }
console.log(data.id, res.headers.get("Idempotent-Replayed") === "true" ? "(replayed)" : "")
break
}
if (res.status !== 409 && res.status < 500) throw new Error(`${res.status}`)
await new Promise((r) => setTimeout(r, 1000 * attempt))
}

Without the header these operations answer 400 VALIDATION_ERROR:

It is optional, and works the same way, on:

Privacy preference center

When you visit tradecrafthub.ai, we store or read a small number of cookies in your browser. Strictly necessary cookies make the website and the Tradecraft app work. Analytics cookies are used only if you allow them. Open a category to learn more, and see our privacy policy for how we handle the information you enter on this site.

Manage consent preferences

  • Always active