Introduction

One client for diarized turns and per-speaker voice measurement

ProsodyAI answers three questions about a conversation: who is speaking, what they said, and how the voice behaved. One client, typed results, and the same capability over a recording or a live socket.

Analyze a conversation

CallReturns
prosody.transcribe(file)Turns, speakers, voice measurement
prosody.stream.session()Live analysis WebSocket (start / send / stop)
prosody.realtime.attach(room, …)Browser-side frame stream over a LiveKit room (see LiveKit plugin for the agent worker path)
const result = await prosody.transcribe('./call.wav');

for (const turn of result.turns) {
  console.log(turn.speaker.label, turn.text, turn.prosody?.state.intonation.pitch);
}

Read the measurements

Every turn carries prosody.state, how the voice sounded, and prosody.change, how that turn moved against the same speaker's own baseline.

turn.prosody.state.intonation.pitch    // median F0, Hz
turn.prosody.state.intonation.range    // F0 span, semitones
turn.prosody.state.intonation.slope    // rising or falling contour
turn.prosody.state.stress.loudness    // loudness, dBFS
turn.prosody.state.stress.peak        // loudest instant
turn.prosody.state.rhythm.voiced      // fraction phonated, 0 to 1
turn.prosody.state.rhythm.pause        // fraction silent, 0 to 1
turn.prosody.state.rhythm.onset        // phonation restarts per second
turn.prosody.state.tilt                // voice quality: spectral slope
turn.prosody.state.clipping            // signal health

turn.prosody.change?.intonation.pitch  // semitones against baseline
turn.prosody.change?.stress.loudness    // dB against baseline

A field is null when the audio did not support the measurement: pitch on a turn with no voiced audio, for example, because pitch does not exist on unphonated audio.

For the whole call measured frame by frame, result.frames gives every measured moment, each attributed to a speaker, with its state, its change, and its affect.

Who is speaking

Every turn carries a speaker, taken from the waveform: no transcript, no channel split, no enrollment step. It holds the label, talk time, and that voice's measured baseline.

speaker.label;                              // "Speaker 1"
speaker.talkSeconds;                        // 142.5
speaker.state.intonation.pitch?.median;     // 118.4

Feedback

CallReturns
prosody.submitCorrection()Corrects a prediction you disagree with
prosody.submitSessionOutcome()Attaches how the conversation actually went

Authentication

Every request carries a psk_* API key. Create one under API keys in the dashboard. See Credits for rates.

On this page