---
title: "Create Agent Session"
method: POST
path: "/v1/agent/sessions"
tags: ["Agent Sessions"]
---

# Create Agent Session

`POST /v1/agent/sessions`

## Request

- Base URL: `https://api.fish.audio`
- URL: `https://api.fish.audio/v1/agent/sessions`
- Auth: HTTP bearer

Start a conversation session with an agent and receive a join token for the
session transport (currently LiveKit WebRTC). Authenticate with an API key to
start sessions with any agent in your team; without credentials only agents
published as public are reachable, and the request `Origin` must match the
agent's allowed origins.

`language` (and `overrides.language`) accepts `en`, `ja`, `zh`, `ko`, `es`,
`fr`, `de`, `pt`, `it`, `nl`; anything else is 422. Omit it to use the agent's configured
speaking language.

`overrides.asr.model` picks the speech recognition model for this session,
nested like the agent config's `asr` section and with the same values as
`asr.model`. It needs an API key.

`overrides.llm.fallback` replaces the agent's `llm.fallback` for this
session, with the same shape and rules; each `custom` model needs its
`api_key`. It needs an API key and `llm.fallback` in the agent's
`overrides_allowed`.

## Headers

- `origin` string, nullable

## Request body

- AgentSessionCreatePayload
  - `agent_id` string, required
  - `name` string, nullable
  - `timezone` string, nullable: IANA timezone (like `Asia/Tokyo`) for the agent's sense of local date and time in this session. Overrides the agent's configured timezone, which defaults to UTC. Invalid names are rejected with 422.
  - `client_timezone` string, nullable: The end user's device timezone as an IANA name (like `Asia/Tokyo`), used as a fallback hint: it applies only when neither `timezone` nor the agent's configured timezone is set, and invalid values are ignored rather than rejected. The Web SDK fills it automatically from the browser for public agents. When your backend creates the session, forward the value from your client.
  - `context` AgentSessionContextPayload: Per-session overrides of the agent's context switches (the config's `context` section). A switch left out follows the agent.
    - `current_time` boolean, nullable: Whether the agent knows the current date and time in this session. Omit it to follow the agent's `context.current_time`. `false` withholds both from this session, `true` injects them even when the agent has them off.
  - `overrides` AgentSessionOverridesPayload: Wire twin of @fishaudio/agent-protocol `SessionOverrides` (session.ts). Every field must be allow-listed in Agent.overrides_allowed; unauthorized fields fail session creation loudly rather than being silently dropped.
    - `first_message` string, nullable
    - `first_message_prompt` string, nullable
    - `system_prompt` string, nullable: Limited to 32000 tokens (o200k_base), same budget as the configured prompt it replaces.
    - `voice_id` string, nullable
    - `language` 'en' | 'ja' | 'zh' | 'ko' | 'es' | 'fr' | 'de' | 'pt' | 'it' | 'nl' | 'ar' | 'hi' | 'id' | 'tr' | 'ru' | 'bg' | 'sr' | 'hr' | 'cs' | 'sk' | 'pl' | 'uk' | 'ro' | 'hu' | 'el' | 'sv' | 'da' | 'no' | 'fi' | 'et' | 'lv' | 'lt' | 'ca' | 'he' | 'fa' | 'ur' | 'kk' | 'ka' | 'hy' | 'bn' | 'ta' | 'te' | 'kn' | 'mr' | 'gu' | 'pa' | 'ne' | 'th' | 'vi' | 'ms' | 'tl' | 'af', nullable
    - `asr` AgentSessionAsrOverridesPayload: Per-session subset of the agent config's asr section, same field names.
      - `model` 'deepgram:nova-3' | 'elevenlabs:scribe_v2_realtime' | 'elevenlabs:scribe_v2_medical' | 'fish_audio:transcribe-stream-1', nullable: Speech recognition model for this session, same values as the agent's `asr.model`.
    - `llm` AgentSessionLlmOverridesPayload: Per-session subset of the agent config's llm section, same field names.
      - `fallback` AgentLLMFallbackPayload: Replaces the whole fallback: `mode` and `models` travel together.
        - `mode` 'platform' | 'manual' | 'off', required
        - `models` AgentLLMFallbackModelPayload[], nullable: Fallback models in order, 1 to 3. Only with mode `manual`.
          - `model` 'google/gemini-3.5-flash-lite' | 'google/gemini-3.6-flash' | 'google/gemini-3.8-flash' | 'google/gemini-3.6-flash-priority' | 'google/gemini-3.8-flash-priority' | 'google/gemini-2.5-flash' | 'google/gemma-4-26b-a4b-it' | 'anthropic/claude-haiku-4.5' | 'anthropic/claude-sonnet-4.6' | 'anthropic/claude-opus-5.5' | 'anthropic/claude-fable-5.1' | 'openai/gpt-5.6-luna' | 'openai/gpt-6-luna' | 'openai/gpt-5' | 'openai/gpt-6.1-sol' | 'openai/gpt-6-astra' | 'openai/gpt-4o' | 'openai/gpt-4.1', nullable
          - `custom` AgentLLMCustomPayload: Write model: full base_url policy + caps; stored values come only from here.
            - `base_url` string, required
            - `model` string, required
            - `api_key` string, nullable: Sent to your endpoint as the Authorization bearer token; write-only, reads return null. Required when introducing `custom`; omit to keep the stored key when updating.
            - `headers` object, nullable: Extra headers sent on every request to your endpoint, such as `x-vercel-protection-bypass`. Reads return the stored map. Omit to keep the stored headers, `{}` clears them.
          - `ttft_timeout_ms` integer, nullable: Milliseconds the model gets to start its reply (first text or tool call). Past it, the reply moves to the next fallback model. Not set: defaults to 5000 ms (5 seconds).
          - `total_timeout_ms` integer, nullable: Milliseconds the model gets to finish its reply. Past it, a reply nothing of which was spoken yet moves to the next fallback model; one already being spoken fails like any failed reply. At least `ttft_timeout_ms` when both are set. Not set: no limit.
          - `parallel` AgentLLMParallelPayload
            - `kick_in_ms` integer: The agent's own model keeps the reply if its first token comes within this many milliseconds; past it, this fallback's reply is used. The other request is cancelled.
        - `primary` AgentLLMTimeoutsPayload: The agent's own model's timeouts, write model. Unset ttft_timeout_ms = 5000 ms (5 seconds); unset total_timeout_ms = no limit. The two are compared only when both are set.
          - `ttft_timeout_ms` integer, nullable: Milliseconds the model gets to start its reply (first text or tool call). Past it, the reply moves to the next fallback model. Not set: defaults to 5000 ms (5 seconds).
          - `total_timeout_ms` integer, nullable: Milliseconds the model gets to finish its reply. Past it, a reply nothing of which was spoken yet moves to the next fallback model; one already being spoken fails like any failed reply. At least `ttft_timeout_ms` when both are set. Not set: no limit.
  - `dynamic_variables` object, nullable
  - `end_user_id` string, nullable: Your identifier for the end user, stored verbatim. Returned on session reads and webhooks, and filterable with `GET /v1/agent/sessions?end_user_id=`.
  - `metadata` object, nullable
  - `llm_extra_body` object, nullable
  - `tool_events` boolean
  - `record_audio` boolean, nullable

## Response `201`

Document created, URL follows

- object: Wire twin of @fishaudio/agent-protocol `SessionToken` (session.ts); keep in sync.
  - `session_id` string, required
  - `expires_at` string, required
  - `max_duration_seconds` integer, required
  - `transport` 'livekit', required
  - `livekit_url` string, required
  - `token` string, required

## Other responses

- `400`: Bad request syntax or unsupported method
- `401`: No permission -- see authorization schemes
- `402`: No payment -- see charging schemes
- `403`: Request forbidden -- authorization will not help
- `404`: Nothing matches the given URI
- `409`: Request conflict
- `429`: The user has sent too many requests in a given amount of time ("rate limiting")
- `502`: Invalid responses from another server/proxy
- `503`: The server cannot process the request due to a high load

## Changes

- **2026-11-03** `42ac421f7a12`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/fish/apis/fishaudio-openapi/changes/v1/agent/sessions/post.md)

---

[API](https://skmtc.dev/fish/apis/fishaudio-openapi.md) - [All operations](https://skmtc.dev/fish/apis/fishaudio-openapi/llms.txt) - [OpenAPI document](https://skmtc.dev/fish/apis/fishaudio-openapi/revisions/42ac421f7a12?raw)
