AI Music API
Home
Home
    • Introduction
    • Credits Usage Guide
    • Error handling
    • Webhook Integration Guide
    • suno
      • Suno Instructions
      • create music (custom mode)
        POST
      • create music (no-custom mode)
        POST
      • create music (Control singer gender)
        POST
      • create music (auto lyrics mode)
        POST
      • extend music
        POST
      • concat music
        POST
      • cover music
        POST
      • stems basic
        POST
      • stems full
        POST
      • create persona
        POST
      • create music with persona
        POST
      • upload music
        POST
      • get wav
        POST
      • get music
        GET
    • riffusion(Deprecated)
      • Riffusion instructions
      • create music (with lyrics)
        POST
      • create music (with description)
        POST
      • cover music
        POST
      • extend music
        POST
      • replace music section
        POST
      • swap music sound
        POST
      • swap music vocals
        POST
      • upload
        POST
      • get music
        GET
    • producer
      • Producer Instructions
      • Complete Request Example
      • create music
      • get music
    • nuro
      • Nuro Instruction
      • Error handling
      • create vocal music
      • create instrument music
      • get music
    • lyrics generation
      • Make Lyrics
    • get-credits
      GET

    Webhook Integration Guide

    🎵 Webhook Integration Guide#

    This document explains how to use the webhook_url and webhook_secret parameters when creating music generation tasks, and provides complete webhook payload examples for the three supported platforms: Suno, Nuro, and Producer.

    1) Parameters#

    webhook_url#

    Type: string
    Optional
    Callback URL. When a task reaches a final state (succeeded or failed), the system sends an HTTP POST request with an application/json body to this URL.
    Supported platforms: suno, nuro, producer
    Use HTTPS whenever possible
    Your endpoint should return a 2xx status to acknowledge receipt
    Example:
    {
      "webhook_url": "https://yourdomain.com/api/music-callback"
    }

    webhook_secret#

    Type: string
    Optional
    Secret used to sign the webhook body so your server can verify authenticity.
    When set, each webhook includes the header:
    X-Signature: HMAC-SHA256(<raw body>, webhook_secret)
    Compute the HMAC on the exact raw request body bytes your server received (do not re-stringify parsed JSON before verifying).
    Example:
    {
      "webhook_secret": "your-secret-key"
    }

    2) Delivery Semantics#

    HTTP Method: POST
    Content-Type: application/json
    Trigger: Sent once a task transitions to a terminal state (typically succeeded; on errors you may receive failed).
    Retries: If your server returns a non-2xx status code or times out, the webhook may be retried. Implement idempotency using task_id.
    Idempotency hint: Deduplicate using (task_id, platform).

    3) Security & Verification#

    Below is a minimal Node.js example that verifies the signature:
    Python (FastAPI) example:

    4) Webhook Payload Examples (Success)#

    4.1 Suno — event: "song.completed"#

    {
      "code": 200,
      "data": [
        {
          "clip_id": "30264033-2b01-43a7-8779-2a834b067486",
          "state": "succeeded",
          "title": "Sunshine in My Pocket",
          "tags": "electric with claps and synths, happy, pop",
          "lyrics": "[Verse]\nWoke up today the sky was gold\nA story untold\nA treasure to hold\nMy feet on fire the ground feels light\nDancing shadows chase the night\n\n[Chorus]\nI got sunshine in my pocket\nA melody that won't stop it\nEvery step feels like a spark\nLighting up the world from dark\n\n[Verse 2]\nThe trees are swaying to my beat\nThe pavement hums beneath my feet\nWhistling wind it sings along\nLife's a stage and I'm the song\n\n[Prechorus]\nNo time for sorrow no time for gray\nWe’re painting colors all the way\n\n[Chorus]\nI got sunshine in my pocket\nA melody that won't stop it\nEvery step feels like a spark\nLighting up the world from dark\n\n[Bridge]\nTurn it up turn it loud\nLet it echo through the crowd\nEvery heart every soul\nTogether now we’re whole",
          "image_url": "https://cdn2.suno.ai/image_30264033-2b01-43a7-8779-2a834b067486.jpeg",
          "audio_url": "https://cdn1.suno.ai/30264033-2b01-43a7-8779-2a834b067486.mp3",
          "video_url": null,
          "created_at": "2025-10-12T13:13:02.488Z",
          "gpt_description_prompt": null,
          "duration": "104.88",
          "negative_tags": null,
          "style_weight": null,
          "weirdness_constraint": null,
          "mv": "chirp-v5"
        },
        {
          "clip_id": "f5250a71-1c27-4cc9-a302-99f2d64a4790",
          "state": "succeeded",
          "title": "Sunshine in My Pocket",
          "tags": "electric with claps and synths, happy, pop",
          "lyrics": "[Verse]\nWoke up today the sky was gold\nA story untold\nA treasure to hold\nMy feet on fire the ground feels light\nDancing shadows chase the night\n\n[Chorus]\nI got sunshine in my pocket\nA melody that won't stop it\nEvery step feels like a spark\nLighting up the world from dark\n\n[Verse 2]\nThe trees are swaying to my beat\nThe pavement hums beneath my feet\nWhistling wind it sings along\nLife's a stage and I'm the song\n\n[Prechorus]\nNo time for sorrow no time for gray\nWe’re painting colors all the way\n\n[Chorus]\nI got sunshine in my pocket\nA melody that won't stop it\nEvery step feels like a spark\nLighting up the world from dark\n\n[Bridge]\nTurn it up turn it loud\nLet it echo through the crowd\nEvery heart every soul\nTogether now we’re whole",
          "image_url": "https://cdn2.suno.ai/image_f5250a71-1c27-4cc9-a302-99f2d64a4790.jpeg",
          "audio_url": "https://cdn1.suno.ai/f5250a71-1c27-4cc9-a302-99f2d64a4790.mp3",
          "video_url": null,
          "created_at": "2025-10-12T13:13:02.488Z",
          "gpt_description_prompt": null,
          "duration": "92.2",
          "negative_tags": null,
          "style_weight": null,
          "weirdness_constraint": null,
          "mv": "chirp-v5"
        }
      ],
      "message": "success",
      "task_id": "c00fc615-dd0a-4fc8-87e0-8a8c4778a71b",
      "platform": "suno",
      "event": "song.completed"
    }

    4.2 Nuro — event: "song.completed"#

    {
      "task_id": "41627516-89bf-43d7-b437-622e03c8c112",
      "status": "succeeded",
      "progress": 100,
      "audio_url": "https://musicapi-cdn.b-cdn.net/song-41627516-89bf-43d7-b437-622e03c8c112.wav",
      "lyrics": "",
      "duration": 90,
      "genre": "",
      "mood": "",
      "gender": "",
      "timbre": "",
      "prompt": "cinematic background score",
      "theme": "",
      "instrument": "",
      "platform": "nuro",
      "event": "song.completed"
    }

    4.3 Producer — event: "song.completed"#

    {
      "code": 200,
      "data": [
        {
          "clip_id": "e7118413-bd9d-4c19-a2f0-c950087251cd",
          "title": "Back to You",
          "sound": "emotional pop with gentle piano, warm synths, and a catchy beat",
          "lyrics": "[Verse 1]\nI’ve been running in circles, chasing my doubts\nTrying to quiet the silence that’s been too loud\nEvery streetlight flickers with a memory\nBut none of them shine like you did to me\n[Pre-Chorus]\nAnd I know we said goodbye\nBut it never felt right\nEvery step I take just pulls me back in time\n[Chorus]\nI keep coming back to you\nLike the ocean to the moon\nEvery night I try to move\nBut the stars still spell your name\nI keep falling into you\nNo matter what I do\nThere’s a gravity, a truth\nThat keeps pulling me back to you\n[Verse 2]\nYour voice echoes through the cracks in my soul\nLike a song that I played, then lost control\nTried to dance with strangers, forget the past\nBut every rhythm brings your shadow back\n[Pre-Chorus]\nAnd I swear I’ve tried to change\nRearrange the pain\nBut some love's too deep to ever fade away\n[Chorus]\nI keep coming back to you\nLike the ocean to the moon\nEvery night I try to move\nBut the stars still spell your name\nI keep falling into you\nNo matter what I do\nThere’s a gravity, a truth\nThat keeps pulling me back to you\n[Bridge]\nMaybe we’re just written in the sky\nA little wrong, but still aligned\nAnd even if we break a thousand times\nI’d still come back to make you mine\n[Chorus - Final]\nI keep coming back to you\nLike the ocean to the moon\nEvery night I try to move\nBut the stars still spell your name\nI keep falling into you\nNo matter what I do\nThere’s a gravity, a truth\nThat keeps pulling me back to you\n[Outro]\nBack to you, back to you\nNo matter where I go, I’m back to you",
          "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/5288569a-a4a1-49b4-a76a-c38a0e6279d3/image/e7118413-bd9d-4c19-a2f0-c950087251cd.jpg",
          "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/5288569a-a4a1-49b4-a76a-c38a0e6279d3/audio/e7118413-bd9d-4c19-a2f0-c950087251cd.m4a",
          "video_url": null,
          "created_at": "2025-10-12T13:04:31.589058Z",
          "mv": "FUZZ-2.0",
          "seed": "4246081782",
          "duration": 176.10013605442177,
          "state": "succeeded"
        }
      ],
      "message": "success",
      "task_id": "a335f5ef-ba6c-4c8b-9135-77efa7bf425c",
      "platform": "producer",
      "event": "song.completed"
    }

    5) Error/Failure Callback (Generic)#

    On failure, you will receive a payload with event: "song.failed"
    Example (generic):
    {
        "type": "failed",
        "message": "Task failed. Credits have been refunded.",
        "refund_processed": true,
        "task_id": "49af4269-d1a5-4a61-9139-4497a73caf9d",
        "platform": "producer",
        "event": "song.failed"
    }

    6) Best Practices#

    Verify the X-Signature header before trusting the payload
    Implement retries and idempotency (use (task_id, platform))
    Store task_id at creation time to correlate with webhooks
    Log full payloads for diagnostics (redact secrets)
    Use HTTPS and enforce authentication/allowlists if feasible

    Last Updated: 2025-10-12
    Modified at 2025-10-12 13:37:01
    Previous
    Error handling
    Next
    Suno Instructions
    Built with