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

# Create realtime TTS session

> Create a short-lived browser-safe token for the realtime text-to-speech WebSocket. This HTTP operation only creates the session. Official SDKs and the CLI prefer the optional query-free `direct_websocket_url` and fall back to `websocket_url`; wait for `session.ready`, and then exchange turn events and binary PCM audio. While no turn is active, send `session.update` with non-empty `instructions` (up to 1,000 characters) and wait for `session.updated`; the confirmed instructions apply starting with the next turn. See the [Realtime TTS WebSocket guide](https://docs.breezeblue.ai/guides/realtime-text-to-speech) for complete raw WebSocket, SDK, browser playback, and CLI examples.



## OpenAPI

````yaml /openapi.json post /v1/text-to-speech/{voice_id}/realtime-sessions
openapi: 3.1.0
info:
  title: Breeze Developer API
  description: >-
    Breeze Developer API for models, voices, text-to-speech, history, balance,
    usage, and browser-managed API keys.
  version: 1.0.0
servers:
  - url: https://api.breeze.blue
security: []
tags:
  - name: Models
    description: Supported TTS models.
  - name: Text to Speech
    description: Text-to-speech synthesis and instruction enhancement.
  - name: Voices
    description: Saved voices and voice settings.
  - name: Voice Previews
    description: Create, audition, and save temporary voice previews.
  - name: Account
    description: Balance, usage, and API keys.
  - name: History
    description: Generated audio history.
paths:
  /v1/text-to-speech/{voice_id}/realtime-sessions:
    post:
      tags:
        - Text to Speech
      summary: Create realtime TTS session
      description: >-
        Create a short-lived browser-safe token for the realtime text-to-speech
        WebSocket. This HTTP operation only creates the session. Official SDKs
        and the CLI prefer the optional query-free `direct_websocket_url` and
        fall back to `websocket_url`; wait for `session.ready`, and then
        exchange turn events and binary PCM audio. While no turn is active, send
        `session.update` with non-empty `instructions` (up to 1,000 characters)
        and wait for `session.updated`; the confirmed instructions apply
        starting with the next turn. See the [Realtime TTS WebSocket
        guide](https://docs.breezeblue.ai/guides/realtime-text-to-speech) for
        complete raw WebSocket, SDK, browser playback, and CLI examples.
      operationId: tts_realtime_sessions_create
      parameters:
        - name: voice_id
          in: path
          required: true
          schema:
            title: Voice Id
            type: string
          description: >-
            Voice identifier to synthesize. Use GET /v1/voices to discover
            available IDs.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RealtimeTtsSessionRequest'
      responses:
        '200':
          description: Realtime WebSocket session token and compatible transport URLs.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RealtimeTtsSessionResponse'
          headers:
            x-breeze-api-key-id:
              description: >-
                Public API key identifier used to authenticate the request, when
                an API key was used.
              schema:
                type: string
        '401':
          description: HTTP 401 error response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: HTTP 403 error response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: HTTP 404 error response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: HTTP 422 error response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'
        '503':
          description: HTTP 503 error response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |-
            curl \
              --request POST \
              --url "https://api.breeze.blue/v1/text-to-speech/voc_xeh3w54cqvnp/realtime-sessions" \
              --header "xi-api-key: $BREEZE_API_KEY" \
              --header "Content-Type: application/json" \
              --data '{
              "model_id": "breeze-tts-2",
              "language_code": "en",
              "instructions": "Keep turns responsive and conversational.",
              "voice_settings": {
                "guidance_scale": 4.0
              },
              "inactivity_timeout_seconds": 30,
              "enable_logging": true
            }'
        - lang: Python
          label: Python SDK
          source: |-
            import asyncio
            from pathlib import Path

            import os

            from breeze_blue import BreezeBlue

            client = BreezeBlue(api_key=os.environ["BREEZE_API_KEY"])

            session = client.text_to_speech.create_realtime_session(
                voice_id="voc_xeh3w54cqvnp",
                model_id="breeze-tts-2",
            )


            async def main() -> None:
                async with client.text_to_speech.connect_realtime(
                    voice_id="voc_xeh3w54cqvnp",
                    client_secret=session["client_secret"],
                    websocket_url=session["websocket_url"],
                    direct_websocket_url=session.get("direct_websocket_url"),
                ) as connection:
                    async def consume_audio() -> bytes:
                        audio = bytearray()
                        async for event in connection:
                            if event["type"] == "audio":
                                audio.extend(event["audio"])
                            elif event["type"] == "error":
                                raise RuntimeError(event["message"])
                            elif event["type"] == "turn.done":
                                return bytes(audio)
                        raise RuntimeError("Realtime session closed before turn.done")

                    consumer = asyncio.create_task(consume_audio())
                    await connection.start_turn("turn_1")
                    await connection.append_text("Hello from Breeze.")
                    await connection.flush()
                    await connection.end_turn()
                    Path("out.pcm").write_bytes(await consumer)


            asyncio.run(main())
        - lang: TypeScript
          label: TypeScript SDK
          source: |-
            import { writeFile } from "node:fs/promises";

            import { BreezeBlueClient } from "@breeze.blue/sdk";

            const client = new BreezeBlueClient({
              apiKey: process.env.BREEZE_API_KEY!,
            });

            const session = await client.textToSpeech.realtime.createSession(
              "voc_xeh3w54cqvnp",
              { modelId: "breeze-tts-2" },
            );

            const connection = await client.textToSpeech.realtime.connect(
              "voc_xeh3w54cqvnp",
              {
                clientSecret: session.clientSecret,
                websocketUrl: session.websocketUrl,
                directWebsocketUrl: session.directWebsocketUrl,
              },
            );

            const consumer = (async () => {
              const pcmChunks: Uint8Array[] = [];
              for await (const message of connection) {
                if (message.type === "audio") pcmChunks.push(message.audio);
                if (message.type === "error") throw new Error(message.message);
                if (message.type === "turn.done") return pcmChunks;
              }
              throw new Error("Realtime session closed before turn.done");
            })();

            connection.startTurn("turn_1");
            connection.appendText("Hello from Breeze.");
            connection.flush();
            connection.endTurn();

            const pcmChunks = await consumer;
            await writeFile(
              "out.pcm",
              Buffer.concat(pcmChunks.map((chunk) => Buffer.from(chunk))),
            );
            connection.close();
components:
  schemas:
    RealtimeTtsSessionRequest:
      properties:
        model_id:
          anyOf:
            - type: string
              maxLength: 120
              minLength: 1
            - type: 'null'
          title: Model Id
          description: Optional model identifier to use for realtime synthesis.
        language_code:
          anyOf:
            - type: string
              maxLength: 2
              minLength: 2
              pattern: ^[A-Za-z]{2}$
            - type: 'null'
          title: Language Code
          description: >-
            Optional ISO 639-1 two-letter language code. The selected model must
            list the code in supported_languages.
        instructions:
          anyOf:
            - type: string
            - type: 'null'
          title: Instructions
          description: >-
            Optional initial performance instructions for the realtime session.
            Use Chinese for Chinese TTS and English for English or any other
            language; realtime sessions do not translate instructions
            automatically. While the WebSocket is idle, send session.update to
            change them; after session.updated confirms the change, the new
            instructions apply starting with the next turn.
        voice_settings:
          anyOf:
            - $ref: '#/components/schemas/RealtimeTtsVoiceSettingsPayload'
            - type: 'null'
          description: Optional realtime voice settings.
        inactivity_timeout_seconds:
          anyOf:
            - type: integer
              maximum: 180
              minimum: 1
            - type: 'null'
          title: Inactivity Timeout Seconds
          description: >-
            Idle timeout for the WebSocket session. Defaults to 30 seconds and
            is capped at 180 seconds.
        enable_logging:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Enable Logging
          description: Whether realtime turns should be stored in generation history.
      additionalProperties: false
      type: object
      title: RealtimeTtsSessionRequest
    RealtimeTtsSessionResponse:
      properties:
        client_secret:
          type: string
          title: Client Secret
          description: Short-lived token for browser WebSocket connections.
        websocket_url:
          type: string
          title: Websocket Url
          description: WebSocket URL including the client_secret query parameter.
        direct_websocket_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Direct Websocket Url
          description: >-
            Optional direct WebSocket URL without credentials in its query.
            Authenticate with the documented WebSocket subprotocols.
        expires_at:
          type: string
          title: Expires At
          description: ISO-8601 expiration timestamp for the client secret.
        audio_format:
          $ref: '#/components/schemas/RealtimeTtsAudioFormat'
          description: Fixed realtime audio stream format.
      type: object
      required:
        - client_secret
        - websocket_url
        - expires_at
      title: RealtimeTtsSessionResponse
    ErrorResponse:
      properties:
        ok:
          default: false
          title: Ok
          type: boolean
        code:
          title: Code
          type: string
        detail:
          title: Detail
          type: string
        error:
          title: Error
          type: string
        meta:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          default: null
          title: Meta
      required:
        - code
        - detail
        - error
      title: ErrorResponse
      type: object
    ValidationErrorResponse:
      properties:
        ok:
          default: false
          title: Ok
          type: boolean
        code:
          title: Code
          type: string
        detail:
          title: Detail
          type: string
        error:
          title: Error
          type: string
        meta:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Meta
      required:
        - code
        - detail
        - error
      title: ValidationErrorResponse
      type: object
    RealtimeTtsVoiceSettingsPayload:
      properties:
        guidance_scale:
          anyOf:
            - type: number
              maximum: 10
              minimum: 1
            - type: 'null'
          title: Guidance Scale
          description: >-
            Generation guidance strength. Accepted range: 1.0 to 10.0. When
            omitted, the voice's saved setting is used.
      additionalProperties: false
      type: object
      title: RealtimeTtsVoiceSettingsPayload
    RealtimeTtsAudioFormat:
      properties:
        codec:
          type: string
          title: Codec
          default: pcm_s16le
        sample_rate:
          type: integer
          title: Sample Rate
          default: 24000
        channels:
          type: integer
          title: Channels
          default: 1
        sample_width_bits:
          type: integer
          title: Sample Width Bits
          default: 16
      type: object
      title: RealtimeTtsAudioFormat
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: xi-api-key
      description: Breeze Developer API key.

````