# Retrieve a copilot profile

`GET https://api.morevoice.ai/v1/copilot_profiles/{id}`

Returns the `CopilotProfile` object. Answers `404` with the code `resource_missing` when nothing has this ID in this organisation and mode.

Authenticate with a secret API key: `Authorization: Bearer $MOREVOICE_API_KEY`.

Operation ID: `copilot_profiles_retrieve`.

## Parameters

### Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | yes | A copilot profile ID (`cop_…`). |

### Headers

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `MoreVoice-Version` | `string` | no | The API version to use for this request. Defaults to the version the API key is pinned to. |

## Responses

### 200 OK

OK Returns `CopilotProfile`.

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` | The profile's ID. |
| `object` | `"copilot_profile"` | — |
| `livemode` | `boolean` | `true` in live mode, `false` in test mode. |
| `name` | `string` | — |
| `version` | `integer` | Goes up on every change. |
| `template_id` | `string \| null` | The template it was created from. |
| `goal` | `string` | What the call should achieve. |
| `tone` | `string` | How the agent should sound. |
| `company` | `string` | Who the agent represents. |
| `product` | `string` | — |
| `language` | `string` | The calls' language (`he`, `en`, …). |
| `stages` | `object[]` | The call's stages, each with a checklist (used when no `script` flow is set). |
| `objections` | `object[]` | The objection library. |
| `kb` | `object` | — |
| `kb.document_ids` | `string[]` | Knowledge-base documents the profile may use (empty: all). |
| `kb.links` | `object[]` | Reference links shown to the agent. |
| `kb.min_score` | `number` | Minimum confidence (0–1) to show a knowledge card unasked. |
| `fields` | `object[]` | Details the copilot picks out of the conversation. |
| `compliance` | `object` | — |
| `compliance.required_disclosures` | `object[]` | — |
| `compliance.forbidden_phrases` | `object[]` | — |
| `coaching` | `object` | — |
| `coaching.talk_ratio_max` | `number` | Agent share of talk time above which to nudge (0–1). |
| `coaching.monologue_seconds_max` | `number` | Continuous agent speech before "ask a question". |
| `coaching.silence_seconds_max` | `number` | Dead air before a nudge. |
| `coaching.wpm_max` | `number` | — |
| `coaching.wpm_min` | `number` | — |
| `alerts` | `object[]` | — |
| `qa_rubric` | `object[]` | The QA rubric this profile's calls are scored against (empty: the organisation's rubric). |
| `script` | `object` | — |
| `script.flow_id` | `string \| null` | An agent-script flow that drives the call branch by branch (null: the linear `stages`). |
| `script.version` | `"published" \| integer` | `published`, or a pinned version number. |
| `model` | `object` | — |
| `model.model` | `string` | — |
| `model.fallback_model` | `string` | — |
| `model.temperature` | `number` | — |
| `model.api` | `"chat" \| "responses"` | — |
| `model.priority` | `boolean` | Priority processing: steadier, lower latency, higher token price. |
| `model.max_calls_per_minute` | `integer` | Model calls per minute per call. |
| `model.speculative` | `boolean` | Start on stable interim text, before the utterance is final. |
| `model.deep_path` | `boolean` | false: the fast path only (no model calls). |
| `model.objection_similarity` | `number` | Meaning-based objection match threshold (cosine). |
| `created` | `string` | An ISO-8601 timestamp in UTC. |
| `updated` | `string` | An ISO-8601 timestamp in UTC. |

Example:

```json
{
  "alerts": [
    {
      "key": "escalation",
      "kind": "escalation",
      "label": "Asks for a manager",
      "message": "Acknowledge and offer a solution.",
      "notify_supervisor": true,
      "phrases": [
        "manager"
      ],
      "severity": "critical",
      "threshold": 0
    }
  ],
  "coaching": {
    "monologue_seconds_max": 40,
    "silence_seconds_max": 7,
    "talk_ratio_max": 0.65,
    "wpm_max": 175,
    "wpm_min": 0
  },
  "company": "Acme",
  "compliance": {
    "forbidden_phrases": [
      {
        "instead": "In most cases",
        "phrase": "guaranteed",
        "reason": "No guarantees",
        "severity": "warn"
      }
    ],
    "required_disclosures": []
  },
  "created": "2026-11-03T09:14:22.000Z",
  "fields": [
    {
      "hint": "",
      "key": "budget",
      "label": "Monthly budget",
      "options": [],
      "pattern": "",
      "required": false,
      "type": "money"
    }
  ],
  "goal": "Book a demo or a clear next step.",
  "id": "cop_8Ps2Ux5Zc7Eh0Jm3Or6Tw9",
  "kb": {
    "document_ids": [
      "kbd_6Nq0Sv3Xa5Cf8Hk1Mp4Rt7"
    ],
    "links": [],
    "min_score": 0.35
  },
  "language": "en",
  "livemode": true,
  "model": {
    "api": "chat",
    "deep_path": true,
    "fallback_model": "gpt-4.1-nano",
    "max_calls_per_minute": 12,
    "model": "gpt-4.1-mini",
    "objection_similarity": 0.72,
    "priority": true,
    "speculative": true,
    "temperature": 0.3
  },
  "name": "Outbound sales",
  "object": "copilot_profile",
  "objections": [
    {
      "examples": [
        "it costs too much"
      ],
      "follow_up": "What do you pay now?",
      "kb_query": "price list",
      "key": "price",
      "label": "Too expensive",
      "response": "Compare it with what downtime costs you today.",
      "triggers": [
        "too expensive"
      ]
    }
  ],
  "product": "Acme Cloud PBX",
  "qa_rubric": [
    {
      "description": "Asked open questions first.",
      "key": "discovery",
      "label": "Discovery",
      "weight": 60
    },
    {
      "description": "Agreed a dated next step.",
      "key": "close",
      "label": "Next step",
      "weight": 40
    }
  ],
  "script": {
    "flow_id": null,
    "version": "published"
  },
  "stages": [
    {
      "checklist": [
        {
          "ask": "",
          "key": "recorded",
          "label": "Say the call is recorded",
          "phrases": [
            "this call is recorded"
          ],
          "required": true
        }
      ],
      "goal": "Introduce yourself and ask for two minutes",
      "key": "opening",
      "label": "Opening"
    }
  ],
  "template_id": "sales-outbound",
  "tone": "Warm, confident, never pushy.",
  "updated": "2026-11-03T09:14:22.000Z",
  "version": 4
}
```

### 400 Bad Request

The request is invalid: a parameter is missing, malformed or unknown, or the version header is unknown. Returns `ErrorEnvelope`.

### 401 Unauthorized

No valid API key was sent. Returns `ErrorEnvelope`.

### 403 Forbidden

The key may not do this (a missing scope, a plan limit, or a compliance block). Returns `ErrorEnvelope`.

### 404 Not Found

No object with this ID exists in this organisation and mode. Returns `ErrorEnvelope`.

### 429 Too Many Requests

Too many requests, or no call capacity right now. Retry after the Retry-After delay. Returns `ErrorEnvelope`.

### 500 Internal Server Error

Something went wrong on MoreVoice's side. Retry with the same Idempotency-Key. Returns `ErrorEnvelope`.

## Code samples

**TypeScript**

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

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

const copilotProfile = await mv.copilotProfiles.retrieve("cop_7Hk2Lm9Qp");
console.log(copilotProfile);
```

**Python**

```python
from morevoice import MoreVoice

client = MoreVoice()  # MOREVOICE_API_KEY from the environment

copilot_profile = client.copilot_profiles.retrieve("cop_7Hk2Lm9Qp")
print(copilot_profile)
```

**cURL**

```sh
curl https://api.morevoice.ai/v1/copilot_profiles/cop_7Hk2Lm9Qp \
  -H "Authorization: Bearer $MOREVOICE_API_KEY"
```
