Neurall

Voice Cloning

audioaudio/voice-clone

Record or upload about thirty seconds of a voice. From then on it reads anything you write.

Cloning produces a reusable voice rather than an asset, so it goes to POST /v3/voices and not /v3/generations. Once it is ready, the id you got back works anywhere a catalog voiceId does, including Avatar Video.

Billed per clone. One-time, $3. The voice is then free to use beyond the per-script cost of speaking with it. Live rate from GET /v3/pricing.

A complete call

Clone a voice from a thirty second sample.

1Upload the sample

POST /v3/files/upload with the recording. One speaker, no music.

curl -X POST "https://api.neurall.io/v3/files/upload" \
  -H "Authorization: nl-YOUR_API_KEY" \
  -F "files=@sample.m4a"

It answers with the file ids

{
  "files": [
    {
      "id": "f_51ac9d20",
      "originalName": "sample.m4a",
      "size": 1284336
    }
  ]
}

2Start the clone

POST /v3/voices, not /v3/generations, with the file id from step 1 as audio. It returns immediately with status running.

curl -X POST "https://api.neurall.io/v3/voices" \
  -H "Authorization: nl-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Founder voice",
    "audio": "f_51ac9d20"
  }'

It answers immediately

{
  "voice": {
    "id": "d77c…",
    "owner": "project",
    "status": "running"
  }
}

3Poll until ready

Poll GET /v3/voices/{id}. When status is done, the voice id is what you pass as args.voiceId in a voiceover or an avatar video, and it does not expire.

# repeat every 5s or so until status is done, error or timeout
curl "https://api.neurall.io/v3/voices/9f2c1d84-6a3b-4f21-9c77-2f0a1b8e5d43" \
  -H "Authorization: nl-YOUR_API_KEY"

Once status is done

{
  "voice": {
    "id": "d77c…",
    "owner": "project",
    "status": "done"
  }
}

The voice’s id is a permanent handle, not a file on a clock. Store it and pass it as args.voiceId from then on.

Arguments

namestringrequired
What to call the voice in your account. Only a label; it does not affect the clone.
audiostringrequired
The sample: a file id from POST /v3/files/upload. One speaker, clean, no music or background voices.
  • MP3, WAV, M4A, OGG, FLAC or WebM, up to 30 MB.
  • At least 10 seconds of speech; about 30 seconds is what actually clones well.
  • The uploaded file is deleted 24 hours after it lands, but the trained voice is permanent.

How the prompt refers to this

args.audioThe voice sample
Not referenced in any prompt. It is the material the voice is built from, and its quality is the ceiling on the result.
descriptionstring
A note to yourself about the voice. Stored and returned, never used to clone.
webhookUrlstring
Be told instead of polling: an https URL we POST voice.done or voice.error to, signed exactly like a generation webhook.

Clone only voices you have the right to clone; the Terms of Use make that your responsibility.

Output

Cloning returns a voice, not a file: once status is done, the voice object itself is the result.

idstring
The permanent handle. Pass it as args.voiceId in a voiceover or an avatar video; unlike a generated file, it never expires.
statusstring
running, done or error. The same vocabulary as a generation, so the poll loop you already have works unchanged.
ownerstring
Always project for a clone; catalog voices list as neurall.
namestring
The label you gave it, echoed back.
descriptionstring
Your note, if you sent one.
errorstring
Present only when status is error. A failed clone is refunded automatically.

Limits and failure

Sample
At least 10 seconds, about 30 recommended, 30 MB max.
Collection
POST /v3/voices, polled at GET /v3/voices/{id}. Generations do not apply.
Result
A permanent voice id. Unlike an output file, it does not expire.
Concurrency
Five voices may be training at once, separately from the generation ceiling. Over it the API answers 429 with a Retry-After header.
Sample lifetime
The uploaded recording is deleted 24 hours after it lands. The cloned voice is unaffected: it is built while cloning, not read from the upload later.
Deletion
DELETE /v3/voices/{id} destroys the voice. It is not reversible, and any later generation passing that voiceId is rejected with a 400.
Failure
A failed or timed-out generation is refunded automatically.

Worth knowing

  • The id that comes back is the whole handle. A clone is reached as args.voiceId, exactly like a catalog voice, so nothing downstream has to know which of the two it was given.
  • GET /v3/voices lists your clones alongside the catalog. Pass ?owner=project for only your own.
  • Deleting a voice cannot be undone; cloning again is a new generation.