URL: /code/apps/media/clone · Id: `page:/code/apps/media/clone`

# Voice.clone

> Trains a Voice on a real speaker’s recordings, after the speaker records consent in that same voice.

POST https://api.sb/&#123;your-domain&#125;/voices/clone

Trains a [Voice](https://startupbuilder.dev/business/nouns/voice) on a real speaker’s recordings, after the speaker records consent in that same voice.

- **Action class:** None
- **Approval:** Runs on its own
- **Emits:** `Voice.cloned`
- **Price:** Free

```text title="Run it · Ask"
Clone my voice for the demo voiceovers, from the three recordings and my recorded consent.
```

```ts title="Run it · SDK"
import { $ } from 'startup-builder'

const result = await $.try.Voice.clone({ speaker: 'https://api.sb/leaseline.app/people/person_DanaOkafor', samples: ['https://api.sb/leaseline.app/files/file_Vc1sA2mP3l', 'https://api.sb/leaseline.app/files/file_Vc2sA2mP3l', 'https://api.sb/leaseline.app/files/file_Vc3sA2mP3l'], consent: 'https://api.sb/leaseline.app/consents/consent_Vo4cE7dK2n', scope: 'leaseline.app demo voiceovers' })
```

```json title="Run it · Response"
{
  "api": "https://api.sb/leaseline.app",
  "voice": {
    "$id": "https://api.sb/leaseline.app/voices/voice_Do8kV3cE5f",
    "$type": "Voice",
    "state": "training"
  },
  "action": {
    "operation": "Voice.clone",
    "mode": "try",
    "status": "done"
  }
}
```

Its Inputs, Outputs, Effects and guards quote [the hub’s `Voice.clone`](https://startupbuilder.dev/business/nouns/voice/clone); this page adds what each Venue honors, its limits and a worked call. It is one of the [Verbs](https://startupbuilder.dev/business/nouns/verb) of [Media](/code/apps/media#verbs).

## Inputs
| Name | Type | Default | Meaning |
| --- | --- | --- | --- |
| `speaker` | `Person` | Required | The person whose voice it is. |
| `samples` | `File[]` | Required | Recordings of the speaker. |
| `consent` | `Consent` | Required | The speaker’s Consent, spoken in the voice being cloned. |
| `scope` | `string` | Required | Who may speak in it. |

## Outputs
| Field | Type | What `null` means |
| --- | --- | --- |
| `voice` | `Voice` | Never null: the Voice, `training` until the upstream finishes. |

## Effects
**Action class**

None: no approval rule names it, so it runs within its seat’s Permissions and Limits

**Modes**

- `try`: Runs every check and returns the record as it would be; nothing is stored.
- `send`: Returns a pending Action at once; `Voice.cloned` fires when it is done.
- `do`: Waits for the Action to finish and returns the record.

**Idempotency**

Only with a key: the same `Idempotency-Key` and input return the first Action, and the same key with other input returns `409`.

**Saved or shared**

Refuses when the Consent is missing, withdrawn, or not spoken by the speaker. Moves the Voice to `ready` when training ends.

**Emits**

`Voice.cloned` with `{ voice }`

**Performed by**

[Content lead](https://startupbuilder.dev/agents/marketing/content-lead)

**Price**

Free on your own account: the platform charges nothing for the call.

## On each Venue
It acts on your own records and reaches no Venue, so every account answers the same way.

## What try does
Runs every check the call meets and returns the record as it would be; nothing is stored, sent or posted.

## Refuses when
The hub sets no guard of its own on this call: it refuses only on the shared checks every write meets (a missing record, a Permission the seat lacks).

## When it waits
Returns in one response; nothing waits.

## Example
In `send` mode the call returns its pending Action at once, and `Voice.cloned` delivers the result.

**Ask**

```text
Clone my voice for the demo voiceovers, from the three recordings and my
recorded consent.
```

**API**

```bash
curl -X POST "https://api.sb/leaseline.app/voices/clone?mode=send" \
  -H "Authorization: Bearer $SB_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "speaker": "https://api.sb/leaseline.app/people/person_DanaOkafor",
  "samples": [
    "https://api.sb/leaseline.app/files/file_Vc1sA2mP3l",
    "https://api.sb/leaseline.app/files/file_Vc2sA2mP3l",
    "https://api.sb/leaseline.app/files/file_Vc3sA2mP3l"
  ],
  "consent": "https://api.sb/leaseline.app/consents/consent_Vo4cE7dK2n",
  "scope": "leaseline.app demo voiceovers"
}'
```

**CLI**

```bash
npx startup-builder do Voice.clone --send --data '{
  "speaker": "https://api.sb/leaseline.app/people/person_DanaOkafor",
  "samples": [
    "https://api.sb/leaseline.app/files/file_Vc1sA2mP3l",
    "https://api.sb/leaseline.app/files/file_Vc2sA2mP3l",
    "https://api.sb/leaseline.app/files/file_Vc3sA2mP3l"
  ],
  "consent": "https://api.sb/leaseline.app/consents/consent_Vo4cE7dK2n",
  "scope": "leaseline.app demo voiceovers"
}'
```

`--send` returns the pending Action at once.

**MCP**

```json
{
  "name": "do",
  "arguments": {
    "mode": "send",
    "code": "return await $.Voice.clone({ speaker: 'https://api.sb/leaseline.app/people/person_DanaOkafor', samples: ['https://api.sb/leaseline.app/files/file_Vc1sA2mP3l', 'https://api.sb/leaseline.app/files/file_Vc2sA2mP3l', 'https://api.sb/leaseline.app/files/file_Vc3sA2mP3l'], consent: 'https://api.sb/leaseline.app/consents/consent_Vo4cE7dK2n', scope: 'leaseline.app demo voiceovers' })"
  }
}
```

**SDK**

```ts
import { $ } from 'startup-builder'

const result = await $.send.Voice.clone({
  speaker: 'https://api.sb/leaseline.app/people/person_DanaOkafor',
  samples: ['https://api.sb/leaseline.app/files/file_Vc1sA2mP3l', 'https://api.sb/leaseline.app/files/file_Vc2sA2mP3l', 'https://api.sb/leaseline.app/files/file_Vc3sA2mP3l'],
  consent: 'https://api.sb/leaseline.app/consents/consent_Vo4cE7dK2n',
  scope: 'leaseline.app demo voiceovers',
})
```


```json title="Response, in send mode"
{
  "mode": "send",
  "action": {
    "$id": "https://api.sb/leaseline.app/actions/action_Sd3kQ9vT2w",
    "operation": "Voice.clone",
    "status": "pending",
    "reason": "running"
  }
}
```

To retry, send the same `Idempotency-Key`: the retry returns the first answer for $0. A new key reads again.

## Used by
- **Jobs:** [Make content](/capabilities/make-content)

## Related
[`Video.draft`](/code/apps/media/draft) · [`Video.finalize`](/code/apps/media/finalize) · [`File.generate`](/code/apps/media/generate) · [`File.edit`](/code/apps/media/edit) · [`Voice.retire`](/code/apps/media/retire)