kokoro-pay exposes an OpenAI-compatible text-to-speech API. If you
can call OpenAI's /v1/audio/speech, you can call this — just change the
base URL and use your kp_live_… key.
Sign in to the dashboard and create an API key. It's shown once —
copy it immediately. Keys look like kp_live_… and can be revoked at any time.
All endpoints live under …/v1.
Authenticate with your key as a Bearer token on every request:
Authorization: Bearer kp_live_your_key_here
POST …/v1/audio/speech
Send input text and a voice; the response body is the
raw audio stream. Cost is one credit per input character.
curl …/v1/audio/speech \
-H "Authorization: Bearer kp_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"model": "kokoro",
"input": "Hello from kokoro-pay.",
"voice": "af_sky",
"response_format": "mp3"
}' \
--output speech.mp3
from openai import OpenAI
client = OpenAI(
base_url="…/v1",
api_key="kp_live_your_key_here",
)
with client.audio.speech.with_streaming_response.create(
model="kokoro",
voice="af_sky",
input="Hello from kokoro-pay.",
) as response:
response.stream_to_file("speech.mp3")
const res = await fetch("…/v1/audio/speech", {
method: "POST",
headers: {
"Authorization": "Bearer kp_live_your_key_here",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "kokoro",
input: "Hello from kokoro-pay.",
voice: "af_sky",
}),
});
const audio = await res.arrayBuffer();
| Field | Type | Notes |
|---|---|---|
input | string | Text to synthesize. Required. Billed at one credit per character. |
voice | string | A voice id — see /v1/audio/voices. |
model | string | Model id — see /v1/models. |
response_format | string | Optional audio format (e.g. mp3, wav), passed through upstream. |
| Endpoint | Returns | Billed |
|---|---|---|
| POST /v1/audio/speech | Audio stream | len(input) credits |
| GET /v1/audio/voices | Available voices | Free |
| GET /v1/models | Available models | Free |
| GET /v1/balance | { balance, unlimited } | Free |
curl …/v1/balance \
-H "Authorization: Bearer kp_live_your_key_here"
input text./v1/audio/voices, /v1/models, /v1/balance) require a valid key but are free.| Status | Meaning |
|---|---|
400 | Invalid JSON body, or missing/empty input. |
401 | Missing, invalid, or revoked API key. |
402 | Insufficient credits — top up your balance. |
502 | Upstream synthesis error. Any charge for this request is refunded. |
Errors return a JSON body of the shape { "detail": "…" }.