- Transcribe a recording with
/audio/transcriptions - Ask for timings, which not every model will give you
- Extract decisions and action items against a schema
- Deal with the fact that the transcript never says who is talking
- Split a long recording without losing the clock
Setup
You need Python 3.9 or newer, therequests package, and a Venice API key. See Generating an API Key if you do not have one. Bring any recording of a conversation, in wav, mp3, m4a, flac, aac, mp4, ogg, or webm.
1. Transcribe the recording
/audio/transcriptions is OpenAI-compatible and takes a multipart upload. The file has to be a real file part, since base64 is not accepted on this endpoint.
Call
GET /models?type=asr for the current list rather than pinning these, since the catalog changes.
2. Ask for timings
Timestamps are what make notes checkable, so this is the choice that matters most, and the default will not give them to you:timestamps is an object rather than a list, and the key inside it depends on the model. Whisper groups by phrase, Scribe by word:
3. Extract the notes
Describe the notes you want as a schema, so the result is a record instead of prose you have to parse:disable_thinking is there for the same reason it belongs in any extraction step. The schema already decides the shape of the answer, so paying a reasoning model to deliberate about it buys nothing and makes the cost of each run different from the last. Extracting Structured Data from Documents measures that difference.
Run it on a fifty-three second standup and the notes come back with the clock attached:
spoken_at is real. Skip to 19.6 seconds and you hear the sentence that created the task.
Give the model lines without times and every
spoken_at comes back as 0. The field is required, the model has nothing to put in it, and a required field is an instruction to produce something rather than an invitation to say it does not know. This is worth remembering whenever a schema seems to be working: the shape being right is not the same as the values being right.4. Nobody is labelled
Two things in that output are wrong, and both come from the same place. The owner of the rollout isMay. Her name is Mei. Speech recognition is at its least reliable on proper nouns, and names are exactly what attribution needs, so this is the failure you should expect rather than the unlucky one.
The last item is unassigned, even though somebody clearly took it. The line was “I’ll ask legal today and report back tomorrow”, and the transcript records the words without recording who said them.
That second one is not a bug you can fix. No Venice transcription model performs diarization, so there is no speaker field to reach for on any of them. The transcript is one voice-less stream of text, and tasks can only be attributed when a name is spoken out loud, as in “Tomas, can you put the deprecation notice in the changelog”.
The first one you can fix, by telling the model who was in the room:
May resolves to Mei Lin because the model now has a short list to match against, and the owners are full names your task tracker can look up. The third item stays unassigned, correctly. A roster fixes mishearing, and nothing recovers information the recording never carried.
5. Longer than one request
Uploads are capped at 25 MB, which arrives sooner than you would think for uncompressed audio, and a long meeting is worth splitting anyway so that one failure does not cost you the whole transcription. For WAV files the standard library is enough, no ffmpeg required:offset argument to timed_lines is for:
awesome. to fill the gap at the end of the chunk, and turned one line into three.
The timings are still right, and the notes step still finds the task. What it loses is the name, which is the thing attribution depends on.
Compressed formats cannot be sliced this way, since you cannot cut an MP3 on a frame boundary with the standard library. Use ffmpeg for those:
Putting it together
Next steps
- Post the action items to your tracker, using the owner names the roster resolved.
- Read the summary back with Text to Speech for people who missed the call.
- Search across past meetings by storing transcripts with Embeddings.
- Let an agent decide when to transcribe and when to answer from notes it already has, with Building a Tool-Using Agent with Function Calling.
Speech-to-Text
Reference for the transcriptions endpoint.
Extracting Structured Data from Documents
The same schema-first extraction, applied to files.
Structured Responses
How json_schema constrains a completion.
Voice Cloning
Give the summary a voice of its own.