Text-to-Speech API
Submit plain text and get a single rendered audio file. A lean, single-voice endpoint — no character detection, portraits, scenes, or music. For full audiobook production use the Audiobook API.
Quick Start
Submit text, poll for completion, fetch the audio URL.
1. Submit text
curl -X POST https://notevibes.com/api/tts/create \
-H "Authorization: Bearer nvb_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"title": "Welcome message",
"content": "Hello, and welcome to Notevibes.",
"voice": "en-US-Chirp3-HD-Achernar"
}'2. Poll for completion
curl https://notevibes.com/api/tts/jobs/{jobId} \
-H "Authorization: Bearer nvb_your_api_key"3. When status is "completed", download result.audioUrl
Create TTS Job
/api/tts/createSubmit plain text to be rendered as a single-voice audio file. Returns immediately with a job ID — synthesis runs asynchronously.
Request Body
| Parameter | Type | Description |
|---|---|---|
title* | string | Label for the job. Shows up in the status response and in your library. |
content* | string | The text to synthesize. Plain text only. |
voice | string | Voice ID. Default: "en-US-Chirp3-HD-Achernar". See the Voices tab for the full list. |
Example
curl -X POST https://notevibes.com/api/tts/create \
-H "Authorization: Bearer nvb_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"title": "Episode intro",
"content": "Welcome back to the show. Today we dive into AI voice technology.",
"voice": "en-US-Chirp3-HD-Leda"
}'Response
{
"jobId": "abc123def456",
"status": "processing",
"estimatedCredits": 68
}Error Responses
| Status | Reason |
|---|---|
400 | Missing title or content |
401 | Invalid or missing API key |
402 | Insufficient credits |
403 | API key lacks write permission |
List Jobs
/api/tts/jobsList TTS jobs for the authenticated organization, newest first. Returns a slim view — fetch /api/tts/jobs/:jobId for the full result payload (including audioUrl).
Query Parameters
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: "queued", "processing", "completed", or "failed". |
limit | number | Max jobs to return (1–100). Default: 20. |
cursor | string | Job ID from the previous response’s nextCursor. Used for pagination. |
Example
curl "https://notevibes.com/api/tts/jobs?status=completed&limit=20" \
-H "Authorization: Bearer nvb_your_api_key"Response
{
"jobs": [
{
"jobId": "abc123def456",
"status": "completed",
"step": "completed",
"title": "Episode intro",
"estimatedCredits": 68,
"createdAt": "2026-04-18T14:23:01.000Z",
"updatedAt": "2026-04-18T14:23:14.000Z"
}
],
"nextCursor": "abc123def456"
}If nextCursor is non-null, pass it back as ?cursor=... to fetch the next page.
Get Job Status
/api/tts/jobs/:jobIdPoll this endpoint to track progress. Recommended interval: every 3-5 seconds for short text.
Response (Processing)
{
"jobId": "abc123def456",
"status": "processing",
"step": "generating_audio",
"title": "Episode intro",
"progress": { "currentChapter": 0, "totalChapters": 1 },
"estimatedCredits": 68
}Response (Queued)
{
"jobId": "abc123def456",
"status": "queued",
"queuePosition": 3,
"title": "Episode intro",
"estimatedCredits": 68
}Response (Completed)
{
"jobId": "abc123def456",
"status": "completed",
"step": "completed",
"title": "Episode intro",
"progress": { "currentChapter": 1, "totalChapters": 1 },
"estimatedCredits": 68,
"result": {
"audioUrl": "https://storage.googleapis.com/notevibes.com/...?X-Goog-Signature=...",
"audioUrlExpiresIn": 3600,
"duration": 9.4,
"credits": {
"total": 68,
"remaining": 9932,
"breakdown": []
}
}
}audioUrl is a fresh signed URL that expires in audioUrlExpiresIn seconds (1 hour). Re-poll this endpoint to get a new URL if the previous one expired.
Response (Failed)
{
"jobId": "abc123def456",
"status": "failed",
"error": "Pipeline failed"
}Status Values
| Status | Meaning |
|---|---|
queued | Waiting for a processing slot. See queuePosition. |
processing | Synthesis in progress. |
completed | Done. result.audioUrl is ready. |
failed | Job failed. See error. |