curl --request POST \
--url https://platform.jobbit.uk/v1/audio/speech \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "openai/gpt-4o-mini-tts-2025-12-15",
"voice": "coral",
"input": "Welcome to Kent Physio. Please take a seat and we will be with you shortly.",
"response_format": "mp3"
}
'import requests
url = "https://platform.jobbit.uk/v1/audio/speech"
payload = {
"model": "openai/gpt-4o-mini-tts-2025-12-15",
"voice": "coral",
"input": "Welcome to Kent Physio. Please take a seat and we will be with you shortly.",
"response_format": "mp3"
}
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({
model: 'openai/gpt-4o-mini-tts-2025-12-15',
voice: 'coral',
input: 'Welcome to Kent Physio. Please take a seat and we will be with you shortly.',
response_format: 'mp3'
})
};
fetch('https://platform.jobbit.uk/v1/audio/speech', 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://platform.jobbit.uk/v1/audio/speech",
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([
'model' => 'openai/gpt-4o-mini-tts-2025-12-15',
'voice' => 'coral',
'input' => 'Welcome to Kent Physio. Please take a seat and we will be with you shortly.',
'response_format' => 'mp3'
]),
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://platform.jobbit.uk/v1/audio/speech"
payload := strings.NewReader("{\n \"model\": \"openai/gpt-4o-mini-tts-2025-12-15\",\n \"voice\": \"coral\",\n \"input\": \"Welcome to Kent Physio. Please take a seat and we will be with you shortly.\",\n \"response_format\": \"mp3\"\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://platform.jobbit.uk/v1/audio/speech")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"openai/gpt-4o-mini-tts-2025-12-15\",\n \"voice\": \"coral\",\n \"input\": \"Welcome to Kent Physio. Please take a seat and we will be with you shortly.\",\n \"response_format\": \"mp3\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://platform.jobbit.uk/v1/audio/speech")
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 \"model\": \"openai/gpt-4o-mini-tts-2025-12-15\",\n \"voice\": \"coral\",\n \"input\": \"Welcome to Kent Physio. Please take a seat and we will be with you shortly.\",\n \"response_format\": \"mp3\"\n}"
response = http.request(request)
puts response.read_body"<string>"{
"error": {
"code": "upstream_rejected",
"message": "response_format must be 'mp3', 'pcm', or 'wav'",
"request_id": "5d3f0b7c8a2e4e19b6c47a90d1e2f3a4"
}
}{
"error": {
"code": "invalid_key",
"message": "the API key is missing or invalid",
"request_id": "5d3f0b7c8a2e4e19b6c47a90d1e2f3a4"
}
}{
"error": {
"code": "insufficient_credits",
"message": "not enough credits to run this request",
"request_id": "5d3f0b7c8a2e4e19b6c47a90d1e2f3a4"
}
}{
"error": {
"code": "insufficient_scope",
"message": "this key does not have the deploy:write permission",
"details": {
"required": "deploy:write"
},
"request_id": "5d3f0b7c8a2e4e19b6c47a90d1e2f3a4"
}
}{
"error": {
"code": "rate_limited",
"message": "too many read requests, retry in 4 s",
"details": {
"group": "read",
"limit": 120,
"window_seconds": 60
},
"request_id": "5d3f0b7c8a2e4e19b6c47a90d1e2f3a4"
}
}Generate speech
Turns text into speech. By default the audio is streamed back as binary data in the chosen format; with store: true it is kept in storage and the answer is JSON with a link. The body may be up to 25 MiB (gzip allowed), and a key limited to some models may only call those models.
Requires the ai permission.
curl --request POST \
--url https://platform.jobbit.uk/v1/audio/speech \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "openai/gpt-4o-mini-tts-2025-12-15",
"voice": "coral",
"input": "Welcome to Kent Physio. Please take a seat and we will be with you shortly.",
"response_format": "mp3"
}
'import requests
url = "https://platform.jobbit.uk/v1/audio/speech"
payload = {
"model": "openai/gpt-4o-mini-tts-2025-12-15",
"voice": "coral",
"input": "Welcome to Kent Physio. Please take a seat and we will be with you shortly.",
"response_format": "mp3"
}
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({
model: 'openai/gpt-4o-mini-tts-2025-12-15',
voice: 'coral',
input: 'Welcome to Kent Physio. Please take a seat and we will be with you shortly.',
response_format: 'mp3'
})
};
fetch('https://platform.jobbit.uk/v1/audio/speech', 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://platform.jobbit.uk/v1/audio/speech",
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([
'model' => 'openai/gpt-4o-mini-tts-2025-12-15',
'voice' => 'coral',
'input' => 'Welcome to Kent Physio. Please take a seat and we will be with you shortly.',
'response_format' => 'mp3'
]),
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://platform.jobbit.uk/v1/audio/speech"
payload := strings.NewReader("{\n \"model\": \"openai/gpt-4o-mini-tts-2025-12-15\",\n \"voice\": \"coral\",\n \"input\": \"Welcome to Kent Physio. Please take a seat and we will be with you shortly.\",\n \"response_format\": \"mp3\"\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://platform.jobbit.uk/v1/audio/speech")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"openai/gpt-4o-mini-tts-2025-12-15\",\n \"voice\": \"coral\",\n \"input\": \"Welcome to Kent Physio. Please take a seat and we will be with you shortly.\",\n \"response_format\": \"mp3\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://platform.jobbit.uk/v1/audio/speech")
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 \"model\": \"openai/gpt-4o-mini-tts-2025-12-15\",\n \"voice\": \"coral\",\n \"input\": \"Welcome to Kent Physio. Please take a seat and we will be with you shortly.\",\n \"response_format\": \"mp3\"\n}"
response = http.request(request)
puts response.read_body"<string>"{
"error": {
"code": "upstream_rejected",
"message": "response_format must be 'mp3', 'pcm', or 'wav'",
"request_id": "5d3f0b7c8a2e4e19b6c47a90d1e2f3a4"
}
}{
"error": {
"code": "invalid_key",
"message": "the API key is missing or invalid",
"request_id": "5d3f0b7c8a2e4e19b6c47a90d1e2f3a4"
}
}{
"error": {
"code": "insufficient_credits",
"message": "not enough credits to run this request",
"request_id": "5d3f0b7c8a2e4e19b6c47a90d1e2f3a4"
}
}{
"error": {
"code": "insufficient_scope",
"message": "this key does not have the deploy:write permission",
"details": {
"required": "deploy:write"
},
"request_id": "5d3f0b7c8a2e4e19b6c47a90d1e2f3a4"
}
}{
"error": {
"code": "rate_limited",
"message": "too many read requests, retry in 4 s",
"details": {
"group": "read",
"limit": 120,
"window_seconds": 60
},
"request_id": "5d3f0b7c8a2e4e19b6c47a90d1e2f3a4"
}
}Authorizations
An API key from Settings → API keys, sent as Authorization: Bearer jb_live_…
Body
Fields not listed here are passed to the speech model.
A text-to-speech model id from GET /v1/audio/models?kind=tts.
The text to speak.
A voice name from GET /v1/audio/voices.
The audio format. pcm is raw 16-bit audio; wav wraps it in a WAV header.
mp3, pcm, wav Speaking speed, for models that support it (see supports_speed in the voice list).
Keep the audio in storage and answer with JSON containing its URL.
Response
The audio, or JSON with its link when store is true.
The response is of type file.