API reference
Transcriptions
Push recordings into a transcription job and read back their transcripts, analysis and attached details. 6 endpoints. Add your API key in the authentication panel to send test requests from this page.
List transcription jobs that accept pushed recordings
/api/external/v1/transcriptions/jobsReturns the jobs this key may push into: API-sourced jobs only.
A job built from a Drive folder, a bucket or an upload batch is deliberately absent - its source already decides what belongs in it, and injecting rows would mean its row count no longer describes the thing the customer pointed at.
Each entry carries the settings every recording in it is transcribed with
(languageMode, speakerMode) and its progress (totalRows, processedRows),
so an integration can confirm it is pushing into the job it meant to.
Parameters
pageinteger (int32)querysizeinteger (int32)query
Responses
200OK
Push one recording by URL
/api/external/v1/transcriptions/jobs/{jobId}/recordingsHands one recording to a standing job, with what is already known about it.
Body: { "url": "...", "fileName": "...", "externalId": "...", "metadata": {} }.
Only url is required.
The URL is passed to the transcription provider as given and never copied here, which is what makes this the cheap path for audio that already sits in your own storage: a presigned S3 or GCS link costs one small JSON request instead of moving the file twice.
Send externalId. It is what makes a retry safe - a repeat of an id already seen
returns the row that exists rather than transcribing, and billing for, the same
audio again.
metadata carries the details this recording should be filed under; call
GET /metadata/fields for the keys this account uses. A key that is not recognised
is still stored, and is named back in unknownMetadataKeys with a warning, so a
typo shows up on the first call rather than as an empty column days later. Where
the job also has a file-name pattern or a spreadsheet, those are applied first and
the values sent here win.
Parameters
jobIdstring (uuid)pathRequired
Request body application/json
object
Responses
200OK
Push one recording as an upload
/api/external/v1/transcriptions/jobs/{jobId}/recordings/uploadThe same ingestion as the URL form, for audio you hold rather than link to.
Two parts: file (the audio) and an optional payload - a JSON object with the
same fileName, externalId and metadata fields the URL form takes.
Multipart rather than base64 inside JSON, which inflates an hour of audio by a third and forces the whole thing through memory on both sides. The details travel as a JSON part rather than as form fields so that a list of tags or a nested value survives without an encoding convention both sides have to agree on.
Parameters
jobIdstring (uuid)pathRequired
Request body multipart/form-data
filestring (binary)Requiredpayloadstring
Responses
200OK
List a job's recordings and their status
/api/external/v1/transcriptions/jobs/{jobId}/rowsOne page of a job's recordings: status, duration, detected language, speaker count, the details attached to each, and the failure reason where there is one.
The transcript and the analysis are left out of this view on purpose - poll this endpoint for progress and read the finished ones individually, rather than pulling every transcript on every poll.
Parameters
jobIdstring (uuid)pathRequiredpageinteger (int32)querysizeinteger (int32)query
Responses
200OK
List the detail fields a pushed recording can carry
/api/external/v1/transcriptions/metadata/fieldsThe keys accepted in a recording's metadata, including the ones this account
defined for itself.
Published so an integration can be written against the account's actual field
keys instead of a list copied out of the dashboard that goes stale the first time
somebody adds a field. Each descriptor carries its key, human label, type,
the rule used to parse it, an example, and whether it is builtIn.
Responses
200OK
Read one recording's transcript, analysis and details
/api/external/v1/transcriptions/rows/{rowId}One recording, with its transcript, its utterances, the summary and everything the analysis outputs produced.
metadata and analysis are returned as separate objects and are never merged.
One is what the caller told us, the other is what a model concluded; an
integration writing either into its own records needs to know which it is holding.
analysis is keyed by output name - a metric pack writes under its own name - and
each judgement field is accompanied by a <field>_reason while the job has
explanations switched on.
Parameters
rowIdstring (uuid)pathRequired
Responses
200OK