> ## Documentation Index
> Fetch the complete documentation index at: https://docs.soundpiece.co/llms.txt
> Use this file to discover all available pages before exploring further.

# New sound effect

> Generate a one-shot sound effect from a description

`create.new_fx` makes a single sound effect from a description: a riser, an impact, a whoosh, a transition, or everyday foley like footsteps or a keyboard. Use it for video edits, games, apps and adverts.

For music rather than a sound, use [`create.new_sample`](/guides/create/new_sample).

***

## The request

| Field | Required | What it is |
| - | - | - |
| `prompt` | yes | A description of the sound, up to 450 characters, e.g. `"rising whoosh transition"`. |
| `duration` | yes | The length you want, in seconds. |
| `idempotency_key` | yes | A UUID that identifies this job. The [reference client](/client) fills it in for you. |
| `callback_url` | no | An HTTPS address to receive a [webhook](/webhooks) when the work is finished. |

Every field, with its exact rules: [submit](/api-reference/create/new_fx/submit) and [poll](/api-reference/create/new_fx/poll) in the API Reference.

***

## Example

This makes a 3-second cinematic impact and saves it. It uses the [reference client](/client); save `soundpiece.py` or `soundpiece.mjs` next to it first.

```python fx.py theme={null}
import soundpiece

fx = soundpiece.run("create.new_fx", {
    "prompt": "a deep cinematic impact with a long metallic tail",
    "duration": 3,
})

soundpiece.download(fx["output"]["url"], "impact.flac")
print("Saved impact.flac")
```

```javascript fx.mjs theme={null}
import { run, download } from "./soundpiece.mjs";

const fx = await run("create.new_fx", {
  prompt: "a deep cinematic impact with a long metallic tail",
  duration: 3,
});

await download(fx.output.url, "impact.flac");
console.log("Saved impact.flac");
```

```bash cURL theme={null}
#!/usr/bin/env bash
# Submit, wait and download by hand. Needs curl, jq and uuidgen.
set -euo pipefail
API=https://api.soundpiece.co/v1
AUTH="Authorization: Bearer $SOUNDPIECE_API_KEY"

# 1. Submit. Sending this exact body again (same idempotency_key) is safe.
body=$(jq -n --arg key "$(uuidgen)" '{
  idempotency_key: $key,
  prompt: "a deep cinematic impact with a long metallic tail",
  duration: 3
}')
response=$(curl --silent --show-error --max-time 30 --request PUT "$API/create.new_fx" \
  --header "$AUTH" --header "Content-Type: application/json" --data "$body")
result=$(jq -e .fx <<<"$response") || { echo "$response"; exit 1; }
id=$(jq -r .id <<<"$result")

# 2. Wait. Each call returns as soon as the work is finished, or after 20 seconds.
while [ "$(jq -r .status <<<"$result")" = processing ]; do
  response=$(curl --silent --show-error --max-time 30 "$API/create.new_fx?id=$id&wait=true" \
    --header "$AUTH")
  result=$(jq -e .fx <<<"$response") || { echo "$response"; exit 1; }
done

# 3. Download, or show what went wrong.
if [ "$(jq -r .status <<<"$result")" = failed ]; then
  jq .error <<<"$result"
  exit 1
fi
curl --silent --show-error --fail --output impact.flac "$(jq -r .output.url <<<"$result")"
echo "Saved impact.flac"
```

***

## The result

`run` returns the finished `fx` object:

```json theme={null}
{
  "id": "op_01ks2qgr1vj06e2f8g9h1k4m7n",
  "status": "ready",
  "created_at": "2026-10-10T09:15:02Z",
  "idempotency_key": "a7b8c9d0-e1f2-4a3b-8c4d-5e6f7a8b9c0d",
  "prompt": "a deep cinematic impact with a long metallic tail",
  "duration": 3.0,
  "output": {
    "url": "https://cdn.soundpiece.co/...signed...",
    "expires_at": "2026-10-10T09:31:40Z",
    "duration": 3.0
  },
  "error": null
}
```

| Field | What it means |
| - | - |
| `prompt`, `duration` | What you asked for. |
| `output.url` | A signed link to the effect, as a FLAC file (44.1 kHz). It needs no API key. |
| `output.expires_at` | When the link stops working. Poll the operation again for a fresh one. |
| `output.duration` | The effect's length in seconds. |

***

## Choosing parameters

* **Prompt.** Describe the sound itself: what makes it, what happens, and where. `"footsteps on gravel, slow, outdoors"` works better than `"walking sound"`. Keep it under 450 characters.
* **Duration.** Match the moment it's for: a second or two for an impact or a click, a few seconds for a riser or a transition.
* **Loudness.** This endpoint doesn't take a `loudness` block. To normalise an effect, pass its URL to [`adapt.normalise_loudness`](/guides/adapt/normalise_loudness).

***

## Errors

**When you submit** (the request is refused, nothing is charged):

| Status | `type` | Why |
| - | - | - |
| `422` | `string_too_short` / `string_too_long` | `prompt` is empty or over 450 characters. |
| `422` | `missing` | `prompt` or `duration` is missing. |
| `422` | `idempotency_key_reused` | The key was already used for a different endpoint. |
| `402` | `insufficient_credits` | Your balance is below 3 credits. |

**While processing** (the operation finishes as `failed`, with an `error.code`):

| Code | Why |
| - | - |
| `tos_violation` | The prompt was rejected by our content policy. |
| `internal_error`, `generation_timeout` | Something went wrong on our side. Resubmit with the same idempotency key. |

This endpoint takes no source audio, so it has no source limits and none of the `source_*` errors.

See [Errors](/errors) for the response shapes, and for the errors every endpoint can return (`401`, `403`, `429`).

***

## Cost

**3 credits** per request. Resending a request with the same idempotency key is not charged again.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.