curl --request GET \
--url https://api.moda.app/v1/voices \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.moda.app/v1/voices"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.moda.app/v1/voices', 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.moda.app/v1/voices",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.moda.app/v1/voices"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.moda.app/v1/voices")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.moda.app/v1/voices")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"id": "<string>",
"name": "<string>",
"description": "<string>",
"provider": "elevenlabs",
"category": "<string>",
"source": "<string>",
"creator_name": "<string>",
"labels": {
"accent": "<string>",
"age": "<string>",
"gender": "<string>",
"use_case": "<string>",
"descriptive": "<string>"
},
"languages": [
{
"language": "<string>",
"accent": "<string>",
"locale": "<string>"
}
],
"compatible_models": [
"<string>"
],
"recommended_models": [
"<string>"
],
"preview": {
"url": "<string>",
"mime_type": "audio/mpeg",
"expires_at": "<string>"
},
"availability": {
"status": "<string>",
"reason": "<string>",
"revoked_at": "<string>"
},
"catalog_refreshed_at": "<string>",
"object": "voice"
}
],
"next_cursor": "<string>",
"returned": 123,
"has_more": true,
"limit": 123,
"total": 123,
"filters_applied": {
"query": "<string>",
"language": "<string>",
"accent": "<string>",
"use_case": "<string>",
"gender": "<string>",
"provider": "elevenlabs",
"category": "<string>",
"include_unavailable": true
},
"object": "list"
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}List Voices
Search the managed voice catalog: ElevenLabs and Inworld premade voices and Fish Audio’s library.
Each voice names its provider; a voice renders only on its own engine’s models
(compatible_models). Every filter is enforced server-side and echoed in
filters_applied. The opaque next_cursor is bound to these filters; changing them with
a cursor is 400 invalid_cursor.
curl --request GET \
--url https://api.moda.app/v1/voices \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.moda.app/v1/voices"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.moda.app/v1/voices', 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.moda.app/v1/voices",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.moda.app/v1/voices"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.moda.app/v1/voices")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.moda.app/v1/voices")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"id": "<string>",
"name": "<string>",
"description": "<string>",
"provider": "elevenlabs",
"category": "<string>",
"source": "<string>",
"creator_name": "<string>",
"labels": {
"accent": "<string>",
"age": "<string>",
"gender": "<string>",
"use_case": "<string>",
"descriptive": "<string>"
},
"languages": [
{
"language": "<string>",
"accent": "<string>",
"locale": "<string>"
}
],
"compatible_models": [
"<string>"
],
"recommended_models": [
"<string>"
],
"preview": {
"url": "<string>",
"mime_type": "audio/mpeg",
"expires_at": "<string>"
},
"availability": {
"status": "<string>",
"reason": "<string>",
"revoked_at": "<string>"
},
"catalog_refreshed_at": "<string>",
"object": "voice"
}
],
"next_cursor": "<string>",
"returned": 123,
"has_more": true,
"limit": 123,
"total": 123,
"filters_applied": {
"query": "<string>",
"language": "<string>",
"accent": "<string>",
"use_case": "<string>",
"gender": "<string>",
"provider": "elevenlabs",
"category": "<string>",
"include_unavailable": true
},
"object": "list"
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}Authorizations
API key from Settings > Developer > REST API
Headers
The voice engines this client understands, comma-separated: elevenlabs,fishaudio,inworld. ElevenLabs is always on; Fish Audio models and voices appear only for a client that lists fishaudio (or, on GET /v1/voices, asks for provider=fishaudio or a featured/community category), and Inworld's only for a client that lists inworld (or asks for provider=inworld).
Calendar-dated API version pin. New integrations should pin 2026-05-01 to opt into the newest response shapes. For back-compat the server also accepts requests with no header and resolves them to the current default (today: 2026-04-12); that default advances on each sunset date. Any unsupported value returns 400 unsupported_version.
2026-04-12, 2026-05-01 "2026-05-01"
Query Parameters
2001610010016elevenlabs, fishaudio or inworld: only that engine's voices.
32premade (ElevenLabs and Inworld stock voices), featured (Fish Audio voices whose rights Fish secured, celebrity and creator voices included) or community (popular public Fish Audio voices).
3210241 <= x <= 100Response
Successful Response