A Text-to-Speech WebSocket session: text in as it is written, audio out.

connect() opens the socket and waits for Begin. Send text with generate() as it is produced, conclude each request with flush(), and read its audio with audio(); speak() does all three for one text. Text need not wait for connect() to resolve: sent while the socket opens, it is held and sent the moment it opens. cancel() is the barge-in: it stops the request in flight and ends its audio() iteration at once. close() sends Terminate and waits for the session's Termination summary.

Audio is delivered one of two ways: pulled with speak() / audio(), one request at a time in order, or pushed to an audio listener registered with on(). Listeners for the other events (flushDone, wordBoundaries, cancelled, termination, error, close) are optional. A listener that throws is logged with console.error and the session goes on. A refusal rejects connect(); a failure mid-session rejects the audio() iteration or the next send, and a failure nothing observed rejects close(). The error and close listeners run once the connection has ended, so either can connect() again; a session opened with a temporary token reconnects with a new one, connect({ token }).

In a browser, create the session with a temporary token your server minted, new TextToSpeechSession({ token }): no client and no API key in the page.

const session = client.tts.session({ voiceId: "aai-jane" });
await session.connect();
for await (const chunk of session.speak("Hello there.")) play(chunk);
await session.close();

Constructors

Properties

The Begin frame, once connected.

The error that ended the session, if one did.

termination?: TtsTerminationEvent

The Termination summary once the session ended cleanly.

Methods

  • The audio of request flushId: an async iterator that ends at its FlushDone, or early if the request is cancelled.

    The request is fixed when audio() is called, not when it is first iterated. Without flushId it is the request being written now, whose id the next flush() returns, so the iterator can be made before the first generate() and read while text is still being sent. Requests are served in order, so read each one once, in order, one iteration at a time. Audio is queued for pulling only while no audio listener is registered. The iteration rejects with a TextToSpeechError if the session fails before the request completes.

    Parameters

    • OptionalflushId: number

    Returns AsyncGenerator<Uint8Array, void, undefined>

    Error if the session was never connected; and, without flushId, once the session has ended with nothing queued for the text being written, since it can no longer be flushed on that connection.

    RangeError for a request not flushed yet, or one an iteration already read past (its FlushDone was consumed by that iteration).

  • Barge-in: stops the request in flight, drops queued requests and the text being written, and returns the flush_id the cancel takes.

    Like flush(), a cancel takes the id of the text being written, so the cancelled requests are those with an id up to the one returned, and the next request's id is one more. An audio() iteration of a cancelled request ends at once, even one waiting for its next chunk. Audio of a cancelled request that the API sent before it read the Cancel can still arrive; neither an audio() iteration nor the audio listener receives it. A cancel the session refuses (after close(), or once the connection is lost) changes nothing: the iterations go on to their own end.

    Returns number

  • Ends the session: Terminate, then the Termination summary.

    Text sent and not flushed is spoken first, and the wait lasts as long as the API keeps sending: it stops after terminateTimeout milliseconds without a message from the API. Then the socket is closed, the API drops the audio still to come, and an audio() iteration still running rejects with a retryable TextToSpeechError. Resolves with the summary, or undefined if the session had already ended or the wait stopped. A connect() still pending is rejected. All calls on one connection share one close: one Terminate is sent, and every call resolves when the connection ends; the arguments of the first call apply.

    Parameters

    • waitForTermination: boolean = true

      Wait for the summary before closing the socket.

    • terminateTimeout: number = ...

      Milliseconds without a message from the API after which the wait stops; 0 waits indefinitely. Defaults to the session's terminateTimeout, else 35 000.

    Returns Promise<undefined | TtsTerminationEvent>

    TextToSpeechError the session's error, when nothing else surfaced it; only the first call throws it.

  • Opens the socket and waits for Begin.

    Frames need not wait for Begin: generate(), flush(), speak(), cancel() and keepAlive() called while connect() is pending are held and sent, in order, the moment the socket opens, and the API reads them once it has sent Begin. A session opened for a reply then gets its first audio sooner: the text travels while the API runs its checks, which saves up to one network round trip. Until Begin arrives the API's default limits apply (2,000 characters per Generate, 8,000 unspoken characters for speak()). If the connection fails, or close() is called, before the socket opens, the held frames are dropped and an audio() iteration rejects with the connection's error (or ends, after close()).

    A session the API has ended can be connected again with the same object. A temporary token opens one connection, so a session opened with a token needs a new one for each connection, reconnects included: mint it on your server and pass it here. The API may refuse a token it has already seen, and always refuses an expired one, with close code 1008 (errorCode: "unauthorized", not retryable).

    Parameters

    • options: {
          token?: string;
      } = {}
      • Optionaltoken?: string

        A new temporary token. It replaces the session's token for this connection and the next ones, and is sent instead of the API key.

    Returns Promise<TtsBeginEvent>

    TextToSpeechError if the API refuses the session, the handshake fails, the socket cannot be opened, or Begin does not arrive in time. status is set when the API or a proxy answered the upgrade with an HTTP status the runtime reports.

    Error, before anything else changes, if websocketBaseUrl is not a ws:// or wss:// URL.

  • Concludes the current request and returns its flush_id.

    Everything sent so far is spoken, then FlushDone arrives for this id. Flushes can be pipelined; the audio comes in order.

    Returns number

  • Appends text to the current request.

    Consecutive texts are joined exactly as sent, so include the spaces. The API speaks a complete sentence before flush() once more text has arrived after it and the request is long enough (about 200 characters, or 50 for the first sentence of text sent in several calls); a shorter request is spoken at flush(), which is what concludes the request.

    Parameters

    • text: string

    Returns void

    RangeError for a text over one frame's limit (2,000 characters); split it.

    Error once close() was called: the API would not read the text.

  • Restarts the API's idle timer (inactivityTimeout, 120 s by default). Send one at least once per timeout while the session waits, including while audio already received is still playing: audio arrives much faster than it plays, and the timer counts from the last frame in either direction. Otherwise the API closes the session with 3006 inactivity_timeout (retryable). Once close() was called it does nothing, so a keepalive timer still running while the session drains does not throw.

    Returns void

  • Speaks one text: generate(), flush(), then its audio.

    Text longer than one frame is split across frames, sent at once. The API holds a limited backlog of text it has not spoken yet (Begin's limits.text_max_buffer_chars, 8,000 characters by default) and ends the session with a non-retryable 3010 when a burst passes it, so longer text is refused before anything is sent. The backlog counts all the session's unspoken text, so this check prevents a sure 3010 without guaranteeing success: split long text and speak() each part once the previous part's audio is read, or pace it with generate(). Returns an async iterable of the request's audio that ends at its FlushDone, or early if the request is cancelled.

    Parameters

    • text: string

    Returns AsyncIterable<Uint8Array>

    RangeError for text over the backlog limit.