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

# Advanced configuration

> Pre/post-conversation workflows, recording locations, and noise cancellation.

The agent wizard covers the common fields, but `AgentConfig` exposes top-level options that the wizard does not surface: pre- and post-conversation workflows, custom recording locations, and noise cancellation. Set them in the agent config JSON or via the API.

The full, authoritative shape of every field is published as a JSON Schema. Fetch it before building requests so you always match the deployed version:

```bash theme={null}
curl https://api.anyreach.ai/core/agent-config-schema \
  -H "Authorization: Bearer <token>"
```

`GET /core/agent-config-schema` returns the JSON Schema generated directly from the `AgentConfig` model, so it is the source of truth for field names, types, defaults, and enum values.

## Pre-conversation workflow

`pre_conversation_workflow` runs a workflow before the agent starts. Use it to look up the caller, gate access, or seed the agent with context. The workflow can return three optional outputs:

| Output            | Type      | Effect                                                         |
| ----------------- | --------- | -------------------------------------------------------------- |
| `reject`          | `boolean` | Set to `true` to abort the conversation (defaults to `false`). |
| `initial_context` | `string`  | Context injected into the agent's system prompt.               |
| `custom_metadata` | `object`  | Custom metadata attached to the conversation.                  |

The field accepts a `WorkflowAction`. Reference a published workflow, or supply an inline definition:

| Field              | Type         | Default      | Description                                                                                                             |
| ------------------ | ------------ | ------------ | ----------------------------------------------------------------------------------------------------------------------- |
| `type`             | `"workflow"` | `"workflow"` | Action type.                                                                                                            |
| `workflow_id`      | `string`     | —            | ID of a published workflow. Pair with `workflow_version`.                                                               |
| `workflow_version` | `integer`    | —            | Version of the referenced workflow.                                                                                     |
| `initial_step`     | `string`     | —            | Step to start from. Required when using `workflow_id`/`workflow_version`; defaults to `trigger` for inline definitions. |
| `definition`       | `object`     | —            | Inline workflow definition. Mutually exclusive with `workflow_id`/`workflow_version`.                                   |
| `condition`        | `string`     | —            | Optional condition controlling whether the action runs.                                                                 |
| `reject_on_error`  | `boolean`    | `false`      | If `true`, abort the conversation when the workflow fails.                                                              |

<Warning>
  You must specify either `workflow_id` plus `workflow_version`, or an inline `definition` — not both, and not neither. When referencing a workflow, `initial_step` is required.
</Warning>

```json theme={null}
{
  "pre_conversation_workflow": {
    "type": "workflow",
    "workflow_id": "wf_...",
    "workflow_version": 3,
    "initial_step": "trigger",
    "reject_on_error": true
  }
}
```

<Tip>
  `reject_on_error: true` plus a `reject` output gives you a hard gate: if the lookup fails or the workflow decides to, the conversation never starts.
</Tip>

## Post-conversation workflow

`post_conversation_workflow` runs a workflow after the conversation ends — for logging, CRM updates, follow-up, or downstream automation. It accepts the same `WorkflowAction` shape as the pre-conversation workflow. Its outputs do not affect the (already finished) conversation, so `reject` has no effect here.

```json theme={null}
{
  "post_conversation_workflow": {
    "type": "workflow",
    "workflow_id": "wf_...",
    "workflow_version": 1,
    "initial_step": "trigger"
  }
}
```

Both hooks invoke standard workflows. For how an agent embeds and triggers a workflow, see [Agent-embedded triggers](/workflows/triggers/agent-embedded).

## Custom recording locations

By default Anyreach stores recordings for you. Set `custom_recording_locations` to copy recordings into your own object storage instead. The field is a list (minimum one entry); each entry is discriminated by `provider`.

Every provider supports `file_type`, either `ogg` (default) or `mp4`.

<Tabs>
  <Tab title="S3">
    | Field               | Type               | Default | Description             |
    | ------------------- | ------------------ | ------- | ----------------------- |
    | `provider`          | `"s3"`             | `"s3"`  | Provider discriminator. |
    | `bucket`            | `string`           | —       | Target bucket.          |
    | `region`            | `string`           | —       | Bucket region.          |
    | `access_key`        | `string`           | —       | AWS access key ID.      |
    | `secret_access_key` | `string`           | —       | AWS secret access key.  |
    | `file_type`         | `"ogg"` \| `"mp4"` | `"ogg"` | Recording file format.  |

    ```json theme={null}
    {
      "custom_recording_locations": [
        {
          "provider": "s3",
          "bucket": "my-recordings",
          "region": "us-east-1",
          "access_key": "AKIA...",
          "secret_access_key": "...",
          "file_type": "ogg"
        }
      ]
    }
    ```
  </Tab>

  <Tab title="GCP">
    | Field         | Type               | Default | Description                      |
    | ------------- | ------------------ | ------- | -------------------------------- |
    | `provider`    | `"gcp"`            | `"gcp"` | Provider discriminator.          |
    | `bucket`      | `string`           | —       | Target bucket.                   |
    | `credentials` | `string`           | —       | GCP service-account credentials. |
    | `file_type`   | `"ogg"` \| `"mp4"` | `"ogg"` | Recording file format.           |

    ```json theme={null}
    {
      "custom_recording_locations": [
        {
          "provider": "gcp",
          "bucket": "my-recordings",
          "credentials": "...",
          "file_type": "mp4"
        }
      ]
    }
    ```
  </Tab>

  <Tab title="Azure">
    | Field            | Type               | Default   | Description             |
    | ---------------- | ------------------ | --------- | ----------------------- |
    | `provider`       | `"azure"`          | `"azure"` | Provider discriminator. |
    | `container_name` | `string`           | —         | Target container.       |
    | `account_name`   | `string`           | —         | Storage account name.   |
    | `account_key`    | `string`           | —         | Storage account key.    |
    | `file_type`      | `"ogg"` \| `"mp4"` | `"ogg"`   | Recording file format.  |

    ```json theme={null}
    {
      "custom_recording_locations": [
        {
          "provider": "azure",
          "container_name": "recordings",
          "account_name": "myaccount",
          "account_key": "...",
          "file_type": "ogg"
        }
      ]
    }
    ```
  </Tab>
</Tabs>

<Note>
  For S3, Anyreach can mint a presigned URL to play back a recording from your bucket. GCP and Azure store the recording but do not return a playback URL.
</Note>

## Noise cancellation

`noise_cancellation` enables LiveKit noise-cancellation models on the audio stream. It holds a `models` list with at least one entry; each entry is discriminated by `provider` and `model.name`.

| `provider` | `model.name`    | When to use                                                                        |
| ---------- | --------------- | ---------------------------------------------------------------------------------- |
| `livekit`  | `bvc`           | General-purpose background voice cancellation for wideband audio (web, SIP, VoIP). |
| `livekit`  | `bvc_telephony` | Background voice cancellation tuned for narrowband telephony (PSTN phone calls).   |

```json theme={null}
{
  "noise_cancellation": {
    "models": [
      { "provider": "livekit", "model": { "name": "bvc_telephony" } }
    ]
  }
}
```

<Tip>
  Match the model to the channel: use `bvc_telephony` for inbound/outbound phone calls and `bvc` for web or higher-fidelity audio.
</Tip>

## Reference

These fields live at the top level of `AgentConfig` (alongside `version`, `agent`, and `metadata`). Always validate against the live schema before sending requests.

| Field                        | Type                         | Description                                                                                               |
| ---------------------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------- |
| `pre_conversation_workflow`  | `WorkflowAction`             | Workflow run before the agent starts; can reject, inject `initial_context`, and attach `custom_metadata`. |
| `post_conversation_workflow` | `WorkflowAction`             | Workflow run after the conversation ends.                                                                 |
| `custom_recording_locations` | array of recording locations | Store recordings in your own S3, GCP, or Azure storage.                                                   |
| `noise_cancellation`         | object                       | LiveKit `bvc` / `bvc_telephony` noise-cancellation models.                                                |

<CardGroup cols={2}>
  <Card title="Agent API usage" icon="code" href="/agents/api-usage">
    Create and update agents, including these config fields, over the API.
  </Card>

  <Card title="Agent-embedded triggers" icon="diagram-project" href="/workflows/triggers/agent-embedded">
    How agents invoke workflows for pre- and post-conversation hooks.
  </Card>
</CardGroup>
