# mv.qa

> The qa methods of @morevoice/sdk: Post-call QA scorecards and rubric.

Post-call QA scorecards and rubric. These methods are on `mv.qa`, 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.

## `overrideScorecardItem()`

**Override a scorecard item.** Sets one rubric item's score (0–5, or null for not applicable) as a supervisor would, or removes the override with `clear: true`. The call's score and pass are recomputed; the change is in the scorecard's history.

```ts
mv.qa.overrideScorecardItem(id: QaOverrideScorecardItemData["path"]["id"], itemKey: QaOverrideScorecardItemData["path"]["item_key"], body?: QaOverrideScorecardItemData["body"], options?: RequestOptions): Promise<QaOverrideScorecardItemResponse>
```

`PATCH /calls/{id}/scorecard/items/{item_key}` · [API reference](https://docs.morevoice.ai/api/operations/qa_override_scorecard_item/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A call ID (`call_…`). |
| `item_key` | `string` | yes | The rubric item's key. |
| `body.clear` | `boolean` | no | true: remove the override (the model's score applies again). |
| `body.note` | `string` | no | Why (shown in the scorecard's history). |
| `body.score` | `number \| null` | no | The item's score, 0–5 (half points round), or null for not applicable. |
| `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

`Scorecard`:

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` | The scorecard's ID (one per call). |
| `object` | `"scorecard"` | Always `scorecard`. |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `call_id` | `string` | A call ID (prefix `call_`). |
| `status` | `"pending" \| "running" \| "done" \| "error" \| "skipped"` | `skipped`: too short to score (`error` says why); `error`: scoring failed. |
| `error` | `string \| null` | — |
| `score` | `number \| null` | 0–100 after supervisor overrides (null: nothing applicable). |
| `model_score` | `number \| null` | 0–100 as the model scored it. |
| `passed` | `boolean \| null` | — |
| `critical_failed` | `string[]` | Keys of the critical items that failed the call. |
| `rubric_source` | `"default" \| "copilot_profile" \| null` | Scored against the organisation's rubric, or the call's copilot profile's. |
| `copilot_profile_id` | `string \| null` | `cop_…` ID. |
| `pass_threshold` | `number \| null` | — |
| `items` | `object[]` | One per rubric item. |
| `compliance` | `object \| null` | — |
| `disposition` | `"sale" \| "appointment" \| "callback_scheduled" \| "follow_up" \| "resolved" \| "unresolved" \| "not_interested" \| "escalated" \| … \| null` | — |
| `summary` | `string \| null` | — |
| `customer_sentiment` | `"positive" \| "neutral" \| "negative" \| "mixed" \| null` | — |
| `strengths` | `string[]` | — |
| `coaching` | `object[]` | — |
| `next_steps` | `string[]` | — |
| `objections` | `object[]` | — |
| `model` | `string \| null` | — |
| `created` | `string` | An ISO-8601 timestamp in UTC. |
| `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 scorecard = await mv.qa.overrideScorecardItem("call_7Hk2Lm9Qp", "item_key_123", {
	note: "Also asked about the decision maker.",
	score: 4,
});
console.log(scorecard);
```

## `retrieveRubric()`

**Retrieve the QA rubric.** Returns the `QaRubric` object.

```ts
mv.qa.retrieveRubric(options?: RequestOptions): Promise<QaRetrieveRubricResponse>
```

`GET /qa/rubric` · [API reference](https://docs.morevoice.ai/api/operations/qa_retrieve_rubric/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `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

`QaRubric`:

| Field | Type | Description |
| --- | --- | --- |
| `object` | `"qa_rubric"` | Always `qa_rubric`. |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `name` | `string` | — |
| `pass_threshold` | `number` | A call passes at this score (0–100) or above, with no critical item failed. |
| `items` | `object[]` | — |
| `builtin` | `boolean` | true: the built-in rubric (you have not saved your own). |

### Example

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

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

const qaRubric = await mv.qa.retrieveRubric();
console.log(qaRubric);
```

## `retrieveScorecard()`

**Retrieve a call's QA scorecard.** The call's post-call QA scorecard. Calls are scored automatically when the organisation's QA policy says so; 404 until one is.

```ts
mv.qa.retrieveScorecard(id: QaRetrieveScorecardData["path"]["id"], options?: RequestOptions): Promise<QaRetrieveScorecardResponse>
```

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

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A call ID (`call_…`). |
| `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

`Scorecard`:

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` | The scorecard's ID (one per call). |
| `object` | `"scorecard"` | Always `scorecard`. |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `call_id` | `string` | A call ID (prefix `call_`). |
| `status` | `"pending" \| "running" \| "done" \| "error" \| "skipped"` | `skipped`: too short to score (`error` says why); `error`: scoring failed. |
| `error` | `string \| null` | — |
| `score` | `number \| null` | 0–100 after supervisor overrides (null: nothing applicable). |
| `model_score` | `number \| null` | 0–100 as the model scored it. |
| `passed` | `boolean \| null` | — |
| `critical_failed` | `string[]` | Keys of the critical items that failed the call. |
| `rubric_source` | `"default" \| "copilot_profile" \| null` | Scored against the organisation's rubric, or the call's copilot profile's. |
| `copilot_profile_id` | `string \| null` | `cop_…` ID. |
| `pass_threshold` | `number \| null` | — |
| `items` | `object[]` | One per rubric item. |
| `compliance` | `object \| null` | — |
| `disposition` | `"sale" \| "appointment" \| "callback_scheduled" \| "follow_up" \| "resolved" \| "unresolved" \| "not_interested" \| "escalated" \| … \| null` | — |
| `summary` | `string \| null` | — |
| `customer_sentiment` | `"positive" \| "neutral" \| "negative" \| "mixed" \| null` | — |
| `strengths` | `string[]` | — |
| `coaching` | `object[]` | — |
| `next_steps` | `string[]` | — |
| `objections` | `object[]` | — |
| `model` | `string \| null` | — |
| `created` | `string` | An ISO-8601 timestamp in UTC. |
| `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 scorecard = await mv.qa.retrieveScorecard("call_7Hk2Lm9Qp");
console.log(scorecard);
```

## `run.scorecard()`

**Score a call.** Scores the call against its rubric now, even when it is too short for automatic scoring, and answers the scorecard (it can take a few seconds). A call that already has a finished scorecard is not scored again unless `force` is true. 409 while the call is in progress.

```ts
mv.qa.run.scorecard(id: QaRunScorecardData["path"]["id"], body?: QaRunScorecardData["body"], options?: RequestOptions): Promise<QaRunScorecardResponse>
```

`POST /calls/{id}/scorecard/run` · [API reference](https://docs.morevoice.ai/api/operations/qa_run_scorecard/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A call ID (`call_…`). |
| `body.force` | `boolean` | no | Score again even when the call already has a finished scorecard (default false: it is returned as it is). |
| `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

`Scorecard`:

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` | The scorecard's ID (one per call). |
| `object` | `"scorecard"` | Always `scorecard`. |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `call_id` | `string` | A call ID (prefix `call_`). |
| `status` | `"pending" \| "running" \| "done" \| "error" \| "skipped"` | `skipped`: too short to score (`error` says why); `error`: scoring failed. |
| `error` | `string \| null` | — |
| `score` | `number \| null` | 0–100 after supervisor overrides (null: nothing applicable). |
| `model_score` | `number \| null` | 0–100 as the model scored it. |
| `passed` | `boolean \| null` | — |
| `critical_failed` | `string[]` | Keys of the critical items that failed the call. |
| `rubric_source` | `"default" \| "copilot_profile" \| null` | Scored against the organisation's rubric, or the call's copilot profile's. |
| `copilot_profile_id` | `string \| null` | `cop_…` ID. |
| `pass_threshold` | `number \| null` | — |
| `items` | `object[]` | One per rubric item. |
| `compliance` | `object \| null` | — |
| `disposition` | `"sale" \| "appointment" \| "callback_scheduled" \| "follow_up" \| "resolved" \| "unresolved" \| "not_interested" \| "escalated" \| … \| null` | — |
| `summary` | `string \| null` | — |
| `customer_sentiment` | `"positive" \| "neutral" \| "negative" \| "mixed" \| null` | — |
| `strengths` | `string[]` | — |
| `coaching` | `object[]` | — |
| `next_steps` | `string[]` | — |
| `objections` | `object[]` | — |
| `model` | `string \| null` | — |
| `created` | `string` | An ISO-8601 timestamp in UTC. |
| `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 scorecard = await mv.qa.run.scorecard("call_7Hk2Lm9Qp", {
	force: false,
});
console.log(scorecard);
```

## `updateRubric()`

**Replace the QA rubric.** Replaces the organisation's rubric. Weights are relative, on one 0–100 scale (only the ratios count). Calls scored from now on use it; existing scorecards keep the rubric they were scored with.

```ts
mv.qa.updateRubric(body: QaUpdateRubricData["body"], options?: RequestOptions): Promise<QaUpdateRubricResponse>
```

`PUT /qa/rubric` · [API reference](https://docs.morevoice.ai/api/operations/qa_update_rubric/)

### Parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `body.items` | `object[]` | yes | The items, in order; keys must be unique and at least one item needs a weight above 0. |
| `body.name` | `string` | no | Default: "Default QA rubric". |
| `body.pass_threshold` | `number` | no | Default 70. |
| `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

`QaRubric`:

| Field | Type | Description |
| --- | --- | --- |
| `object` | `"qa_rubric"` | Always `qa_rubric`. |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `name` | `string` | — |
| `pass_threshold` | `number` | A call passes at this score (0–100) or above, with no critical item failed. |
| `items` | `object[]` | — |
| `builtin` | `boolean` | true: the built-in rubric (you have not saved your own). |

### Example

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

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

const qaRubric = await mv.qa.updateRubric({
	items: [
		{
			key: "discovery",
			label: "Discovery",
			weight: 60,
		},
		{
			key: "closing",
			label: "Next step",
			type: "boolean",
			weight: 40,
		},
	],
	pass_threshold: 75,
});
console.log(qaRubric);
```
