Callbacks & WebhooksFree Webhook (0 Credits)Continuous Audio AppendAsynchronous HTTP POST

Extend Music Callbacks

Real-time asynchronous webhook notifications delivered to your callBackUrl when song extension tasks finish. Receive dual-track lengthened songs combining original audio segments with newly rendered musical parts.

WEBHOOKYour Callback Endpoint (Client HTTPS URL)

Usage Guide & Overview

  • Seamless Continuation Architecture: When extending a song from a designated timestamp (e.g. second 120), the AI synthesizes an extended section that smoothly blends with harmonic tempo and key signatures. Submitting a callBackUrl enables instant notification upon final mastering.
  • Dual Extension Arrangements: Suno AI produces 2 unique continuation takes per task, providing variations in chord progression, instrumentation, or lyrical delivery.
  • Zero Credit Surcharge: Webhook callback delivery is completely free (0 credits) and incurs no extra fees.
  • Source Reference Auditing: The callback includes source_audio_url so your system can verify lineage and link parent and extended child tracks in your database.

Delivery Conditions & Technical Constraints

Callback Stages (data.callbackType)

  • text : Extended lyrics and section timestamps structured successfully.
  • first : First extended audio variant ready for streaming preview.
  • complete : Final state. Both extended variations fully merged, mastered, and hosted on CDN.
  • error : Task failed due to safety moderation filter, invalid timestamp, or rendering timeout.

HTTP Transport & Timeout Specification

  • HTTP Method: Requests are delivered via POST with Content-Type: application/json.
  • 15-Second Response Window: Your server must acknowledge receipt with HTTP 200 within 15 seconds.
  • Automated Retries: If your server fails to respond, returns 4xx/5xx, or times out, the dispatcher retries up to 3 times before abandoning.
  • Public Accessibility: The callBackUrl must be accessible via public HTTPS. Localhost or private IP addresses will fail to receive callbacks.

Production Best Practices

  • Immediate 200 Acknowledgment: Return HTTP 200 immediately before performing file downloads, audio transcoding, or S3 uploads.
  • Idempotent Handling: Use task_id + callbackType as a compound unique key in your database to prevent duplicate processing on retries.
  • Track Lineage: Save the returned source_audio_url to maintain parent-child versioning in your application.

Troubleshooting & Verification Checklist

  • Ensure your firewall and ingress load balancer permit incoming POST requests on your callback URL.
  • For local development and testing, use reverse tunneling tools such as ngrok or Cloudflare Tunnel.
  • Ensure your web application uses JSON body parsing middleware (e.g. express.json()).
  • Confirm that your endpoint returns HTTP 200 rather than 301/302 redirects.

Inbound HTTP Headers

HeaderRequirementDescription
Content-Typerequired

application/json

Inbound webhook payload encoded in UTF-8 JSON format

User-Agentoptional

Suno-Webhook-Dispatcher/1.0

User agent identifier sent by the webhook worker

When Callbacks Are Sent

The SongMesh API automatically triggers an HTTP POST request to your designated callBackUrl under these events:

  • Text Planned (callbackType: 'text'): Dispatched when lyrical continuation verses and extended song structure are planned.
  • First Extended Track Ready (callbackType: 'first'): Dispatched when the first extended track variation is synthesized and ready for streaming.
  • All Extended Tracks Complete (callbackType: 'complete'): Dispatched when both extended song variations have been rendered, seamlessly spliced, and hosted.
  • Task Failure (callbackType: 'error'): Dispatched if the extension prompt triggers moderation filters or the source audio clip cannot be located.

Webhook Payload Format

Response Body(200 status)
{
  "code": 200,
  "msg": "All generated successfully.",
  "data": {
    "callbackType": "complete",
    "task_id": "2fac9a8109bf4a6385cf71e3b6999f72",
    "data": [
      {
        "id": "e231a481-9b11-4cb3-a9d2-5a218cadc7dc",
        "audio_url": "https://example.cn/music/extended_part1.mp3",
        "stream_audio_url": "https://example.cn/stream/extended_part1",
        "image_url": "https://example.cn/images/extended_cover1.jpeg",
        "prompt": "[Chorus]\nSailing beyond the edge of dawn\nEchoes of glory carrying on",
        "model_name": "chirp-v4-5",
        "title": "Cosmic Voyager (Part 2)",
        "tags": "progressive synth rock, epic guitar solo, cinematic climax",
        "createTime": 1786343609818,
        "duration": 242.85,
        "source_audio_url": "https://example.cn/music/original_intro.mp3",
        "source_image_url": "https://example.cn/images/original_cover.jpeg",
        "source_stream_audio_url": "https://example.cn/stream/original_stream"
      },
      {
        "id": "e231a482-9b11-4cb3-a9d2-5a218cadc7dd",
        "audio_url": "https://example.cn/music/extended_part2.mp3",
        "stream_audio_url": "https://example.cn/stream/extended_part2",
        "image_url": "https://example.cn/images/extended_cover2.jpeg",
        "prompt": "[Chorus]\nSailing beyond the edge of dawn\nEchoes of glory carrying on",
        "model_name": "chirp-v4-5",
        "title": "Cosmic Voyager (Part 2 - Extended Outro)",
        "tags": "progressive synth rock, ambient acoustic fading, rhythmic drums",
        "createTime": 1786343609818,
        "duration": 251.1,
        "source_audio_url": "https://example.cn/music/original_intro.mp3",
        "source_image_url": "https://example.cn/images/original_cover.jpeg",
        "source_stream_audio_url": "https://example.cn/stream/original_stream"
      }
    ]
  }
}

Callback Payload Fields

FieldTypeDescription
codeintegerStatus code of task processing. 200 indicates success; 400 or 500 indicates a failure.
msgstringDescriptive status message explaining the extension outcome (e.g. "All generated successfully.").
data.callbackTypestringLifecycle stage identifier: "text" (planning ready), "first" (track 1 ready), "complete" (all tracks ready), or "error" (failed).
data.task_idstringUnique task identifier, identical to the taskId returned when submitting the extension task to POST /api/v1/createTask.
data.dataarrayArray containing generated extended audio variations (typically 2 distinct continuation arrangements).
data.data[].idstringUnique UUID for the extended audio variation record.
data.data[].audio_urlstringHigh-speed CDN direct download URL for the seamless extended MP3 audio track.
data.data[].stream_audio_urlstringStreaming audio URL (HLS / m3u8 format) for real-time web playback.
data.data[].image_urlstringHigh-resolution album artwork cover image URL created for the extended track.
data.data[].promptstringExtension lyrics, continuation verse structure, or musical style prompt used.
data.data[].model_namestringUnderlying AI audio synthesis model used (e.g. "chirp-v4-5", "chirp-v4", "V6").
data.data[].titlestringSong title of the extended audio track.
data.data[].tagsstringGenre, tempo, instrument, and mood tags applied to the extended segment.
data.data[].createTimeintegerUnix millisecond timestamp when the extended track was synthesized.
data.data[].durationnumberCombined total duration of the extended audio track in seconds (original length + new extension).
data.data[].source_audio_urlstringDirect audio URL of the original source track that was lengthened.
data.data[].source_image_urlstringCover artwork image URL of the original reference song.
data.data[].source_stream_audio_urlstringStreaming audio URL of the original reference song.

Receiver Implementation Example

Webhook Receiver
const express = require('express');
const app = express();

app.use(express.json({ limit: '10mb' }));

app.post('/suno-extend-callback', (req, res) => {
  const { code, msg, data } = req.body;
  
  console.log('Received Suno music extension callback:', {
    taskId: data?.task_id,
    callbackType: data?.callbackType,
    status: code,
    message: msg
  });

  if (code === 200 && data) {
    const { callbackType, task_id, data: tracks } = data;

    switch (callbackType) {
      case 'text':
        console.log(`[${task_id}] Extended lyrics and structure planned:`, tracks);
        break;

      case 'first':
        console.log(`[${task_id}] First extended variation ready:`, tracks?.[0]?.audio_url);
        break;

      case 'complete':
        console.log(`[${task_id}] Both extended tracks completed successfully!`);
        tracks?.forEach((track, index) => {
          console.log(`Track #${index + 1}: ${track.title} (${track.duration}s)`);
          console.log(`- MP3 URL: ${track.audio_url}`);
          console.log(`- Stream URL: ${track.stream_audio_url}`);
          console.log(`- Original Song: ${track.source_audio_url}`);
        });
        break;

      case 'error':
        console.error(`[${task_id}] Extension failed:`, msg);
        break;
    }
  } else {
    console.error('Task failed or returned non-200 code:', code, msg);
  }

  // Always return HTTP 200 within 15 seconds to acknowledge receipt
  return res.status(200).json({ status: 'received' });
});

app.listen(3000, () => {
  console.log('Suno extend webhook listener running on port 3000');
});

Webhook Security Recommendation

Always verify incoming webhook payloads on your server. Respond with a 200 OK immediately after parsing the payload to prevent redundant delivery retries from the webhook dispatcher.

Webhook Implementation
// app/api/webhook/suno-extend/route.ts
import { NextRequest, NextResponse } from 'next/server';

interface ExtendedTrackItem {
  id: string;
  audio_url: string;
  stream_audio_url: string;
  image_url: string;
  prompt: string;
  model_name: string;
  title: string;
  tags: string;
  createTime: number;
  duration: number;
  source_audio_url?: string;
  source_image_url?: string;
  source_stream_audio_url?: string;
}

interface ExtendCallbackPayload {
  code: number;
  msg: string;
  data: {
    callbackType: 'text' | 'first' | 'complete' | 'error';
    task_id: string;
    data?: ExtendedTrackItem[];
  };
}

export async function POST(req: NextRequest) {
  try {
    const payload: ExtendCallbackPayload = await req.json();
    const { code, msg, data } = payload;

    console.log(`[Extend Webhook] Task ${data?.task_id} -> Stage: ${data?.callbackType} (Code: ${code})`);

    if (code === 200 && data) {
      if (data.callbackType === 'complete') {
        console.log(`Extended tracks generated: ${data.data?.length || 0}`);
        for (const track of data.data || []) {
          console.log(`Track: "${track.title}" (Extended Duration: ${track.duration}s)`);
          console.log(`- MP3 URL: ${track.audio_url}`);
          console.log(`- Original Source: ${track.source_audio_url}`);
        }
      } else if (data.callbackType === 'first') {
        console.log(`[First Extended Track Ready] Stream: ${data.data?.[0]?.stream_audio_url}`);
      } else if (data.callbackType === 'text') {
        console.log('[Text Ready] Extended lyrics and structure planned');
      }
    } else {
      console.error(`Music extension failed: ${msg}`);
    }

    // Always acknowledge receipt immediately with HTTP 200
    return NextResponse.json({ code: 200, msg: 'success' });
  } catch (error) {
    console.error('Webhook error:', error);
    return NextResponse.json({ code: 500, msg: 'Internal server error' }, { status: 500 });
  }
}
Your Server's Expected Response (HTTP 200 OK)
Response Body(200 status)
{
  "code": 200,
  "msg": "success"
}

Ready to integrate Extend Music Callbacks?

Create your free account, obtain your Secret Key, and receive real-time music extension updates with 5 free generation credits.

Generate Secret Key