> ## Documentation Index
> Fetch the complete documentation index at: https://docs.verbeo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Update assistant

> Change an assistant's name, type or any part of its configuration. Send only what you are changing.

Updates an assistant in place. Send only what you are changing: everything you leave out stays as it is, down to a single setting inside `config`. You do not need to read the assistant first, and you do not overwrite a change someone else made in the dashboard a moment earlier.

## Path parameters

<ParamField path="id" type="string" required>
  UUID of the assistant.
</ParamField>

## Body

At least one field is required.

<ParamField body="agent_name" type="string">
  New display name, 1–255 characters.
</ParamField>

<ParamField body="agent_type" type="string">
  New prompt style.
</ParamField>

<ParamField body="config" type="object">
  The changes to make to the [configuration document](/api-reference/assistants/overview#the-configuration-document). They are merged into the stored document following [JSON Merge Patch (RFC 7386)](https://www.rfc-editor.org/rfc/rfc7386):

  * **An object merges** key by key, at any depth. `{"settings": {"webhookUrl": "…"}}` changes the webhook and no other setting.
  * **An array is replaced whole**: `toolIds`, `kbStoreIds`, `fileSearchStoreIds` and `settings.postCallAnalysis.fields`. To add one item, read the assistant, add it to the array, and send the whole array.
  * **`null` removes a key**, which then goes back to its default. `{"settings": {"webhookUrl": null}}` stops webhook delivery, and `{"systemPrompt": null}` restores the default prompt.
  * **`null` on a native tool switches it off.** See [below](#switching-a-native-tool-on-or-off).

  The merged document is checked, and missing settings are filled in with their defaults, as on create. That is what is saved.
</ParamField>

## Request

<CodeGroup>
  ```bash Set the webhook URL theme={null}
  curl -X PATCH "https://api.verbeo.ai/v1/assistant/550e8400-e29b-41d4-a716-446655440000" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "config": {
        "settings": { "webhookUrl": "https://api.yourcompany.com/verbeo-events" }
      }
    }'
  ```

  ```bash Rename and change the voice theme={null}
  curl -X PATCH "https://api.verbeo.ai/v1/assistant/550e8400-e29b-41d4-a716-446655440000" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "agent_name": "Customer Support (EU)",
      "config": { "voice": { "voiceId": "Kore" } }
    }'
  ```

  ```javascript Node.js theme={null}
  const id = "550e8400-e29b-41d4-a716-446655440000";

  const res = await fetch(`https://api.verbeo.ai/v1/assistant/${id}`, {
    method: "PATCH",
    headers: {
      Authorization: `Bearer ${process.env.VERBEO_API_KEY}`,
      "Content-Type": "application/json",
    },
    // Only the call length changes; every other setting is kept.
    body: JSON.stringify({ config: { settings: { maxCallDuration: 5 } } }),
  });
  const { data: assistant } = await res.json();
  ```

  ```python Python theme={null}
  import os, requests

  assistant_id = "550e8400-e29b-41d4-a716-446655440000"

  assistant = requests.patch(
      f"https://api.verbeo.ai/v1/assistant/{assistant_id}",
      headers={"Authorization": f"Bearer {os.environ['VERBEO_API_KEY']}"},
      # Only the call length changes; every other setting is kept.
      json={"config": {"settings": {"maxCallDuration": 5}}},
  ).json()["data"]
  ```
</CodeGroup>

## Response

`200 OK` with the updated assistant: its whole configuration, completed, with its `toolIds` re-checked.

```json theme={null}
{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "agent_name": "Customer Support (EU)",
    "agent_type": "Single Prompt",
    "config": { "…": "the stored document, with your changes merged in" },
    "updated_at": "2026-01-23T09:12:00.000Z"
  }
}
```

## Switching a native tool on or off

`nativeTools` entries are three-state, so an update only touches the tools you mention:

```json theme={null}
{
  "config": {
    "nativeTools": {
      "transfer_call": {
        "enabled": true,
        "mode": "static",
        "staticDestination": "+15551234567"
      },
      "send_sms": { "enabled": false }
    }
  }
}
```

A tool you switch on is provisioned if it does not exist yet. A tool you switch off keeps its settings for when you switch it back on. A tool you do not mention is left alone: it is not changed, provisioned or switched on or off. On a tool you do mention, only the fields you send change. Its other settings stay as the tool itself holds them, so retargeting a transfer does not disturb its wording, and the assistant's `nativeTools` entry is updated to show the tool as it now is.

`"send_sms": null` and `"send_sms": {"enabled": null}` do the same as `"send_sms": {"enabled": false}`, and `"nativeTools": null` switches all three native tools off. `null` on any other setting of a tool is refused. Send the value you want instead; an empty string clears a transfer's `staticDestination` or an SMS's `smsStaticMessage`.

## Two updates at once

Two updates sent to the same assistant at the same moment both land. An update that finds the assistant was changed after it read it reads the assistant again and merges again. If the assistant keeps changing, the update gives up with `409 CONFLICT`. Send it again: native tool settings you sent may already have been written, and repeating the same update is safe. Two updates that change the same native tool at the same moment are the exception: the last one written wins.

## Errors

| Code | Status | When |
| - | - | - |
| `VALIDATION_FAILED` | 422 | An empty body, a blank `agent_name`, a `config` that is not an object, an unsupported `voice.voiceId`, a knowledge-base id from another workspace, an enabled static transfer with no `staticDestination`, a native tool that is not an object or `null`, or `null` on a setting inside a native tool. The merged document is checked as a whole, so a stored value that is no longer accepted is refused too, even if you did not touch it; the message names the field. |
| `NOT_FOUND` | 404 | No such assistant, or it belongs to another workspace. |
| `CONFLICT` | 409 | The assistant kept changing while the update was being saved. Send it again; repeating it is safe. |

<Note>
  To replace the whole configuration instead, for example to save a document you edited in full, use [Replace assistant](/api-reference/assistants/replace) (`PUT`).
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.