Skip to content

Endpointing

Endpointing decides when an utterance ends: after a pause of endpointing seconds, its final transcript is sent. It sets the trade-off between fast finals and whole sentences.

field range when omitted
endpointing 0.01 to 10 s 0.64 s
maximum_duration_without_endpointing 5 to 60 s no limit
{ "endpointing": 0.3, "maximum_duration_without_endpointing": 15 }

In a session, with the SDKs:

endpointing.py
# pip install gladiaio-sdk
import os
import sys
import threading
import wave
from gladiaio_sdk import GladiaClient, LiveV2InitRequest
API_URL = os.environ.get("GLADIA_API_URL", "https://eu1.api.gladia.io")
API_KEY = os.environ["GLADIA_API_KEY"]
with wave.open(sys.argv[1]) as wav: # a 16-bit PCM WAV file
rate, channels = wav.getframerate(), wav.getnchannels()
audio = wav.readframes(wav.getnframes())
config = {
"encoding": "wav/pcm",
"sample_rate": rate,
"bit_depth": 16,
"channels": channels,
"model": "solaria-3",
"language_config": {
"languages": [
"en"
]
},
"endpointing": 0.3,
"maximum_duration_without_endpointing": 15
}
client = GladiaClient(api_key=API_KEY, api_url=API_URL)
session = client.live_v2().start_session(LiveV2InitRequest.from_dict(config))
ended, errors = threading.Event(), []
@session.on("message")
def on_message(message):
if message.type == "transcript" and message.data.is_final:
print(message.data.utterance.text)
session.on("error", errors.append)
session.once("ended", lambda _: ended.set())
step = rate * channels * 2 // 10 # 100 ms of audio per chunk
for start in range(0, len(audio), step):
session.send_audio(audio[start : start + step]) # live audio: send each chunk as it is captured
session.stop_recording()
ended.wait(timeout=60)
sys.exit(1 if errors or not ended.is_set() else 0)
  • A short endpointing (0.2 to 0.4 s) gives faster finals, and cuts sentences at short hesitations.
  • A long one (0.8 s and more) gives whole sentences, later.
  • maximum_duration_without_endpointing forces a final after that much speech without a pause; such an utterance carries "forced": "max_duration".

GET /v2/live/defaults returns the values in force for your account.

For a voice agent, keep endpointing for the transcript and use end-of-turn detection to decide when to answer: a pause in the middle of a sentence is not the end of a turn.

  • Too short cuts words. Under 0.2 s, a breath or a hesitation ends the utterance: finals split mid-sentence.
  • maximum_duration_without_endpointing cuts anywhere. A forced final can end mid-word: keep it for monologues and noisy lines without pauses.
  • It is not end of turn. A pause ends an utterance, not the speaker’s turn: voice agents should answer on end of turn.
  • Python SDK: an utterance’s forced is not in the SDK’s objects (gladiaio/sdk#61); the JavaScript SDK has it.

A phone number, an amount or an address dictated in pieces (“my card number is 4970… 1234… 5678”) would be cut into several finals, one per pause. The number hold keeps the utterance open while the number is still being dictated, up to 2 seconds without new words, then closes it as usual.

It is on by default where the model supports it (Models); the session is never refused for it. Turn it off with:

{ "turn_router": false }