Documentation Index
Fetch the complete documentation index at: https://docs.soundpiece.co/llms.txt
Use this file to discover all available pages before exploring further.
Why two layers of errors?
Soundpiece returns two distinct kinds of error, and they mean different things:
- HTTP-level errors (
4xx / 5xx) — your request was rejected. The work never started.
- Operation-level errors — your request was accepted (you got
200 OK and an operation id), but the operation itself failed during processing. You poll the operation just like any other and find status: "failed" with a populated error object.
This split is deliberate: the request layer is about whether you talked to us correctly, the operation layer is about whether the work succeeded. They have different causes, different retry rules, and different recovery strategies. A successful HTTP response doesn’t mean the operation succeeded — you still need to check status.
HTTP errors
The two rules of thumb:
4xx — fix your request. Something in what you sent doesn’t work. Retrying with the same body won’t help; you need to change the request.
5xx — something unexpected happened on our side. You can retry. PUT endpoints are idempotent on idempotency_key (see Async operations), so retrying with the same key is safe — you won’t double-create work.
Response shape
HTTP errors return a JSON body with a detail field. For most errors it’s a plain string:
{
"detail": "Missing or invalid Authorization header"
}
For request-body validation errors (422), detail is a list of per-field entries:
{
"detail": [
{
"loc": ["body", "lyrics"],
"msg": "String should have at least 1 character",
"type": "string_too_short"
},
{
"loc": ["body", "idempotency_key"],
"msg": "Field required",
"type": "missing"
}
]
}
| Field | Meaning |
|---|
loc | Path to the offending field — e.g. ["body", "lyrics"] for a top-level body field, or ["body", "reference", "url"] for a nested one. |
msg | Human-readable description of the problem. |
type | Stable machine-readable code (e.g. missing, string_too_short, url_parsing). |
Status reference
| Status | When you’ll see it | Recommended handling |
|---|
400 Bad Request | Malformed JSON or unparseable request body. | Fix the request. |
401 Unauthorized | Missing, invalid, or revoked API key (and, on Enterprise plans with IP allowlisting, a request from a non-allowlisted IP). | Check your Authorization header and source IP. Don’t retry. |
404 Not Found | Only returned when the endpoint URL itself doesn’t exist — e.g. a typo in the path. Entity-not-found (operation id, etc.) is reported as a 422 validation error, not a 404. | Check the URL. |
405 Method Not Allowed | Wrong HTTP verb on a known route (e.g. POST on a PUT-only endpoint). | Use the documented verb. |
410 Gone | The endpoint existed on this API version but has been sunset. The detail field points to the replacement. | Migrate to the replacement endpoint. See versioning. |
422 Unprocessable Entity | Request body validation failed — missing field, wrong type, out-of-range value, invalid URL, or a referenced entity (operation id etc.) wasn’t found. | Read detail to see which field is bad. |
429 Too Many Requests | You’ve hit your account’s request rate limit. | Read the Retry-After header (seconds) and back off. See rate limits. |
5xx | Transient server-side issue. | Retry safely — PUT requests are idempotent if you supply the same idempotency_key. Use exponential backoff. |
Operation-level failures
When an operation fails, the response looks like this:
{
"song": {
"id": "op_01h7k...",
"status": "failed",
"error": {
"code": "tos_violation",
"message": "The provided lyrics were rejected by our content policy."
},
...
}
}
error.code is a stable machine-readable identifier — safe to branch on. error.message is a human-readable description suitable for surfacing to your end-users.
Not every code applies to every endpoint. The sections below group codes by which endpoints can return them.
Codes returned by all endpoints
| Code | Meaning | Recommended handling |
|---|
internal_error | Generic failure with no more specific classification available. | Re-submit with the same idempotency_key. If it persists, contact support. |
generation_timeout | The operation took longer than our hard timeout to complete. | Re-submit. Persistent timeouts are worth raising with support. |
quota_exceeded | Your account is out of monthly capacity. | Top up your account or wait for the next billing cycle. |
Codes for endpoints with a source or reference
(applies to adapt.separate_stems, adapt.auto_cut_down, create.remix_song, create.remix_instrumental, and the reference variant of create.new_song / create.new_instrumental)
| Code | Meaning |
|---|
source_unreachable | We couldn’t fetch the URL — DNS failure, connection refused, TLS error, 4xx/5xx from the host. |
source_format_unsupported | The file at the URL is not a supported audio format (we accept wav, mp3, flac). |
source_too_short | The fetched audio is too short for this operation (typically under 10 seconds). |
source_too_long | The fetched audio exceeds the maximum length for this operation. |
Codes for generation endpoints
(applies to create.new_song, create.new_instrumental, create.new_sample, create.new_fx, create.remix_song, create.remix_instrumental)
| Code | Meaning |
|---|
tos_violation | The lyrics, prompt, or reference were rejected by our content policy. |
Why retries don’t risk double-billing
PUT endpoints are idempotent on idempotency_key. The same key always returns the same operation, regardless of how many times you retry. This means:
5xx HTTP responses are safely retryable — retry with the same key and you’ll either get a fresh attempt or the existing successful result.
429 is retryable — back off using Retry-After, then send the same key again.
4xx other than 429 indicate a bad request that won’t get better; fix the request before retrying.
You will never accidentally create two operations from one logical request, no matter how many times the network drops between you and us.
The idempotency_key is also echoed on every response and webhook payload so you can correlate work against your own records without a separate request-id-to-state map.
Reporting persistent issues
If you receive internal_error (operation-level) or 5xx (HTTP-level) that persists across retries, please contact business@soundpiece.co.uk with:
- The endpoint called.
- The operation
id if one was returned.
- The
idempotency_key you sent.
- The approximate timestamp.
- Any
error.code / error.message from the response body.