> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://murf.ai/api/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://murf.ai/api/docs/_mcp/server.

# Instant Voice Cloning

Instant Voice Cloning builds a workspace-owned AI voice from one reference recording of up to 30 seconds. Upload a sample or point Murf at a publicly reachable URL, poll until the clone is ready, then use the voice ID you get back with any [Falcon 2](/api/docs/text-to-speech-models/falcon-2) endpoint. There is no studio session to book and no model training to wait on.

Clones are multilingual out of the box. A sample recorded in one language can speak any locale Falcon 2 supports, so one clone per speaker is usually enough.

> **Note**
>
> **Instant Voice Cloning is available on the Enterprise plan only.** It is enabled per workspace, so until it has been turned on for yours, the voice cloning endpoints return `403`.

#### [Contact Sales](https://murf.ai/enterprise)

Talk to our enterprise team about enabling Instant Voice Cloning for your workspace. Already on Enterprise? Reach out to your Customer Success Manager or email [support@murf.ai](mailto:support@murf.ai).

## Instant vs. Professional Voice Cloning

Murf offers two ways to build a custom voice. This should help you pick the one that fits.

|                 | Instant Voice Cloning                            | [Professional Voice Cloning](/api/docs/voices-styles/professional-voice-cloning) |
| --------------- | ------------------------------------------------ | -------------------------------------------------------------------------------- |
| Reference audio | One short sample, max 30 seconds and up to 40 MB | Up to 90 minutes of studio-grade recordings                                      |
| Turnaround      | A few minutes, self-serve over the API           | 1 to 4 weeks, managed by our team                                                |
| Best for        | Agent personas, prototyping, cloning at scale    | Flagship brand voices and long-form narration                                    |
| Availability    | Enterprise plan, API only                        | Enterprise plan, Murf Studio and API                                             |
| Models          | Falcon 2                                         | Falcon 2 and Gen2                                                                |

## What you get

#### Two ways to send audio

Post a file as `multipart/form-data`, or pass a public `audioUrl` as JSON. The audio requirements are the same either way.

#### Jobs you can poll

Create returns a `requestId` right away. Poll the status endpoint until it reports `COMPLETED` or `FAILED`. There are no webhooks to set up.

#### Falcon 2 speed

Clones stream over HTTP or WebSockets at Falcon 2 latency of roughly 100 ms, which is fast enough for live conversational agents.

#### Workspace-scoped control

List the clones in your workspace that are ready to use, and delete any of them for good once you are done with it.

Pricing is the same as standard Falcon 2 synthesis. Creating a clone and keeping it in your workspace costs nothing extra, so you only pay for the speech you generate with it.

## Before you start

Cloning has to be switched on for your workspace before any of the endpoints below will work. [Get in touch with our sales team](https://murf.ai/enterprise) and brief them on your exact needs and the voice profile you want to create. If you are already on Enterprise, your Customer Success Manager can do this for you.

Once it is enabled, [generate your API key](https://murf.ai/api/dashboard?utm_source=murf_api_docs) from the Murf API Dashboard and send it as the `api-key` header on every request.

Then get your reference audio ready. The same requirements apply whether you upload a file or pass a URL:

| Requirement         | Value                                                                         |
| ------------------- | ----------------------------------------------------------------------------- |
| Formats             | WAV, MP3, FLAC, ALAW, ULAW                                                    |
| Maximum duration    | 30 seconds                                                                    |
| Minimum sample rate | 24 kHz                                                                        |
| Maximum file size   | 40 MB                                                                         |
| Content             | Clear, continuous speech from a single speaker, with limited background noise |

> **Tip**
>
> If you are passing `audioUrl`, the URL has to be `http` or `https`, and its path needs a supported file extension, for example `https://example.com/sample.wav`. Private and localhost URLs are rejected.

## Clone a voice

#### Create the clone

Call [Create Voice Clone](/api/docs/api-reference/voice-cloning/create) with a `tag` (a unique identifier for the voice), an optional `displayName` to name it, plus either an `audio` file or an `audioUrl`. If you leave `displayName` empty, it falls back to the `tag`.

**`Python (multipart upload)`**

```python title="Python (multipart upload)"
import requests

url = "https://api.murf.ai/v1/speech/voices/create"
headers = {"api-key": "YOUR_API_KEY"}

with open("/path/to/reference.wav", "rb") as audio:
    response = requests.post(
        url,
        headers=headers,
        data={"tag": "my-voice", "displayName": "My Voice"},
        files={"audio": ("reference.wav", audio, "audio/wav")},
    )

print(response.json())
# {
#   "responseCode": "SUCCESS",
#   "responseMessage": "Operation was successful",
#   "requestId": "req_123"
# }
```

**`Python (JSON with audio URL)`**

```python title="Python (JSON with audio URL)"
import requests

url = "https://api.murf.ai/v1/speech/voices/create"
headers = {
    "api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
}

response = requests.post(
    url,
    headers=headers,
    json={
        "tag": "my-voice",
        "displayName": "My Voice",
        "audioUrl": "https://example.com/reference.wav",
    },
)

print(response.json())
```

**`cURL (multipart upload)`**

```curl title="cURL (multipart upload)"
curl -X POST https://api.murf.ai/v1/speech/voices/create \
  -H "api-key: YOUR_API_KEY" \
  -F tag=my-voice \
  -F "displayName=My Voice" \
  -F audio=@/path/to/reference.wav
```

**`cURL (JSON with audio URL)`**

```curl title="cURL (JSON with audio URL)"
curl -X POST https://api.murf.ai/v1/speech/voices/create \
  -H "api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tag": "my-voice",
    "displayName": "My Voice",
    "audioUrl": "https://example.com/reference.wav"
  }'
```

**`JavaScript (multipart upload)`**

```javascript title="JavaScript (multipart upload)"
import fs from "fs";
import FormData from "form-data";
import axios from "axios";

const form = new FormData();
form.append("tag", "my-voice");
form.append("displayName", "My Voice");
form.append(
  "audio",
  fs.createReadStream("/path/to/reference.wav"),
  "reference.wav",
);

const response = await axios.post(
  "https://api.murf.ai/v1/speech/voices/create",
  form,
  { headers: { "api-key": "YOUR_API_KEY", ...form.getHeaders() } },
);

console.log(response.data);
```

**`JavaScript (JSON with audio URL)`**

```javascript title="JavaScript (JSON with audio URL)"
import axios from "axios";

const response = await axios.post(
  "https://api.murf.ai/v1/speech/voices/create",
  {
    tag: "my-voice",
    displayName: "My Voice",
    audioUrl: "https://example.com/reference.wav",
  },
  {
    headers: {
      "api-key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
  },
);

console.log(response.data);
```

Hold on to the `requestId` in the response. That is how you track the job.

### Response (200)

```json
{
  "requestId": "req_123",
  "responseCode": "SUCCESS",
  "responseMessage": "Operation was successful"
}
```

If something is wrong with the request itself, you get a `400` back with an `error_message`. The usual causes are a missing `tag` or audio, an unsupported format or file extension, a file over 40 MB, or an `audioUrl` we cannot reach. Problems with the audio itself, such as a low sample rate, are accepted here with a `200` and show up later as a `FAILED` status.

#### Poll the creation status

Cloning runs in the background. Call [Voice Clone Creation Status](/api/docs/api-reference/voice-cloning/get-creation-status) with your `requestId` until `status` comes back as `COMPLETED` or `FAILED`. Checking every couple of seconds is plenty.

**`Python`**

```python title="Python"
import time
import requests

request_id = "req_123"
url = f"https://api.murf.ai/v1/speech/voice-clone-creation-status/{request_id}"
headers = {"api-key": "YOUR_API_KEY"}

while True:
    status = requests.get(url, headers=headers).json()
    print(status)
    if status["status"] in ("COMPLETED", "FAILED"):
        break
    time.sleep(2)

voice_id = status.get("voiceId")
```

**`cURL`**

```curl title="cURL"
curl -X GET "https://api.murf.ai/v1/speech/voice-clone-creation-status/req_123" \
  -H "api-key: YOUR_API_KEY"
```

**`JavaScript`**

```javascript title="JavaScript"
import axios from "axios";

const requestId = "req_123";
const statusUrl = `https://api.murf.ai/v1/speech/voice-clone-creation-status/${requestId}`;

let status;
while (true) {
  const { data } = await axios.get(statusUrl, {
    headers: { "api-key": "YOUR_API_KEY" },
  });
  status = data;
  console.log(status);
  if (status.status === "COMPLETED" || status.status === "FAILED") {
    break;
  }
  await new Promise((resolve) => setTimeout(resolve, 2000));
}

const voiceId = status.voiceId;
```

| Status       | Meaning                                                          |
| ------------ | ---------------------------------------------------------------- |
| `QUEUED`     | Job accepted and waiting to process                              |
| `PROCESSING` | Voice clone is being created                                     |
| `COMPLETED`  | Ready to use. `voiceId` is in the response, prefixed with `cln_` |
| `FAILED`     | Creation did not go through. Check `errorMessage`                |

### Response (200)

```json
{
  "requestId": "req_123",
  "status": "COMPLETED",
  "responseCode": "SUCCESS",
  "responseMessage": "Operation was successful",
  "voiceId": "cln_abcdefgh_0123456789abcdef"
}
```

#### Synthesize with Falcon 2

Use the `cln_` voice ID as your `voiceId` on any [Falcon 2](/api/docs/text-to-speech-models/falcon-2) endpoint. Nothing else about the request changes. The [streaming](/api/docs/api-reference/text-to-speech/stream) response body is raw audio bytes rather than JSON, and you get WAV back unless you set `format`.

**`Python`**

```python title="Python"
import requests

response = requests.post(
    "https://api.murf.ai/v1/speech/stream",
    headers={
        "api-key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "voiceId": "cln_abcdefgh_0123456789abcdef",
        "text": "Hello from my cloned voice.",
        "model": "falcon-2",
    },
)
response.raise_for_status()

with open("speech.wav", "wb") as f:
    f.write(response.content)
```

**`cURL`**

```curl title="cURL"
curl -X POST https://api.murf.ai/v1/speech/stream \
  -H "api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "voiceId": "cln_abcdefgh_0123456789abcdef",
    "text": "Hello from my cloned voice.",
    "model": "falcon-2"
  }' \
  --output speech.wav
```

**`JavaScript`**

```javascript title="JavaScript"
import fs from "fs";
import axios from "axios";

const response = await axios.post(
  "https://api.murf.ai/v1/speech/stream",
  {
    voiceId: "cln_abcdefgh_0123456789abcdef",
    text: "Hello from my cloned voice.",
    model: "falcon-2",
  },
  {
    headers: {
      "api-key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    responseType: "arraybuffer",
  },
);

fs.writeFileSync("speech.wav", Buffer.from(response.data));
```

For live agents, pass the same voice ID in the [WebSockets](/api/docs/text-to-speech/web-sockets) `voice_config` message:

```json
{
  "voice_config": {
    "voiceId": "cln_abcdefgh_0123456789abcdef",
    "locale": "en-US",
    "rate": 0,
    "pitch": 0
  }
}
```

> **Warning**
>
> Cloned voices only work on Falcon 2. Sending one with `model: "gen2"`, or to the non-streaming [generate](/api/docs/api-reference/text-to-speech/generate) endpoint, returns a `400`.

## Manage your cloned voices

### List cloned voices

[List Cloned Voices](/api/docs/api-reference/voice-cloning/list) gives you every clone in your workspace that is ready to use. Each one comes with a `voiceId` (prefixed with `cln_`), its `displayName`, the `tag` you set when you created it, and a `createdAt` timestamp in UTC. When you did not pass a `displayName` at creation, it mirrors the `tag`.

**`Python`**

```python title="Python"
import requests

response = requests.get(
    "https://api.murf.ai/v1/speech/voices/cloned",
    headers={"api-key": "YOUR_API_KEY"},
)
print(response.json())
```

**`cURL`**

```curl title="cURL"
curl -X GET https://api.murf.ai/v1/speech/voices/cloned \
  -H "api-key: YOUR_API_KEY"
```

**`JavaScript`**

```javascript title="JavaScript"
import axios from "axios";

const response = await axios.get(
  "https://api.murf.ai/v1/speech/voices/cloned",
  { headers: { "api-key": "YOUR_API_KEY" } },
);
console.log(response.data);
```

### Response (200)

```json
[
  {
    "voiceId": "cln_abcdefgh_0123456789abcdef",
    "displayName": "My Voice",
    "tag": "my-voice",
    "createdAt": "2026-09-02T07:50:15.296Z"
  }
]
```

> **Note**
>
> Clones do not show up in [`GET /v1/speech/voices`](/api/docs/api-reference/voices/get-voices). That endpoint covers Murf's standard voice library, so use the cloned voices endpoint above instead.

### Delete a cloned voice

[Delete Cloned Voice](/api/docs/api-reference/voice-cloning/delete) removes a clone from your workspace for good. There is no undo, and anything still sending that `voiceId` will start failing.

**`Python`**

```python title="Python"
import requests

voice_id = "cln_abcdefgh_0123456789abcdef"
response = requests.delete(
    f"https://api.murf.ai/v1/speech/voices/cloned/{voice_id}",
    headers={"api-key": "YOUR_API_KEY"},
)
print(response.status_code, response.text)
```

**`cURL`**

```curl title="cURL"
curl -X DELETE https://api.murf.ai/v1/speech/voices/cloned/cln_abcdefgh_0123456789abcdef \
  -H "api-key: YOUR_API_KEY"
```

**`JavaScript`**

```javascript title="JavaScript"
import axios from "axios";

const voiceId = "cln_abcdefgh_0123456789abcdef";
const response = await axios.delete(
  `https://api.murf.ai/v1/speech/voices/cloned/${voiceId}`,
  { headers: { "api-key": "YOUR_API_KEY" } },
);
console.log(response.status, response.data);
```

### Response (200)

```json
{
  "responseCode": "SUCCESS",
  "responseMessage": "Operation was successful"
}
```

## Endpoints

| Endpoint                                                                                                              | What it does                               |
| --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| [`POST /v1/speech/voices/create`](/api/docs/api-reference/voice-cloning/create)                                       | Send reference audio and start a clone job |
| [`GET /v1/speech/voice-clone-creation-status/{requestId}`](/api/docs/api-reference/voice-cloning/get-creation-status) | Check on a job and pick up the `voiceId`   |
| [`GET /v1/speech/voices/cloned`](/api/docs/api-reference/voice-cloning/list)                                          | List the clones in your workspace          |
| [`DELETE /v1/speech/voices/cloned/{voiceId}`](/api/docs/api-reference/voice-cloning/delete)                           | Delete a clone permanently                 |

## Responsible use

Only clone a voice you own or have clear, documented consent to clone. Murf's [Enterprise](/api/docs/resources/enterprise) commitments apply to Instant Voice Cloning as well. Your audio and text are never used to train Murf models, data is encrypted in transit and at rest, and clones stay private to the workspace that created them.

## FAQ

#### How is Instant Voice Cloning priced?

You are charged the same rates as standard Falcon 2 synthesis. Creating a clone and keeping it in your workspace carries no additional charge, so the only thing you pay for is the speech you generate with it, exactly as you would with a library voice. See [Pricing](https://murf.ai/pricing?product=api) for Falcon 2 rates, or the rates set out in your Enterprise agreement.

#### How long does a clone take to create?

Most clones are ready within a few minutes. Creation is asynchronous, so poll the status endpoint until it reports `COMPLETED` rather than building a fixed wait into your code.

#### Does the reference audio need to be in the language I want to synthesize?

No. A clone can speak any locale Falcon 2 supports, whatever language the sample was recorded in. Set `locale` on the synthesis request to pick the output language.

#### Can I clone from a video file or an unsupported format?

Not directly. Only WAV, MP3, FLAC, ALAW, and ULAW are accepted. If your source is a video or some other container, extract the audio track and export it at 24 kHz or higher before you upload it.

#### What do \`tag\` and \`displayName\` do?

`tag` is a mandatory, unique identifier for the clone. Use it to reference the voice or for any bookkeeping of your own, such as grouping clones by speaker or project. It comes back on list responses, so pick something you will still recognize later, such as the speaker name plus a version.

`displayName` is optional and sets the human-readable name of the cloned voice. If you leave it empty, `displayName` falls back to the `tag`.

#### Can I update or retrain an existing clone?

No. A clone is fixed once it has been created, and there is no update endpoint. If you want a different result, create a new clone from a better sample, point your integration at the new `voiceId`, and delete the old one once you have switched over. Deletion is permanent, so do it in that order.

#### Can everyone on my team use a clone?

Yes. Clones belong to the workspace rather than to the API key that created them, so any key in the same workspace can synthesize with them and your whole team sees them in the cloned voices list. A `voiceId` from another workspace returns a `404`.

#### Is my reference audio used to train Murf models?

No. Your reference audio and the text you synthesize are never used to train Murf models, and clones stay private to the workspace that created them. See [Enterprise](/api/docs/resources/enterprise) for the full set of data commitments.

#### Can I use a cloned voice with speech customization features?

Yes. Clones take the same Falcon 2 controls as library voices, including `rate`, `pitch`, `locale`, `format`, `sampleRate`, and pauses. See [Speech Customization](/api/docs/text-to-speech/speech-customization) for the full list. Styles are not available on cloned voices, since the clone already carries the delivery of your reference sample.

#### What does a FAILED status mean?

When `status` comes back as `FAILED`, `errorMessage` tells you why:

| `errorMessage`                                             | Likely cause                                                                                     | What to try                                                                               |
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
| `Audio File should have sample rate greater than 24KHz`    | Reference audio is below 24 kHz                                                                  | Re-export or re-record at 24 kHz or higher                                                |
| `No valid audio chunks could be extracted from the upload` | Not enough clear speech in the file, usually too much silence or noise, or very short utterances | Use a cleaner sample with continuous speech and less background noise                     |
| `Audio processing failed.`                                 | Audio could not be processed after upload                                                        | Retry with a different file. If it keeps happening, send support the full status response |

Other messages can show up for unexpected failures. Try once more with a different reference file, and if the job still fails, contact support with the full status response.

#### What are the common HTTP errors?

Error responses look like `{ "error_code": <httpStatus>, "error_message": "..." }`. These are failures on the request itself, not the `FAILED` status you get from polling.

| Case                                                                                                               | Status |
| ------------------------------------------------------------------------------------------------------------------ | ------ |
| Instant Voice Cloning is not enabled for the workspace                                                             | `403`  |
| Invalid or expired `api-key` or token                                                                              | `403`  |
| Missing `tag` or audio, unsupported format or extension, a file over 40 MB, or an unreachable `audioUrl` on create | `400`  |
| A model other than Falcon 2 used with a `cln_*` voice                                                              | `400`  |
| Malformed `voiceId` on delete, which has to use the `cln_` prefix                                                  | `400`  |
| Unknown `requestId` on the status poll                                                                             | `404`  |
| Unknown `voiceId` on delete, or one that belongs to another workspace                                              | `404`  |

Low sample rates and poor audio quality usually pass the create call with a `200`, then show up as `status: "FAILED"` when you poll.

#### How many voices can I clone, and what are the rate limits?

Clone volume and concurrency are part of your Enterprise agreement. [Rate Limits](/api/docs/resources/rate-limits) covers Falcon 2 synthesis, and your Customer Success Manager can confirm the cloning limits on your contract.