How to Generate Music Video from Audio via API
A developer workflow for turning an audio file, reference images, and creative direction into a hosted MP4 music video with BeatAPI.

To generate music video from audio via API, treat the request as an asynchronous workflow: make the audio and references reachable, create a music-video task, poll or listen for webhooks, then store the hosted MP4 URL returned by the task.
- Use
POST /v1/fileswhen the user's audio, images, or subtitles are local files. - Create the render with
POST /v1/music-video/tasks. - Poll
GET /v1/tasks/{task_id}every 5-10 seconds with jitter, or add/v1/webhooksfor completion events. - Read the final MP4 from
output.media[].urlafterstatusbecomessucceeded. - Keep provider-specific jobs behind your backend; expose BeatAPI task ids to your product.
Quick answer
The shortest reliable path is:
- Upload or host the input audio and references as public HTTPS URLs.
- Send those URLs to
POST /v1/music-video/taskswith a visual prompt and output controls. - Save the returned task id in your database.
- Poll
GET /v1/tasks/{task_id}until the task is terminal. - On success, persist the hosted MP4 URL from
output.media. - On failure, show
error_code,error_message, and any usage/refund evidence to your support flow.
That workflow is better than trying to hold one HTTP request open while generation runs. Music-video generation is long-running, may need storyboard or composition stages, and should remain observable after the user closes the browser tab.
The workflow model
Generating a music video from audio through an API is not just "send MP3, get video." A production music video generation API has five jobs:

The useful API boundary is the whole task workflow: input validation, async state, billing evidence, webhooks, and hosted output.
| Job | What your product should own | BeatAPI surface |
|---|---|---|
| Asset readiness | Make local audio, references, and subtitles reusable HTTPS URLs. | POST /v1/files |
| Generation request | Capture audio, images, prompt, language, style, aspect ratio, resolution, and lip-sync/subtitle options. | POST /v1/music-video/tasks |
| Progress state | Show queued, processing, storyboard, compose, success, or failure states without blocking the UI. | GET /v1/tasks/{task_id} |
| Completion events | Update backend records when a task succeeds or fails. | /v1/webhooks |
| Delivery | Store the final MP4 URL and support evidence tied to the task. | output.media[].url, usage, request_id |
Prepare audio and images
BeatAPI music-video tasks require a public HTTPS audio URL and 1-7 public HTTPS image URLs. If the user uploads local files in your app, upload them first with POST /v1/files, then use the returned url in the task request.
For launch integrations, use these practical limits as preflight checks before you call the API:
- Audio: public HTTPS
mp3,wav,aac, orm4a. - Audio duration: 10-180 seconds.
- Audio file size: 50 MB or smaller.
- Images: public HTTPS
png,jpg,jpeg, orwebp. - Image count: 1-7.
- Image size: 50 MB or smaller each.
- Image aspect ratio: roughly between 1:4 and 4:1.
- Prompt: optional, up to 3000 characters.
srt_url: optional, but should point to an.srtfile.duration: only a billing fallback when BeatAPI cannot detect audio length; it should not be used to override detected audio duration.
Preflight these in your UI because it gives users faster feedback and protects credits. BeatAPI still validates URL shape, enum values, text limits, audio duration, and file metadata at task creation.
Create the task
The create-task request can be small. Start with audio, images, prompt, and output controls; add lip-sync or subtitle fields only when the product scenario needs them.
export BEATAPI_API_KEY="sk_your_key"
curl https://api.beatapi.io/v1/music-video/tasks \
-H "Authorization: Bearer $BEATAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"audio_url": "https://media.beatapi.io/samples/neon-singer-preview.mp3",
"images": ["https://media.beatapi.io/samples/neon-singer.png"],
"prompt": "Neon rooftop performance with cinematic light trails, slow dolly movement, energetic chorus cuts.",
"language": "en",
"aspect_ratio": "9:16",
"resolution": "720p",
"quality": "standard",
"lip_sync": false,
"add_subtitle": false,
"compose_mode": "auto"
}'
Store the returned task id immediately. Your product should not depend on a browser tab, a queue worker's memory, or a provider job id as the only reference.
Poll or use webhooks
BeatAPI tasks move through explicit states such as queued, processing, storyboard_ready, requires_action, editing, composing, succeeded, and failed.

Polling remains the source of truth. Webhooks are useful for backend updates, but your app can always recover from the task endpoint.
Poll every 5-10 seconds with a little jitter:
curl https://api.beatapi.io/v1/tasks/task_8K2qA \
-H "Authorization: Bearer $BEATAPI_API_KEY"
A successful response exposes the final media in output.media:
{
"data": {
"id": "task_8K2qA",
"object": "task",
"workflow": "music-video",
"status": "succeeded",
"output": {
"media": [
{
"type": "video",
"url": "https://media.beatapi.io/outputs/task_8K2qA/0.mp4",
"mime_type": "video/mp4"
}
]
},
"usage": {
"credits_reserved": 150,
"credits_charged": 150,
"credits_settled": 150,
"credits_refunded": 0
},
"request_id": "req_abc123"
}
}
If your product has a backend job runner, add webhooks for task.succeeded and task.failed. Still keep polling as a recovery path because webhook delivery failures should not hide the real task state from users.
Worked example
Imagine a creator platform where musicians upload a 30-second preview track and one artist image. The product goal is a vertical social clip, not a full editor.
Use this implementation shape:
- Browser uploads the MP3 and image to your backend.
- Backend sends each local file to
POST /v1/files. - Backend creates a BeatAPI music-video task with the returned URLs.
- Backend stores
{ user_id, beatapi_task_id, status, request_id }. - Frontend polls your backend, not BeatAPI directly.
- Backend polls BeatAPI or receives a webhook.
- When
statusissucceeded, backend storesoutput.media[0].url. - UI shows the MP4, plus retry/support details if the task failed.
The reusable task payload:
{
"audio_url": "https://media.beatapi.io/inputs/file_song_preview.mp3",
"images": ["https://media.beatapi.io/inputs/file_artist_portrait.png"],
"prompt": "Create a vertical artist promo video for a synth-pop chorus. Use neon reflections, close-up performance energy, quick cuts on beat, and no visible text.",
"language": "en",
"aspect_ratio": "9:16",
"resolution": "720p",
"quality": "standard",
"lip_sync": false,
"add_subtitle": false,
"compose_mode": "auto"
}
For a lyric-video product, change only the workflow controls:
{
"audio_url": "https://media.beatapi.io/inputs/file_song_preview.mp3",
"images": ["https://media.beatapi.io/inputs/file_cover_art.png"],
"prompt": "Create a clean lyric visualizer with soft camera movement, rhythmic background motion, and safe empty space for subtitles.",
"language": "en",
"aspect_ratio": "16:9",
"resolution": "1080p",
"quality": "standard",
"add_subtitle": true,
"subtitle_color": "#FFFFFF",
"srt_url": "https://media.beatapi.io/inputs/file_lyrics.srt",
"compose_mode": "auto"
}
Mistakes and fixes
| Mistake | Why it fails | Fix |
|---|---|---|
| Sending a local file path | The API cannot fetch files from a user's machine or your private network. | Upload with /v1/files and pass the returned HTTPS URL. |
| Polling every second | Long-running video tasks do not benefit from aggressive polling and may hit rate limits. | Poll every 5-10 seconds with jitter; use webhooks for backend completion updates. |
| Trusting only a webhook | Delivery can fail even when the task succeeded. | Keep GET /v1/tasks/{task_id} as the source of truth. |
Using duration to force billing length | Detected audio duration is authoritative when BeatAPI can read it. | Use duration only as a fallback for duration detection. |
| Returning provider URLs directly | Temporary or provider-specific URLs make support and storage harder. | Store the BeatAPI hosted MP4 URL from output.media. |
Production checklist
Before you launch a "generate music video from audio via API" feature, make sure your integration has:
- API key storage on the server only.
- File upload path for local audio, images, and subtitles.
- UI preflight for file type, size, duration, and image count.
- A database record for BeatAPI task id, workflow, status, request id, usage, and output URL.
- Polling with 5-10 second cadence and jitter.
- Webhook verification for backend updates.
- A user-visible failed state that includes retry guidance without exposing provider internals.
- Credit balance and usage display through your own account UI.
- A support view that can inspect task id, request id,
error_code,error_message, andusage.
FAQ
Can I generate a music video from only an audio file?
BeatAPI music-video tasks require an audio URL and at least one image URL. The image anchors the visual direction and gives the workflow a concrete reference for the generated video.
Do I need to upload files before every task?
No. If you already have public HTTPS URLs that satisfy the input requirements, you can use them directly. Use /v1/files when your product starts from local uploads or private assets that need reusable public URLs.
Should my frontend call BeatAPI directly?
Usually no. Keep the API key on your backend. Let the frontend upload through your app, create a task through your backend, and poll your own task record.
When should I use webhooks instead of polling?
Use polling for the simplest integration and webhooks when your backend needs automatic completion updates. Even with webhooks, keep the task endpoint as the recovery source of truth.
What happens if the task fails?
The task returns failed with error_code, error_message, usage, and request_id evidence. Use that record to decide whether to show a retry, refund, or support path.
How do credits work for music-video tasks?
BeatAPI charges music-video tasks by detected or fallback billable duration and output controls. The public launch rates include 540p, 720p, 1080p, high quality, and a lip-sync add-on. Tie your product's billing display to the task record so support can explain the final result.
Is the final output a downloadable MP4?
Successful tasks return hosted MP4 media in output.media. Your product can store and render that URL instead of passing provider-specific output links to customers.
