> ## 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 sample

> Generate a short music clip at the length you choose, optionally loopable

`create.new_sample` makes a short piece of music (a "sample") from a description, at the length you ask for. Set `loopable` to make a clip that repeats seamlessly, end to start. Use it for loops in a music app, stings and idents, short backgrounds for video, or building blocks for your own tracks. Samples have no vocals.

For a full-length piece, use [`create.new_instrumental`](/guides/create/new_instrumental). For a sound rather than music (a whoosh, an impact, a door slam), use [`create.new_fx`](/guides/create/new_fx).

***

## The request

| Field | Required | What it is |
| - | - | - |
| `prompt` | yes | A description of the music, up to 1,024 characters, e.g. `"rock, guitar, energetic, no drums"`. |
| `duration` | yes | The length you want, in seconds. |
| `loopable` | no | `true` to make a clip designed to repeat seamlessly. Defaults to `false`. |
| `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_sample/submit) and [poll](/api-reference/create/new_sample/poll) in the API Reference.

***

## Example

This makes an 8-second guitar loop and saves it. It uses the [reference client](/client); save `soundpiece.py` or `soundpiece.mjs` next to it first.

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

sample = soundpiece.run("create.new_sample", {
    "prompt": "rock, guitar, energetic, no drums",
    "duration": 8,
    "loopable": True,
})

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

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

const sample = await run("create.new_sample", {
  prompt: "rock, guitar, energetic, no drums",
  duration: 8,
  loopable: true,
});

await download(sample.output.url, "sample.flac");
console.log("Saved sample.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: "rock, guitar, energetic, no drums",
  duration: 8,
  loopable: true
}')
response=$(curl --silent --show-error --max-time 30 --request PUT "$API/create.new_sample" \
  --header "$AUTH" --header "Content-Type: application/json" --data "$body")
result=$(jq -e .sample <<<"$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_sample?id=$id&wait=true" \
    --header "$AUTH")
  result=$(jq -e .sample <<<"$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 sample.flac "$(jq -r .output.url <<<"$result")"
echo "Saved sample.flac"
```

***

## The result

`run` returns the finished `sample` object:

```json theme={null}
{
  "id": "op_01ks2qcp9thz5d1e7f8g0j3k6m",
  "status": "ready",
  "created_at": "2026-10-10T09:15:02Z",
  "idempotency_key": "f6a7b8c9-d0e1-4f2a-9b3c-4d5e6f7a8b9c",
  "prompt": "rock, guitar, energetic, no drums",
  "duration": 8.0,
  "loopable": true,
  "output": {
    "url": "https://cdn.soundpiece.co/...signed...",
    "expires_at": "2026-10-10T09:31:40Z",
    "duration": 8.0
  },
  "error": null
}
```

| Field | What it means |
| - | - |
| `prompt`, `duration`, `loopable` | What you asked for. |
| `output.url` | A signed link to the sample, 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 sample's length in seconds. |

***

## Choosing parameters

* **Prompt.** Mix genre, mood and instruments, separated by commas. Say what you *don't* want too, e.g. `"no drums"`, when the sample will be layered with other parts.
* **Duration.** For a loop, choose a length that holds a whole number of bars at your tempo: at 120 BPM in 4/4, one bar is 2 seconds, so 8 seconds is four bars.
* **`loopable`.** Turn it on when the clip will repeat, so the end flows back into the start without a click or a jump. Leave it off for a one-off sting or ident.
* **Loudness.** This endpoint doesn't take a `loudness` block. To normalise a sample, 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 1,024 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.