curl --request POST \
--url https://api.moda.app/v1/voices/similar \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"source_audio": "<string>",
"limit": 5
}
'import requests
url = "https://api.moda.app/v1/voices/similar"
payload = {
"source_audio": "<string>",
"limit": 5
}
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({source_audio: '<string>', limit: 5})
};
fetch('https://api.moda.app/v1/voices/similar', 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/similar",
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([
'source_audio' => '<string>',
'limit' => 5
]),
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.moda.app/v1/voices/similar"
payload := strings.NewReader("{\n \"source_audio\": \"<string>\",\n \"limit\": 5\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.moda.app/v1/voices/similar")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"source_audio\": \"<string>\",\n \"limit\": 5\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.moda.app/v1/voices/similar")
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 \"source_audio\": \"<string>\",\n \"limit\": 5\n}"
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>",
"settings_defaults": {
"stability": 123,
"similarity_boost": 123,
"style": 123,
"use_speaker_boost": true,
"speed": 123
},
"favorite": {
"user": true,
"workspace": true,
"workspace_default": true
},
"object": "voice"
}
],
"returned": 123,
"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
}Find Similar Voices
Find ElevenLabs Voice Library voices that sound like an uploaded recording, closest first.
source_audio is a file_ id from POST /v1/uploads (mp3, wav or aac, 1-300 seconds); it
is streamed to the provider and no copy is kept. Each result is the same voice object as GET /v1/voices/{voice_id}: speak it by its vox_ id like any catalog voice. These voices never
appear in GET /v1/voices. Free (model_not_in_plan, required_plan: starter) is refused;
the search itself is not charged.
curl --request POST \
--url https://api.moda.app/v1/voices/similar \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"source_audio": "<string>",
"limit": 5
}
'import requests
url = "https://api.moda.app/v1/voices/similar"
payload = {
"source_audio": "<string>",
"limit": 5
}
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({source_audio: '<string>', limit: 5})
};
fetch('https://api.moda.app/v1/voices/similar', 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/similar",
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([
'source_audio' => '<string>',
'limit' => 5
]),
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.moda.app/v1/voices/similar"
payload := strings.NewReader("{\n \"source_audio\": \"<string>\",\n \"limit\": 5\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.moda.app/v1/voices/similar")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"source_audio\": \"<string>\",\n \"limit\": 5\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.moda.app/v1/voices/similar")
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 \"source_audio\": \"<string>\",\n \"limit\": 5\n}"
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>",
"settings_defaults": {
"stability": 123,
"similarity_boost": 123,
"style": 123,
"use_speaker_boost": true,
"speed": 123
},
"favorite": {
"user": true,
"workspace": true,
"workspace_default": true
},
"object": "voice"
}
],
"returned": 123,
"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"