Replace Music Section Callbacks
Understand the callback mechanism for replace music section tasks.
When you submit a replace music section task to the API, you can provide a callBackUrl to receive real-time notifications about task progress and completion.
Callback Mechanism
Webhook Security
To ensure the authenticity and integrity of callback requests, we strongly recommend implementing webhook signature verification. See our Webhook Verification Guide for detailed implementation steps.
When Callbacks Are Sent
The system sends callbacks at the following times:
- Complete: When the replacement task is fully completed
Callback Method
- HTTP Method: POST
- Content-Type: application/json
- Timeout: 10 seconds
- Retry Policy: Up to 3 attempts with exponential backoff
Callback Request Format
When the task progresses or completes, the system will send a POST request to your callBackUrl in the following format:
Complete Success Callback
{
"code": 200,
"msg": "All generated successfully.",
"data": {
"callbackType": "complete",
"task_id": "2fac****9f72",
"data": [
{
"id": "e231****-****-****-****-****8cadc7dc",
"audio_url": "https://example.cn/****.mp3",
"stream_audio_url": "https://example.cn/****",
"image_url": "https://example.cn/****.jpeg",
"prompt": "[Verse] Night city lights shining bright",
"model_name": "chirp-v4-5",
"title": "Iron Man",
"createTime": 1786343609818,
"duration": 198.44,
"tags": "electrifying, rock",
"source_audio_url":"https://example.cn/****.mp3",
"source_image_url":"https://example.cn/****.jpeg",
"source_stream_audio_url":"https://example.cn/****"
},
{
"id": "e231****-****-****-****-****8cadc7dc",
"audio_url": "https://example.cn/****.mp3",
"stream_audio_url": "https://example.cn/****",
"image_url": "https://example.cn/****.jpeg",
"prompt": "[Verse] Night city lights shining bright",
"model_name": "chirp-v4-5",
"title": "Iron Man",
"createTime": 1786343609818,
"duration": 198.44,
"tags": "electrifying, rock",
"source_audio_url":"https://example.cn/****.mp3",
"source_image_url":"https://example.cn/****.jpeg",
"source_stream_audio_url":"https://example.cn/****"
}
]
}
}First Track Success Callback
{
"code": 200,
"msg": "First audio generated successfully.",
"data": {
"callbackType": "first",
"task_id": "2fac****9f72",
"data": [
{
"id": "e231****-****-****-****-****8cadc7dc",
"audio_url": "https://example.cn/****.mp3",
"stream_audio_url": "https://example.cn/****",
"image_url": "https://example.cn/****.jpeg",
"prompt": "[Verse] Night city lights shining bright",
"model_name": "chirp-v4-5",
"title": "Iron Man",
"createTime": 1786343609818,
"duration": 198.44,
"tags": "electrifying, rock",
"source_audio_url":"https://example.cn/****.mp3",
"source_image_url":"https://example.cn/****.jpeg",
"source_stream_audio_url":"https://example.cn/****"
}
]
}
}Text Generation Callback
{
"code": 200,
"msg": "Text generated successfully.",
"data": {
"callbackType": "text",
"task_id": "2fac****9f72",
"data": [
{
"id": "e231****-****-****-****-****8cadc7dc",
"audio_url": "",
"stream_audio_url": "https://example.cn/****",
"image_url": "https://example.cn/****.jpeg",
"prompt": "[Verse] Night city lights shining bright",
"model_name": "chirp-v4-5",
"title": "Iron Man",
"createTime": 1786343609818,
"tags": "electrifying, rock",
"source_image_url":"https://example.cn/****.jpeg",
"source_stream_audio_url":"https://example.cn/****"
},
{
"id": "e231****-****-****-****-****8cadc7dc",
"audio_url": "",
"stream_audio_url": "https://example.cn/****",
"image_url": "https://example.cn/****.jpeg",
"prompt": "[Verse] Night city lights shining bright",
"model_name": "chirp-v4-5",
"title": "Iron Man",
"createTime": 1786343609818,
"tags": "electrifying, rock",
"source_image_url":"https://example.cn/****.jpeg",
"source_stream_audio_url":"https://example.cn/****"
}
]
}
}Failure Callback
{
"code": 400,
"msg": "Audio generation failed",
"data": {
"callbackType": "complete",
"task_id": "2fac****9f72"
}
}On failure, code is not 200, callbackType is "complete" and data.data is absent. Check code before reading data.data.
Status Codes
200 means success; any other value means failure (for example, 501).
msg (string, required)
Status message providing detailed status description
data.callbackType (string, required)
Callback type indicating the stage of generation:
- text: Text generation complete
- first: First track complete
- complete: All tracks complete
data.task_id (string, required)
Task ID, consistent with the taskId returned when you submitted the task
data.data (array)
Array of generated audio data.
data.data[].id (string)
Unique identifier of the audio.
data.data[].audio_url (string)
Audio file URL.
data.data[].stream_audio_url (string)
Streaming audio URL.
data.data[].image_url (string)
Cover image URL.
data.data[].prompt (string)
Generation prompt or lyrics.
data.data[].model_name (string)
Name of the model used.
data.data[].title (string)
Music title.
data.data[].tags (string)
Music tags.
data.data[].createTime (integer)
Creation time.
data.data[].duration (number)
Audio duration in seconds.
data.data[].source_audio_url (string)
Source audio file URL.
data.data[].source_image_url (string)
Source cover image URL.
data.data[].source_stream_audio_url (string)
Source streaming audio URL.
Implementation Examples
Node.js (Express)
const express = require('express');
const app = express();
app.use(express.json());
app.post('/replace-section-callback', (req, res) => {
const { code, msg, data } = req.body;
console.log('Replace section callback received:', {
code,
msg,
taskId: data.task_id,
callbackType: data.callbackType
});
if (code === 200 && data.callbackType === 'complete') {
// Handle successful replacement
console.log('Replacement completed successfully');
data.data.forEach((music, index) => {
console.log(`Music ${index + 1}:`, {
id: music.id,
title: music.title,
duration: music.duration,
audioUrl: music.audio_url
});
});
} else {
// Handle failure
console.log('Replacement failed:', msg);
}
// Always respond with success to acknowledge receipt
res.json({ code: 200, msg: 'success' });
});
app.listen(3000, () => {
console.log('Callback server running on port 3000');
});Python (Flask)
from flask import Flask, request, jsonify
import logging
app = Flask(__name__)
logging.basicConfig(level=logging.INFO)
@app.route('/replace-section-callback', methods=['POST'])
def replace_section_callback():
data = request.json
code = data.get('code')
msg = data.get('msg')
callback_data = data.get('data', {})
logging.info(f"Replace section callback received: code={code}, msg={msg}")
if code == 200 and callback_data.get('callbackType') == 'complete':
# Handle successful replacement
logging.info("Replacement completed successfully")
music_data = callback_data.get('data', [])
for i, music in enumerate(music_data):
logging.info(f"Music {i + 1}: {music.get('title')} - {music.get('duration')}s")
else:
# Handle failure
logging.error(f"Replacement failed: {msg}")
# Always respond with success
return jsonify({"code": 200, "msg": "success"})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)PHP
<?php
header('Content-Type: application/json');
// Get the raw POST data
$input = file_get_contents('php://input');
$data = json_decode($input, true);
if ($data === null) {
http_response_code(400);
echo json_encode(['code' => 400, 'msg' => 'Invalid JSON']);
exit;
}
$code = $data['code'] ?? null;
$msg = $data['msg'] ?? '';
$callbackData = $data['data'] ?? [];
error_log("Replace section callback received: code=$code, msg=$msg");
if ($code === 200 && ($callbackData['callbackType'] ?? '') === 'complete') {
// Handle successful replacement
error_log("Replacement completed successfully");
$musicData = $callbackData['data'] ?? [];
foreach ($musicData as $index => $music) {
$title = $music['title'] ?? 'Unknown';
$duration = $music['duration'] ?? 0;
error_log("Music " . ($index + 1) . ": $title - {$duration}s");
}
} else {
// Handle failure
error_log("Replacement failed: $msg");
}
// Always respond with success
echo json_encode(['code' => 200, 'msg' => 'success']);
?>Callback Security
Verification Recommendations
- IP Whitelist: Restrict callback endpoints to known IP addresses
- HTTPS Only: Always use HTTPS for callback URLs in production
- Request Validation: Validate the structure and content of callback requests
- Timeout Handling: Implement proper timeout handling for callback processing
Example Security Implementation
const crypto = require('crypto');
function verifyCallback(req, res, next) {
// Verify request structure
const { code, msg, data } = req.body;
if (typeof code !== 'number' || typeof msg !== 'string' || !data) {
return res.status(400).json({ code: 400, msg: 'Invalid callback format' });
}
// Verify task ID format
const taskId = data.task_id;
if (!taskId || !/^[a-f0-9\*]{12}$/.test(taskId)) {
return res.status(400).json({ code: 400, msg: 'Invalid task ID' });
}
next();
}
app.post('/replace-section-callback', verifyCallback, (req, res) => {
// Process verified callback
// ... callback handling logic
});Troubleshooting
Common Issues
Q: Callbacks are not being received
- Verify your callback URL is publicly accessible
- Check that your server is responding within 10 seconds
- Ensure your endpoint accepts POST requests with JSON content
Q: Receiving duplicate callbacks
- This can happen due to network issues or timeouts
- Implement idempotency using the task_id to handle duplicates
Q: Callback data is missing or incomplete
- Check the
callbackTypefield to understand the callback stage - For error callbacks, check the error message for details
Q: How to handle callback failures?
- Always return a 200 status code to acknowledge receipt
- Use the Get Task Details endpoint to poll task status as a fallback
Best Practices
- Always Acknowledge: Return HTTP 200 even if your processing fails
- Implement Retry Logic: Handle temporary failures gracefully
- Log Everything: Keep detailed logs for debugging
- Use Fallback Polling: Don't rely solely on callbacks for critical workflows
- Validate Data: Always validate callback data before processing