Audio creatives
Songs and podcasts as editable codai Studio creatives — a multitrack timeline with sections, tracks, clips, MIDI, effects, a master bus and timed lyrics, edited with small ops.
An audio creative (kind: "audio") is a creative whose document is a multitrack audio timeline: a song or a podcast episode. It uses the same API as every other creative — create, read, edit with ops, versions, revert, fork, lint, share — and the same document, with the timeline in doc.audio. Creating, reading and editing it is free; the files you put on it come from media operations, music and speech generation or your own uploads.
curl https://ai.codai.ro/v1/studio/creatives \
-H "Authorization: Bearer $CODAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "kind": "audio", "title": "Episode 12" }'The document model
An audio document has one format, stereo (48 kHz mixdown; its 1920×1080 canvas is only used by an optional cover / visualiser scene), at most one scene (captions only) and an optional fps. Everything that matters lives in doc.audio (schema CreativeAudio):
| Field | What it holds |
|---|---|
meta | bpm (20–300), key ({ tonic, mode }), timeSignature ([4, 4]), language, loudnessTarget, sampleRate (44100 | 48000) |
sections | Song or episode parts: { id, kind, startMs, durationMs, label?, lyrics?, styleHint?, locked? }; kind is intro, verse, pre_chorus, chorus, bridge, outro, instrumental or custom |
tracks | Up to 16: { id, role, kind?, name?, gainDb?, pan?, mute?, solo?, locked?, sends?, fx?, automation?, clips[], midiClips? } |
master | The master bus: fx, targetLufs, truePeakDb, limiter |
lyrics | Timed lines { startMs, endMs, text, sectionId? } (LRC-ready) |
humanLog | Who did what: { op, actor: human | ai, ts, detail? }, appended by the server on every edit |
Milliseconds are the source of truth; bars and beats are derived from meta.bpm and meta.timeSignature.
Tracks. role is one of voice, music, sfx, drums, bass, keys, guitar, vocal, lead, pad, fx, bus, podcast_host, podcast_guest. kind is audio (default), midi (holds midiClips only) or bus (no clips; other tracks reach it through sends). fx is a chain of up to 16 effects (eq, compressor, reverb, delay, limiter, gate, deesser, pitch, chorus, saturation) with numeric params and bypass; automation envelopes target gainDb, pan or fx.<fxId>.<param>.
Clips. { id, assetId, startMs, inMs?, outMs?, gainDb?, pan?, fadeInMs?, fadeOutMs?, fadeCurve?, stretch?, pitchSemitones?, loop?, duck?, color?, generation?, locked? }. inMs / outMs are offsets into the source asset: a clip ends on the timeline at startMs + (outMs − inMs) × stretch. fadeCurve is linear, exp or s; stretch (0.25–4) keeps the pitch; generation records how a generated clip was made (public codai provider and model, prompt, seed, parent clip, op).
Ducking. Music tracks of an audio creative duck automatically under voice, vocal, podcast_host and podcast_guest clips (150 ms attack, 400 ms release, 12 dB); any clip can opt in or out with duck.
Editing with ops
Audio creatives take every common op (setMeta, setAsset, setAudioClip, removeAudioClip, setLocale…) plus 16 audio ops, sent to POST /v1/studio/creatives/{id}/ops like any other edit:
| Op | Shape |
|---|---|
| Sections | addSection { section }, updateSection { target, patch }, removeSection { target }, moveSection { target, startMs } |
| Tracks | addTrack { track, index? }, updateTrack { target, patch }, removeTrack { target } |
| Clips | splitClip { clipId, atMs, newId }, trimClip { clipId, startMs?, endMs? }, moveClip { clipId, startMs?, trackId? }, setFades { clipId, fadeInMs?, fadeOutMs?, fadeCurve? } |
| MIDI | addMidiClip { trackId, clip }, removeMidiClip { clipId }, updateMidiNotes { clipId, update?, remove?, add?, replace? } |
| Master and lyrics | setMaster { master }, setLyrics { lines } |
setMeta also accepts audio (a patch of meta) and setAudioClip a trackId. In every patch null removes an optional field, so each edit has an exact inverse and can be reverted.
{
"base_seq": 4,
"ops": [
{ "op": "addSection", "section": { "id": "chorus1", "kind": "chorus", "startMs": 32000, "durationMs": 16000 } },
{ "op": "setFades", "clipId": "c7", "fadeInMs": 500, "fadeCurve": "s" },
{ "op": "setMaster", "master": { "targetLufs": -14, "truePeakDb": -1, "limiter": true } }
]
}Mastering targets
meta.loudnessTarget takes a preset or a number of integrated LUFS (−40…−5):
| Preset | LUFS | Use |
|---|---|---|
streaming | −14 | Spotify, Apple Music, YouTube (the default when nothing is set) |
podcast | −16 | Podcast platforms |
broadcast | −23 | EBU R128 radio and TV |
master.targetLufs overrides the preset; the true peak defaults to −1 dBTP. To master a mixdown file, run audio.master with target_lufs −14, −16 or −23.
Lint
Lint adds five audio rules: clipping_risk (summed clip gain above 0 dB), missing_lyrics (a verse / pre-chorus / chorus / bridge without lyrics when the song has a vocal track), missing_loudness_target, audio_overlap (overlapping clips on one track) and audio_out_of_range (a clip or note outside its source or the timeline).
Media operations for audio
The building blocks of a song or an episode come from media operations: music.generate_ace, music.repaint, music.extend and music.cover for songs, sfx.generate for effects, audio.separate_stems to split a mix into vocal / drum / bass / other tracks, audio.denoise to clean a voice, audio.to_midi to turn a melody into a MIDI clip, audio.analyze to read BPM, key and loudness into meta, and audio.master for the final loudness. Each output is a new asset you place on a track with setAudioClip; its lineage (parent_asset_id, op) stays on the asset.
Rendering and exports
POST /v1/studio/creatives/{id}/render on an audio creative renders the mixdown: every track, clip, MIDI note, effect, send and automation is mixed with ffmpeg, mastered to the loudness target (two-pass loudnorm + true-peak limiter) and exported. The answer is 202 with the render id; poll GET /v1/studio/renders/{id} like any render.
| Field | Default | What it does |
|---|---|---|
formats | ["wav", "mp3"] | 1–3 of wav (24-bit), mp3 (320 kb/s), flac, each a separate file |
stems | false | Also one WAV per audible track (audio tracks with clips, MIDI tracks with notes) |
lrc | on when the document has timed lyrics | An LRC file of doc.audio.lyrics; true without lyrics is 400 no_lyrics |
loudness | the document's master.targetLufs / meta.loudnessTarget, else −14 | streaming (−14), podcast (−16), broadcast (−23) or LUFS (−40…−5) |
title | the creative title | Stored with the render |
curl https://ai.codai.ro/v1/studio/creatives/$ID/render \
-H "Authorization: Bearer $CODAI_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: mix-12" \
-d '{ "formats": ["wav", "mp3"], "stems": true, "loudness": "podcast" }'The 202 lists the planned outputs (kind: mix / stem / lrc, format, track_id), the resolved target_lufs and true_peak_db, duration_seconds and quote_micro_usd. When the render has succeeded, its data[] holds one asset per output (1-hour signed url, output, format, track_id) and qa the measured lufs, true_peak_db and clipping. Every file carries the AI mark inside it (WAV RIFF ICMT, MP3 ID3v2.4, FLAC Vorbis comment) and its lineage points at the render.
Price: $0.001 per output second ($0.06 per minute), minimum $0.01; stems: true adds 50 %. The quote is held on your wallet before dispatch (402 insufficient_funds when short) and the measured length is billed once. At most 20 minutes per render (400 too_long); a document with nothing audible is 400 empty_audio; every referenced asset must be yours and ready (400 asset_not_found).
Lyrics for the song come from the lyrics writer, and karaoke timing from lyrics alignment.
SDKs
TypeScript: creatives.create({ kind: 'audio' }), creatives.edit(id, { baseSeq, ops }) (types CreativeAudio, CreativeOp), creatives.renderAudio(id, { formats, stems, lrc, loudness }) (types CreativeAudioRenderRequest, CreativeAudioRenderAccepted, StudioAudioRender), plus mediaOps and lyrics. Python: client.creatives.create(...), client.creatives.edit(...), client.creatives.render_audio(id, formats=, stems=, lrc=, loudness=), client.media_ops and client.lyrics.
Creatives
Editable creative documents in codai Studio — create a video, image or deck as JSON, edit it with small, versioned changes, keep every version and render it to MP4.
Media operations
codai Studio media operations — remove backgrounds, upscale, inpaint, separate stems, denoise, master, convert audio to MIDI and generate music or sound effects from your assets.