Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions agents/build/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

## Voice

The Voice panel selects the voice profile your agent speaks with (`voice_profile_id`) and its speaking language (`speaking_language`: `en`, `ja`, `zh`, `ko`, `es`, `fr`, `de`). See [Voice & language](/agents/build/voice-language) for picking a voice and how automatic language detection interacts with this setting.
The Voice panel selects the voice your agent speaks with (`voice_id`) and its speaking language (`speaking_language`: `en`, `ja`, `zh`, `ko`, `es`, `fr`, `de`). See [Voice & language](/agents/build/voice-language) for picking a voice and how automatic language detection interacts with this setting.

## Conversation settings

Expand Down Expand Up @@ -68,7 +68,7 @@

`conversation.timezone` is the default IANA timezone (like `Asia/Shanghai`) the agent uses for dates and times in conversation. Leave it empty for **automatic** — each session follows the caller's device or phone number, falling back to UTC. Set one when your agent serves a single region regardless of who calls. A per-session `timezone` on the [session request](/agents/build/time-timezone) overrides this. See [Time & timezone](/agents/build/time-timezone) for the full resolution order.

## Autosave and publishing

Check warning on line 71 in agents/build/configuration.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

agents/build/configuration.mdx#L71

Did you really mean 'Autosave'?

There is no Save button. Each change is written to the agent's draft moments after you stop editing, and the **Saving… / Saved** indicator at the bottom-left of the page shows the current state. If a save fails, the Builder tells you and keeps your pending edits so nothing is lost.

Expand All @@ -94,7 +94,7 @@
"first_message": "Hi, thanks for calling Acme. How can I help?"
},
"voice": {
"voice_profile_id": "802e3bc2b27e49c2995d23ef70e6ac89",
"voice_id": "802e3bc2b27e49c2995d23ef70e6ac89",
"speaking_language": "en"
},
"conversation": {
Expand Down
77 changes: 12 additions & 65 deletions agents/build/dynamic-variables.mdx
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
---
title: "Dynamic Variables & Overrides"
description: "Personalize each session with template variables and per-session configuration overrides"
title: "Dynamic Variables"
description: "Personalize each session with template variables supplied at creation time"
icon: "brackets-curly"
---

An agent's published configuration is shared by every caller — but each session can be personalized at creation time. Two mechanisms cover this, and both travel in the same `POST /v1/agent/sessions` request:

| Mechanism | What it does | Gated by |
|---|---|---|
| `dynamic_variables` | Fills `{{placeholder}}` templates in your configuration text | Nothing per-agent — no allowlist |
| `overrides` | Replaces whole configuration fields for this session | Per-agent allowlist of overridable fields |

## Dynamic variables

Write `{{variable_name}}` placeholders in your agent's system prompt or first message and supply values when you create the session. Substitution happens once, when the published configuration is assembled for the session.
An agent's published configuration is shared by every caller — dynamic variables personalize it per session. Write `{{variable_name}}` placeholders in your agent's system prompt or first message and supply values when you create the session. Substitution happens once, when the published configuration is assembled for the session.

```text System prompt
You are a support agent for {{company}}. The caller's name is {{customer_name}}
and they are on the {{plan}} plan. Greet them by name.
```

Pass values as a flat object of strings, numbers, or booleans. Variable names must match `[A-Za-z][A-Za-z0-9_]*` (no hyphens or dots), string values are capped at 1,000 characters, and a request can carry at most 50 variables — violations reject session creation with `422`:

Check warning on line 14 in agents/build/dynamic-variables.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

agents/build/dynamic-variables.mdx#L14

Did you really mean 'booleans'?

<CodeGroup>
```bash API (curl)
Expand Down Expand Up @@ -60,61 +51,18 @@
You don't need a variable for the current date or time — the agent already knows both, in the session's timezone. See [Time & timezone](/agents/build/time-timezone).
</Tip>

## Overrides

Overrides replace configuration fields wholesale for one session — for example, forcing a different language for a caller. Because they change agent behavior, each agent declares which fields callers may override; everything else is rejected.

<CodeGroup>
```bash API (curl)
curl --request POST https://api.fish.audio/v1/agent/sessions \
--header "Authorization: Bearer $FISH_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"agent_id": "YOUR_AGENT_ID",
"overrides": { "language": "ja" }
}'
```

```javascript JavaScript SDK
import { AgentSession } from "@fishaudio/agent-client";

const session = await AgentSession.start({
agentId: "YOUR_AGENT_ID",
overrides: { language: "ja" },
});
```
</CodeGroup>

### The `language` shorthand

Overriding the session language is common enough that the request accepts a top-level `language` field as shorthand for `overrides.language`. Both forms pass through the same allowlist gate — if `language` is not overridable on the agent, both are rejected.

```json
{ "agent_id": "YOUR_AGENT_ID", "language": "ja" }
```

### Validation

| Case | Result |
|---|---|
| Override field not on the agent's allowlist | `400` |
| Unknown field inside `overrides` | `422` |
| Unknown top-level field in the request | `422` |

<Note>
The session record stores which overrides took effect.
</Note>
Variables fill placeholders in the configured text. To replace whole configuration fields for a session — the prompt itself, the opener, voice, language — use [overrides](/agents/deploy/authenticated-sessions#overrides) on the same request; `{{placeholders}}` render inside overridden text too.

## Who supplies the values

Where variables and overrides come from depends on the session's [access mode](/agents/deploy/overview#who-may-start-sessions):
Where variable values come from depends on the session's [access mode](/agents/deploy/overview#who-may-start-sessions):

| Mode | Who creates the session | Who supplies variables and overrides |
| Mode | Who creates the session | Who supplies the values |
|---|---|---|
| `agentId` ([public agents](/agents/deploy/public-agents)) | The SDK, directly from the browser | The browser, via `AgentSession.start()` options |
| `sessionToken` (private agents) | Your backend, with your API key | Your backend, in its `POST /v1/agent/sessions` call |

In `sessionToken` mode the SDK's `overrides`, `dynamicVariables`, and `language` options have no effect — the session already exists by the time the token reaches the browser. Attach personalization server-side instead:
In `sessionToken` mode the SDK's `dynamicVariables` option has no effect — the session already exists by the time the token reaches the browser. Attach personalization server-side instead:

```javascript Backend (sessionToken mode)
// Your backend endpoint, called by your own frontend
Expand All @@ -127,28 +75,27 @@
body: JSON.stringify({
agent_id: "YOUR_AGENT_ID",
dynamic_variables: { customer_name: user.name, plan: user.plan },
overrides: { language: user.locale },
}),
});
const sessionToken = await response.json(); // pass to AgentSession.start({ sessionToken })
```

<Tip>
In `agentId` mode, values arrive from the end user's browser — treat them as untrusted input. Keep the override allowlist limited to fields you are comfortable letting anyone set, and use `sessionToken` mode when personalization must come from data only your backend knows.
In `agentId` mode, values arrive from the end user's browser — treat them as untrusted input, and use `sessionToken` mode when personalization must come from data only your backend knows.

Check warning on line 84 in agents/build/dynamic-variables.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

agents/build/dynamic-variables.mdx#L84

Did you really mean 'untrusted'?
</Tip>

## Going further

<CardGroup cols={2}>
<Card title="Agent configuration" icon="sliders" href="/agents/build/configuration">
The fields your placeholders and overrides act on.
The fields your placeholders act on.
</Card>
<Card
title="Authenticated sessions"
title="Overrides"
icon="server"
href="/agents/deploy/authenticated-sessions"
href="/agents/deploy/authenticated-sessions#overrides"
>
Set variables from your backend when creating the session.
Replace whole configuration fields for one session.
</Card>
<Card title="Versions & publishing" icon="code-branch" href="/agents/deploy/versions-publishing">
Sessions assemble the published configuration.
Expand Down
6 changes: 4 additions & 2 deletions agents/build/voice-language.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ The voice picker on the **Configuration** page has two levels: a curated list fo

## Use any voice model

The agent's voice is a **voice model id** (`voice_profile_id`) — the same ids used as `reference_id` in [Text to Speech](/features/text-to-speech). Any public voice model from the Voice Library works, including:
The agent's voice is a **voice model id** (`voice_id`) — the same ids used as `reference_id` in [Text to Speech](/features/text-to-speech). Any public voice model from the Voice Library works, including:

- **Library voices** — ready-made public voices. Find ids in the [Voice Library](/features/manage-voices).
- **Your cloned voices** — [clone a voice](/features/voice-cloning) once, then use its model id as your agent's voice.
Expand All @@ -55,7 +55,7 @@ curl --request PATCH "https://api.fish.audio/v1/agent/agents/$AGENT_ID/config" \
--header "Content-Type: application/json" \
--data '{
"voice": {
"voice_profile_id": "802e3bc2b27e49c2995d23ef70e6ac89"
"voice_id": "802e3bc2b27e49c2995d23ef70e6ac89"
}
}'
```
Expand All @@ -80,6 +80,8 @@ curl --request PATCH "https://api.fish.audio/v1/agent/agents/$AGENT_ID/config" \
The voice model and the speaking language are independent settings: picking a voice does not change the language, and vice versa. Choose a voice that sounds natural in the language you configure.
</Note>

Both settings can also be replaced for a single session — send `overrides.voice_id` or `overrides.language` on the session request. See [Overrides](/agents/deploy/authenticated-sessions#overrides).

## Going further

<CardGroup cols={2}>
Expand Down
34 changes: 31 additions & 3 deletions agents/deploy/authenticated-sessions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<Note>
No backend, and anyone may talk to the agent? A [public
agent](/agents/deploy/public-agents) lets the SDK create sessions with just an
`agentId` — no token involved, gated by an origin allowlist and rate limits.

Check warning on line 21 in agents/deploy/authenticated-sessions.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

agents/deploy/authenticated-sessions.mdx#L21

Did you really mean 'allowlist'?
</Note>

## Create a token on your backend
Expand Down Expand Up @@ -109,7 +109,7 @@

<Note>
`overrides`, `dynamic_variables`, `language`, `tool_events`, `timezone`, and
`world_context` belong in your backend's creation request — the SDK forwards

Check warning on line 112 in agents/deploy/authenticated-sessions.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

agents/deploy/authenticated-sessions.mdx#L112

Did you really mean 'backend's'?
these options only in [public agent](/agents/deploy/public-agents) mode.
</Note>

Expand All @@ -118,13 +118,12 @@
| Field | Type | Description |
| ------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `agent_id` | string, required | The agent to talk to. It must have a [published version](/agents/deploy/versions-publishing). |
| `name` | string, optional | Display name for this session in the console's Conversations list, up to 128 characters. Omit it to show the session's start time instead. API-key requests only — keyless (public) creation rejects it with `400`. |

Check warning on line 121 in agents/deploy/authenticated-sessions.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

agents/deploy/authenticated-sessions.mdx#L121

Did you really mean 'keyless'?
| `language` | string, optional | Shorthand for `overrides.language`; subject to the same override allow-list. See [Voice & language](/agents/build/voice-language). |
| `overrides` | object, optional | Per-session config overrides. Each field must be enabled in the agent's override allow-list — unauthorized fields are rejected with `400`. |
| `overrides` | object, optional | Replace parts of the published configuration for this session — see [Overrides](#overrides). |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Align all language guidance with the wire contract.

Top-level language is an SDK/widget shorthand for overrides.language. It is not a field in the backend session-creation payload, and it cannot modify a session that already exists behind sessionToken.

  • agents/deploy/authenticated-sessions.mdx#L122-L122: Update the request guidance so backend callers send overrides.language, not top-level language.
  • agents/deploy/web-sdk.mdx#L64-L64: Qualify the language option as agentId-mode shorthand and direct sessionToken callers to configure it on the backend.
📍 Affects 2 files
  • agents/deploy/authenticated-sessions.mdx#L122-L122 (this comment)
  • agents/deploy/web-sdk.mdx#L64-L64
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@agents/deploy/authenticated-sessions.mdx` at line 122, Update
agents/deploy/authenticated-sessions.mdx:122-122 to state that backend
session-creation requests must send the language setting as overrides.language
rather than top-level language. Update agents/deploy/web-sdk.mdx:64-64 to
qualify language as shorthand for agentId mode and direct sessionToken callers
to configure the language on the backend.

Source: Coding guidelines

| `dynamic_variables` | object, optional | Up to 50 entries of string, number, or boolean values, substituted into `{{placeholders}}`. See [Dynamic variables](/agents/build/dynamic-variables). |
| `tool_events` | boolean, optional | Stream tool lifecycle events (`toolCallStarted` / `toolCallCompleted` / `toolCallFailed`) to the client. Default `true`; set `false` to keep tool inputs and outputs off the client. |
| `end_user_id` | string, optional | Your identifier for the end user, for attribution in [conversation history](/agents/monitor/conversation-history). |
| `metadata` | object, optional | Your own key-value namespace. Stored and returned verbatim on session queries and webhooks — never read or interpreted by the platform. |

Check warning on line 126 in agents/deploy/authenticated-sessions.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

agents/deploy/authenticated-sessions.mdx#L126

Did you really mean 'namespace'?
| `record_audio` | boolean, optional | Whether to record this session's audio. Overrides the agent's [recording setting](/agents/monitor/conversation-history#what-gets-stored) for this session only — it never changes the agent; omit it to use the agent's configuration. |
| `timezone` | string, optional | IANA timezone (like `Asia/Shanghai`) for the agent's sense of local time. Invalid names are rejected with `422`. See [Time & timezone](/agents/build/time-timezone). |
| `client_timezone` | string, optional | The end user's browser timezone, filled automatically by the SDK in public-agent mode. A hint, not a demand: it applies only when neither `timezone` nor the agent's configured timezone is set, and invalid values are ignored. See the [resolution order](/agents/build/time-timezone). |
Expand All @@ -132,6 +131,35 @@

Unknown fields — top-level or inside `overrides` — are rejected with `422`.

## Overrides

`overrides` replaces parts of the agent's published configuration for one session — the agent itself never changes:

| Field | Type | Effect for this session |
| ---------------------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `first_message` | string, up to 10,000 characters | The agent opens with exactly this text, spoken verbatim — whatever first-message mode the configuration sets. `{{placeholders}}` render inside it. |
| `first_message_prompt` | string, up to 10,000 characters | Instructions the agent generates its opener from, replacing the configured first-message behavior. `{{placeholders}}` render inside it. Mutually exclusive with `first_message` — sending both is `422`. |
| `system_prompt` | string, up to 8,000 characters | Replaces the configured system prompt entirely. `{{placeholders}}` render inside it. |
| `voice_id` | string | The voice the agent speaks with — any [voice model id](/agents/build/voice-language#use-any-voice-model) from the Voice Library. Voices bias pronunciation toward their own language, so pair it with `language`. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Document the voice_id length limit.

The OpenAPI schema limits overrides.voice_id to 256 characters. The table only states string. Add the limit so users can predict validation failures.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@agents/deploy/authenticated-sessions.mdx` at line 143, Update the voice_id
field description in the overrides table to document the 256-character maximum
enforced by the OpenAPI schema, while preserving the existing voice model and
language guidance.

Source: Coding guidelines

| `language` | `en`, `ja`, `zh`, `ko`, `es`, `fr`, `de` | Pins the conversation language, taking precedence over the configured [speaking language](/agents/build/voice-language#speaking-language) and automatic language detection. |

```json
{
"agent_id": "YOUR_AGENT_ID",
"overrides": {
"first_message": "Welcome back, {{name}} — picking up where we left off.",
"voice_id": "802e3bc2b27e49c2995d23ef70e6ac89",

Check warning on line 151 in agents/deploy/authenticated-sessions.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

agents/deploy/authenticated-sessions.mdx#L151

Did you really mean 'voice_id'?
"language": "ja"
}
}
```
Comment on lines +146 to +155

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the override example self-contained.

The example sends {{name}} in first_message but provides no dynamic_variables.name. The documented behavior leaves unmatched placeholders as literal text.

Add a matching variable or remove the placeholder.

Proposed example update
     "first_message": "Welcome back, {{name}} — picking up where we left off.",
     "voice_id": "802e3bc2b27e49c2995d23ef70e6ac89",
     "language": "ja"
-  }
+  },
+  "dynamic_variables": { "name": "Ada" }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```json
{
"agent_id": "YOUR_AGENT_ID",
"overrides": {
"first_message": "Welcome back, {{name}} — picking up where we left off.",
"voice_id": "802e3bc2b27e49c2995d23ef70e6ac89",
"language": "ja"
}
}
```
🧰 Tools
🪛 GitHub Check: Mintlify Validation (hanabiaiinc) - vale-spellcheck

[warning] 151-151: agents/deploy/authenticated-sessions.mdx#L151
Did you really mean 'voice_id'?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@agents/deploy/authenticated-sessions.mdx` around lines 146 - 155, Make the
JSON override example self-contained by adding a dynamic_variables.name value
matching the {{name}} placeholder in overrides.first_message, or remove the
placeholder from first_message while preserving the example’s intent.

Source: Coding guidelines


On [public agents](/agents/deploy/public-agents), keyless (browser-created) sessions may override only `language` and `voice_id` — the prompt-shaping fields are rejected with `400` regardless of the agent. Create the session from your backend to use them.

The session record stores which overrides took effect.

Everything else on the request is not an override: `dynamic_variables`, `timezone`, `record_audio`, and `tool_events` are separate top-level fields. Session length is not settable per session — `max_duration_seconds` comes from the agent's [conversation configuration](/agents/build/configuration#call-duration).

## Response

```json JSON
Expand Down Expand Up @@ -187,7 +215,7 @@

| Status | Meaning |
| ------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `400` | An `overrides` field is not on the agent's override allow-list. |
| `400` | An `overrides` field is not enabled for this agent, or a keyless request sent an override [public sessions don't accept](#overrides). |

Check warning on line 218 in agents/deploy/authenticated-sessions.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

agents/deploy/authenticated-sessions.mdx#L218

Did you really mean 'keyless'?
| `401` | Invalid API key. A request with no `Authorization` header at all is treated as a public-agent request instead. |
| `402` | Quota exceeded. |
| `403` | Public-agent request rejected: the agent is not public, or the page's `Origin` is not on the allow-list. |
Expand Down
2 changes: 1 addition & 1 deletion agents/deploy/public-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
icon: "globe"
---

A public agent accepts sessions straight from the browser: the SDK calls the session endpoint with just an `agent_id` — no API key, no server of your own. The platform gates access with three controls: an agent-level public switch (off by default), a required origin allowlist, and rate limiting.

Check warning on line 7 in agents/deploy/public-agents.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

agents/deploy/public-agents.mdx#L7

Did you really mean 'allowlist'?

Use this mode for demos, marketing pages, and support bubbles where standing up a backend isn't worth it. For production apps with their own users, [authenticated sessions](/agents/deploy/authenticated-sessions) are usually the better fit — see [when to use session tokens instead](#when-to-use-session-tokens-instead).

Expand All @@ -23,7 +23,7 @@
</Step>
<Step title="Add allowed origins">
On the same page, list every web origin that may start sessions under
**Allowed origins** (`allowed_origins` in the API). The allowlist is

Check warning on line 26 in agents/deploy/public-agents.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

agents/deploy/public-agents.mdx#L26

Did you really mean 'allowlist'?
**required**: a request whose `Origin` doesn't match any entry is rejected
with `403`.
</Step>
Expand Down Expand Up @@ -62,7 +62,7 @@

An entry matches only on **exact scheme + host + port**. The host is case-insensitive, and a trailing slash on an entry is tolerated — everything else must match exactly.

| Allowlist entry | Browser origin | Allowed |

Check warning on line 65 in agents/deploy/public-agents.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

agents/deploy/public-agents.mdx#L65

Did you really mean 'Allowlist'?
| ------------------------- | ------------------------------ | ------------------------------ |
| `https://app.example.com` | `https://app.example.com` | Yes |
| `https://app.example.com` | `https://APP.example.com` | Yes — host is case-insensitive |
Expand Down Expand Up @@ -90,11 +90,11 @@
backend becomes the gate, and the platform-side public limits no longer apply.
</Note>

## Treat public input as untrusted

Check warning on line 93 in agents/deploy/public-agents.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

agents/deploy/public-agents.mdx#L93

Did you really mean 'untrusted'?

On the public path, the entire session request originates in the visitor's browser. The platform enforces its own guardrails — `overrides` are filtered against the agent's allowlist and unauthorized fields are rejected with `400` — but anything that passes through verbatim is attacker-controllable:
On the public path, the entire session request originates in the visitor's browser. The platform enforces its own guardrails — public sessions accept only the `language` and `voice_id` [overrides](/agents/deploy/authenticated-sessions#overrides), rejecting everything else with `400` — but anything that passes through verbatim is attacker-controllable:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Distinguish unknown fields from unsupported public overrides.

The sentence says that every override other than language and voice_id is rejected with 400. Unknown fields inside overrides are documented elsewhere as 422; 400 applies to recognized fields that are not allowed for the public session.

Limit the 400 statement to recognized prompt-shaping overrides.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@agents/deploy/public-agents.mdx` at line 95, Update the public-path
documentation sentence to distinguish unknown override fields, which return 422,
from recognized prompt-shaping overrides that are unsupported for public
sessions and return 400; keep language and voice_id as the allowed overrides.

Source: Coding guidelines


- **`metadata`** is stored and returned exactly as sent, never interpreted by the platform. When you read it back in [conversation history](/agents/monitor/conversation-history) or [webhooks](/agents/monitor/webhooks), treat it as untrusted data — never as proof of who the visitor is.

Check warning on line 97 in agents/deploy/public-agents.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

agents/deploy/public-agents.mdx#L97

Did you really mean 'untrusted'?
- **`dynamic_variables`** are chosen by the page that starts the session. Don't inject anything through them that the visitor shouldn't control. See [Dynamic variables](/agents/build/dynamic-variables).

For trusted attribution (a verified `end_user_id`, server-set metadata), create sessions from your backend instead.
Expand Down
2 changes: 1 addition & 1 deletion agents/deploy/react-sdk.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
}
```

`status`, `mode`, and `isSpeaking` are React state — your component re-renders as the conversation progresses. When the component unmounts, the session ends automatically.

Check warning on line 89 in agents/deploy/react-sdk.mdx

View check run for this annotation

Mintlify / Mintlify Validation (hanabiaiinc) - vale-spellcheck

agents/deploy/react-sdk.mdx#L89

Did you really mean 'unmounts'?

<Note>
Call `startSession` from a user gesture (such as a click handler) so the
Expand All @@ -103,7 +103,7 @@
await startSession({ sessionToken });
```

See [Authenticated sessions](/agents/deploy/authenticated-sessions) for the backend side. `startSession` accepts the same options as `AgentSession.start` in the [Web SDK](/agents/deploy/web-sdk), including [`clientTools`](/agents/build/client-tools). Session settings such as `overrides` and `dynamicVariables` apply when you connect with an `agentId`; with a `sessionToken`, your backend sets them in its session-creation request instead.
See [Authenticated sessions](/agents/deploy/authenticated-sessions) for the backend side. `startSession` accepts the same options as `AgentSession.start` in the [Web SDK](/agents/deploy/web-sdk), including [`clientTools`](/agents/build/client-tools). Session settings such as [`overrides`](/agents/deploy/authenticated-sessions#overrides) and `dynamicVariables` apply when you connect with an `agentId`; with a `sessionToken`, your backend sets them in its session-creation request instead.

## What `useConversation` returns

Expand Down
Loading
Loading