Files

12 KiB

Extended API Endpoints Guide

This document describes all the extended endpoints added to the Qwen3-TTS API beyond basic TTS functionality.

Table of Contents

Voice Management

Upload Custom Voice

Uploads and registers a custom voice for voice cloning.

Endpoint: POST /v1/voices/upload

Parameters:

  • name (string, required): Display name for the voice
  • language (string, required): Language code (e.g., "English", "Russian")
  • audio (file, required): WAV audio file (5-30 seconds recommended)
  • ref_text (string, required): Exact transcription of the audio

Example:

curl -X POST "http://localhost:8000/v1/voices/upload" \
  -F "name=Alice" \
  -F "language=English" \
  -F "ref_text=This is a test of voice cloning." \
  -F "audio=@ref_audio.wav"

Python Example:

import requests

with open("voice.wav", "rb") as f:
    response = requests.post(
        "http://localhost:8000/v1/voices/upload",
        data={
            "name": "Alice",
            "language": "English",
            "ref_text": "This is a test of voice cloning."
        },
        files={"audio": f}
    )

voice = response.json()
print(f"Voice ID: {voice['id']}")

Response:

{
  "id": "voice_abc123def456",
  "name": "Alice",
  "language": "English",
  "created_at": 1708284000,
  "object": "voice"
}

List Voices

Lists all uploaded custom voices.

Endpoint: GET /v1/voices

Example:

curl "http://localhost:8000/v1/voices"

Response:

{
  "object": "list",
  "data": [
    {
      "id": "voice_abc123def456",
      "name": "Alice",
      "language": "English",
      "created_at": 1708284000,
      "object": "voice"
    },
    {
      "id": "voice_xyz789uvw012",
      "name": "Bob",
      "language": "Russian",
      "created_at": 1708280000,
      "object": "voice"
    }
  ]
}

Delete Voice

Deletes a custom voice from storage.

Endpoint: DELETE /v1/voices/{voice_id}

Example:

curl -X DELETE "http://localhost:8000/v1/voices/voice_abc123def456"

Response:

{
  "object": "voice.deleted",
  "id": "voice_abc123def456"
}

Text Validation

Validate Text

Validates text for TTS synthesis and provides analysis.

Endpoint: POST /v1/text/validate

Request:

{
  "text": "Your text to validate",
  "language": "English"
}

Features:

  • Character count validation
  • Maximum length check (10,000 characters)
  • Estimated audio duration (using ~150 wpm)
  • Warnings for edge cases
  • Language compatibility check

Example:

curl -X POST "http://localhost:8000/v1/text/validate" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "This is a test message.",
    "language": "English"
  }'

Response:

{
  "valid": true,
  "language": "English",
  "character_count": 23,
  "estimated_duration": 1.5,
  "warnings": []
}

Warnings Examples:

  • "Text is very short, may result in poor quality" (< 3 chars)
  • "Text is very long, generation may take several minutes" (> 5000 chars)
  • "Text contains emoji which may be handled differently"

Batch Processing

Batch processing allows you to submit multiple texts for asynchronous generation and retrieve results later.

Create Batch Job

Creates a new batch job for processing multiple texts.

Endpoint: POST /v1/batch/create

Request:

{
  "items": [
    {
      "text": "First item",
      "language": "English",
      "voice_clone_mode": "disabled"
    },
    {
      "text": "Second item",
      "language": "Russian",
      "voice_clone_mode": "disabled"
    }
  ],
  "model": "Qwen/Qwen3-TTS-12Hz-1.7B-Base"
}

Constraints:

  • Maximum 100 items per batch
  • Each item must have at least text field
  • Language defaults to "English" if not specified

Example:

curl -X POST "http://localhost:8000/v1/batch/create" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {"text": "Hello world"},
      {"text": "Goodbye world"}
    ]
  }'

Response:

{
  "id": "batch_abc123def456",
  "object": "batch",
  "status": "pending",
  "created_at": 1708284000,
  "updated_at": 1708284000,
  "request_counts": {
    "total": 2,
    "processing": 0,
    "completed": 0,
    "failed": 0
  },
  "output_file_id": null
}

Get Batch Status

Checks the status of a batch job.

Endpoint: GET /v1/batch/{job_id}

Example:

curl "http://localhost:8000/v1/batch/batch_abc123def456"

Response:

{
  "id": "batch_abc123def456",
  "object": "batch",
  "status": "completed",
  "created_at": 1708284000,
  "updated_at": 1708284060,
  "request_counts": {
    "total": 2,
    "processing": 0,
    "completed": 2,
    "failed": 0
  }
}

Status Values:

  • pending: Job waiting to be processed
  • processing: Currently processing items
  • completed: All items processed
  • failed: Job failed (check results for details)
  • cancelled: Job was cancelled

Get Batch Results

Retrieves results from a completed batch job.

Endpoint: GET /v1/batch/{job_id}/results

Example:

curl "http://localhost:8000/v1/batch/batch_abc123def456/results"

Response:

{
  "job_id": "batch_abc123def456",
  "object": "batch.results",
  "status": "completed",
  "data": [
    {
      "index": 0,
      "status": "success",
      "error": null,
      "audio_base64": "UklGRi4AAAA...",
      "duration": 1.2
    },
    {
      "index": 1,
      "status": "success",
      "error": null,
      "audio_base64": "UklGRi4AAAA...",
      "duration": 1.3
    }
  ]
}

Usage & Quotas

Get Usage Statistics

Retrieves your API usage statistics.

Endpoint: GET /v1/usage

Example:

curl "http://localhost:8000/v1/usage"

Response:

{
  "object": "usage",
  "requests_made": 42,
  "audio_generated_seconds": 245.5,
  "audio_generated_minutes": 4.09,
  "requests_by_model": {
    "Qwen/Qwen3-TTS-12Hz-1.7B-Base": 42
  },
  "requests_by_language": {
    "English": 25,
    "Russian": 12,
    "Chinese": 5
  }
}

Get Quota & Rate Limits

Retrieves current quota information and rate limits.

Endpoint: GET /v1/quota

Example:

curl "http://localhost:8000/v1/quota"

Response:

{
  "object": "quota",
  "requests_per_minute": 60,
  "max_text_length": 10000,
  "max_batch_size": 100,
  "concurrent_requests": 4,
  "remaining_requests": 58
}

Fields:

  • requests_per_minute: Rate limit (requests per single minute)
  • max_text_length: Maximum characters per TTS request
  • max_batch_size: Maximum items per batch job
  • concurrent_requests: Maximum concurrent requests
  • remaining_requests: How many requests left in current minute

Audio Conversion

Convert Audio Format & Sample Rate

Converts audio format or resamples to a different sample rate.

Endpoint: POST /v1/audio/convert

Request:

{
  "audio_base64": "UklGRi4AAAA...",
  "target_format": "wav",
  "target_sample_rate": 16000
}

Supported Formats:

  • wav: WAV (Waveform Audio)
  • mp3: MPEG Audio
  • ogg: Ogg Vorbis
  • flac: FLAC (Free Lossless Audio)

Sample Rates:

  • Valid range: 8kHz - 48kHz
  • Common values: 8000, 16000, 22050, 44100, 48000

Example:

curl -X POST "http://localhost:8000/v1/audio/convert" \
  -H "Content-Type: application/json" \
  -d '{
    "audio_base64": "UklGRi4AAAA...",
    "target_format": "wav",
    "target_sample_rate": 16000
  }'

Python Example:

import requests
import base64
import soundfile as sf
from io import BytesIO

# Get audio (from TTS or elsewhere)
response = requests.post(
    "http://localhost:8000/v1/audio/speech",
    json={"text": "Test"}
)
audio_b64 = response.json()["audio_base64"]

# Convert to 16kHz
response = requests.post(
    "http://localhost:8000/v1/audio/convert",
    json={
        "audio_base64": audio_b64,
        "target_sample_rate": 16000
    }
)

converted = response.json()
audio_bytes = base64.b64decode(converted["audio_base64"])
audio, sr = sf.read(BytesIO(audio_bytes))

Response:

{
  "id": "req_xyz789uvw012",
  "object": "audio",
  "created": 1708284000,
  "format": "wav",
  "sample_rate": 16000,
  "audio_base64": "UklGRi4AAAA...",
  "duration": 1.5
}

Model Configuration

Get Model Configuration

Retrieves detailed configuration for a specific model.

Endpoint: GET /v1/models/{model_id}/config

Example:

curl "http://localhost:8000/v1/models/Qwen/Qwen3-TTS-12Hz-1.7B-Base/config"

Response:

{
  "id": "Qwen/Qwen3-TTS-12Hz-1.7B-Base",
  "object": "model.config",
  "size": "1.7B",
  "tokenizer_type": "Qwen3TTSTokenizer",
  "languages": ["English", "Russian", "Chinese", "Japanese", "Korean"],
  "max_text_length": 10000,
  "output_sample_rate": 24000,
  "streaming_supported": true,
  "voice_cloning_supported": true,
  "recommended_parameters": {
    "temperature": 0.9,
    "top_p": 1.0,
    "top_k": 50,
    "do_sample": true,
    "repetition_penalty": 1.05,
    "emit_every_frames": 8,
    "decode_window_frames": 80
  }
}

Get Model Languages

Retrieves list of supported languages with codes.

Endpoint: GET /v1/models/{model_id}/languages

Example:

curl "http://localhost:8000/v1/models/Qwen/Qwen3-TTS-12Hz-1.7B-Base/languages"

Response:

{
  "object": "list",
  "model": "Qwen/Qwen3-TTS-12Hz-1.7B-Base",
  "languages": [
    {"code": "en", "name": "English"},
    {"code": "ru", "name": "Russian"},
    {"code": "zh", "name": "Chinese"},
    {"code": "ja", "name": "Japanese"},
    {"code": "ko", "name": "Korean"},
    {"code": "auto", "name": "Auto-detect"}
  ]
}

Error Handling

All endpoints follow consistent error response format:

Error Response:

{
  "error": "Error description",
  "code": "error_code",
  "details": {
    "field": "Additional context"
  }
}

Common HTTP Status Codes:

  • 200: Success
  • 400: Bad request (validation error)
  • 404: Resource not found
  • 409: Conflict (e.g., batch job not ready)
  • 503: Service unavailable (model loading)
  • 500: Server error

Rate Limiting

By default, the API enforces these limits:

  • 60 requests per minute per client
  • 100 items maximum per batch job
  • 10,000 characters maximum per text
  • 4 concurrent requests maximum

Python Integration Examples

Complete Workflow Example

import requests
import base64
import soundfile as sf
from io import BytesIO

BASE_URL = "http://localhost:8000"

# 1. Validate text
response = requests.post(
    f"{BASE_URL}/v1/text/validate",
    json={"text": "Hello world", "language": "English"}
)
validation = response.json()
print(f"Valid: {validation['valid']}, Duration: {validation['estimated_duration']:.2f}s")

# 2. Generate speech
response = requests.post(
    f"{BASE_URL}/v1/audio/speech",
    json={"text": "Hello world"}
)
audio_data = response.json()

# 3. Convert sample rate
response = requests.post(
    f"{BASE_URL}/v1/audio/convert",
    json={
        "audio_base64": audio_data["audio_base64"],
        "target_sample_rate": 16000
    }
)
converted = response.json()

# 4. Save to file
audio_bytes = base64.b64decode(converted["audio_base64"])
audio, sr = sf.read(BytesIO(audio_bytes))
sf.write("output.wav", audio, sr)

# 5. Check usage
response = requests.get(f"{BASE_URL}/v1/usage")
usage = response.json()
print(f"Total requests: {usage['requests_made']}")

See Also