curl --request POST \
--url https://api.fish.audio/v1/voice-design \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'model: voice-design-1' \
--data '{
"instruction": "Warm, confident studio narrator with a natural tone",
"reference_text": "Welcome to Fish Audio.",
"language": "en",
"n": 2,
"speed": 1,
"num_step": 32,
"guidance_scale": 2,
"instruct_guidance_scale": 0,
"seed": 42
}'import requests
url = "https://api.fish.audio/v1/voice-design"
payload = {
"guidance_scale": 2,
"instruct_guidance_scale": 0,
"instruction": "Warm, confident studio narrator with a natural tone",
"language": "en",
"n": 2,
"num_step": 32,
"reference_text": "Welcome to Fish Audio.",
"seed": 42,
"speed": 1
}
headers = {
"model": "<model>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
model: '<model>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
guidance_scale: 2,
instruct_guidance_scale: 0,
instruction: 'Warm, confident studio narrator with a natural tone',
language: 'en',
n: 2,
num_step: 32,
reference_text: 'Welcome to Fish Audio.',
seed: 42,
speed: 1
})
};
fetch('https://api.fish.audio/v1/voice-design', 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/voice-design",
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([
'guidance_scale' => 2,
'instruct_guidance_scale' => 0,
'instruction' => 'Warm, confident studio narrator with a natural tone',
'language' => 'en',
'n' => 2,
'num_step' => 32,
'reference_text' => 'Welcome to Fish Audio.',
'seed' => 42,
'speed' => 1
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"model: <model>"
],
]);
$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/voice-design"
payload := strings.NewReader("{\n \"guidance_scale\": 2,\n \"instruct_guidance_scale\": 0,\n \"instruction\": \"Warm, confident studio narrator with a natural tone\",\n \"language\": \"en\",\n \"n\": 2,\n \"num_step\": 32,\n \"reference_text\": \"Welcome to Fish Audio.\",\n \"seed\": 42,\n \"speed\": 1\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("model", "<model>")
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/voice-design")
.header("model", "<model>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"guidance_scale\": 2,\n \"instruct_guidance_scale\": 0,\n \"instruction\": \"Warm, confident studio narrator with a natural tone\",\n \"language\": \"en\",\n \"n\": 2,\n \"num_step\": 32,\n \"reference_text\": \"Welcome to Fish Audio.\",\n \"seed\": 42,\n \"speed\": 1\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fish.audio/v1/voice-design")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["model"] = '<model>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"guidance_scale\": 2,\n \"instruct_guidance_scale\": 0,\n \"instruction\": \"Warm, confident studio narrator with a natural tone\",\n \"language\": \"en\",\n \"n\": 2,\n \"num_step\": 32,\n \"reference_text\": \"Welcome to Fish Audio.\",\n \"seed\": 42,\n \"speed\": 1\n}"
response = http.request(request)
puts response.read_body{
"candidates": [
{
"id": "<string>",
"index": 1,
"audio_base64": "<string>",
"sample_rate": 123,
"duration_ms": 1,
"text": "<string>",
"instruct": "<string>",
"language": "<string>"
}
]
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}Voice Design
Generate candidate voices from a prompt
curl --request POST \
--url https://api.fish.audio/v1/voice-design \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'model: voice-design-1' \
--data '{
"instruction": "Warm, confident studio narrator with a natural tone",
"reference_text": "Welcome to Fish Audio.",
"language": "en",
"n": 2,
"speed": 1,
"num_step": 32,
"guidance_scale": 2,
"instruct_guidance_scale": 0,
"seed": 42
}'import requests
url = "https://api.fish.audio/v1/voice-design"
payload = {
"guidance_scale": 2,
"instruct_guidance_scale": 0,
"instruction": "Warm, confident studio narrator with a natural tone",
"language": "en",
"n": 2,
"num_step": 32,
"reference_text": "Welcome to Fish Audio.",
"seed": 42,
"speed": 1
}
headers = {
"model": "<model>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
model: '<model>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
guidance_scale: 2,
instruct_guidance_scale: 0,
instruction: 'Warm, confident studio narrator with a natural tone',
language: 'en',
n: 2,
num_step: 32,
reference_text: 'Welcome to Fish Audio.',
seed: 42,
speed: 1
})
};
fetch('https://api.fish.audio/v1/voice-design', 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/voice-design",
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([
'guidance_scale' => 2,
'instruct_guidance_scale' => 0,
'instruction' => 'Warm, confident studio narrator with a natural tone',
'language' => 'en',
'n' => 2,
'num_step' => 32,
'reference_text' => 'Welcome to Fish Audio.',
'seed' => 42,
'speed' => 1
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"model: <model>"
],
]);
$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/voice-design"
payload := strings.NewReader("{\n \"guidance_scale\": 2,\n \"instruct_guidance_scale\": 0,\n \"instruction\": \"Warm, confident studio narrator with a natural tone\",\n \"language\": \"en\",\n \"n\": 2,\n \"num_step\": 32,\n \"reference_text\": \"Welcome to Fish Audio.\",\n \"seed\": 42,\n \"speed\": 1\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("model", "<model>")
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/voice-design")
.header("model", "<model>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"guidance_scale\": 2,\n \"instruct_guidance_scale\": 0,\n \"instruction\": \"Warm, confident studio narrator with a natural tone\",\n \"language\": \"en\",\n \"n\": 2,\n \"num_step\": 32,\n \"reference_text\": \"Welcome to Fish Audio.\",\n \"seed\": 42,\n \"speed\": 1\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fish.audio/v1/voice-design")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["model"] = '<model>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"guidance_scale\": 2,\n \"instruct_guidance_scale\": 0,\n \"instruction\": \"Warm, confident studio narrator with a natural tone\",\n \"language\": \"en\",\n \"n\": 2,\n \"num_step\": 32,\n \"reference_text\": \"Welcome to Fish Audio.\",\n \"seed\": 42,\n \"speed\": 1\n}"
response = http.request(request)
puts response.read_body{
"candidates": [
{
"id": "<string>",
"index": 1,
"audio_base64": "<string>",
"sample_rate": 123,
"duration_ms": 1,
"text": "<string>",
"instruct": "<string>",
"language": "<string>"
}
]
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}{
"status": 123,
"message": "<string>",
"reason": "<string>"
}application/json.You must include the model: voice-design-1 header. Extra request fields are rejected.audio_base64
audio payloads. Decode the base64 value to write the candidate audio to a
file.Example
curl --request POST https://api.fish.audio/v1/voice-design \
--header "Authorization: Bearer $FISH_API_KEY" \
--header "Content-Type: application/json" \
--header "model: voice-design-1" \
--data '{
"instruction": "Warm, confident studio narrator with a natural tone",
"reference_text": "Welcome to Fish Audio.",
"language": "en",
"n": 2,
"speed": 1,
"num_step": 32,
"guidance_scale": 2,
"instruct_guidance_scale": 0,
"seed": 42
}'
Usage notes
instructionis required and must be 1 to 2000 characters.reference_textis optional preview text and can be up to 150 characters.ncontrols how many candidates are returned. The supported range is 1 to 4.seedis optional and can help reproduce candidate generation.- The endpoint is stateless: it does not create batches, samples, voice models, or presigned URLs.
- Billing happens once per successful generation request, not once per candidate.
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
Specify which voice-design model to use.
"voice-design-1"Body
Request body for synchronous voice design generation. The endpoint returns generated voice candidates with base64-encoded audio.
Voice design prompt. Must contain 1 to 2000 characters.
1 - 2000Optional text used as reference content for the generated voice.
150Optional BCP-47 language hint, such as en, zh, or ja.
Number of voice candidates to generate.
1 <= x <= 4Speaking speed multiplier for candidate generation.
x <= 3Number of diffusion steps used by the voice-design model.
1 <= x <= 128Classifier-free guidance scale. Higher values follow the prompt more strongly.
x >= 0Instruction guidance scale for prompt conditioning.
x >= 0Optional deterministic seed for candidate generation.
Response
Request fulfilled, document follows
Generated voice candidates.
Show child attributes
Show child attributes
Was this page helpful?

