How it works
Voice moderation analyzes live voice and call audio as it happens. You open a streaming connection and send call audio; the speech is transcribed and each finalized utterance is moderated by your enabled text policies—toxicity, hate, PII, wordlists, guidelines, and the rest—with no extra configuration. You receive a moderation result for every utterance as it’s spoken. Unlike audio file moderation, which analyzes a complete recording after the fact, voice moderation works on a live stream and returns a verdict for each utterance during the call.Conversations
A voice call is a conversation: a single live session with a start and an end, where every utterance belongs to the same thread. This lets you review an entire call as one unit instead of a series of disconnected messages.- Bring your own id. Supply a
conversationIdto link the call to a record in your own system. If you don’t, one is generated for you and returned when the session starts—every utterance in the call shares it. - Filter by type. Voice utterances are tagged with the
voicecontent type, so you can separate them from messages, posts, and other content.
Real-time voice is in early access and the streaming interface may still
change. Coordinate with us before building a production integration so we can
confirm the current contract and your account’s limits.
Connecting
Open a WebSocket connection to the streaming endpoint, authenticating with your API key on the upgrade request and requesting themoderationapi.v1 subprotocol.
4401.
Start the session
Send astart frame as the first message. It declares the conversation, the audio format, and the tracks you’ll stream (for example a caller and an agent), each with an optional author id.
conversationId— optional. Omit it to have one generated and returned insession.started.channel— optional. Selects which channel’s policy configuration applies.tracks— stream one or both tracks. Send bothinboundandoutboundto moderate the full call with each side attributed to its own author, or just one track (for example onlyinbound) if that’s all you have access to. Audio for any track you don’t declare is ignored.mediaFormat.encoding—audio/x-mulaw(PCMU),audio/x-alaw(PCMA), linear PCM (audio/l16,linear16), or common encoded containers (wav,mp3,ogg,flac).sampleRatemay be 8000–48000 Hz. Audio is passed through without resampling. The spoken language is detected automatically.emitPartials— optional. Settrueto also receive interim, non-final transcripts.metadata— optional, arbitrary JSON attached to the conversation. Put anything you want to associate with the call here (your own ids, tags, context); it’s stored on the conversation and not interpreted by moderation.
session.started:
Stream audio
Sendmedia frames as audio arrives, one per track, with the audio chunk base64-encoded in payload:
End the session
Send astop frame to end the call gracefully (or simply disconnect). The server drains any in-flight utterances, emits session.ended, and closes.
Using Twilio or another telephony provider
Telephony providers like Twilio stream call audio but can’t consume the moderation verdicts the gateway streams back, so they don’t connect to the gateway directly. Instead, run a thin bridge in your own backend:- Accept the provider’s media stream (for Twilio, its
connected/start/mediamessages). - Open this WebSocket and map those onto the
startandmediaframes above—pass your call id asconversationIdand the caller/agent identifiers as each track’sauthorId. - Relay the
utterance.finalverdicts back to your application to act on them.
Events you receive
Every outbound message carries"v": 1 and an event field.
The key event is
utterance.final—the transcribed text plus the standard moderation result (evaluation, recommendation, and policies), in the same shape as every other moderation response:
recommendation.action (allow, review, or reject) to decide what to do—see Acting on responses.
When the call ends you receive session.ended with a summary: