const audio = await client.textToSpeech({ text: 'Hello, world!', voice_id: 'default-voice', enhance: true, speed: 1.0, language:"en-us"});### Get all voicesconst voices = await client.getVoices();### Get all lanuagesconst lanuages = await client.getLanguages();### audio is an ArrayBuffer containing the audio data
Omit context entirely to skip refinement. Note: this is the REST shape — the WebSocket streaming endpoint takes a {general, text, terms} object instead.
Scores content against a rubric you define, and parses conversational turns.
A classifier, not a generator — every answer is a probability distribution over
your options, so results are comparable and sortable.Authenticated with the same 60db API key as the rest of the SDK — the client
you already constructed works; there is no separate Judge credential.
const run = await client.judge.evaluate({ state: callTranscript, questions: { tone: { type: 'choice', instructions: 'How did the agent come across?', criteria: { professional: 'Calm, courteous, takes ownership', dismissive: 'Brushes the caller off', unknown: 'Not enough of the call to tell', // always add an escape hatch }, }, satisfaction: { type: 'score', criteria: ['Angry', 'Neutral', 'Happy'] }, resolved: { type: 'noul', instructions: 'Was it solved?' }, },});run.answers.tone.choice // 'dismissive'run.answers.tone.probabilities // { dismissive: 0.86, professional: 0.11, unknown: 0.03 }run.answers.tone.confidence // 0.79run.answers.satisfaction.score // 1.87 — weighted position on your ladder, not an indexrun.answers.resolved.noul // 0.28 — raw probability of true, NOT a confidencerun.min_confidence // lowest across the answersrun.credits_charged // 0.00000161
Under 0.85 is the upstream’s own escalation line — route those to a person
rather than trusting them.
const turn = await client.judge.extract({ text: 'move my 10am appointment to friday', schema: { intents: { booking: 'Wants to arrange or change a booking' }, operations: { reschedule: 'Move an existing booking' }, entities: { date: 'A calendar date', time: 'A clock time' }, // responsePaths: { confirm: 'Read the change back' } ← selects the v2 model },});turn.intent.label // 'booking'turn.operation.label // 'reschedule'turn.entities // [{ label: 'date', text: 'friday', start: 28, end: 34, confidence: 0.8 }]
start/end are Unicode code point offsets, not UTF-16 indices. Slice
with Array.from(text).slice(start, end).join('') — a plain text.slice()
lands in the wrong place once the turn contains an emoji.
const { runs, pagination } = await client.judge.runs.list({ needs_review: true, // only runs the judge was under 85% sure about limit: 20,});await client.judge.runs.get(id); // one run, with what was sent and returnedawait client.judge.runs.delete(id);
Billed per input token. The upstream re-encodes the shared content once per
question, so a 10-question rubric costs ten times the transcript. Context is
200,000 tokens per question, and an over-long request is rejected with a 400
before anything is charged (in practice the 512 KiB whole-request cap binds first).A failed run — 429 busy, 503 unavailable, 400 invalid rubric — is
refunded automatically.