Skip to content

Latest commit

 

History

History
190 lines (156 loc) · 7.64 KB

File metadata and controls

190 lines (156 loc) · 7.64 KB

Suno API Intelligence — Reverse-Engineered April 6, 2026

Auth

  • Base URL: https://studio-api-prod.suno.com
  • Auth: Clerk-based. Browser has Clerk session cookies → exchanges for JWT → JWT used as Authorization: Bearer <jwt>
  • Required headers:
    • authorization: Bearer <jwt>
    • device-id: <uuid> (from browser, persisted)
    • browser-token: {"token":"<base64({"timestamp":<ms>})>"} (dynamic, generated per-request)
    • origin: https://suno.com
    • referer: https://suno.com/
  • JWT lifetime: ~1 hour. Auto-refreshed by Clerk SDK in browser.
  • Clerk session ID: Found in JWT sid claim (e.g., session_eece6e4f36131cbcb12aeb)

Account Response

  • /api/billing/info/ returns the active plan, remaining credits, usage period, feature flags, model list, and model limits.
  • Do not commit live account-specific credit balances to this file; they drift quickly and are not useful as implementation evidence.

Models (from /api/billing/info/)

Display Name External Key Default Max Prompt Max Tags Max Neg Tags Max GPT Desc
v5.5 chirp-fenix YES 5000 1000 1000 500
v5 chirp-crow No 5000 1000 1000 500
v4.5+ chirp-bluejay No 5000 1000 1000 500
v4.5 chirp-auk No 5000 1000 1000 500
v4.5-all chirp-auk-turbo Free default 5000 1000 1000 500
v4 chirp-v4 No 3000 200 1000 500
v3.5 chirp-v3-5 No 3000 200 1000 500
v3 chirp-v3-0 No 1250 200 1000 500
v2 chirp-v2-xxl-alpha No 1250 200 1000 500

Remaster Models

Name Key
v5.5 (default) chirp-flounder
v5 chirp-carp
v4.5+ chirp-bass

Verified Endpoints

GET /api/billing/info/

Returns full account info, credits, plan, models, features, limits.

POST /api/generate/lyrics/

Request: {"prompt": "description of song"} Response: {"id": "<uuid>"} (async — poll for result)

GET /api/generate/lyrics/{id}

Response (when complete):

{
  "text": "[Verse 1]\n...\n[Chorus]\n...",
  "title": "Generated Title",
  "status": "complete",
  "error_message": "",
  "tags": ["style description auto-generated by Suno"]
}

POST /api/generate/v2-web/

Generate music. Payload shape captured from the current web route and represented by src/api/types.rs::GenerateRequest:

{
  "make_instrumental": false,
  "mv": "chirp-fenix",
  "prompt": "",
  "generation_type": "TEXT",
  "continue_at": null,
  "continue_clip_id": null,
  "metadata": {
    "web_client_pathname": "/create",
    "create_mode": "custom",
    "create_session_token": "<uuid>"
  },
  "token": "<captcha_token>",
  "tags": "pop, upbeat, synths",
  "title": "Summer Vibes",
  "negative_tags": "metal, heavy, dark"
}

IMPORTANT: Some accounts/flows require a fresh hCaptcha token field. The Rust CLI uses a piloted Chrome path when needed and also accepts --token for externally supplied solutions. Do not send a token_provider field: the v2-web endpoint 422s on the string (verified 2026; the CLI dropped it), so only token rides on the request body. Whether a captcha is needed at all is answered by the preflight below.

POST /api/c/check

Captcha preflight (verified live 2026-07-18 on both studio-api-prod.suno.com and studio-api.prod.suno.com). Request: {"ctype": "generation"} with Bearer JWT. Response: {"required": false, "captcha_version": 1}required is false for accounts above Suno's trust threshold, so the solver can be skipped entirely. When required is true, generating one song in the suno.com UI clears the challenge.

Two modes:

  1. Description mode (metadata.create_mode = "inspiration", prompt is the description) — Suno writes lyrics from description
  2. Custom mode (metadata.create_mode = "custom", prompt = lyrics, tags + title + negative_tags set)

Response: {"clips": [...], "metadata": {...}, "status": "..."}

POST /api/generate/concat/v2/

Concatenate/extend clips. {"clip_id": "<id>"}

POST /api/feed/v3

Request: {"cursor": "<opaque next_cursor from previous response>", "limit": 20, "filters": {...}} — omit cursor for the first page. Page numbers are NOT accepted. Response: {"clips": [...], "next_cursor": "...", "has_more": true}

Clip structure:

id, title, status, model_name, audio_url, audio_url_2, video_url,
image_url, image_large_url, created_at, play_count, upvote_count,
metadata: { tags, prompt, duration, avg_bpm, min_bpm, max_bpm,
            has_stem, is_mumble, is_remix, make_instrumental, type,
            can_remix, priority, stream, uses_latest_model }

GET /api/playlist/me

User's playlists. Returns {"num_total_results": N, "current_page": N, "playlists": [...]}

GET /api/trending/

Trending clips. Returns playlist-like structure.

POST /api/edit/stems/{clip_id}

Stem separation. Endpoint per gcui-art/paean-ai evidence; implemented in src/api/stems.rs. (An earlier capture guessed /api/generate/stems/ — wrong path.)

POST /api/cover/

Cover generation (not tested, likely needs POST).

POST /api/remaster/

Remaster with different model (not tested).

Voices / Persona Creation Flow (captured April 6, 2026)

Full pipeline for creating a Voice persona from audio:

Step 1: Upload initial voice sample

The S3 presigned upload happens first (not captured here), then:

POST /api/uploads/audio/{upload_id}/upload-finish/

Response: 200 OK (empty body, content-length: 2)

Step 2: Poll upload status

GET /api/uploads/audio/{upload_id}/

Response: JSON with processing status.

Step 3: Extract vocal stem

POST /api/processed_clip/voice-vox-stem
Content-Length: ~90 bytes

Extracts clean vocals from uploaded audio. Body likely: {"upload_id": "<id>"}. Called multiple times — once per upload (sample + verification).

Step 4: Record & upload verification phrase

User reads: "Listening to the melody of a gentle summer breeze" Second upload goes through the same upload-finish flow with a new upload_id.

Step 5: Voice verification

POST /api/voice-verification/
Content-Length: 179 bytes

Verifies the voice matches. Body likely includes both upload IDs + verification text.

Step 6: Create persona

POST /api/persona/create/
Content-Length: 47261 bytes (large — likely includes audio data as base64)

Creates the voice persona from the verified audio clips.

Endpoints summary:

  • POST /api/uploads/audio/{id}/upload-finish/ — mark upload complete
  • GET /api/uploads/audio/{id}/ — poll upload processing
  • POST /api/processed_clip/voice-vox-stem — extract vocals
  • POST /api/voice-verification/ — verify voice sample
  • POST /api/persona/create/ — create voice persona (47KB payload)

To implement in CLI:

Need to capture the REQUEST BODIES (not just headers) to see exact JSON payloads. The S3 presigned upload step (before upload-finish) also needs capturing.

Key Insights for Rust CLI

  1. Captcha is the main challenge — generation requires a captcha token that gcui-art solves via Playwright browser automation
  2. Lyrics generation is free and easy — no captcha needed, just JWT auth
  3. JWT refresh — need Clerk cookie exchange or session keepalive
  4. Browser-token header — dynamically generated from current timestamp, base64-encoded
  5. Cookie-based approach — store Clerk session cookies, exchange for JWT via auth.suno.com/v1/client/sessions/<session_id>/tokens
  6. Two auth strategies: a. Cookie-based: Store browser cookies, auto-refresh JWT (what gcui-art does) b. Direct JWT: User pastes JWT, works for ~1 hour (simpler but expires)