Concepts

Errors & limits

Errors are predictable JSON. Every job also reports how much it cost in credits_charged.

Error shape

Every failure comes with success: false and an error object with a stable code (for your code to branch on) and a human-readable message:

json
{
  "success": false,
  "error": {
    "code": "insufficient_credits",
    "message": "Not enough credits."
  }
}

Common codes

HTTPcodeWhat happened
401invalid_api_keyKey missing, malformed, invalid, or revoked.
403api_disabledAPI disabled globally, or your account isn't in the beta / has no active plan.
400invalid_requestInvalid parameters (missing field, value outside the enum/range).
400insufficient_creditsNot enough balance for the job. Check GET /balance and top up.
404not_foundModel slug or generation id doesn't exist.
429rate_limitRate limit exceeded. Wait and retry (backoff).

Job failures (async)

The codes above are request errors (returned on the POST /generations HTTP call). An accepted job can still fail during processing — it then comes back with status: "failed" and a stable error.code, one of:

codeWhat happened
insufficient_creditsAccount balance can't cover the job cost.
content_policy_violationPrompt or media rejected by content policy.
generation_timeoutThe job exceeded the maximum processing time.
rate_limitedToo many requests per minute during processing.
invalid_inputA required parameter is missing or outside the model's schema.
generation_failedGeneric processing failure.
copyright_conflictAudio rejected for copyright or a source conflict. Do not automatically retry the same file; use your own or authorized recording.

These are the same codes listed on every model page. Branch on code, never on message.

Rate limits

Generations are capped at roughly 20 per minute per account (uploads share the same cap). The rest of the /dev surface has a higher global limit. On a 429, apply exponential backoff before retrying.

Credits

credits_charged and credits_net report the net cost after refunds. credits_debited preserves the initial debit and credits_refunded reports the actual ledger refund. A refunded failure returns credits_debited: 29, credits_refunded: 29, credits_charged: 0, credits_net: 0. REST, MCP and webhooks share these fields.

Audio cover

Use suno-upload-and-cover with a public, authorized audio_url. Simple mode uses a transformation prompt (up to 500 characters). Custom mode requires custom_mode: true, style, title, and lyrics in lyrics or prompt for vocal output. Both instrumental and the legacy make_instrumental alias are accepted. Versions: V4, V4_5, V4_5ALL, V4_5PLUS, V5 and V5_5. Source audio must not exceed 8 minutes (1 minute for V4_5ALL). Personas require custom mode and V5/V5_5; output duration of 10–360 seconds requires custom mode and V5_5. A technically valid request can still be rejected by content checks.

Each generation debits credits from the account balance. The cost is model/tool-specific and comes back in credits_charged on the completed job. Check your balance at any time:

bash
curl https://caranguejo.art/api/v1/dev/balance \
  -H "Authorization: Bearer $CK"
json
{ "data": { "credits": 4820 } }