{"openapi":"3.1.0","info":{"title":"sunoapi2","version":"1.0.0","description":"Suno-AI music generation API. Generation is **always async**: submit returns `202 {job_id}`; poll `GET /api/jobs/{id}` or pass `callback_url` for an HMAC-signed webhook. Billed in **tokens, on success only** (a failed render is refunded). Every response carries `X-Request-Id`. An **MCP server** for AI agents (Claude, Cursor, …) is also available at `POST /mcp` (stateless Streamable HTTP; tools `generate_song` / `wait_for_song` / `check_song`) — same `X-API-Key`, same token billing."},"servers":[{"url":"https://s.serge.cc","description":"production"}],"security":[{"ApiKeyAuth":[]}],"tags":[{"name":"generation","description":"Create songs (async)"},{"name":"jobs","description":"Poll async jobs"},{"name":"utility","description":"Lyrics, clips, limits"}],"paths":{"/api/generate":{"post":{"tags":["generation"],"summary":"Generate a song from a prompt","description":"Simple mode: a text description. Returns 202 + a job_id. Costs 10 tokens (settled on success).","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateRequest"}}}},"responses":{"202":{"$ref":"#/components/responses/JobAccepted"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/InsufficientTokens"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/custom_generate":{"post":{"tags":["generation"],"summary":"Generate a song from your own lyrics + style","description":"Custom mode: supply `prompt` (your lyrics) plus `tags` (style) and `title`. Returns 202 + a job_id. Costs 10 tokens.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomGenerateRequest"}}}},"responses":{"202":{"$ref":"#/components/responses/JobAccepted"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/InsufficientTokens"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/jobs/{id}":{"get":{"tags":["jobs"],"summary":"Get job status + final clips","description":"Poll fallback for the webhook. When `status` is `complete`, `clips` carry stable cdn MP3 URLs.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Job state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"401":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/api/lyrics":{"post":{"tags":["utility"],"summary":"Generate song lyrics","description":"Synchronous. Returns lyrics text. Costs 2 tokens on success (refunded on failure).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string","description":"Theme / brief for the lyrics"}}}}}},"responses":{"200":{"description":"Lyrics","content":{"application/json":{"schema":{"type":"object","properties":{"lyrics":{"type":"object","additionalProperties":true}}}}}},"400":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/InsufficientTokens"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/clips":{"get":{"tags":["utility"],"summary":"Read clips by id","parameters":[{"name":"ids","in":"query","schema":{"type":"string"},"description":"Comma-separated clip ids"}],"responses":{"200":{"description":"Clips","content":{"application/json":{"schema":{"type":"object","properties":{"clips":{"type":"array","items":{"$ref":"#/components/schemas/Clip"}}}}}}},"401":{"$ref":"#/components/responses/Error"}}}},"/api/limits":{"get":{"tags":["utility"],"summary":"Account credit/limit snapshot","responses":{"200":{"description":"Limits","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"$ref":"#/components/responses/Error"}}}}},"webhooks":{"jobComplete":{"post":{"summary":"Delivered to your callback_url on terminal state","description":"Signed: `X-Webhook-Signature: sha256=<hmac>` over `<X-Webhook-Timestamp>.<body>` (key = your webhook secret, `whsec_…` — view/rotate it on the dashboard's API keys page). Retried 3× with backoff.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"job_id":{"type":"string"},"status":{"type":"string","enum":["complete","failed"]},"clips":{"type":"array","items":{"$ref":"#/components/schemas/Clip"}},"error":{"type":["string","null"]}}}}}},"responses":{"200":{"description":"Acknowledged (any 2xx)"}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Per-customer key, e.g. sk_live_…"}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"A retried submit with the same key returns the SAME job — no double charge."}},"schemas":{"GenerateRequest":{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string","description":"Free-text description of the song"},"make_instrumental":{"type":"boolean","default":false},"model":{"type":"string","enum":["v4.5","v5","v5.5"],"description":"Suno model version (default: account default)"},"callback_url":{"type":"string","format":"uri","description":"Public https URL for the completion webhook"}}},"CustomGenerateRequest":{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string","description":"Your lyrics"},"tags":{"type":"string","description":"Style / genre tags"},"title":{"type":"string"},"make_instrumental":{"type":"boolean","default":false},"model":{"type":"string","enum":["v4.5","v5","v5.5"],"description":"Suno model version (default: account default)"},"callback_url":{"type":"string","format":"uri"}}},"JobAccepted":{"type":"object","properties":{"job_id":{"type":"string"},"status":{"type":"string","example":"queued"},"status_url":{"type":"string","example":"/api/jobs/…"},"idempotent_replay":{"type":"boolean","description":"Present when an Idempotency-Key matched an existing job"}}},"Job":{"type":"object","properties":{"job_id":{"type":"string"},"status":{"type":"string","enum":["queued","processing","submitted","complete","failed"]},"clips":{"type":"array","items":{"$ref":"#/components/schemas/Clip"}},"error":{"type":["string","null"]},"created_at":{"type":"integer"},"updated_at":{"type":"integer"}}},"Clip":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"audio_url":{"type":"string","format":"uri"},"image_url":{"type":"string","format":"uri"},"title":{"type":"string"},"duration":{"type":"number"}}},"Error":{"type":"object","required":["code","detail"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"detail":{"type":"string"},"request_id":{"type":"string","description":"Echoed in the X-Request-Id header; quote it in support requests"}}}},"responses":{"JobAccepted":{"description":"Accepted — generation is async","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"Error":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InsufficientTokens":{"description":"402 — token balance too low (billed on success only)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"429 — per-key rate limit; honor Retry-After","headers":{"Retry-After":{"schema":{"type":"integer"}},"RateLimit-Limit":{"schema":{"type":"integer"}},"RateLimit-Remaining":{"schema":{"type":"integer"}},"RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}