# Beatra API — Reference audio to music

> Generate new music based on the style of a reference audio clip.
> Self-contained integration guide for AI coding assistants.
> Human-readable page: https://docs.beatra.ai/en/docs/capabilities/music/reference-audio-to-music

- Base URL: `https://api.beatra.ai/v1`
- Auth: `Authorization: Bearer <BEATRA_API_KEY>` — create keys in the console at https://console.beatra.ai (Developer → API keys)
- Headers: `Content-Type: application/json`; send `Idempotency-Key` (stable UUID) on create-style POSTs (24h dedupe window); optional `X-Request-Id` is echoed back.
- Interaction model: async task — create returns `202` with a `task_id`; poll `GET /v1/tasks/{task_id}` until terminal status (`succeeded` / `failed` / `canceled`), or pass `callback_url` to be notified (see appendix).

---

## Primary agent path

Use the Universal Skill with the MCP tool `beatra.music.generate` and a
`reference_audio` input. The tool is billable and returns an asynchronous task.

1. Upload local reference audio with `beatra.assets.upload` and use its
   artifact ID; an artifact from any successful Beatra music task also works
   directly.
2. If a model, reference constraint, or price matters, call
   `beatra.models.list` with `capability: "reference_audio_to_music"`.
   Otherwise use `model: "auto"` or omit `model`.
3. Create one opaque `client_request_id` and submit the final arguments once.
4. Poll the returned task with `beatra.tasks.get` until it is terminal.

## Tool arguments

```json
{
  "prompt": "Keep the groove of the reference track, shift it to a festive mood",
  "reference_audio": { "type": "artifact", "artifact_id": "artifact_01JX..." },
  "client_request_id": "music-cover-opaque-1"
}
```

`reference_audio` accepts an artifact, HTTPS URL, or data URI.

## Models, controls, and cost

Common controls are `prompt`, `reference_audio`, `lyrics`,
`instrumental`, `title`, and `model_options`. Use each only according to the
selected model's metadata.

`beatra.models.list` is the current source for selectable models, reference
duration/size/format limits (`constraints.reference_audio`), prompt and lyrics
limits, and the per-task customer price. Do not copy a model catalog or price
table into an agent prompt.

Not every control is available on every model — an instrumental
reference-audio request, for example, requires a model that supports it.
Unsupported combinations fail validation instead of being silently ignored.
Music is prepaid and billed per successful task at the selected model's
catalog price.

## Task status and recovery

`queued` and `running` are not failures. Keep polling the same `task_id`; never
submit a replacement because work is still running. On a lost create response,
retry the identical arguments with the same `client_request_id`. If any input
changes, use a new ID. Failed tasks automatically refund the charged credits.

A successful task returns the same `clips[]` structure as
[text to music](https://docs.beatra.ai/en/docs/capabilities/music/text-to-music) (`output.type` is
`reference_audio_to_music`). Artifact URLs are CDN addresses — copy them to
your own storage promptly.

## REST API

Direct protocol integrations may use `POST /v1/music/reference-audio-to-music`
and the shared task endpoints. Follow the generated [API operation](https://docs.beatra.ai/en/docs/api-reference/operations/music/ref_audio_to_music_v1_music_reference_audio_to_music_post).
Skill + MCP is the recommended integration; use REST for custom, non-agent
applications.

---

## Appendix: shared contract for async tasks

### Callbacks (optional)

Pass `callback_url` (HTTPS) when creating the task. After the task reaches a
    terminal state Beatra POSTs to it and expects a 2xx within 10 seconds:

```json
{ "event_id": "evt_...", "event_type": "task.succeeded", "event_time": "...", "task": { "...": "full task envelope" } }
```

Headers: `X-Event-Id` (stable across retries — use for idempotent dedupe),
`X-Delivery-Id`, `X-Delivery-Attempt`, `X-Task-Id`, `X-Event-Type`, `X-Timestamp`,
and, for signed delivery, `X-Signature-Key-Id` plus
`X-Signature: t=<unix_ts>,v1=<hex>` where `v1 = HMAC-SHA256(signing_secret, "<unix_ts>." + raw_body)`.
Callback signing keys are independent of API keys and are managed through the
account signing-key API or Console. Pass `callback_signing_key_id` with
`callback_url` for signed delivery, or omit it for unsigned delivery. The
secret is returned once when a signing key is created or rotated. Reject
timestamps more than 300s off. Retries on failure: 1m / 5m / 30m / 2h / 12h.
Polling `GET /v1/tasks/{task_id}` always remains the source of truth.

### Billing

Credits are an independent billing unit with no fixed exchange rate to a fiat
currency. Media tasks are charged up-front at creation; insufficient balance returns `402 insufficient_balance`
and no task is created. Failed tasks are refunded automatically — see
`billing.charged_credits` / `billing.refunded_credits` in the task envelope.

### Errors

Every non-2xx response uses one envelope:

```json
{ "error": { "code": "...", "type": "...", "message": "...", "retryable": false, "request_id": "req_..." } }
```

Retry only when `retryable` is `true`, with exponential backoff and the SAME
`Idempotency-Key`. `429` responses include `X-RateLimit-*` headers.
