Start, steer and stop live translation on a call in progress
Switch translation on partway through a call, speak a translated line into it, ask for a summary, and switch it off, each with one REST command.
The claim
The document-level version of this decides before anyone speaks. This one does not. The call is up, the agent has realised what is needed, and a REST command turns translation on for the rest of the conversation.
Why it holds
The vendored REST spec, tools/openapi/rest.json, is the authority. The command requires action, which is a oneOf of four shapes.
startrequiresfrom_lang,to_langanddirection. Direction is an array ofremote-callerandlocal-caller, so translating both sides means naming both. It also takes voices per language, awebhookfor translation events, aspeech_engineofdeepgramorgoogle, and voice-activity settings.injectrequiresmessageanddirection, and here direction is a single value from that same pair. The message is translated on the way in, which is how a supervisor says something to one side in their own language.summarizerequires nothing, and takes awebhookand aprompt. It is an on-demand AI summary of the translated conversation.stopis the bare action.
How it works
def start(call_id, from_lang="en-US", to_lang="es-ES", webhook=None):
action = {"start": {"from_lang": from_lang, "to_lang": to_lang,
"direction": list(DIRECTIONS),
"speech_engine": "deepgram", "live_events": True}}
if webhook:
action["start"]["webhook"] = webhook
return client.calling.live_translate(call_id, action=action)
def say(call_id, message, direction="remote-caller"):
if direction not in DIRECTIONS:
raise ValueError(...)
return client.calling.live_translate(
call_id, action={"inject": {"message": message, "direction": direction}})What the platform receives for say:
{"command": "calling.live_translate",
"id": "6d3f4a0e-2b1c-4e7a-9f0d-1c2b3a4d5e6f",
"params": {"action": {"inject": {"message": "A supervisor is joining.",
"direction": "remote-caller"}}}}One command, four bodies. The action name is the key that selects the variant, so the verifier checks which variant each body matches, not only that its params are documented.
stop sends an empty object rather than nothing at all, because the action is the key that selects the variant.
Limitations
The verifier proves the requests, not the translation. Accuracy, latency and what the far side hears are live behaviour, tuned by the voices and the speech engine you choose.
The summary is generated by a model from the translated conversation. Treat it as a summary, not as a record of what was said.
What to change first
Drop "direction" from start and run the verifier. The exact body comparison fails, which is the point. The spec marks it required alongside the two languages, and translating one side is a different feature.