Skip to content

TTS / STT API ​

Synthesize Speech ​

Convert text to audio.

POST /v1/synthesize

Request Body ​

json
{
  "text": "Hello world, this is a test.",
  "voiceId": "default",
  "format": "wav",
  "speed": 1.0,
  "pitch": 1.0,
  "provider": "cartesia"
}
FieldTypeDefaultDescription
textstringrequiredText to synthesize (1-10,000 chars)
voiceIdstring"default"Voice identifier
formatstring"wav"Output format: mp3, wav, ogg
speednumber1.0Playback speed (0.5-2.0)
pitchnumber1.0Pitch adjustment (0.5-2.0)
providerstring"default"TTS provider. See providers.

Response 200 ​

Binary audio stream with Content-Type set to the requested format.

TTS Providers ​

ProviderIDNotes
Cartesiacartesia~40ms TTFB. Recommended for production.
ElevenLabselevenlabsHigh quality, wide language support
DeepgramdeepgramFast, cost-effective
Fish Audiofish-audioOpen-source friendly
Resemble AIresemble-aiEnterprise voice cloning
InworldinworldGaming/interactive focus
ChatterboxchatterboxOpen-source, GPU-accelerated
KokorokokoroLightweight cheap/open fallback
F5 TTSf5-ttsOpen-source
CosyVoicecosyvoiceMultilingual
VoxCPMvoxcpmMultilingual open voice research
Qwen TTSqwen-ttsHuggingFace-hosted

Transcribe Audio ​

Synchronous transcription. Blocks until complete.

POST /v1/transcribe

JSON Body (URL reference) ​

json
{
  "audioUrl": "https://example.com/audio.mp3",
  "language": "en",
  "mode": "accurate",
  "diarize": true,
  "timestamps": "segment"
}

Multipart Form (file upload) ​

bash
curl -X POST https://api.ph0ny.com/v1/transcribe \
  -H "Authorization: Bearer $PH0NY_API_KEY" \
  -F "file=@recording.mp3" \
  -F "language=en" \
  -F "mode=accurate" \
  -F "diarize=true"
FieldTypeDefaultDescription
audioUrlstring-URL to audio file
filebinary-Audio file upload (multipart)
languagestring""Language code (auto-detect if empty)
modestring"accurate"accurate or fast
diarizebooleanfalseEnable speaker diarization
timestampsstring"segment"segment or word

Max file size: 25MB.

Response 200 ​

json
{
  "text": "Hello, welcome to the meeting. Today we'll discuss...",
  "segments": [
    {
      "start": 0.0,
      "end": 2.5,
      "text": "Hello, welcome to the meeting.",
      "speaker": "Speaker 1"
    }
  ],
  "words": [
    { "start": 0.0, "end": 0.4, "word": "Hello" }
  ],
  "language": "en",
  "duration": 45.2
}

Async Transcribe ​

Start a transcription job and poll for results. Useful for large files.

POST /v1/transcribe/async

Same request body as /v1/transcribe.

Response 202 ​

json
{
  "id": "job_abc123",
  "status": "processing",
  "createdAt": "2026-03-21T00:00:00.000Z"
}

Get Job ​

GET /v1/transcribe/:jobId

Response 200 ​

json
{
  "id": "job_abc123",
  "status": "completed",
  "result": {
    "text": "...",
    "segments": [...],
    "language": "en",
    "duration": 45.2
  },
  "createdAt": "2026-03-21T00:00:00.000Z",
  "completedAt": "2026-03-21T00:00:01.500Z"
}

Status values: processing, completed, failed.


OpenAI-Compatible Endpoints ​

Drop-in replacements for OpenAI's audio API:

TTS ​

POST /v1/audio/speech

Same interface as OpenAI's /v1/audio/speech. Billed per character of input, at the rate of the provider that answered — including when a x-phony.fallback provider serves the request.

The response names the vendor and the model that answered, in X-Phony-Provider and X-Phony-Model. These can differ from the model you sent: ph0ny does not forward your model segment to the vendor, so tts-1 runs Cartesia's own default model.

Choosing a provider ​

A model id that names a vendor selects that vendor. cartesia/sonic-3 and the bare slug cartesia both name Cartesia. tts-1, tts-1-hd and every auto strategy name none, so ph0ny chooses.

ph0ny does not answer with a vendor you named on behalf of one you did not. If the vendor you named fails, the request fails with that vendor's error, and no other vendor receives your text. If you named no vendor, ph0ny falls through to another one and sets X-Phony-Fallback: true on the response.

Send X-Phony-Strict-Provider to override that default.

ValueEffect
0, false, no, offAllow ph0ny to answer with another vendor
any other valueRefuse to answer with another vendor

A model id whose vendor ph0ny does not serve is refused with 400 unknown_provider before any vendor is called.

STT ​

POST /v1/audio/transcriptions

Same interface as OpenAI's /v1/audio/transcriptions. Max 25MB.

This endpoint transcribes with Deepgram, OpenAI and ElevenLabs. Send one of their model ids, or auto to let ph0ny choose. Any other model id is refused with 400 unsupported_model; ph0ny does not transcribe with a vendor you did not name.

The response carries X-Phony-Provider, X-Phony-Latency-Ms and X-Phony-Audio-Seconds — the audio length the transcription was billed on. With response_format=verbose_json, duration reports that same measured length. Transcription is billed per minute of audio, rounded up, minimum one minute.

List Models ​

GET /v1/audio/models

Returns available audio models for TTS and STT.

Built by ph0ny.