Music Generations
Minimum-discount routing: Prefix the path with a min{N} segment (e.g. /min30/v1/music/generations) to require marketplace seller offers to meet a minimum estimated buyer discount before routing. Buyer-owned providers are not covered. See Minimum-Discount Routing.
Async music and text-to-audio generation via the marketplace. Same flow as video: submit, poll, retrieve.
Submit Job
Auth: API key required (Authorization: Bearer ***).
modelstringrequiredModel ID, e.g.venice-ace-step-15; legacyvenice-music-genmaps to ACE-SteppromptstringrequiredPrompt or narration text (max 2000 chars)duration_secondsintegerTrack/audio duration. Optional; omitted values use the model's default duration when knownlyrics_promptstringLyrics text (max 5000 chars) for models that support lyricsforce_instrumentalbooleanGenerate without vocals when supportedvoicestringVoice selection for TTS-like audio modelslanguage_codestringLanguage for lyrics or speech models when supportedwebhook_urlstringAccepted and validated, but not delivered yet — terminal-state callbacks are not enabled in production. Poll insteadmetadataobjectClient pass-through metadata
Current Venice-backed examples include venice-ace-step-15, venice-elevenlabs-music, venice-minimax-music-v26, venice-stable-audio-25, venice-elevenlabs-sound-effects-v2, venice-mmaudio-v2-text-to-audio, and Venice audio TTS models. Query /v1/models and /api/markets for the live catalog and active order book.
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"object": "media.job",
"kind": "music",
"status": "queued",
"created": 1713200000,
"expires_at": 1713200900,
"estimated_cost_usdc": "30000",
"max_cost_usdc": "33000",
"poll_url": "/v1/music/generations/550e8400-...",
"cancel_url": "/v1/music/generations/550e8400-...",
"job_token": "mjt_abc123..."
}- SubmitReturns job id + poll_url
- Poll2s then back off to 10s
- Terminalcompleted, failed, or expired
Poll Status
Auth: API key OR X-Job-Token header.
Rolling out. The error object below is the shape the API is moving to. Until the rollout completes,
a terminal job may instead carry type set to its status ("failed", "canceled") and no retryable
field. Write your handler to tolerate both: treat a missing retryable as "safe to retry unless type is
invalid_request", and do not assume error is absent on a cancel.
The error object. Present on a terminal job that failed, and absent on one that succeeded or was
cleanly canceled. type comes from a closed vocabulary, so it is safe to branch on:
type | retryable | Means |
|---|---|---|
invalid_request | false | The request was refused on its merits. It will be refused again — change the request. |
provider_error | true | The job failed while it was being generated. |
provider_unavailable | true | The job could not be completed in time, or could not be confirmed with any provider. |
expired | true | The job passed its deadline before it completed. |
execution_start_failed | true | The job could not be started. |
unknown | true | The job failed without a reported reason. |
invalid_requestretryable · falseMeans · The request was refused on its merits. It will be refused again — change the request.provider_errorretryable · trueMeans · The job failed while it was being generated.provider_unavailableretryable · trueMeans · The job could not be completed in time, or could not be confirmed with any provider.expiredretryable · trueMeans · The job passed its deadline before it completed.execution_start_failedretryable · trueMeans · The job could not be started.unknownretryable · trueMeans · The job failed without a reported reason.retryable is the field to branch on rather than type: it is false for exactly one value today, and a
new type added later will carry the right retryable without your code changing. You are not charged for
a job that ends in any of these.
{
"id": "550e8400-...",
"object": "media.job",
"kind": "music",
"status": "succeeded",
"results": [
{
"artifact_index": 0,
"url": "$SURPLUS_BASE_URL/media/artifacts/job-id/0",
"content_type": "audio/mpeg",
"duration_seconds": 60,
"bytes": 1200000
}
],
"usage": {
"seller_cost_usdc": "30000",
"buyer_cost_usdc": "30000",
"settlement_status": "confirmed"
}
}Cancel Job
Same as video.
Errors
| Status | Code | When |
|---|---|---|
400 | invalid_request | A malformed parameter, or an image-to-video-only model submitted with no source image |
402 | insufficient_credit / insufficient_balance / insufficient_allowance | The job's max_cost_usdc is more than you can cover on any rail |
402 | account_frozen / org_frozen / org_closed | The paying account is under review or closed |
404 | model_not_found | The model is not in the media catalog |
404 | no_sellers_for_model | No seller can serve this model on this endpoint. This includes a model whose only offers are listed against a host that does not run async music at all — those offers are excluded from routing rather than accepted and failed later, so the refusal arrives before you are charged |
503 | no_healthy_sellers | Sellers exist and can serve the endpoint, but none is currently healthy or able to accept this input. Retryable |
400Code · invalid_requestWhen · A malformed parameter, or an image-to-video-only model submitted with no source image402Code · insufficient_credit / insufficient_balance / insufficient_allowanceWhen · The job's max_cost_usdc is more than you can cover on any rail402Code · account_frozen / org_frozen / org_closedWhen · The paying account is under review or closed404Code · model_not_foundWhen · The model is not in the media catalog404Code · no_sellers_for_modelWhen · No seller can serve this model on this endpoint. This includes a model whose only offers are listed against a host that does not run async music at all — those offers are excluded from routing rather than accepted and failed later, so the refusal arrives before you are charged503Code · no_healthy_sellersWhen · Sellers exist and can serve the endpoint, but none is currently healthy or able to accept this input. RetryableA 404 is a statement about supply and will not fix itself on retry; a 503 is transient.
Differences from Video
- Default expiry: 15 minutes.
- Poll schedule is faster: 2s initial, 10s cap.
- Supports
lyrics_prompt,force_instrumental,voice, andlanguage_codewhere the selected Venice model supports them. - Seller validation and offer health use
/audio/quoteso onboarding does not spend provider credits on full generations. results[].urlis an authenticated URL on this API, exactly as for video — sendAuthorizationorX-Job-Tokenand follow redirects. The retention window runs from when the job reached a terminal state (3 hours by default) and stored artifacts are purged within a day regardless, so download promptly.