---
title: "The playback manifest"
method: GET
path: "/v1/reader/audiobooks/{audiobookId}/timeline"
tags: ["reader"]
---

# The playback manifest

`GET /v1/reader/audiobooks/{audiobookId}/timeline`

## Request

- Base URL: `https://api.ditto.audio` (the document declares no server; this is the origin it was published from)
- URL: `https://api.ditto.audio/v1/reader/audiobooks/{audiobookId}/timeline`
- Auth: HTTP bearer

Every narration segment for one `(voice, speed)`, in playback order, each with a stable `url`. This is what you hand a player.

One voice per timeline on purpose — merging two would change narrator mid-chapter. Omit `voice` and the audiobook's dominant narration is used.

`durationMs` is null when any segment never reported its sentence layout; `available: false` marks a segment rendered on a device but not backed up to the cloud, which is the one case where a gap is expected rather than a render still in flight.

## Path parameters

- `audiobookId` string, required

## Query parameters

- `voice` string
- `speed` number

## Response `200`

- object
  - `audiobookId` string
  - `voice` string, nullable
  - `speed` number, nullable
  - `segmentCount` integer
  - `availableSegments` integer
  - `durationMs` integer, nullable
  - `complete` boolean: Every segment is downloadable right now.
  - `segments` object[]
    - `id` string
    - `index` integer
    - `chapterIndex` integer
    - `paragraphIndex` integer
    - `voice` string
    - `speed` number
    - `format` string
    - `sampleRate` integer
    - `sizeBytes` integer
    - `durationMs` integer, nullable
    - `contentHash` string, nullable
    - `available` boolean
    - `url` string, nullable

---

[API](https://skmtc.dev/ditto/apis/ditto-audio-api.md) · [All operations](https://skmtc.dev/ditto/apis/ditto-audio-api/llms.txt) · [OpenAPI document](https://skmtc.dev/ditto/apis/ditto-audio-api/revisions/30c8d7c218da?raw)
