media

Generate speech, music, or a sound effect from text (metered).

Pick mode first: text_to_speech (a voice saying your exact words — prompt IS the script), text_to_music, or text_to_sfx. The model card on GET /v1/media/models says which modes each model serves.

Managed voice models (elevenlabs-native-*, listed by GET /v1/voices/capabilities) are a durable task lane instead: the answer is an audio_generation task envelope (or, with quote: true, an audio_generation_quote that starts nothing). wait: false returns it queued; poll GET /v1/media/generate-audio/{task_id} no sooner than its retry_after_ms, and stop it with POST /v1/media/generate-audio/{task_id}/cancel. voice is a vox_ id, speech_to_speech converts a source_audio upload, and an idempotency_key makes the call safe to repeat: the same key and input return the same task (replayed: true), whatever its state. Everything below this paragraph describes the other models.

Synchronous: the render runs inside this call and there is no wait: false task lane. Speech returns in seconds. Music and sound effects can be asked for at up to 600 seconds of output and may take correspondingly longer; a render that outruns this call's wait is asked to cancel and reported as a retryable 503. Repeat that call with the same idempotency_key: it adopts the existing provider job, so it returns the audio if the render finished anyway and reports it cancelled if it did not — and it can never pay for a second render. Only once it reports cancelled is a new request worth making — and that one needs a NEW idempotency_key as well as a shorter duration or fewer samples, since a changed payload under the old key is a 409 idempotency_conflict.

Direct elevenlabs-eleven-v4-turbo speech also returns ElevenLabs character alignment and normalized_alignment in each result when available, so captions can use the generated narration's timings without a transcription call.

results carries one entry per delivered take (num_samples), applied reports the knobs that actually ran, and adjustments names every field that differed from the ask, with a reason — read them before describing the output to a user. A take that came back more than half a second longer than duration_seconds is trimmed to it with a short fade-out; the full take is results[].untrimmed, and an adjustments entry says so. A take that missed by more than max(2 s, 10%) and was not trimmed is reported there too.

In a Voyager-billed workspace, the direct ElevenLabs models (speech, music and sound effects) are billed to Voyager credits, and the receipt says so (usage.billing_product: "voyager", usage.estimated_credits in Voyager credits). Every fal-hosted model, the -fal ElevenLabs copies included, is refused with 403 not_available_on_voyager_billing.

post/media/generate-audio

Request

  • Base URL
    https://api.moda.app/v1
  • URL
    https://api.moda.app/v1/media/generate-audio
  • Auth
    HTTP bearer

Headers

Moda-Version'2026-04-12' | '2026-05-01'
Example:2026-05-01

Calendar-dated API version pin. New integrations should pin 2026-05-01 to opt into the newest response shapes. For back-compat the server also accepts requests with no header and resolves them to the current default (today: 2026-04-12); that default advances on each sunset date. Any unsupported value returns 400 unsupported_version.

Request body

promptstring nullable

Sent to the selected model VERBATIM. For text_to_speech this IS the script — the words that get spoken, with no stage directions. For the other modes it describes the result: genre, instrumentation, mood, tempo, texture. Required for every mode except speech_to_speech.

modelstring required

Concrete audio model id; see GET /v1/media/models. Managed voice models (elevenlabs-native-, fishaudio-native- and inworld-native-*) are listed by GET /v1/voices/capabilities instead.

modestring required

text_to_speech, text_to_music, or text_to_sfx. Stated rather than derived — every mode takes exactly text, so there is no input role to derive it from. The model card on GET /v1/media/models says which modes each model serves. Managed voice models also take speech_to_speech (aliases sts, voice_conversion) and require mode to equal the model's operation.

voicestring nullable

Speech only. Normally a preset name from the mode's voices on GET /v1/media/models; on a mode whose card sets voice_is_free_form, voices is empty and this takes any provider voice name or cloned-voice id instead, checked for shape here and resolved by the provider. Omit for the mode's default. Managed voice models require a vox_ id from GET /v1/voices, of the model's own provider (a Fish Audio voice on a fishaudio-native-* model, an Inworld voice on an inworld-native-* model). The fishaudio-* models take a Fish voice model id or a Fish vox_ id.

num_samplesinteger nullable

Distinct takes to render, where the mode has a sample axis (max_samples on GET /v1/media/models). EVERY sample is billed, and a mode with a billing floor bills each short take at the floor.

model_paramsobject nullable

Model settings. For a managed voice model, exactly the control names its capabilities list; an unknown or out-of-range setting is a 422 unsupported_model_setting, never silently dropped.

idempotency_keystring nullable

Keys the provider-job checkpoint: a retried call with the same key resumes the existing render instead of paying for a duplicate. On a managed voice model it keys the durable execution: the same key and input return the same task (replayed: true), a different input is 409 idempotency_conflict, and keys never expire.

waitboolean

Managed voice models only. true (the default) runs the generation inside this call for up to about 210 seconds and returns the task envelope, terminal when it finished in time; false returns the queued task envelope at once — poll its poll_url no sooner than retry_after_ms.

quoteboolean

Managed voice models only. true validates the request and returns an audio_generation_quote (committed: false) with the usage estimate and a credit check. Nothing is started, held or charged, and the idempotency_key is ignored.

source_audiostring nullable

speech_to_speech only: the recording to convert, as a file_ id from POST /v1/uploads (MP3, WAV or AAC).

source_audio_cleanup'on_failure' | 'never' nullable

speech_to_speech only. on_failure deletes a source recording this user uploaded for this generation if the generation fails or is canceled; never (the default) keeps it.

quote_source_secondsnumber nullable

speech_to_speech quotes without source_audio: the recording's length in seconds (above 0, at most 300).

max_estimated_creditsinteger nullable

Managed voice models only: the credit estimate the caller approved. A generation whose admission estimate is higher is refused (422 validation_failed, estimate_exceeds_approval) before anything is held or run.

voicesstring[] nullable

Managed voice models whose capabilities set multi_speaker.supported (the Fish Audio models) only: every vox_ id of a scene rendered in one take, in speaker order, with voices[0] equal to voice. Start each turn of the prompt with <|speaker:N|>, N indexing voices.

Response

Successful Response

object required

Changes