Appearance
Sound effects
Sound effects from a description (up to four takes at once), and sound effects for a video, timed to what happens on screen.
For a drop-in endpoint that returns one take as MP3, see POST /v1/sound-generation.
Endpoints:
GET /v1/sound-effects/optionsPOST /v1/sound-effectsPOST /v1/sound-effects/videoGET /v1/sound-effects/{id}GET /v1/sound-effects/{id}/files/{name}
Get sound effect options
GET /v1/sound-effects/options
Response
200 OK
json
{
"creditsPerSecond": 20,
"videoCreditsPerSecond": 100,
"minSeconds": 0.5,
"maxSeconds": 22,
"promptMax": 450,
"maxVariations": 4,
"videoMaxSeconds": 120,
"videoPromptMax": 450,
"maxSegments": 12,
"maxUploadBytes": 2147483648,
"examples": [
"Footsteps on gravel, slow and steady",
"A heavy wooden door creaking open",
"Cinematic whoosh transition"
]
}examples is shortened above.
Credits
Free.
Example
bash
curl https://api.cinara.ai/v1/sound-effects/options \
-H "Authorization: Bearer $CINARA_API_KEY"Create sound effects from text
POST /v1/sound-effects
Starts making one to four takes of a described sound.
Needs a verified phone.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
prompt | string | yes | The sound. 1–450 characters. |
durationSeconds | number, null or "auto" | no | Length of each take, 0.5–22 seconds, rounded to 0.1. Omit, null or "auto" lets the length fit the sound. |
loop | boolean | no | Make a sound that repeats seamlessly. Default false. |
promptInfluence | number | no | How strictly to follow the prompt, 0–1. Higher means less variation. Default 0.3. |
variations | integer | no | Takes to make, 1–4. Default 4. |
Response
201 Created
json
{
"generation": {
"id": "4e7a1c9d-2b5f-4d3e-8a6c-0f9b3e1d7a52",
"module": "sound_effects",
"status": "running",
"input": {
"kind": "text",
"fileName": "a-heavy-wooden-door-creaking-open.mp3",
"prompt": "A heavy wooden door creaking open",
"durationSeconds": 4,
"loop": false,
"promptInfluence": 0.3,
"variations": 2
},
"output": { "stage": "queued", "stageLabel": "Generating sounds" },
"credits": 160,
"error": null,
"created_at": "2026-09-15T16:05:12.774310+00:00",
"completed_at": null
},
"credits": 47972
}Errors
| Status | error | Message |
|---|---|---|
| 400 | invalid_request | Describe the sound |
| 400 | invalid_request | Keep the description under 450 characters |
| 400 | invalid_request | Choose a length from 0.5 to 22 seconds, or automatic |
| 400 | invalid_request | Prompt influence must be between 0 and 1 |
| 400 | invalid_request | Choose 1 to 4 takes |
| 402 | insufficient_credits | This needs 160 credits |
| 403 | phone_unverified | Verify your phone number to start creating. |
| 502 | generation_failed | Sound effect couldn't start. Your credits were refunded. |
Credits
- Reserved:
ceil(length × 20) × variations, where length isdurationSeconds, or 22 when automatic. - Final: for each take made,
ceil(seconds × 20). With a set length,secondsisdurationSeconds. With an automatic length, it's the take's length estimated from its file size (at 128 kbps), clamped to 0.5–22. - Takes that couldn't be made aren't charged. If no take is made, everything is refunded.
Example
bash
curl -X POST https://api.cinara.ai/v1/sound-effects \
-H "Authorization: Bearer $CINARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "A heavy wooden door creaking open", "durationSeconds": 4, "variations": 2}'Create sound effects for a video
POST /v1/sound-effects/video
Starts making sound effects for an uploaded video, and optionally puts them on the video.
Needs a verified phone.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
key | string | yes | The storage key of a finished video upload (MP4, MOV or WebM). |
durationSeconds | number | for WebM | The video's length, 1–120 seconds. Cinara reads the real length from MP4 and MOV files; a WebM's length can't be read, so send it. |
prompt | string | no | A description of the sound for the whole video. Up to 450 characters. |
segments | object[] | no | Parts of the video with their own description. 2 to 12 parts, or leave it out. |
segments[].start | number | yes | Start in seconds. The first part starts at 0; each later part starts where the one before ends. |
segments[].end | number | yes | End in seconds. After start. The last part can't end after the video. |
segments[].prompt | string | no | This part's sound. Up to 200 characters. |
keepVideo | boolean | no | Also return the video with the sound on it. Default true. |
fileName | string | no | Up to 200 characters. Defaults to the upload's file name. |
Response
201 Created
json
{
"generation": {
"id": "a1d6f3b8-7c2e-4b9a-8e5d-3f0c6a2b9e14",
"module": "sound_effects",
"status": "running",
"input": {
"kind": "video",
"key": "workspaces/3f6b2a1c-8d4e-4b7a-9c2d-5e1f0a9b8c7d/uploads/7e2b9d4a-1c6f-4a8e-b3d5-9f0a2c7e4b61/puddle-jump.mp4",
"fileName": "puddle-jump.mp4",
"contentType": "video/mp4",
"size": 18420736,
"durationSeconds": 12.5,
"durationMeasured": true,
"prompt": "A girl jumps into a puddle on a rainy street",
"segments": [],
"keepVideo": true,
"totalSteps": 2
},
"output": { "stage": "queued", "step": 1, "stageLabel": "Creating the sound" },
"credits": 1250,
"error": null,
"created_at": "2026-09-15T16:20:31.118542+00:00",
"completed_at": null
},
"credits": 46722
}Errors
| Status | error | Message |
|---|---|---|
| 400 | invalid_request | Upload the video first |
| 400 | invalid_request | The video needs to be at least 1 second long |
| 400 | invalid_request | Videos can be up to 2 minutes |
| 400 | invalid_request | Keep the description under 450 characters |
| 400 | invalid_request | Split the video into at least two parts, or leave the parts out |
| 400 | invalid_request | Use up to 12 parts |
| 400 | invalid_request | Part 2 must end after it starts |
| 400 | invalid_request | Keep part 2's description under 200 characters |
| 400 | invalid_request | The first part must start at 0:00 |
| 400 | invalid_request | Part 3 must start where part 2 ends |
| 400 | invalid_request | The last part can't end after the video |
| 404 | not_found | That upload isn't finished. Upload the video again. |
| 400 | invalid_request | Upload a video (MP4, MOV or WebM) |
| 402 | insufficient_credits | This needs 1,250 credits |
| 403 | phone_unverified | Verify your phone number to start creating. |
| 502 | generation_failed | Sound effect couldn't start. Your credits were refunded. |
Credits
max(1, ceil(seconds × 100)). Putting the sound on the video is included.
- MP4 and MOV: the length is read from the video, and a video over 2 minutes is refused before anything is charged. Charged on its real length.
- WebM: the length can't be read, so a
durationSecondsover 2 minutes is refused, a reserve is held on the longer ofdurationSecondsand an estimate from the file size, and the charge is settled to the length of the sound made.
Refunded if it fails.
Example
bash
curl -X POST https://api.cinara.ai/v1/sound-effects/video \
-H "Authorization: Bearer $CINARA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"key": "workspaces/3f6b2a1c-8d4e-4b7a-9c2d-5e1f0a9b8c7d/uploads/7e2b9d4a-1c6f-4a8e-b3d5-9f0a2c7e4b61/puddle-jump.mp4", "durationSeconds": 12.5, "prompt": "A girl jumps into a puddle on a rainy street"}'Get a sound effect job
GET /v1/sound-effects/{id}
Checks a sound effect job (text or video), moves it forward, and returns it with its files once finished.
Response
200 OK
json
{
"generation": {
"id": "4e7a1c9d-2b5f-4d3e-8a6c-0f9b3e1d7a52",
"module": "sound_effects",
"status": "succeeded",
"input": {
"kind": "text",
"fileName": "a-heavy-wooden-door-creaking-open.mp3",
"prompt": "A heavy wooden door creaking open",
"durationSeconds": 4,
"loop": false,
"promptInfluence": 0.3,
"variations": 2
},
"output": { "failedVariations": 0 },
"credits": 160,
"error": null,
"created_at": "2026-09-15T16:05:12.774310+00:00",
"completed_at": "2026-09-15T16:05:19.002187+00:00"
},
"files": [
{ "name": "sound-1", "label": "Take 1", "contentType": "audio/mpeg", "size": 64992, "url": "https://api.cinara.ai/media/1789525519/Zp81q…/workspaces/…/sound-1.mp3" },
{ "name": "sound-2", "label": "Take 2", "contentType": "audio/mpeg", "size": 64574, "url": "https://api.cinara.ai/media/1789525519/b0Wc4…/workspaces/…/sound-2.mp3" }
],
"mediaUrl": null,
"credits": 47972
}| Field | Description |
|---|---|
output.failedVariations | Text: takes that couldn't be made. |
files | Text: one file per take made, named sound-<take number> and labelled Take <n>. A missing take leaves a gap in the numbers. Video: sound ("Sound effects"), plus video ("Video with sound") when keepVideo was true. Empty until the job succeeds. |
mediaUrl | Video: a signed link (6 hours) to the uploaded video. Text: null. |
Video jobs have output.step (1 = creating the sound, 2 = putting it on the video) while running.
Failures: Sound effect took too long and was stopped., This file couldn't be read. Try MP3, WAV, M4A, MP4 or WebM., Sound effect failed.
Errors
| Status | error | Message |
|---|---|---|
| 404 | not_found | Not found |
Credits
Free to read.
Polling example
bash
while :; do
RES=$(curl -s "https://api.cinara.ai/v1/sound-effects/$ID" -H "Authorization: Bearer $CINARA_API_KEY")
[ "$(echo "$RES" | jq -r .generation.status)" != "running" ] && break
sleep 3
done
echo "$RES" | jq -r '.files[] | "\(.name) \(.url)"'Download a sound effect file
GET /v1/sound-effects/{id}/files/{name}
Downloads one finished file (sound-1, sound, video, …) as an attachment.
Response
200 OK with the file and Content-Disposition: attachment; filename="<file name>-<name>.<ext>".
Errors
| Status | error | Message |
|---|---|---|
| 404 | not_found | File not found |
Credits
Free.
Example
bash
curl -L "https://api.cinara.ai/v1/sound-effects/4e7a1c9d-2b5f-4d3e-8a6c-0f9b3e1d7a52/files/sound-1" \
-H "Authorization: Bearer $CINARA_API_KEY" -o door.mp3