API Reference
Async Jobs
LiveCreate, poll, and download audio for long-running TTS synthesis jobs.
Overview
When you submit text longer than 2,000 characters to the TTS endpoint, it automatically returns a 202 response with a job_id. Use the Jobs API to poll status and download the completed audio.
You can also create jobs explicitly using the endpoint below.
Create job
POST /v1/tts/jobs
Creates an async synthesis job. Returns 202 with job metadata.
bash
curl -X POST https://sauti.finiflowlabs.com/v1/tts/jobs \
-H "xi-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "A long Swahili text exceeding 2000 characters...",
"voice_id": "sauti-swahili-v1",
"voice_settings": {
"speaking_rate": 1.0,
"noise_scale": 0.667,
"noise_scale_duration": 0.8
}
}'json
{
"job_id": "job_abc123",
"status": "queued",
"created_at": "2026-03-15T10:30:00Z"
}Get job status
GET /v1/tts/jobs/{job_id}
Returns the current status of a job. Status transitions: queued → running → succeeded or failed.
bash
curl https://sauti.finiflowlabs.com/v1/tts/jobs/job_abc123 \
-H "xi-api-key: YOUR_KEY"json
{
"job_id": "job_abc123",
"status": "succeeded",
"created_at": "2026-03-15T10:30:00Z",
"completed_at": "2026-03-15T10:30:12Z"
}Download audio
GET /v1/tts/jobs/{job_id}/audio
Downloads the completed audio file. Returns audio/wav binary data. Returns 409 Conflict if the job has not completed yet.
bash
curl https://sauti.finiflowlabs.com/v1/tts/jobs/job_abc123/audio \
-H "xi-api-key: YOUR_KEY" \
--output long_speech.wavPolling example
python
import time
import requests
API_BASE = "https://sauti.finiflowlabs.com"
HEADERS = {"xi-api-key": "YOUR_KEY"}
# 1. Create the job
job = requests.post(
f"{API_BASE}/v1/tts/jobs",
headers=HEADERS,
json={
"text": "A long Swahili text...",
"voice_id": "sauti-swahili-v1",
},
).json()
job_id = job["job_id"]
print(f"Job created: {job_id}")
# 2. Poll until complete
while True:
status = requests.get(
f"{API_BASE}/v1/tts/jobs/{job_id}",
headers=HEADERS,
).json()
if status["status"] in ("succeeded", "failed"):
break
print(f"Status: {status['status']}, waiting...")
time.sleep(2)
# 3. Download audio
if status["status"] == "succeeded":
audio = requests.get(
f"{API_BASE}/v1/tts/jobs/{job_id}/audio",
headers=HEADERS,
)
with open("output.wav", "wb") as f:
f.write(audio.content)
print("Audio saved.")
else:
print(f"Job failed: {status}")Error responses
| Status | Meaning |
|---|---|
404 | Job not found |
409 | Job not complete — audio cannot be downloaded yet |