# How to get the timestamp of every word in a recording

> Call POST /transcribe with output_format set to json and word_timestamps set to true (both are the default). Every segment in the result includes a words array of {start, end, word} objects with times in seconds. This guide covers the response shape, which models return word times, and what you can build with them.

Last updated: 2026-10-18 · HTML: https://console.kolwrite.com/guides/word-timestamps-api

## The request

```json
{
  "audio_url": "https://example.com/interview.mp3",
  "model": "oracle",
  "language": "auto",
  "word_timestamps": true,
  "output_format": "json"
}
```

Start the job with `POST /transcribe`, then poll `GET /transcribe/{jobId}` until it reaches `COMPLETED`. Always pass `model` explicitly, because if you omit it, the API defaults to the legacy `core` model.

## The response

```json
{
  "jobId": "34c63d45-4cb5-473b-bc60-25c175e69c57",
  "status": "COMPLETED",
  "result": {
    "language": "en",
    "segments": [
      {
        "start": 1.0,
        "end": 3.75,
        "text": "Hello everyone and welcome to the show.",
        "speaker": "Speaker 1",
        "words": [
          { "start": 1.0, "end": 1.35, "word": "Hello" },
          { "start": 1.4, "end": 1.75, "word": "everyone" }
        ]
      }
    ]
  }
}
```

- `segments[]`: contains `start` and `end` in seconds, `text`, `speaker` (when diarization is enabled), and `words[]`.
- `words[]`: contains `start`, `end`, and `word`, with times in seconds rounded to three decimal places.
- A short word might only last a few hundredths of a second, and sometimes `start` and `end` are identical. Never divide by a word's duration in your code.
- If you set `word_timestamps` to `false`, or use a model that only outputs segment timings, the `words` array is omitted and you only get `start` and `end` on each segment.

## Which models return word times

| Model | Word times |
| --- | --- |
| `base`, `oracle`, `oracle_pro`, `oracle_max` | Yes |
| `oracle_mini` | Returns segment times for plain transcription, and word times when a speaker mode (diarization or channel separation) is enabled |
| `core`, `edge` (legacy) | Yes |

Plain text (`txt`) output does not include timings. SRT files built by the API follow the same switch. See the [SRT guide](https://console.kolwrite.com/guides/srt-subtitles-api) for details.

## Find where a phrase is said

You can search the flattened word list to get a time range. That lets an agent answer a question like "where does she mention pricing?" with the time, or pull that sentence out as a clip.

find.py

```python
# find.py — where is a phrase said? Returns (start, end) in seconds.
import re


def find_phrase(result, phrase):
    words = [w for segment in result["segments"] for w in segment.get("words", [])]
    clean = lambda text: re.sub(r"[^\w]", "", text.lower())
    target = [clean(p) for p in phrase.split()]
    tokens = [clean(w["word"]) for w in words]
    for i in range(len(tokens) - len(target) + 1):
        if tokens[i:i + len(target)] == target:
            return words[i]["start"], words[i + len(target) - 1]["end"]
    return None


# start, end = find_phrase(result, "welcome to the show")
# ffmpeg -ss <start> -to <end> -i talk.mp4 -c:v libx264 -c:a aac clip.mp4
```

Cutting a clip from a time range:

```bash
ffmpeg -ss 41.2 -to 47.8 -i talk.mp4 -c:v libx264 -c:a aac clip.mp4
```

## Tighten pauses and jump cuts

Having timestamps for every word lets you measure the silence between them. You can keep continuous speech and cut out any pause longer than your threshold:

silences.py

```python
# silences.py — keep the speech, drop pauses longer than max_gap seconds
def speech_ranges(words, max_gap=0.7, pad=0.1):
    ranges = []
    for word in words:
        if ranges and word["start"] - ranges[-1][1] <= max_gap:
            ranges[-1][1] = word["end"]
        else:
            ranges.append([word["start"], word["end"]])
    return [[max(0.0, s - pad), e + pad] for s, e in ranges]

# Pass the ranges to cut() from cut.py to build the tightened video.
```

Stitch the remaining ranges together using `cut()` from the [video editing guide](https://console.kolwrite.com/guides/video-editing-with-ai).

## Other ways to use word timings

- Read-along highlighting in a web player: highlight whichever word covers the player's `currentTime`.
- Clickable transcripts: link each word to `?t=<start>` so clicking it jumps the player to that point.
- Chapters and key moments: have an LLM pick the relevant segment numbers, then use your code to look up their timestamps.
- Library search: index words alongside their start times so search results open the recording at the exact second.
- Alignment and corpus work: you can convert the JSON word timings into the annotation formats your tools read.

## Pricing

Word timestamps do not change the price: usage is metered per second of audio at the model rate, from US$0.48 per hour on `base`. One hour on `oracle` is US$1.44. Rates: [/llms/pricing.md](https://console.kolwrite.com/llms/pricing.md).

## Questions and answers

### How do I get word-level timestamps from a transcription API?

Send your request with `output_format: "json"` and `word_timestamps: true`. Every segment in the response will include a `words[]` array with `start`, `end`, and `word` in seconds.

### Which models support word timestamps?

`base`, `oracle`, `oracle_pro` and `oracle_max` return them. `oracle_mini` returns segment times unless a speaker mode is on. Text output has no timing.

### How accurate are the word times?

KolWrite does not publish per-language accuracy figures for this API. Word times work well for highlighting and cutting between words, though you should test a sample of your own recordings and leave a bit of padding around cut points.

### Can I get timestamps for a video file?

Yes. When you upload a video, the API reads its audio track directly. If your video is over 100 MiB, extract the audio with ffmpeg before uploading.

### Are timestamps in seconds or milliseconds?

They are in seconds, formatted as numbers with up to three decimal places (like `41.236`).

## Related pages

- [Edit video with AI agents](https://console.kolwrite.com/guides/video-editing-with-ai)
- [SRT subtitles API](https://console.kolwrite.com/guides/srt-subtitles-api)
- [Podcast and YouTube captions](https://console.kolwrite.com/guides/podcast-youtube-captions)
- [Language research & linguistics](https://console.kolwrite.com/use-cases/researchers)
- [Developers & product teams](https://console.kolwrite.com/use-cases/developers)
- [API documentation](https://console.kolwrite.com/public_api_docs)

---
Get an API key: https://console.kolwrite.com/auth · API documentation: https://console.kolwrite.com/public_api_docs · llms.txt: https://console.kolwrite.com/llms.txt
