Idempotency
A network failure after you sent a create leaves you not knowing whether the job exists. Send an Idempotency-Key header with POST /v1/conversions and retrying is safe: the retry returns the first job and never burns a second concurrency slot or a second slice of your minutes.
Using it
curl -X POST "https://api.esfera.audio/v1/conversions" \
-H "Authorization: Bearer $ESFERA_API_KEY" \
-H "Idempotency-Key: 7d6f2b1c-0a3e-4c58-9b41-2f8e5a6d9c07" \
-H "Content-Type: application/json" \
-d '{"filename":"master.wav","durationSec":1800,"preset":"esfera"}'Any unique string per logical create. Reuse on retry. The key is a string of at most 255 characters. Use one fresh value per logical create, such as a UUID, and reuse it only to retry that same create.
What a replay returns
The first call answers 201 with the upload URL. A repeat with the same key answers 200 with the same job and duplicate: true, and no new upload URL. The first response is the only one that carries it.
{ "id": "3f2b8c1e-5a47-4d0e-9c1a-7b6e2d8f4a10", "duplicate": true }If the first call's response was lost, you do not have the upload URL. Read the conversion with GET /v1/conversions/{id} and, when it is still in uploading, open a multipart upload to get fresh part URLs.
Scope
Keys are matched within your account. The same key on two different accounts does not collide.
The SDK and the CLI
conversions.create() in the SDK always sends an Idempotency-Key (a random UUID unless you pass idempotencyKey) and retries on 429, 5xx and network errors. A POST without a key is never retried automatically, because retrying it could double-spend.
Guide
Idempotency in practice covers what the server compares, what it does not, and how to recover when the first response was lost.
Other methods
GET and DELETE are idempotent by nature and can be retried freely. The remaining POST calls (analyze, start, the multipart calls, webhook replay) are not keyed: a repeat after success answers already-started or replay-in-flight instead of repeating the work.