Start or stop background transcription on a live call through REST and receive available transcript text at your status webhook.
transcription
The claim
The vendored REST spec has a calling.transcribe variant of the call command. Its params require control_id and take a status_url, “An HTTP or HTTPS URL that receives the status callback when the transcription completes”. calling.transcribe.stop takes the same control_id. The spec also documents what may arrive: the transcribe status callback, whose event_type is calling.transcript.completed or calling.transcript.failed. Its params.text is “The transcribed text of the call. Omitted when there is no transcribed text.“ The spec calls the callback advisory and best-effort. You reach the two commands as client.calling.transcribe and client.calling.transcribe_stop.
What the platform receives, then what it sends you:
POST /api/calling/calls
{"command": "calling.transcribe", "id": "<call_id>",
"params": {"control_id": "call-transcript", "status_url": "https://<your-host>/transcripts"}}
POST https://<your-host>/transcripts
{"event_type": "calling.transcript.completed", "timestamp": 1788350400.5,
"project_id": "...", "space_id": "...",
"params": {"id": "...", "call_id": "<call_id>", "segment_id": "...", "text": "Hi, this is ..."}}
record reads text with .get, because the spec omits it when nothing was transcribed, whichever status the event carries; the verifier’s failed fixture omits it. Before record runs, the route checks SignalWire’s signature over the request, hex(HMAC(signing_key, url + raw_body)), as signalwire.com/docs/swml/guides/webhook-security documents it and verify-a-webhook-signature explains, so a forged callback cannot overwrite a transcript. GET /transcripts/<call_id> serves what arrived, or pending until something does, to a caller with your READ_TOKEN as a bearer token.
Limitations
You prove the requests and the handler against the documented shapes. What the platform transcribes, and when the callback arrives, are the platform’s side of a live call. The spec calls the callback best-effort, so a transcript that never arrives is a case your job has to expect.
SWML has a transcribe verb for the same job at document time, but it is absent from the 3.0.1 bundled schema. This recipe cannot prove it offline, so it uses the REST command instead.
What to change first
Change record to read params["text"] and run the verifier. The failed callback raises KeyError, because the spec omits the field, which is why the handler reads it with .get.