Ditto Audio · Schema

SpeechBatchDto

Text-to-SpeechVoice PluginsAudiobooksNeural VoiceOn-Device AI

Properties

Name Type Description
model string Default model for every item that doesn’t set its own.
voice string Default voice for every item that doesn’t set its own. With no voice anywhere (or `default` / `auto` / a language tag), each item gets the voice the server picks for its language, as POST speech does.
gender string With no voice named: prefer a voice of this gender.
language string Default language. Omit to infer per item from its own text; text with no clear sign of its language is read in the item voice’s own.
speed number
response_format string Default audio encoding for every item that doesn’t set its own. Every item is a COMPLETE file — real sizes in its header, not the streaming placeholder — so the result is directly playable and directl
pauses object Default for every item; an item’s own `pauses` override it field by field. Pauses placed between engine calls, in milliseconds. Long text is synthesized in several calls (by sentence: about 120 charac
items array Up to 64 items, answered on this one connection. For more than that (or for work you don’t want to hold a socket open for), create an async job with POST /v1/audio/batches instead.
stream boolean true (default): `application/x-ndjson` — one JSON object per line, written the moment that item finishes, so you can start using results before the batch is done. false: one buffered `application/json
View JSON Schema on GitHub

JSON Schema

ditto-audio-speech-batch-dto-schema.json Raw ↑
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/ditto-audio/json-schema/ditto-audio-speech-batch-dto-schema.json",
  "title": "SpeechBatchDto",
  "x-generated": "2026-11-05",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/ditto-audio-openapi.json#/components/schemas/SpeechBatchDto",
  "type": "object",
  "properties": {
    "model": {
      "type": "string",
      "enum": [
        "kokoro",
        "xtts",
        "pocket"
      ],
      "description": "Default model for every item that doesn’t set its own."
    },
    "voice": {
      "type": "string",
      "description": "Default voice for every item that doesn’t set its own. With no voice anywhere (or `default` / `auto` / a language tag), each item gets the voice the server picks for its language, as POST speech does."
    },
    "gender": {
      "type": "string",
      "enum": [
        "female",
        "male",
        "neutral"
      ],
      "description": "With no voice named: prefer a voice of this gender."
    },
    "language": {
      "type": "string",
      "description": "Default language. Omit to infer per item from its own text; text with no clear sign of its language is read in the item voice’s own."
    },
    "speed": {
      "type": "number",
      "default": 1,
      "minimum": 0.5,
      "maximum": 2
    },
    "response_format": {
      "type": "string",
      "enum": [
        "mp3",
        "mp3_64",
        "mp3_160",
        "wav",
        "wav24",
        "wav32f",
        "flac",
        "flac24",
        "pcm",
        "pcm_f32",
        "aiff",
        "caf",
        "au",
        "mulaw",
        "alaw"
      ],
      "default": "mp3",
      "description": "Default audio encoding for every item that doesn’t set its own. Every item is a COMPLETE file — real sizes in its header, not the streaming placeholder — so the result is directly playable and directly saveable. Hi-fidelity formats bill at 1.2× the normal rate, multiplied by the model’s own weighting — the audio is identical, but the bytes are several times larger. `mp3` (the default), `mp3_64`, `mulaw` and `alaw` are unchanged at 1×. Each format’s exact multiplier is in GET /v1/audio/format and in the `X-Ditto-Audio-Cost-Multiplier` response header."
    },
    "pauses": {
      "description": "Default for every item; an item’s own `pauses` override it field by field. Pauses placed between engine calls, in milliseconds. Long text is synthesized in several calls (by sentence: about 120 characters a call for xtts and pocket, 60 for Pocket Japanese and 75 for Pocket Korean; one sentence a call for kokoro) and joined; inside a call the model places every pause itself. Omit a field (or the whole object) and that join gets the pause the model itself leaves at that kind of boundary, scaled by `speed`. A value you set is exact: not scaled by `speed`. The pause is what a listener hears between the two words: whatever silence each side already ends or starts with counts toward it. The clip also ends with its last boundary's pause, so clips can be concatenated. Defaults at speed 1 (ms): `xtts`: sentence 540 (460 after ?, 500 after !), clause 330 (after a comma), paragraph 810; `kokoro`: sentence 430 (420 after ?, 440 after !), clause 150 (after a comma), paragraph 640; `pocket`: sentence 770 (850 after ?, 670 after !), clause 240 (after a comma), paragraph 1160.",
      "allOf": [
        {
          "$ref": "#/$defs/PausesDto"
        }
      ]
    },
    "items": {
      "maxItems": 64,
      "description": "Up to 64 items, answered on this one connection. For more than that (or for work you don’t want to hold a socket open for), create an async job with POST /v1/audio/batches instead.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/SpeechBatchItemDto"
      }
    },
    "stream": {
      "type": "boolean",
      "default": true,
      "description": "true (default): `application/x-ndjson` — one JSON object per line, written the moment that item finishes, so you can start using results before the batch is done. false: one buffered `application/json` envelope `{ results, summary }` with results in REQUEST order."
    }
  },
  "required": [
    "items"
  ],
  "$defs": {
    "PausesDto": {
      "type": "object",
      "properties": {
        "sentence": {
          "type": "number",
          "minimum": 0,
          "maximum": 5000,
          "description": "Milliseconds after a sentence (. ! ? …). Setting it sends every sentence as its own engine call, so EVERY sentence boundary gets exactly this pause instead of the model’s own."
        },
        "clause": {
          "type": "number",
          "minimum": 0,
          "maximum": 5000,
          "description": "Milliseconds where a sentence too long for one engine call is cut at a comma, semicolon, colon or dash. Commas inside a call are paced by the model and are not affected."
        },
        "paragraph": {
          "type": "number",
          "minimum": 0,
          "maximum": 5000,
          "description": "Milliseconds at a blank line in `input`."
        }
      }
    },
    "SpeechBatchItemDto": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Your own correlation id, echoed back on this item’s result. Never interpreted by us and never required to be unique — results also carry `index`, which always identifies the item unambiguously."
        },
        "model": {
          "type": "string",
          "enum": [
            "kokoro",
            "xtts",
            "pocket"
          ],
          "description": "Overrides the batch default for this item."
        },
        "voice": {
          "type": "string",
          "description": "Overrides the batch default for this item. Omit both and the server picks the voice for the item’s language."
        },
        "gender": {
          "type": "string",
          "enum": [
            "female",
            "male",
            "neutral"
          ],
          "description": "Overrides the batch default for this item: with no voice named, prefer this gender."
        },
        "input": {
          "type": "string",
          "maxLength": 8000,
          "description": "The text to speak. The only required field."
        },
        "language": {
          "type": "string",
          "description": "Overrides the batch default for this item. See GET /v1/audio/languages."
        },
        "speed": {
          "type": "number",
          "minimum": 0.5,
          "maximum": 2,
          "description": "Overrides the batch default for this item."
        },
        "response_format": {
          "type": "string",
          "enum": [
            "mp3",
            "mp3_64",
            "mp3_160",
            "wav",
            "wav24",
            "wav32f",
            "flac",
            "flac24",
            "pcm",
            "pcm_f32",
            "aiff",
            "caf",
            "au",
            "mulaw",
            "alaw"
          ],
          "description": "Overrides the batch default for this item — each result is its own complete file, so a batch may mix formats freely. Billed at this item’s own rate."
        },
        "pauses": {
          "description": "Overrides the batch default for this item, field by field. Pauses placed between engine calls, in milliseconds. Long text is synthesized in several calls (by sentence: about 120 characters a call for xtts and pocket, 60 for Pocket Japanese and 75 for Pocket Korean; one sentence a call for kokoro) and joined; inside a call the model places every pause itself. Omit a field (or the whole object) and that join gets the pause the model itself leaves at that kind of boundary, scaled by `speed`. A value you set is exact: not scaled by `speed`. The pause is what a listener hears between the two words: whatever silence each side already ends or starts with counts toward it. The clip also ends with its last boundary's pause, so clips can be concatenated. Defaults at speed 1 (ms): `xtts`: sentence 540 (460 after ?, 500 after !), clause 330 (after a comma), paragraph 810; `kokoro`: sentence 430 (420 after ?, 440 after !), clause 150 (after a comma), paragraph 640; `pocket`: sentence 770 (850 after ?, 670 after !), clause 240 (after a comma), paragraph 1160.",
          "allOf": [
            {
              "$ref": "#/$defs/PausesDto"
            }
          ]
        }
      },
      "required": [
        "input"
      ]
    }
  }
}

Work with this as data

Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for schemas

4 MCP tools reach this
  • find_json_schemasBrowse and filter every JSON Schema in the catalog.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This JSON Schema
curl "https://apis.io/api/v1/json-schemas/ditto-audio-speech-batch-dto"
All schemas
curl "https://apis.io/api/v1/json-schemas?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.