Speech to text in Python: transcribe audio with timestamps

Speech to text in Python with Requests: send the audio URL, poll the job, then read the transcript and word timestamps. A script for Sume STT 1.0.

5 min readSume
All posts

To do speech to text in Python without running a model on your own machine, call a hosted speech-to-text API with requests: POST the audio file's URL, poll the job until it finishes, then read the transcript and its timestamps from the JSON result. With Sume STT 1.0 that is POST /v1/stt-1.0/transcribe, then GET /v1/jobs/{id}/status until terminal is true, then GET /v1/jobs/{id}/result for text, words, and segments.

Sume documents a TypeScript SDK, @sume-com/sdk; from Python you call the HTTP API directly, here with Requests as its Quickstart shows. The STT facts come from the STT 1.0 schema in the Sume API reference, the OpenAPI document behind the API reference docs, and Jobs and results, all read on 2026-09-27. The submit-and-poll loop, its timeouts, and the retry key work as in Text to speech API in Python, so this post covers only what is specific to transcription.

How do I send an audio file from Python?

Send a link, not the file. The body's one required field is audio_url, a public HTTPS URL, and the schema has no field for file bytes, so the recording must already be at a public HTTPS address, such as your own storage; the API reference prefers a Sume media URL. It lists no accepted audio formats, and its examples point audio_url at .m4a and .wav files.

  • language_code is an optional hint such as en or ko. Omit it and the language is detected.
  • duration_seconds (1–600) sizes the usage reservation. Omit it and Sume reserves for 1 minute.
  • segmentation: {"mode": "sentence"} adds sentence segments to the result.

What does the whole script look like?

Submit, poll until terminal is true, then print the detected language, the transcript, and each word's start time.

import os, time, requests

AUTH = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
body = {"audio_url": "https://example.com/audio/interview.m4a",
        "segmentation": {"mode": "sentence"}}
r = requests.post("https://api.sume.com/v1/stt-1.0/transcribe", json=body,
                  headers={**AUTH, "Idempotency-Key": "interview-001"}, timeout=30)
r.raise_for_status()
job = r.json()["data"]
while True:
    s = requests.get(job["status_url"], headers=AUTH, timeout=30)
    s.raise_for_status()
    status = s.json()["data"]
    if status["terminal"]:
        break
    time.sleep(status["next_poll_after_seconds"] or 2)
if status["sume_status"] != "completed":
    raise RuntimeError(f"STT job ended as {status['sume_status']}")
res = requests.get(job["result_url"], headers=AUTH, timeout=30)
res.raise_for_status()
result = res.json()["data"]["result"]
print(result.get("language_code"), result["text"])
for w in result["words"]:
    if w.get("type") != "spacing":
        print(f"{w['start']:7.2f}s  {w['word']}")

How do I get timestamps for each word or sentence?

Word timestamps need no flag: words is always present on an STT result, ordered by start, with times in seconds from the start of the audio. An entry may carry a type such as word or spacing, which is why the script skips spacing. Sentence timestamps need segmentation in the request.

From the STT 1.0 schema in the Sume API reference, read 2026-09-27.
You wantAdd to the bodyRead from the result
Word timestampsNothingresult["words"]: word, start, end
Sentence timestamps"segmentation": {"mode": "sentence"}result["segments"]: index, text, start, end, duration_seconds
The detected languageLeave out language_coderesult["language_code"] and result["language_probability"], when available
The full transcriptNothingresult["text"]

Do I need to set the language?

No. Leave out language_code and STT 1.0 detects the language; the result then reports language_code and language_probability, the detection confidence, when available. If you already know the language, send it as a hint, such as ko for a Korean recording. Detect language from audio covers detection on its own, and Translate audio to English picks up from the transcript.

What are the limits, and what does it cost?

STT 1.0 costs $0.01 per audio minute on API pricing, plus a 5.5% agent fee by default. If your balance can't cover the estimate, the submit fails with 402 insufficient_credits and no job starts.

  • Up to 10 minutes of audio per request, the documented maximum: duration_seconds stops at 600. For a longer file, transcribe it in parts and add each part's start time to its timestamps, as Transcribe long audio files shows.
  • No speaker labels. In current code STT 1.0 runs with speaker separation (diarize) off, and a request that sends diarize or tag_audio_events is rejected.
  • No microphone streaming: the job reads a file at a URL, and the Developer API has no SSE or WebSocket transport today.
  • words is capped at 20,000 entries. A 600-second transcript stays well under that, and a capped result says so with words_truncated.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume