curl --request POST \
--url https://api.fish.audio/v1/agent/sessions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"agent_id": "<agent-id>"
}'import requests
url = "https://api.fish.audio/v1/agent/sessions"
payload = {
"agent_id": "<string>",
"name": "<string>",
"timezone": "<string>",
"client_timezone": "<string>",
"world_context": True,
"overrides": {
"first_message": "<string>",
"first_message_prompt": "<string>",
"system_prompt": "<string>",
"voice_id": "<string>"
},
"dynamic_variables": {},
"end_user_id": "<string>",
"metadata": {},
"llm_extra_body": {},
"tool_events": True,
"record_audio": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
agent_id: '<string>',
name: '<string>',
timezone: '<string>',
client_timezone: '<string>',
world_context: true,
overrides: {
first_message: '<string>',
first_message_prompt: '<string>',
system_prompt: '<string>',
voice_id: '<string>'
},
dynamic_variables: {},
end_user_id: '<string>',
metadata: {},
llm_extra_body: {},
tool_events: true,
record_audio: true
})
};
fetch('https://api.fish.audio/v1/agent/sessions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.fish.audio/v1/agent/sessions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'agent_id' => '<string>',
'name' => '<string>',
'timezone' => '<string>',
'client_timezone' => '<string>',
'world_context' => true,
'overrides' => [
'first_message' => '<string>',
'first_message_prompt' => '<string>',
'system_prompt' => '<string>',
'voice_id' => '<string>'
],
'dynamic_variables' => [
],
'end_user_id' => '<string>',
'metadata' => [
],
'llm_extra_body' => [
],
'tool_events' => true,
'record_audio' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.fish.audio/v1/agent/sessions"
payload := strings.NewReader("{\n \"agent_id\": \"<string>\",\n \"name\": \"<string>\",\n \"timezone\": \"<string>\",\n \"client_timezone\": \"<string>\",\n \"world_context\": true,\n \"overrides\": {\n \"first_message\": \"<string>\",\n \"first_message_prompt\": \"<string>\",\n \"system_prompt\": \"<string>\",\n \"voice_id\": \"<string>\"\n },\n \"dynamic_variables\": {},\n \"end_user_id\": \"<string>\",\n \"metadata\": {},\n \"llm_extra_body\": {},\n \"tool_events\": true,\n \"record_audio\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.fish.audio/v1/agent/sessions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"agent_id\": \"<string>\",\n \"name\": \"<string>\",\n \"timezone\": \"<string>\",\n \"client_timezone\": \"<string>\",\n \"world_context\": true,\n \"overrides\": {\n \"first_message\": \"<string>\",\n \"first_message_prompt\": \"<string>\",\n \"system_prompt\": \"<string>\",\n \"voice_id\": \"<string>\"\n },\n \"dynamic_variables\": {},\n \"end_user_id\": \"<string>\",\n \"metadata\": {},\n \"llm_extra_body\": {},\n \"tool_events\": true,\n \"record_audio\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fish.audio/v1/agent/sessions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"agent_id\": \"<string>\",\n \"name\": \"<string>\",\n \"timezone\": \"<string>\",\n \"client_timezone\": \"<string>\",\n \"world_context\": true,\n \"overrides\": {\n \"first_message\": \"<string>\",\n \"first_message_prompt\": \"<string>\",\n \"system_prompt\": \"<string>\",\n \"voice_id\": \"<string>\"\n },\n \"dynamic_variables\": {},\n \"end_user_id\": \"<string>\",\n \"metadata\": {},\n \"llm_extra_body\": {},\n \"tool_events\": true,\n \"record_audio\": true\n}"
response = http.request(request)
puts response.read_body{
"session_id": "<string>",
"expires_at": "<string>",
"max_duration_seconds": 123,
"transport": "livekit",
"livekit_url": "<string>",
"token": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}Create Agent Session
Start a conversation session with an agent and receive a join token for the session transport (currently LiveKit WebRTC).
curl --request POST \
--url https://api.fish.audio/v1/agent/sessions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"agent_id": "<agent-id>"
}'import requests
url = "https://api.fish.audio/v1/agent/sessions"
payload = {
"agent_id": "<string>",
"name": "<string>",
"timezone": "<string>",
"client_timezone": "<string>",
"world_context": True,
"overrides": {
"first_message": "<string>",
"first_message_prompt": "<string>",
"system_prompt": "<string>",
"voice_id": "<string>"
},
"dynamic_variables": {},
"end_user_id": "<string>",
"metadata": {},
"llm_extra_body": {},
"tool_events": True,
"record_audio": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
agent_id: '<string>',
name: '<string>',
timezone: '<string>',
client_timezone: '<string>',
world_context: true,
overrides: {
first_message: '<string>',
first_message_prompt: '<string>',
system_prompt: '<string>',
voice_id: '<string>'
},
dynamic_variables: {},
end_user_id: '<string>',
metadata: {},
llm_extra_body: {},
tool_events: true,
record_audio: true
})
};
fetch('https://api.fish.audio/v1/agent/sessions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.fish.audio/v1/agent/sessions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'agent_id' => '<string>',
'name' => '<string>',
'timezone' => '<string>',
'client_timezone' => '<string>',
'world_context' => true,
'overrides' => [
'first_message' => '<string>',
'first_message_prompt' => '<string>',
'system_prompt' => '<string>',
'voice_id' => '<string>'
],
'dynamic_variables' => [
],
'end_user_id' => '<string>',
'metadata' => [
],
'llm_extra_body' => [
],
'tool_events' => true,
'record_audio' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.fish.audio/v1/agent/sessions"
payload := strings.NewReader("{\n \"agent_id\": \"<string>\",\n \"name\": \"<string>\",\n \"timezone\": \"<string>\",\n \"client_timezone\": \"<string>\",\n \"world_context\": true,\n \"overrides\": {\n \"first_message\": \"<string>\",\n \"first_message_prompt\": \"<string>\",\n \"system_prompt\": \"<string>\",\n \"voice_id\": \"<string>\"\n },\n \"dynamic_variables\": {},\n \"end_user_id\": \"<string>\",\n \"metadata\": {},\n \"llm_extra_body\": {},\n \"tool_events\": true,\n \"record_audio\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.fish.audio/v1/agent/sessions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"agent_id\": \"<string>\",\n \"name\": \"<string>\",\n \"timezone\": \"<string>\",\n \"client_timezone\": \"<string>\",\n \"world_context\": true,\n \"overrides\": {\n \"first_message\": \"<string>\",\n \"first_message_prompt\": \"<string>\",\n \"system_prompt\": \"<string>\",\n \"voice_id\": \"<string>\"\n },\n \"dynamic_variables\": {},\n \"end_user_id\": \"<string>\",\n \"metadata\": {},\n \"llm_extra_body\": {},\n \"tool_events\": true,\n \"record_audio\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fish.audio/v1/agent/sessions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"agent_id\": \"<string>\",\n \"name\": \"<string>\",\n \"timezone\": \"<string>\",\n \"client_timezone\": \"<string>\",\n \"world_context\": true,\n \"overrides\": {\n \"first_message\": \"<string>\",\n \"first_message_prompt\": \"<string>\",\n \"system_prompt\": \"<string>\",\n \"voice_id\": \"<string>\"\n },\n \"dynamic_variables\": {},\n \"end_user_id\": \"<string>\",\n \"metadata\": {},\n \"llm_extra_body\": {},\n \"tool_events\": true,\n \"record_audio\": true\n}"
response = http.request(request)
puts response.read_body{
"session_id": "<string>",
"expires_at": "<string>",
"max_duration_seconds": 123,
"transport": "livekit",
"livekit_url": "<string>",
"token": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
Body
128IANA 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.
64The 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.
64Wire 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.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
256Show child attributes
Show child attributes
Show child attributes
Show child attributes
Was this page helpful?

