Skip to content
DUETA
Docs

Errors & limits

Every status the API answers with, what it means, and the ceilings it enforces.

On this page

The error body

Every refusal is JSON with a detail: one sentence written for a person, or, on a 422, a list that names the offending field. Do not parse the sentence; branch on the status.

json
// Every refusal: one sentence a person can act on.
{ "detail": "separation takes exactly 1 audio file (got 2)" }

// A JSON body that failed schema validation (422): one entry per field.
{ "detail": [ { "type": "value_error", "loc": ["body", "email"],
                "msg": "value is not a valid email address: An email address must have an @-sign." } ] }

Status codes

StatusMeaningWhat to do
400The request reached the endpoint but could not be turned into an upload or a job: a bad filename, the wrong number of inputs, a malformed Content-Range, audio that will not decode, is under 0.5 s, or is digital silence, a total duration over the per-job cap, Dominant inputs that are not the same take, or a used or expired password-reset link.Read detail; it names the field or the file. Do not retry unchanged.
401No credential, a malformed one, a wrong password, or a key that has been revoked or rotated away.Re-issue the key. A rotated key stops working the moment its replacement is returned.
402Not enough credit to cover the job, checked before it is queued. Uploads are never charged, so only job creation answers this.Top up and create the job again from the same upload ids: nothing was charged and the uploads are untouched. POST /v1/jobs/quote answers sufficient_credit before you commit.
403The account is disabled.Contact support. No request from a disabled account succeeds.
404No upload, job, key, or stem with that name under your account; a share token that is unknown, revoked, or expired; or a result that is not available yet or has been pruned.Ids are scoped to the owning account. Take stem names from result.stems[].name and upload ids from the create response. Shares never say why a token failed.
409The request is out of order. Upload content: the piece did not start at bytes_received, or the upload is already complete. Delete upload: a job still uses it. Job creation: an input is not ready, or the account's email is unverified. Cancel: the job is already terminal. Share: the job has not succeeded. Signup: the email is registered. Key rotate: the key is revoked.For an offset mismatch, detail names the byte to send from. For a cancel on a finished job, treat it as success. For an unverified email, click the link or call /v1/auth/verify/resend.
410The upload expired. An unused upload is swept with its bytes 24 hours after creation.Create a new upload and send the file again. A job hardlinks its inputs, so expiry never takes a finished job's audio away.
413The body exceeded the 200 MB per-file cap. A declared size_bytes over the cap is refused before a byte moves; a body that grows past it is refused mid-stream.Split or shorten the input. The upload is left failed; sending again from byte 0 reopens it.
415The file is video (.mp4, .mov, .mkv, .webm, .avi, .m4v by name, or a picture track found by the probe).Export the audio track (M4A, WAV, MP3) and upload that.
422A JSON body or query failed schema validation, or ?format= on a stem download is not wav or flac.detail is an array of {loc, msg, type}; loc points at the offending field.
429A rate limit, the ceiling on jobs in progress, or the ceiling on recent unbilled jobs.Wait Retry-After seconds. For the in-progress ceiling, retry when one of your jobs finishes rather than on a timer.
501Google sign-in isn't available yet on this deployment.Use email and password.
502The verification or reset email could not be handed to the mailer.Retry in a minute; the account itself exists.
503A feature is closed rather than broken: card payments are not available yet (topup, checkout), password reset is not enabled, FLAC transcoding is unavailable for a track, or the job queue could not be reached.Payments and reset stay 503 until the feature ships; surface it and stop. For FLAC, download the WAV. For the queue, retry with backoff.
504A FLAC transcode took too long.Retry, or download the WAV.
5xxA fault on our side.Retry with exponential backoff. A failed job releases its hold and is never charged.

Rate limits

Limited routes answer with X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (whole seconds from now). A 429 adds Retry-After in the same unit. The two per-account ceilings send only Retry-After, as a poll interval rather than a prediction.

ScopeLimitKeyed onNote
POST /v1/auth/signup5 / minuteIPSlows bulk account creation for the signup credit.
POST /v1/auth/login10 / minuteIPSlows password guessing.
POST /v1/contact3 / minuteIPKeeps the contact form from relaying spam.
GET /v1/shares/{token}60 / minuteIPMakes token guessing pointless.
GET /v1/shares/{token}/stems, /original240 / minuteIPEnough for a player seeking; not for a scraper.
POST /v1/uploads, POST /v1/jobs/*20 / minuteaccountUploads and job submissions share one budget.
POST /v1/jobs/{id}/share30 / minuteaccount
Jobs in progress5 at onceaccountQueued or running. 429 with Retry-After until one finishes.
Unbilled jobs20 / houraccountJobs that failed or were canceled without a charge. 429 until the window rolls.

Limits & retention

LimitValue
FormatsWAV, AIFF, FLAC, MP3, M4A / AAC, OGG / Opus, WMA, CAF, or AMR. Video refused.
File size200 MB per file.
Duration per fileAt least 0.5 s, not digital silence.
Duration per jobAll inputs added together, at most 2 hours. The quote says the exact cap.
Inputs per jobDuplex 1. Dominant 2 to 10, longest at most 2× the shortest.
Unused uploadSwept 24 hours after creation. Making a job from it extends it.
Results and inputsKept 7 days after the job finishes. Shares cannot outlive them.
Session token7 days. API keys do not expire.
Verification link24 hours.

Every figure above is also stated where it applies: the quote, the upload's expires_at, the share's expires_at. Prefer the value the API hands back over a number copied from this page. Routes are listed in the API reference.