# Voice

URL: /business/nouns/voice · Id: `noun:voice`

> A Voice is a reusable synthetic speaking voice, cloned from a consenting speaker or designed from a description, that speech Files are rendered in.

A Voice is a reusable synthetic speaking voice, cloned from a consenting speaker or designed from a description, that speech [Files](/business/nouns/file) are rendered in.

## Properties
| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `origin` | `string` | Yes | `cloned` from a real speaker’s recordings, or `designed` from a description and sounding like no real person. |
| `speaker` | [Person](/business/nouns/person) | No | The real person a cloned Voice sounds like. |
| `consent` | [Consent](/business/nouns/consent) | No | The speaker’s Consent, recorded in that voice, naming the Startup and the uses allowed; required for a cloned Voice. Never randomized. |
| `scope` | `string` | Yes | Who may speak in it: every sibling, one Startup, or one Customer. |
| `samples` | list of [File](/business/nouns/file) | No | The recordings it was trained from, kept forever. |
| `status` | `string` | Yes | `training` until the upstream finishes, `ready` for speech, `retired` once its trained copy is deleted. |

## Object
```json
{
  "$id": "https://api.sb/kilnbakery.com/voices/voice_1",
  "$type": "Voice",
  "origin": "cloned",
  "speaker": "person_1",
  "consent": "consent_1",
  "scope": "studio",
  "samples": [
    "file_1"
  ],
  "status": "training"
}
```

## Relationships
- <a id="rel-sounds-like"></a>A Voice **sounds like** one [Person](/business/nouns/person): a cloned Voice sounds like one real person, and exists only while that person’s [Consent](/business/nouns/consent) holds. `soundsLike`, inverse [`voices`](/business/nouns/person#rel-voices).

## Lifecycle

| State | Meaning | Moves to |
| --- | --- | --- |
| `training` (first) | The upstream is training it from the speaker’s recordings. | `ready` on [`Voice.trained`](/business/nouns/voice#voicetrained); `retired` by [Voice.retire](/business/nouns/voice/retire) |
| `ready` | Speech Files render in it, within its scope. | `retired` by [Voice.retire](/business/nouns/voice/retire) |
| `retired` | Its trained copy is deleted at the upstream; its record and every File made in it stay. | None: it ends here. |

## Verbs
| Verb | Description | Subject | Event | Class |
| --- | --- | --- | --- | --- |
| [Voice.clone](/business/nouns/voice/clone) | Clone trains a Voice from a real speaker’s recordings after the speaker records Consent in that same voice. | [Content Lead](/agents/marketing/content-lead) | [`Voice.cloned`](/business/events/Voice.cloned) | Two-way: `try`, `send`, `do` |
| [Voice.retire](/business/nouns/voice/retire) | Retire deletes a Voice’s trained copy at the upstream and refuses new speech in it, keeping the record and every File made. | [Privacy Officer](/agents/legal/privacy-officer) | [`Voice.retired`](/business/events/Voice.retired) | One-way (brand): `send`, `do` |
| <a id="get"></a>[Voice.get](/business/nouns/voice/get) | Returns one Voice by id. Inherited from [Noun](/business/nouns/noun). | None. | None. | Read: `try`, `do` |
| <a id="list"></a>[Voice.list](/business/nouns/voice/list) | Returns Voices, newest first, one page at a time. Inherited from [Noun](/business/nouns/noun). | None. | None. | Read: `try`, `do` |
| <a id="update"></a>[Voice.update](/business/nouns/voice/update) | Changes the given properties of a Voice. Inherited from [Noun](/business/nouns/noun). | None. | `Voice.updated` | Two-way: `try`, `send`, `do` |

A Voice is never deleted: it ends by [Voice.retire](/business/nouns/voice/retire), and its records stay.

## Events
Events no Verb emits. Each Verb’s Event is in the Verbs table above; every Event is delivered in the same shape.

### Voice.trained
The upstream finished training a cloned or designed Voice, so speech renders in it. Raised by the rail.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | `string` | Yes | `Voice.trained`. |
| `at` | `datetime` | Yes | When it happened. |
| `seq` | `integer` | No | Its position in the namespace, one more than the Event before; any seq is a cursor into the history. |
| `data` | `json` | Yes | The Thing as the Action left it. |
| `data.voice` | [Voice](/business/nouns/voice) | Yes | The Voice as the change left it. |
| `data.voice.origin` | `string` | Yes | `cloned` from a real speaker’s recordings, or `designed` from a description and sounding like no real person. |
| `data.voice.speaker` | [Person](/business/nouns/person) | No | The real person a cloned Voice sounds like. |
| `data.voice.consent` | [Consent](/business/nouns/consent) | No | The speaker’s Consent, recorded in that voice, naming the Startup and the uses allowed; required for a cloned Voice. |
| `data.voice.scope` | `string` | Yes | Who may speak in it: every sibling, one Startup, or one Customer. |
| `data.voice.samples` | list of [File](/business/nouns/file) | No | The recordings it was trained from, kept forever. |
| `data.voice.status` | `string` | Yes | `training` until the upstream finishes, `ready` for speech, `retired` once its trained copy is deleted. |
| `data.previous.status` | `string` | Yes | The `status` before this Event: `training`. |

```json
{
  "$id": "https://api.sb/kilnbakery.com/events/event_1",
  "$type": "Event",
  "name": "Voice.trained",
  "at": "2026-10-22T12:00:00Z",
  "data": {
    "voice": {
      "$id": "https://api.sb/kilnbakery.com/voices/voice_1",
      "$type": "Voice",
      "origin": "cloned",
      "speaker": "person_1",
      "consent": "consent_1",
      "scope": "studio",
      "samples": [
        "file_1"
      ],
      "status": "ready"
    },
    "previous": {
      "status": "training"
    }
  },
  "seq": 1
}
```

## Permissions
Which Access level may call each Verb. One-way Verbs wait their delay window.

| Operation | `owner` | `admin` | `member` | `viewer` |
| --- | --- | --- | --- | --- |
| `Voice.get` | Yes | Yes | Yes | Yes |
| `Voice.list` | Yes | Yes | Yes | Yes |
| `Voice.update` | Yes | Yes | Yes | No |
| `Voice.clone` | Yes | Yes | Yes | No |
| `Voice.retire` | Yes | No | No | No |

## Call it

**Ask**

```text
Clone the latest voice with a person and a file and consent.
```

**API**

```bash
curl -X POST https://api.sb/ledgerlark.com/voices/clone \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"speaker":"person_1","samples":["file_1"],"consent":"consent_1","scope":"studio"}'
```

```json
{
  "api": "https://api.sb/ledgerlark.com",
  "voice": {
    "$id": "https://api.sb/ledgerlark.com/voices/voice_1",
    "$type": "Voice",
    "origin": "cloned",
    "scope": "studio",
    "status": "training"
  },
  "action": {
    "$id": "https://api.sb/ledgerlark.com/actions/action_1",
    "operation": "Voice.clone",
    "status": "done"
  },
  "links": {
    "self": "https://api.sb/ledgerlark.com/actions/action_1"
  }
}
```

**SDK**

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

const voice = await $.Voice.clone({ speaker: 'person_1', samples: ['file_1'], consent: 'consent_1', scope: 'studio' })
```

**CLI**

```bash
npx startup-builder do Voice.clone --json '{"speaker":"person_1","samples":["file_1"],"consent":"consent_1","scope":"studio"}'
```

**MCP**

```json
{
  "name": "do",
  "arguments": {
    "code": "return await $.Voice.clone({ speaker: 'person_1', samples: ['file_1'], consent: 'consent_1', scope: 'studio' })"
  }
}
```

## Example
A language-learning app designs a Voice from the description "warm, mid-pitch, unhurried". Its scope is the one [Startup](/business/nouns/startup), and every lesson's audio [File](/business/nouns/file) renders in it.