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.
// 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
| Status | Meaning | What to do |
|---|---|---|
| 400 | The 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. |
| 401 | No 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. |
| 402 | Not 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. |
| 403 | The account is disabled. | Contact support. No request from a disabled account succeeds. |
| 404 | No 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. |
| 409 | The 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. |
| 410 | The 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. |
| 413 | The 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. |
| 415 | The 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. |
| 422 | A 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. |
| 429 | A 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. |
| 501 | Google sign-in isn't available yet on this deployment. | Use email and password. |
| 502 | The verification or reset email could not be handed to the mailer. | Retry in a minute; the account itself exists. |
| 503 | A 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. |
| 504 | A FLAC transcode took too long. | Retry, or download the WAV. |
| 5xx | A 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.
| Scope | Limit | Keyed on | Note |
|---|---|---|---|
| POST /v1/auth/signup | 5 / minute | IP | Slows bulk account creation for the signup credit. |
| POST /v1/auth/login | 10 / minute | IP | Slows password guessing. |
| POST /v1/contact | 3 / minute | IP | Keeps the contact form from relaying spam. |
| GET /v1/shares/{token} | 60 / minute | IP | Makes token guessing pointless. |
| GET /v1/shares/{token}/stems, /original | 240 / minute | IP | Enough for a player seeking; not for a scraper. |
| POST /v1/uploads, POST /v1/jobs/* | 20 / minute | account | Uploads and job submissions share one budget. |
| POST /v1/jobs/{id}/share | 30 / minute | account | |
| Jobs in progress | 5 at once | account | Queued or running. 429 with Retry-After until one finishes. |
| Unbilled jobs | 20 / hour | account | Jobs that failed or were canceled without a charge. 429 until the window rolls. |
Limits & retention
| Limit | Value |
|---|---|
| Formats | WAV, AIFF, FLAC, MP3, M4A / AAC, OGG / Opus, WMA, CAF, or AMR. Video refused. |
| File size | 200 MB per file. |
| Duration per file | At least 0.5 s, not digital silence. |
| Duration per job | All inputs added together, at most 2 hours. The quote says the exact cap. |
| Inputs per job | Duplex 1. Dominant 2 to 10, longest at most 2× the shortest. |
| Unused upload | Swept 24 hours after creation. Making a job from it extends it. |
| Results and inputs | Kept 7 days after the job finishes. Shares cannot outlive them. |
| Session token | 7 days. API keys do not expire. |
| Verification link | 24 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.