---
title: "Trillet OEM call flow settings"
sidebarTitle: "Call flow settings"
description: "Read and change a Trillet OEM tenant's call flow settings: greeting, speech, recording and call handling."
lastUpdated: "2026-10-28"
---

> **For AI agents:** the complete documentation index is at [llms.txt](https://docs.trillet.ai/llms.txt). Append `.md` to any page URL for its markdown version.

<Note>
  **Early access.** Trillet OEM is built and in testing with design partners. Contact your account manager to have it enabled for your account. Details may still change.
</Note>

The standard call flow create and update endpoints are not available to partner keys. Instead, Trillet OEM has one endpoint for the basic settings of a tenant's call flow: the greeting, speech timing, recording and call handling timers.

The agent's voice, language and model are set on the agent with `PUT /v1/api/agents/{agentId}`, not here. See [Building an agent](https://docs.trillet.ai/voice-engine/authentication#building-an-agent).

## Endpoints

| Method | Path | Scope |
|---|---|---|
| `GET` | `/partner/v1/tenants/{tenantId}/call-flows/{callFlowId}/settings` | `resources:read` |
| `PATCH` | `/partner/v1/tenants/{tenantId}/call-flows/{callFlowId}/settings` | `resources:write` |

`callFlowId` is the ID of a call flow in the tenant. For a node flow, it is `pathway._id` in the response of `GET /v2/api/node-graphs/{id}`.

## The settings object

```json
{
  "object": "call_flow_settings",
  "callFlowId": "6a9623bb1b2c3d4e5f6a7b8c",
  "tenantId": "6a9622d2c1e8f3a4b5d6e7f8",
  "greeting": {
    "inbound": {
      "mode": "customMessage",
      "text": "Thanks for calling Harbour Dental. How can I help?",
      "instructions": null
    },
    "outbound": {
      "mode": "aiFirst",
      "text": null,
      "instructions": "Introduce yourself and confirm you are speaking with {{customer_name}}."
    },
    "delaySeconds": 0
  },
  "speech": {
    "responsiveness": 10,
    "interruptionSensitivity": 5.5
  },
  "recording": { "enabled": true },
  "callHandling": {
    "maxCallDurationSeconds": 1800,
    "checkInAfterSeconds": 10,
    "checkInAttempts": 1,
    "hangUpAfterCheckInSeconds": 10
  },
  "updatedAt": "2026-11-02T10:40:00.000Z"
}
```

A setting the call flow has never stored is returned as `null`.

| Field | Type | Values |
|---|---|---|
| `greeting.inbound.mode`, `greeting.outbound.mode` | string | `aiFirst` (the agent speaks first, with a greeting it writes), `customMessage` (the agent speaks first with `text`) or `userFirst` (the agent waits for the caller to speak) |
| `greeting.inbound.text`, `greeting.outbound.text` | string | The greeting spoken in `customMessage` mode. Up to 2,000 characters. |
| `greeting.inbound.instructions`, `greeting.outbound.instructions` | string | Instructions for the greeting in `aiFirst` mode. Up to 2,000 characters. |
| `greeting.delaySeconds` | number | Pause before the greeting, 0 to 5 |
| `speech.responsiveness` | number | How quickly the agent replies once the caller stops, 1 to 10 |
| `speech.interruptionSensitivity` | number | How easily the caller can interrupt the agent, 1 to 10 |
| `recording.enabled` | boolean | Record calls on this flow |
| `callHandling.maxCallDurationSeconds` | integer | Longest call allowed, 10 to 1800 |
| `callHandling.checkInAfterSeconds` | integer | Silence before the agent checks the caller is still there: `10`, `20` or `30` |
| `callHandling.checkInAttempts` | integer | Check-ins before the agent ends the call: `0` (never), `1`, `2` or `3` |
| `callHandling.hangUpAfterCheckInSeconds` | integer | Wait after the last check-in before hanging up: `10`, `20` or `30` |

Node flows created with a partner key start with `speech.responsiveness` 10 and `speech.interruptionSensitivity` 5.5.

## Read the settings

```bash
curl https://api.trillet.ai/partner/v1/tenants/6a9622d2c1e8f3a4b5d6e7f8/call-flows/6a9623bb1b2c3d4e5f6a7b8c/settings \
  -H "Authorization: Bearer tpk_live_..."
```

## Change the settings

Send only the settings you want to change, nested as in the settings object. Everything else is left as it is.

```bash
curl -X PATCH https://api.trillet.ai/partner/v1/tenants/6a9622d2c1e8f3a4b5d6e7f8/call-flows/6a9623bb1b2c3d4e5f6a7b8c/settings \
  -H "Authorization: Bearer tpk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "greeting": {
      "inbound": {
        "mode": "customMessage",
        "text": "Thanks for calling Harbour Dental. How can I help?"
      }
    },
    "recording": { "enabled": true },
    "callHandling": { "maxCallDurationSeconds": 900 }
  }'
```

Returns the full settings object, plus `activeDraftUpdated` (see [Active drafts](#active-drafts)).

- Values are not converted: `"10"` is refused where a number is expected.
- A field this endpoint does not manage is refused by name with `400` `unknown_setting`, so a setting can never be silently ignored.
- `customMessage` mode needs greeting text, either in the same request or already stored on the flow.
- An `Idempotency-Key` header is optional. When sent, it works as described in [Idempotency](https://docs.trillet.ai/voice-engine/conventions#idempotency).

The change applies to calls that start after it. Editors open on the flow in the Trillet portal reload it.

## Active drafts

The change is written to the live call flow. If the flow has an active draft, which test calls use, the same settings are copied onto that draft, so a test call hears the change and publishing the draft later does not put the old values back. `activeDraftUpdated` is `true` when a draft was updated.

## Errors

| Status | Code | When |
|---|---|---|
| `400` | `unknown_setting` | A field is not a setting this endpoint can change. `error.param` names it, for example `greeting.inbound.voice`. |
| `400` | `invalid_request` | A value has the wrong type or is out of range, the body is not a JSON object, it contains no settings, or `customMessage` mode has no text. `error.param` names the field when there is one. |
| `404` | `tenant_not_found` | The tenant does not exist, is deleted, is not yours, or the key is restricted to other tenants |
| `404` | `call_flow_not_found` | The call flow does not exist in this tenant |
| `409` | `call_flow_archived` | The call flow is archived and read-only. Restore it with `PATCH /v1/api/call-flows/{id}/restore` first. |
| `409` | `hipaa_recording_conflict` | `recording.enabled: true` on a call flow in HIPAA mode, which keeps recording off. `error.param` is `recording.enabled`. |

```json
{
  "error": {
    "type": "invalid_request_error",
    "code": "unknown_setting",
    "message": "greeting.inbound.voice is not a setting this endpoint can change.",
    "param": "greeting.inbound.voice",
    "requestId": "req-1a2b"
  }
}
```
