# mv.flows

> The flows methods of @morevoice/sdk: Call flows: drafts, published versions and simulation.

Call flows: drafts, published versions and simulation. These methods are on `mv.flows`, where `mv` is your client (see [the Node.js SDK](https://docs.morevoice.ai/sdk/node/#connect)). Each one returns the response object and throws when the API answers with an error.

## `create()`

**Create a flow.** Creates a flow with an empty draft, a template's, or the `graph` you send. It runs on calls once published (POST /v1/flows/{id}/publish).

```ts
mv.flows.create(body: FlowsCreateData["body"], options?: RequestOptions): Promise<FlowsCreateResponse>
```

`POST /flows` · [API reference](https://docs.morevoice.ai/api/operations/flows_create/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `body.name` | `string` | yes |  |
| `body.assistant_id` | `string \| null` | no | `asst_…` ID. |
| `body.description` | `string` | no |  |
| `body.graph` | `FlowGraphParamsInput` | no | A whole graph to write. Nodes are matched to the stored draft by `key`. |
| `body.kind` | `"voice" \| "agent_script" \| "ivr"` | no |  |
| `body.language` | `"he" \| "en"` | no | The template's / empty flow's language (default he). |
| `body.template_id` | `string` | no | Start from a template instead of an empty flow. |
| `options.headers["MoreVoice-Version"]` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `options.headers["Idempotency-Key"]` | `string` | no | A unique key (for example a UUID) that makes this request safe to retry: for 24 hours, a retry with the same key and parameters returns the first response instead of acting twice. |
| `options` | `RequestOptions` | no | `idempotencyKey`, extra `headers` and an abort `signal`: see [retries and idempotency](https://docs.morevoice.ai/sdk/typescript/retries/). |

### Returns

`Flow`:

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` | The flow's ID. |
| `object` | `"flow"` | Always `flow`. |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `name` | `string` | — |
| `description` | `string` | — |
| `kind` | `"voice" \| "agent_script" \| "ivr"` | voice: drives an AI assistant; agent_script: a human agent's branching script; ivr: a phone menu. |
| `status` | `"draft" \| "published" \| "archived"` | — |
| `published_version` | `integer \| null` | The version calls run (null: never published). |
| `latest_version` | `integer` | — |
| `draft_rev` | `integer` | The draft's revision: send it as `base_rev` when you write the draft. |
| `assistant_id` | `string \| null` | `asst_…` ID. |
| `template_id` | `string \| null` | — |
| `node_count` | `integer` | — |
| `updated` | `string` | An ISO-8601 timestamp in UTC. |

### Example

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

const flow = await mv.flows.create({
	kind: "voice",
	language: "en",
	name: "Reception",
});
console.log(flow);
```

## `delete()`

**Delete a flow.** Deletes the flow and its versions. 409 while an assistant or a copilot profile uses it (details list them): detach it first.

```ts
mv.flows.delete(id: FlowsDeleteData["path"]["id"], options?: RequestOptions): Promise<FlowsDeleteResponse>
```

`DELETE /flows/{id}` · [API reference](https://docs.morevoice.ai/api/operations/flows_delete/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A flow ID (`flow_…`). |
| `options.headers["MoreVoice-Version"]` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `options.headers["Idempotency-Key"]` | `string` | no | A unique key (for example a UUID) that makes this request safe to retry: for 24 hours, a retry with the same key and parameters returns the first response instead of acting twice. |
| `options` | `RequestOptions` | no | `idempotencyKey`, extra `headers` and an abort `signal`: see [retries and idempotency](https://docs.morevoice.ai/sdk/typescript/retries/). |

### Returns

`DeletedFlow`:

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` | A flow ID (prefix `flow_`). |
| `object` | `"flow"` | Always `flow`. |
| `deleted` | `true` | — |

### Example

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

const deletedFlow = await mv.flows.delete("flow_7Hk2Lm9Qp");
console.log(deletedFlow);
```

## `duplicate()`

**Duplicate a flow.** Creates a new flow from this one's draft (unpublished, linked to no assistant).

```ts
mv.flows.duplicate(id: FlowsDuplicateData["path"]["id"], body?: FlowsDuplicateData["body"], options?: RequestOptions): Promise<FlowsDuplicateResponse>
```

`POST /flows/{id}/duplicate` · [API reference](https://docs.morevoice.ai/api/operations/flows_duplicate/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A flow ID (`flow_…`). |
| `body.name` | `string` | no | Default: the original's name with "(copy)". |
| `options.headers["MoreVoice-Version"]` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `options.headers["Idempotency-Key"]` | `string` | no | A unique key (for example a UUID) that makes this request safe to retry: for 24 hours, a retry with the same key and parameters returns the first response instead of acting twice. |
| `options` | `RequestOptions` | no | `idempotencyKey`, extra `headers` and an abort `signal`: see [retries and idempotency](https://docs.morevoice.ai/sdk/typescript/retries/). |

### Returns

`Flow`:

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` | The flow's ID. |
| `object` | `"flow"` | Always `flow`. |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `name` | `string` | — |
| `description` | `string` | — |
| `kind` | `"voice" \| "agent_script" \| "ivr"` | voice: drives an AI assistant; agent_script: a human agent's branching script; ivr: a phone menu. |
| `status` | `"draft" \| "published" \| "archived"` | — |
| `published_version` | `integer \| null` | The version calls run (null: never published). |
| `latest_version` | `integer` | — |
| `draft_rev` | `integer` | The draft's revision: send it as `base_rev` when you write the draft. |
| `assistant_id` | `string \| null` | `asst_…` ID. |
| `template_id` | `string \| null` | — |
| `node_count` | `integer` | — |
| `updated` | `string` | An ISO-8601 timestamp in UTC. |

### Example

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

const flow = await mv.flows.duplicate("flow_7Hk2Lm9Qp", {
	name: "Reception B",
});
console.log(flow);
```

## `list()`

**List flows.** Your flows, most recently changed first (archived ones only with include_archived=true).

```ts
mv.flows.list(query?: NonNullable<FlowsListData["query"]>, options?: RequestOptions): PagedList<FlowsListResponse["data"][number], NonNullable<FlowsListData["query"]>>
```

`GET /flows` · [API reference](https://docs.morevoice.ai/api/operations/flows_list/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `query.limit` | `integer` | no | How many objects to return, 1–100 (default 20). |
| `query.starting_after` | `string` | no | A cursor (`next_cursor`) or object ID: return the objects after it (older). |
| `query.ending_before` | `string` | no | A cursor or object ID: return the objects before it (newer). |
| `query.kind` | `string` | no | Only flows of this kind. |
| `query.assistant_id` | `string` | no | Only flows linked to this assistant. |
| `query.include_archived` | `string` | no | Include archived flows (default false). |
| `options.headers["MoreVoice-Version"]` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `options` | `RequestOptions` | no | `idempotencyKey`, extra `headers` and an abort `signal`: see [retries and idempotency](https://docs.morevoice.ai/sdk/typescript/retries/). |

### Returns

A [`PagedList`](https://docs.morevoice.ai/sdk/typescript/pagination/): `await` it for the first page, `for await` it for every item.

### Example

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

for await (const flow of mv.flows.list()) {
	console.log(flow);
}
```

## `listVersions()`

**List a flow's versions.** Returns a page of `FlowVersion` objects, newest first. Pass `next_cursor` as `starting_after` for the next page; the SDKs iterate every page for you. Answers `404` with the code `resource_missing` when nothing has this ID in this organisation and mode.

```ts
mv.flows.listVersions(id: FlowsListVersionsData["path"]["id"], query?: NonNullable<FlowsListVersionsData["query"]>, options?: RequestOptions): PagedList<FlowsListVersionsResponse["data"][number], NonNullable<FlowsListVersionsData["query"]>>
```

`GET /flows/{id}/versions` · [API reference](https://docs.morevoice.ai/api/operations/flows_list_versions/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A flow ID (`flow_…`). |
| `query.limit` | `integer` | no | How many objects to return, 1–100 (default 20). |
| `query.starting_after` | `string` | no | A cursor (`next_cursor`) or object ID: return the objects after it (older). |
| `query.ending_before` | `string` | no | A cursor or object ID: return the objects before it (newer). |
| `options.headers["MoreVoice-Version"]` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `options` | `RequestOptions` | no | `idempotencyKey`, extra `headers` and an abort `signal`: see [retries and idempotency](https://docs.morevoice.ai/sdk/typescript/retries/). |

### Returns

A [`PagedList`](https://docs.morevoice.ai/sdk/typescript/pagination/): `await` it for the first page, `for await` it for every item.

### Example

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

for await (const flow of mv.flows.listVersions("flow_7Hk2Lm9Qp")) {
	console.log(flow);
}
```

## `publish()`

**Publish a flow.** Publishes the draft as a new immutable version; calls start using it at once. A draft with errors is refused with 409 flow_invalid (details.issues: what to fix).

```ts
mv.flows.publish(id: FlowsPublishData["path"]["id"], body?: FlowsPublishData["body"], options?: RequestOptions): Promise<FlowsPublishResponse>
```

`POST /flows/{id}/publish` · [API reference](https://docs.morevoice.ai/api/operations/flows_publish/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A flow ID (`flow_…`). |
| `body.note` | `string` | no | What changed (shown in the version history). |
| `options.headers["MoreVoice-Version"]` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `options.headers["Idempotency-Key"]` | `string` | no | A unique key (for example a UUID) that makes this request safe to retry: for 24 hours, a retry with the same key and parameters returns the first response instead of acting twice. |
| `options` | `RequestOptions` | no | `idempotencyKey`, extra `headers` and an abort `signal`: see [retries and idempotency](https://docs.morevoice.ai/sdk/typescript/retries/). |

### Returns

`Flow`:

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` | The flow's ID. |
| `object` | `"flow"` | Always `flow`. |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `name` | `string` | — |
| `description` | `string` | — |
| `kind` | `"voice" \| "agent_script" \| "ivr"` | voice: drives an AI assistant; agent_script: a human agent's branching script; ivr: a phone menu. |
| `status` | `"draft" \| "published" \| "archived"` | — |
| `published_version` | `integer \| null` | The version calls run (null: never published). |
| `latest_version` | `integer` | — |
| `draft_rev` | `integer` | The draft's revision: send it as `base_rev` when you write the draft. |
| `assistant_id` | `string \| null` | `asst_…` ID. |
| `template_id` | `string \| null` | — |
| `node_count` | `integer` | — |
| `updated` | `string` | An ISO-8601 timestamp in UTC. |

### Example

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

const flow = await mv.flows.publish("flow_7Hk2Lm9Qp", {
	note: "New opening hours",
});
console.log(flow);
```

## `restore.version()`

**Restore a flow version into the draft.** Copies the version's graph into the draft (a new draft revision). It is not published: publish to run it.

```ts
mv.flows.restore.version(id: FlowsRestoreVersionData["path"]["id"], version: FlowsRestoreVersionData["path"]["version"], options?: RequestOptions): Promise<FlowsRestoreVersionResponse>
```

`POST /flows/{id}/versions/{version}/restore` · [API reference](https://docs.morevoice.ai/api/operations/flows_restore_version/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A flow ID (`flow_…`). |
| `version` | `string` | yes | The version number. |
| `options.headers["MoreVoice-Version"]` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `options.headers["Idempotency-Key"]` | `string` | no | A unique key (for example a UUID) that makes this request safe to retry: for 24 hours, a retry with the same key and parameters returns the first response instead of acting twice. |
| `options` | `RequestOptions` | no | `idempotencyKey`, extra `headers` and an abort `signal`: see [retries and idempotency](https://docs.morevoice.ai/sdk/typescript/retries/). |

### Returns

`FlowDraft`:

| Field | Type | Description |
| --- | --- | --- |
| `object` | `"flow_draft"` | Always `flow_draft`. |
| `flow_id` | `string` | A flow ID (prefix `flow_`). |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `rev` | `integer` | Send as `base_rev` on the next write. |
| `graph` | `FlowGraph` | A flow's graph: nodes (v1 node schema) wired by their transitions' `next`, variables and settings. |
| `updated` | `string` | An ISO-8601 timestamp in UTC. |

### Example

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

const flowDraft = await mv.flows.restore.version("flow_7Hk2Lm9Qp", "3");
console.log(flowDraft);
```

## `retrieve()`

**Retrieve a flow.** The flow's details. Its graph: GET /v1/flows/{id}/draft (editable) or /versions/{version} (published).

```ts
mv.flows.retrieve(id: FlowsRetrieveData["path"]["id"], options?: RequestOptions): Promise<FlowsRetrieveResponse>
```

`GET /flows/{id}` · [API reference](https://docs.morevoice.ai/api/operations/flows_retrieve/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A flow ID (`flow_…`). |
| `options.headers["MoreVoice-Version"]` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `options` | `RequestOptions` | no | `idempotencyKey`, extra `headers` and an abort `signal`: see [retries and idempotency](https://docs.morevoice.ai/sdk/typescript/retries/). |

### Returns

`Flow`:

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` | The flow's ID. |
| `object` | `"flow"` | Always `flow`. |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `name` | `string` | — |
| `description` | `string` | — |
| `kind` | `"voice" \| "agent_script" \| "ivr"` | voice: drives an AI assistant; agent_script: a human agent's branching script; ivr: a phone menu. |
| `status` | `"draft" \| "published" \| "archived"` | — |
| `published_version` | `integer \| null` | The version calls run (null: never published). |
| `latest_version` | `integer` | — |
| `draft_rev` | `integer` | The draft's revision: send it as `base_rev` when you write the draft. |
| `assistant_id` | `string \| null` | `asst_…` ID. |
| `template_id` | `string \| null` | — |
| `node_count` | `integer` | — |
| `updated` | `string` | An ISO-8601 timestamp in UTC. |

### Example

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

const flow = await mv.flows.retrieve("flow_7Hk2Lm9Qp");
console.log(flow);
```

## `retrieveAnalytics()`

**Retrieve a flow's analytics.** How this key's mode's calls went through the flow (the latest 5000 in the range): visits, calls, drop-off, caller turns and errors per node, how often each transition was taken, how calls ended, and IVR KPIs for IVR flows. Filter by `from` / `to` (start time) and a published `version`.

```ts
mv.flows.retrieveAnalytics(id: FlowsRetrieveAnalyticsData["path"]["id"], query?: NonNullable<FlowsRetrieveAnalyticsData["query"]>, options?: RequestOptions): Promise<FlowsRetrieveAnalyticsResponse>
```

`GET /flows/{id}/analytics` · [API reference](https://docs.morevoice.ai/api/operations/flows_retrieve_analytics/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A flow ID (`flow_…`). |
| `query.from` | `string` | no | Calls that started at or after this time (ISO 8601). |
| `query.to` | `string` | no | Calls that started at or before this time (ISO 8601). |
| `query.version` | `string` | no | Only calls that ran this published version. |
| `options.headers["MoreVoice-Version"]` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `options` | `RequestOptions` | no | `idempotencyKey`, extra `headers` and an abort `signal`: see [retries and idempotency](https://docs.morevoice.ai/sdk/typescript/retries/). |

### Returns

`FlowAnalytics`:

| Field | Type | Description |
| --- | --- | --- |
| `object` | `"flow_analytics"` | Always `flow_analytics`. |
| `flow_id` | `string` | A flow ID (prefix `flow_`). |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `from` | `string \| null` | — |
| `to` | `string \| null` | — |
| `version` | `integer \| null` | — |
| `calls` | `integer` | Calls that ran the flow in the range (at most the latest 5000). |
| `nodes` | `object[]` | — |
| `transitions` | `object[]` | — |
| `ends` | `object[]` | — |
| `ivr` | `object \| null` | IVR flows: containment, abandon rate, keypad vs speech, per menu. |

### Example

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

const flowAnalytics = await mv.flows.retrieveAnalytics("flow_7Hk2Lm9Qp");
console.log(flowAnalytics);
```

## `retrieveDraft()`

**Retrieve a flow's draft.** The editable graph and its revision (`rev`: send it back as `base_rev`).

```ts
mv.flows.retrieveDraft(id: FlowsRetrieveDraftData["path"]["id"], options?: RequestOptions): Promise<FlowsRetrieveDraftResponse>
```

`GET /flows/{id}/draft` · [API reference](https://docs.morevoice.ai/api/operations/flows_retrieve_draft/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A flow ID (`flow_…`). |
| `options.headers["MoreVoice-Version"]` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `options` | `RequestOptions` | no | `idempotencyKey`, extra `headers` and an abort `signal`: see [retries and idempotency](https://docs.morevoice.ai/sdk/typescript/retries/). |

### Returns

`FlowDraft`:

| Field | Type | Description |
| --- | --- | --- |
| `object` | `"flow_draft"` | Always `flow_draft`. |
| `flow_id` | `string` | A flow ID (prefix `flow_`). |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `rev` | `integer` | Send as `base_rev` on the next write. |
| `graph` | `FlowGraph` | A flow's graph: nodes (v1 node schema) wired by their transitions' `next`, variables and settings. |
| `updated` | `string` | An ISO-8601 timestamp in UTC. |

### Example

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

const flowDraft = await mv.flows.retrieveDraft("flow_7Hk2Lm9Qp");
console.log(flowDraft);
```

## `retrieveUsage()`

**Retrieve what uses a flow.** Returns the `FlowUsage` object. Answers `404` with the code `resource_missing` when nothing has this ID in this organisation and mode.

```ts
mv.flows.retrieveUsage(id: FlowsRetrieveUsageData["path"]["id"], options?: RequestOptions): Promise<FlowsRetrieveUsageResponse>
```

`GET /flows/{id}/usage` · [API reference](https://docs.morevoice.ai/api/operations/flows_retrieve_usage/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A flow ID (`flow_…`). |
| `options.headers["MoreVoice-Version"]` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `options` | `RequestOptions` | no | `idempotencyKey`, extra `headers` and an abort `signal`: see [retries and idempotency](https://docs.morevoice.ai/sdk/typescript/retries/). |

### Returns

`FlowUsage`:

| Field | Type | Description |
| --- | --- | --- |
| `object` | `"flow_usage"` | Always `flow_usage`. |
| `flow_id` | `string` | A flow ID (prefix `flow_`). |
| `assistants` | `object[]` | — |
| `copilot_profiles` | `object[]` | — |

### Example

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

const flowUsage = await mv.flows.retrieveUsage("flow_7Hk2Lm9Qp");
console.log(flowUsage);
```

## `retrieveVersion()`

**Retrieve a flow version.** A published version, with its graph.

```ts
mv.flows.retrieveVersion(id: FlowsRetrieveVersionData["path"]["id"], version: FlowsRetrieveVersionData["path"]["version"], options?: RequestOptions): Promise<FlowsRetrieveVersionResponse>
```

`GET /flows/{id}/versions/{version}` · [API reference](https://docs.morevoice.ai/api/operations/flows_retrieve_version/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A flow ID (`flow_…`). |
| `version` | `string` | yes | The version number. |
| `options.headers["MoreVoice-Version"]` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `options` | `RequestOptions` | no | `idempotencyKey`, extra `headers` and an abort `signal`: see [retries and idempotency](https://docs.morevoice.ai/sdk/typescript/retries/). |

### Returns

`FlowVersion`:

| Field | Type | Description |
| --- | --- | --- |
| `object` | `"flow_version"` | Always `flow_version`. |
| `flow_id` | `string` | A flow ID (prefix `flow_`). |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `version` | `integer` | — |
| `note` | `string` | — |
| `checksum` | `string` | — |
| `node_count` | `integer` | — |
| `edge_count` | `integer` | — |
| `created` | `string` | An ISO-8601 timestamp in UTC. |
| `graph` | `FlowGraph` | A flow's graph: nodes (v1 node schema) wired by their transitions' `next`, variables and settings. |

### Example

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

const flowVersion = await mv.flows.retrieveVersion("flow_7Hk2Lm9Qp", "3");
console.log(flowVersion);
```

## `simulate()`

**Simulate a call through a flow.** Runs a text-only call through the flow's draft (or a published `version`) with the real flow engine and the assistant's model, and answers what happened: the turns, the nodes entered, the actions (dry runs: no API or tool request is sent) and where the call stands. Send the caller's lines as `messages` / `message`, keys as `dtmf`, silence as `no_response`. Continue the same simulation with `sim_id` (it lives 15 minutes). With a test key the models are mocks.

Send `Accept: text/event-stream` to receive the same simulation as Server-Sent Events while it runs: `sim.started` (`sim_id`, `resumed`, `kind`), then `sim.node`, `sim.turn` and `sim.action` (each with the fields of the matching FlowSimulation entry) in order, and last `sim.done`, whose data is this endpoint's JSON answer; `error` ends a failed run. Closing the connection stops the simulation. A streamed answer counts against the key's stream limit and is not stored for Idempotency-Key replays.

```ts
mv.flows.simulate(id: FlowsSimulateData["path"]["id"], body?: FlowsSimulateData["body"], options?: RequestOptions): Promise<FlowsSimulateResponse>
```

`POST /flows/{id}/simulate` · [API reference](https://docs.morevoice.ai/api/operations/flows_simulate/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A flow ID (`flow_…`). |
| `body.dtmf` | `string` | no | Keys the caller presses, in order (after `messages`, before `message`); the entry then completes. |
| `body.message` | `string` | no | One more caller line (after `messages`). |
| `body.messages` | `string[]` | no | What the caller says, one line per turn, in order. |
| `body.no_response` | `boolean` | no | The caller stays silent (a no-response timeout). |
| `body.sim_id` | `string` | no | Continue this simulation (the `id` of an earlier answer; it lives 15 minutes after its last turn). Default: a new one. |
| `body.variables` | `Record<string, string \| number \| boolean \| null>` | no | Variables for the simulated call (merged over the flow's sample values). |
| `body.version` | `integer` | no | Simulate this published version. Default: the draft. |
| `options.headers["MoreVoice-Version"]` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `options.headers["Idempotency-Key"]` | `string` | no | A unique key (for example a UUID) that makes this request safe to retry: for 24 hours, a retry with the same key and parameters returns the first response instead of acting twice. |
| `options` | `RequestOptions` | no | `idempotencyKey`, extra `headers` and an abort `signal`: see [retries and idempotency](https://docs.morevoice.ai/sdk/typescript/retries/). |

### Returns

`FlowSimulation`:

| Field | Type | Description |
| --- | --- | --- |
| `object` | `"flow_simulation"` | Always `flow_simulation`. |
| `id` | `string` | The simulation's ID: send it as `sim_id` to continue. |
| `flow_id` | `string` | A flow ID (prefix `flow_`). |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `resumed` | `boolean` | This request continued an existing simulation. |
| `turns` | `object[]` | What was said during this request, in order. |
| `path` | `object[]` | The nodes entered during this request, in order. |
| `actions` | `object[]` | Actions and tool calls during this request (dry runs). |
| `ended` | `boolean` | — |
| `end_reason` | `string \| null` | — |
| `current_node_key` | `string \| null` | — |
| `variables` | `object` | The call's variables now (sensitive ones redacted). |
| `coverage` | `object` | — |

### Example

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

const flowSimulation = await mv.flows.simulate("flow_7Hk2Lm9Qp", {
	messages: [
		"Hi, I'd like to book an appointment",
		"Tomorrow at 10",
	],
});
console.log(flowSimulation);
```

## `update()`

**Update a flow.** Changes only the fields you send. Returns the updated `Flow`. Answers `404` with the code `resource_missing` when nothing has this ID in this organisation and mode.

```ts
mv.flows.update(id: FlowsUpdateData["path"]["id"], body?: FlowsUpdateData["body"], options?: RequestOptions): Promise<FlowsUpdateResponse>
```

`PATCH /flows/{id}` · [API reference](https://docs.morevoice.ai/api/operations/flows_update/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A flow ID (`flow_…`). |
| `body.archived` | `boolean` | no | true archives the flow (hidden from lists); false restores it. |
| `body.assistant_id` | `string \| null` | no | `asst_…` ID. |
| `body.description` | `string` | no |  |
| `body.name` | `string` | no |  |
| `options.headers["MoreVoice-Version"]` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `options` | `RequestOptions` | no | `idempotencyKey`, extra `headers` and an abort `signal`: see [retries and idempotency](https://docs.morevoice.ai/sdk/typescript/retries/). |

### Returns

`Flow`:

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` | The flow's ID. |
| `object` | `"flow"` | Always `flow`. |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `name` | `string` | — |
| `description` | `string` | — |
| `kind` | `"voice" \| "agent_script" \| "ivr"` | voice: drives an AI assistant; agent_script: a human agent's branching script; ivr: a phone menu. |
| `status` | `"draft" \| "published" \| "archived"` | — |
| `published_version` | `integer \| null` | The version calls run (null: never published). |
| `latest_version` | `integer` | — |
| `draft_rev` | `integer` | The draft's revision: send it as `base_rev` when you write the draft. |
| `assistant_id` | `string \| null` | `asst_…` ID. |
| `template_id` | `string \| null` | — |
| `node_count` | `integer` | — |
| `updated` | `string` | An ISO-8601 timestamp in UTC. |

### Example

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

const flow = await mv.flows.update("flow_7Hk2Lm9Qp", {
	name: "Reception (2026)",
});
console.log(flow);
```

## `updateDraft()`

**Replace a flow's draft.** Replaces the draft graph. Nodes are matched to the stored ones by `id`: what the v1 schema does not carry (groups, notes, editor state) is kept, and `internal` nodes stay exactly as stored. `base_rev` must be the draft's current revision, else 409 (details.draft_rev) and nothing is written — read the draft again and retry. Calls keep running the published version until you publish.

```ts
mv.flows.updateDraft(id: FlowsUpdateDraftData["path"]["id"], body: FlowsUpdateDraftData["body"], options?: RequestOptions): Promise<FlowsUpdateDraftResponse>
```

`PUT /flows/{id}/draft` · [API reference](https://docs.morevoice.ai/api/operations/flows_update_draft/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A flow ID (`flow_…`). |
| `body.graph` | `FlowGraphParamsInput` | yes | A whole graph to write. Nodes are matched to the stored draft by `key`. |
| `body.base_rev` | `integer` | yes | The draft `rev` you read: a newer draft (changed elsewhere) answers 409 and nothing is written. |
| `options.headers["MoreVoice-Version"]` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `options` | `RequestOptions` | no | `idempotencyKey`, extra `headers` and an abort `signal`: see [retries and idempotency](https://docs.morevoice.ai/sdk/typescript/retries/). |

### Returns

`FlowDraft`:

| Field | Type | Description |
| --- | --- | --- |
| `object` | `"flow_draft"` | Always `flow_draft`. |
| `flow_id` | `string` | A flow ID (prefix `flow_`). |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `rev` | `integer` | Send as `base_rev` on the next write. |
| `graph` | `FlowGraph` | A flow's graph: nodes (v1 node schema) wired by their transitions' `next`, variables and settings. |
| `updated` | `string` | An ISO-8601 timestamp in UTC. |

### Example

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

const flowDraft = await mv.flows.updateDraft("flow_7Hk2Lm9Qp", {
	base_rev: 17,
	graph: {
		nodes: [
			{
				key: "start",
				start: {
					greeting: "Hello!",
				},
				transitions: [
					{
						condition: {
							kind: "always",
						},
						next: "bye",
					},
				],
				type: "start",
			},
			{
				end: {
					message: "Goodbye.",
				},
				key: "bye",
				type: "end",
			},
		],
	},
});
console.log(flowDraft);
```

## `validate()`

**Validate a flow graph.** Checks a graph without saving it: the errors that would block publishing, plus warnings and tasks. A malformed graph answers 400.

```ts
mv.flows.validate(body: FlowsValidateData["body"], options?: RequestOptions): Promise<FlowsValidateResponse>
```

`POST /flows/validate` · [API reference](https://docs.morevoice.ai/api/operations/flows_validate/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `body.graph` | `FlowGraphParamsInput` | yes | A whole graph to write. Nodes are matched to the stored draft by `key`. |
| `options.headers["MoreVoice-Version"]` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |
| `options.headers["Idempotency-Key"]` | `string` | no | A unique key (for example a UUID) that makes this request safe to retry: for 24 hours, a retry with the same key and parameters returns the first response instead of acting twice. |
| `options` | `RequestOptions` | no | `idempotencyKey`, extra `headers` and an abort `signal`: see [retries and idempotency](https://docs.morevoice.ai/sdk/typescript/retries/). |

### Returns

`FlowValidation`:

| Field | Type | Description |
| --- | --- | --- |
| `object` | `"flow_validation"` | Always `flow_validation`. |
| `valid` | `boolean` | No errors: it can be published. |
| `issues` | `object[]` | — |

### Example

```ts
import MoreVoice from "@morevoice/sdk";

const mv = new MoreVoice(); // MOREVOICE_API_KEY from the environment

const flowValidation = await mv.flows.validate({
	graph: {
		kind: "voice",
		nodes: [
			{
				key: "start",
				transitions: [
					{
						condition: {
							kind: "always",
						},
						next: null,
					},
				],
				type: "start",
			},
		],
	},
});
console.log(flowValidation);
```
