> ## Documentation Index
> Fetch the complete documentation index at: https://docs.jogg.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Synthesize Speech

> Generate speech with an optional ElevenLabs model: Flash v2.5 or v4 Turbo.

Generate speech audio from text using a public voice or a custom voice you can access.
The result includes a task ID, audio URL, and a subtitle URL when available.

## Choose a model

`model_id` is **optional** and applies only to ElevenLabs voices.

| Value | Behavior |
| - | - |
| Omitted | Uses `eleven_flash_v2_5` for an ElevenLabs voice |
| `eleven_flash_v2_5` | Selects Flash v2.5 |
| `eleven_v4_turbo` | Selects v4 Turbo |

Empty strings, whitespace, `null`, non-string values, and all other model IDs are
rejected. For a voice from another provider, omit `model_id` to keep that
provider's existing behavior; explicitly choosing an ElevenLabs model is rejected.

Find a `voice_id` in [Get Voices](https://docs.jogg.ai/api-reference/v2/Voice/GetVoices.md) or
[Get Custom Voices](https://docs.jogg.ai/api-reference/v2/Voice/GetCustomVoices.md).

## Pauses and audio tags

ElevenLabs documents different text controls for these models:

| Model | SSML `<break>` | Audio tags |
| - | - | - |
| `eleven_flash_v2_5` | Supported: `<break time="1.5s" />`. Use seconds, with a maximum of 3 seconds per break. | Does not support the square-bracket audio-tag controls used by v3/v4. |
| `eleven_v4_turbo` | Not supported. | Supports instructions such as `[whispers]`, `[laughs]`, `[short pause]`, `[pause]`, and `[long pause]` inside the text. |

Place the control directly in `text`; no additional tag parameter is needed.
Pause tags do not specify a fixed number of seconds, so they are not an exact
replacement for a timed SSML break. Delivery can vary with the voice and context.
ElevenLabs also warns that excessive SSML breaks can cause faster speech or audio
artifacts.

Jogg adapts pause syntax when sending the synthesis request:

| Selected model | Input control | Sent to ElevenLabs |
| - | - | - |
| `eleven_v4_turbo` | Timed break greater than 0 and up to 0.5 seconds | `[short pause]` |
| `eleven_v4_turbo` | Timed break over 0.5 and up to 1 second | `[pause]` |
| `eleven_v4_turbo` | Timed break over 1 second, including breaks over 2 seconds | `[long pause]` |
| `eleven_v4_turbo` | Zero-second break | Removed |
| `eleven_flash_v2_5` | `[short pause]` | `<break time="0.3s"/>` |
| `eleven_flash_v2_5` | `[pause]` | `<break time="0.75s"/>` |
| `eleven_flash_v2_5` | `[long pause]` | `<break time="1.5s"/>` |

Supported millisecond break values are converted to seconds before selecting the
v4 Turbo pause tag. These are Jogg compatibility rules; ElevenLabs does not define
an exact duration for each pause tag. Changing models can therefore change the
length of the pause. Flash only converts these three pause tags and preserves
other bracketed text. Delivery tags such as `[whispers]` need v4 Turbo.

Conversion uses a copy for synthesis and preserves your original text. Model
selection, request identity, and billing continue to follow the rules on this page.

New v4 Turbo subtitles omit complete square-bracket audio tags and SSML breaks.
When adapting v4 pause tags for Flash, subtitles omit those controls and their
converted breaks while retaining other bracketed text. These v4 compatibility
paths split words at explicit pauses and preserve the returned timing gap.
Native Flash SSML breaks continue to use the existing subtitle processing.
The input-text fallback uses the same filtering when word timestamps are
unavailable. A control-only result has no subtitle text. Existing subtitles are
not rewritten.

Flash v2.5 with a timed break:

```json theme={null}
{
  "text": "I will check the schedule.<break time=\"1.5s\" />The next session starts at noon.",
  "voice_id": "YOUR_ELEVENLABS_VOICE_ID",
  "model_id": "eleven_flash_v2_5",
  "idempotency_key": "speech-example-flash-pause"
}
```

v4 Turbo with delivery and pause tags:

```json theme={null}
{
  "text": "[whispers] The room is quiet. [short pause] You can begin.",
  "voice_id": "YOUR_ELEVENLABS_VOICE_ID",
  "model_id": "eleven_v4_turbo",
  "idempotency_key": "speech-example-turbo-tags"
}
```

Official ElevenLabs references (checked November 5, 2026):

* [Pause syntax, supported models, and the 3-second limit](https://elevenlabs.io/docs/help-center/product/core-capabilities/text-to-speech/how-can-i-add-pauses).
* [Audio tags, including explicit v4 Turbo support](https://elevenlabs.io/docs/help-center/product/core-capabilities/text-to-speech/how-do-audio-tags-work-with-eleven-v3-and-v4).
* [Prompting guidance and pause-tag examples](https://elevenlabs.io/docs/overview/capabilities/text-to-speech/best-practices#prompting-eleven-v4).
* [Official SSML guide: audio-tag compatibility FAQ](https://elevenlabs.io/blog/ssml-tags-explained).

## Example: select v4 Turbo

```bash theme={null}
curl --request POST \
  --url 'https://api.jogg.ai/v2/audio/tts/synthesize' \
  --header 'x-api-key: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "text": "Hello from JoggAI.",
    "voice_id": "YOUR_ELEVENLABS_VOICE_ID",
    "model_id": "eleven_v4_turbo",
    "idempotency_key": "speech-example-turbo"
  }'
```

To use the default Flash v2.5 model, omit `model_id`:

```json theme={null}
{
  "text": "Hello from JoggAI.",
  "voice_id": "YOUR_ELEVENLABS_VOICE_ID",
  "idempotency_key": "speech-example-flash"
}
```

## Retry the same request

Keep the returned `task_id`. Use the same optional `idempotency_key` only when
retrying the same request. A key already used with a different explicit model
causes a conflict; use a new key when intentionally changing the model or text.

Synthesis consumes API credits based on the generated audio duration. After a
timeout, check the existing [speech task](https://docs.jogg.ai/api-reference/v2/Voice/GetSpeechTask.md)
when its ID is known, or retry the unchanged request with its original key.
Avoid creating another paid request just because the connection timed out.

## Use the same selection through MCP

The `jogg_post_audio_tts_synthesize` tool accepts the same optional field under
`body.model_id`. See [MCP speech model selection](https://docs.jogg.ai/mcp/tools-billing-safety#speech-model-selection)
for a `tools/call` example.


## OpenAPI

````yaml POST /v2/audio/tts/synthesize
openapi: 3.0.1
info:
  title: JoggAI OpenAPI v2
  description: >
    JoggAI OpenAPI v2 provides a comprehensive suite of endpoints for creating
    and managing AI-powered video content.


    ## Authentication

    All API requests require authentication using an API key provided in the
    `x-api-key` header.


    ## Base URL

    Production: https://api.jogg.ai/v2


    ## Rate Limiting

    API calls are subject to rate limiting based on your subscription plan.


    ## Error Handling

    All endpoints return standard HTTP status codes along with detailed error
    messages in the response body.
  version: 2.0.0
  license:
    name: MIT
servers:
  - url: https://api.jogg.ai
    description: Production server
security:
  - apiKeyAuth: []
tags:
  - name: Video
    description: Video creation and management operations
  - name: Avatar
    description: Avatar management and creation operations
  - name: Voice
    description: Voice and timbre management operations
  - name: Asset
    description: Asset management including music, scripts, and uploads
  - name: Template
    description: Template management operations
  - name: Product
    description: Product management operations
  - name: User
    description: User account operations
  - name: Webhook
    description: Webhook endpoint management for event notifications
paths:
  /v2/audio/tts/synthesize:
    post:
      tags:
        - Voice
      summary: Synthesize speech
      description: >
        Generate speech audio and an optional subtitle file from text.

        For ElevenLabs voices, model_id optionally selects eleven_flash_v2_5 or
        eleven_v4_turbo.

        Omitting model_id uses eleven_flash_v2_5 for ElevenLabs voices and
        preserves existing behavior for other providers.

        Explicit model_id values are only supported for ElevenLabs voices. Empty
        strings, null, non-string values, and unsupported model IDs are
        rejected.

        Reuse the same idempotency_key only for the same request; changing an
        explicit model with the same key causes a conflict.

        Flash v2.5 supports SSML `<break time="1.5s" />` up to 3 seconds and
        does not support audio tags.

        v4 Turbo supports audio tags such as `[whispers]`, `[short pause]`,
        `[pause]`, and `[long pause]`, but does not support SSML `<break>`.
        Pause tags do not specify an exact duration.

        Put controls in text; no additional tag parameter is needed. When
        sending a v4 Turbo synthesis request, Jogg converts positive timed
        breaks of up to 0.5 seconds to `[short pause]`, over 0.5 and up to 1
        second to `[pause]`, and over 1 second to `[long pause]`; zero-second
        breaks are removed. Supported millisecond inputs are converted to
        seconds first.

        For Flash v2.5, Jogg converts `[short pause]`, `[pause]`, and `[long
        pause]` to SSML breaks of 0.3, 0.75, and 1.5 seconds respectively. These
        are Jogg compatibility rules, not exact duration equivalences specified
        by ElevenLabs. Other bracketed text is retained for Flash.

        Conversion uses a synthesis request copy and preserves the original text
        and existing request identity and billing rules. Newly generated v4
        Turbo subtitles omit audio tags and break tags. When adapting v4 pause
        tags for Flash, subtitles omit those controls and their converted breaks
        while retaining other bracketed text. These v4 compatibility paths split
        words at explicit pauses and retain provider timing gaps. Native Flash
        breaks continue to use the existing subtitle processing. Input-text
        subtitle fallback uses model-specific filtering.

        See ElevenLabs' [pause
        guide](https://elevenlabs.io/docs/help-center/product/core-capabilities/text-to-speech/how-can-i-add-pauses)
        and [audio-tag
        guide](https://elevenlabs.io/docs/help-center/product/core-capabilities/text-to-speech/how-do-audio-tags-work-with-eleven-v3-and-v4).
      operationId: jogg_post_audio_tts_synthesize
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - text
                - voice_id
              properties:
                text:
                  type: string
                  minLength: 1
                  description: Text to synthesize.
                voice_id:
                  type: string
                  minLength: 1
                  description: Public voice or an authorized custom voice ID.
                model_id:
                  type: string
                  description: >-
                    ElevenLabs-only speech model. Omit to use eleven_flash_v2_5
                    for ElevenLabs voices and retain the voice provider's
                    existing behavior otherwise. Explicit values for other
                    providers, empty strings, null, and unsupported model IDs
                    are rejected.
                  enum:
                    - eleven_flash_v2_5
                    - eleven_v4_turbo
                  default: eleven_flash_v2_5
                idempotency_key:
                  type: string
                  maxLength: 255
                  description: >-
                    Stable key for retries of this request. Use a new key for a
                    different model or text.
            examples:
              defaultModel:
                summary: Omit the model to use Flash v2.5 for an ElevenLabs voice
                value:
                  text: Hello from JoggAI.
                  voice_id: YOUR_ELEVENLABS_VOICE_ID
                  idempotency_key: speech-example-flash
              turboModel:
                summary: Select v4 Turbo for an ElevenLabs voice
                value:
                  text: Hello from JoggAI.
                  voice_id: YOUR_ELEVENLABS_VOICE_ID
                  model_id: eleven_v4_turbo
                  idempotency_key: speech-example-turbo
              flashPause:
                summary: Flash v2.5 with a timed SSML pause
                value:
                  text: >-
                    I will check the schedule.<break time="1.5s" />The next
                    session starts at noon.
                  voice_id: YOUR_ELEVENLABS_VOICE_ID
                  model_id: eleven_flash_v2_5
                  idempotency_key: speech-example-flash-pause
              turboAudioTags:
                summary: v4 Turbo with audio tags
                value:
                  text: '[whispers] The room is quiet. [short pause] You can begin.'
                  voice_id: YOUR_ELEVENLABS_VOICE_ID
                  model_id: eleven_v4_turbo
                  idempotency_key: speech-example-turbo-tags
      responses:
        '200':
          description: Speech task result. Check the business code before reading data.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SpeechTaskResponse'
components:
  schemas:
    SpeechTaskResponse:
      allOf:
        - $ref: '#/components/schemas/BaseResponse'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/SpeechTask'
    BaseResponse:
      type: object
      required:
        - code
        - msg
      properties:
        code:
          type: integer
          description: |
            Business status code:
            * 0 - Success
            * 10104 - Record not found
            * 10105 - Invalid API key
            * 18020 - Insufficient credit
            * 18025 - No permission to call APIs
            * 40000 - Parameter error
            * 50000 - System error
          example: 0
        msg:
          type: string
          description: Response message
          example: Success
    SpeechTask:
      type: object
      required:
        - task_id
        - status
        - progress
        - url
        - subtitle_url
        - duration_seconds
      properties:
        task_id:
          type: string
          description: Speech task ID to keep for status queries and retries.
          example: tts_123
        status:
          type: string
          enum:
            - processing
            - succeeded
            - failed
          example: succeeded
        progress:
          type: integer
          minimum: 0
          maximum: 100
          example: 100
        url:
          type: string
          description: Generated audio URL when the task succeeds; otherwise empty.
        subtitle_url:
          type: string
          description: Subtitle file URL when available; otherwise empty.
        duration_seconds:
          type: number
          description: Generated audio duration in seconds.
          example: 2.5
        error_message:
          type: string
          description: Failure details when the task fails.
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: API key for authentication. Obtain your key from the JoggAI dashboard.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.