OPDS Progression 1.0 defines a JSON based API to fetch and update the last known progression in an OPDS publication.
A progression service is tied to a specific publication and can be discovered in links using either OPDS 1.x or 2.0.
It can be detected using:
http://opds-spec.org/progression for rel valueapplication/opds-progression+json for the media typeExample 1: Link to a progression service in OPDS 2.0
{
"href": "https://example.com/019c0435-5361-7e59-89b7-4ee01a6d87b8/progression",
"type": "application/opds-progression+json",
"rel": "http://opds-spec.org/progression"
}
When authentication is required, OPDS Catalogs should use an authenticate hint to avoid unnecessary round-trips.
Example 2: Link that requires authentication
{
"href": "https://example.com/019c0435-5361-7e59-89b7-4ee01a6d87b8/progression",
"type": "application/opds-progression+json",
"rel": "http://opds-spec.org/progression",
"properties": {
"authenticate": {
"href": "https://example.com/authentication.json",
"type": "application/opds-authentication+json"
}
}
}
| Key | Definition | Format | Required |
|---|---|---|---|
title |
Contains text that can be relevant to identify or contextualize the progression, such as a chapter title. | String | No |
modified |
Timestamp for the last-known progression. | ISO 8601 time and date | Yes |
device |
Identifies the device that provided the last-known progression. | Device Object | Yes |
progression |
Total progression in the publication expressed as a percentage (%). | Float between 0 and 1 | Yes |
references |
References inside the publication. | Array of URI references | No |
[!NOTE] WHATWG is in the process of integrating scroll to text fragments into the HTML specification. Once that’s done, we’ll remove this reference to the WICG draft.
References are meant to refine the progression expressed in progression.
Common use-cases for these references include:
#t=67)chapter1.html#par26)https://example.com/chapter1#par26)This document has identified the following specifications for media fragments:
| Specification | Scope | Examples |
|---|---|---|
| HTML | HTML | #id |
| Scroll to Text Fragment | Text | #:~:text=an%20example |
| Media Fragment URI 1.0 | Audio, Video and Images | #t=67, #xywh=160,120,320,240 |
| PDF documents | #page=6 |
This document does not provide processing rules for clients or servers.
In general, it is recommended to use more specific references over more generic one and to always fallback to progression when none of the URI references included in references can be resolved.
| Key | Definition | Format | Required |
|---|---|---|---|
id |
A unique identifier, not meant to be displayed to the user. | URI | Yes |
name |
A device name, meant to be displayed to the user. | String | Yes |
Example 3: Progression in a reflowable EPUB
{
"title": "Chapter 1 - A New Dawn",
"modified": "2026-01-27T11:00:00Z",
"device": {
"id": "urn:uuid:019c0047-cc8d-7ec4-a3c3-938ccadc020a",
"name": "Ebook Reader (Pixel 10 Pro)"
},
"progression": 0.0174920,
"references": ["chapter1.html#:~:text=It%20was%20expected"]
}
Example 4: Progression in a reflowable EPUB with Media Overlays
{
"title": "Chapter 1 - A New Dawn",
"modified": "2026-01-28T00:24:00Z",
"device": {
"id": "urn:uuid:019c0047-cc8d-7ec4-a3c3-938ccadc020a",
"name": "Ebook Reader (Pixel 10 Pro)"
},
"progression": 0.0174920,
"references": ["#t=40.274", "chapter1.html#par36"]
}
Example 5: Progression in a pre-paginated EPUB
{
"title": "Chapter 5 - A twist",
"modified": "2026-02-05T13:14:00Z",
"device": {
"id": "urn:uuid:019c0047-cc8d-7ec4-a3c3-938ccadc020a",
"name": "Ebook Reader (Pixel 10 Pro)"
},
"progression": 0.0528999,
"references": ["chapter5.html"]
}
Example 6: Progression in a PDF on a Web Reader
{
"modified": "2026-01-28T19:00:00Z",
"device": {
"id": "https://reader.example.com",
"name": "Web Reader"
},
"progression": 0.048204,
"references": ["#page=87"]
}
Example 7: Progression in a CBZ
{
"modified": "2026-02-05T14:24:00Z",
"device": {
"id": "urn:uuid:019c2df6-90f8-7096-b162-a0e69cd52844",
"name": "Comics Reader"
},
"progression": 0.4999,
"references": ["page78.jxl"]
}
Example 8: Progression in an audiobook
{
"title": "Part 4",
"modified": "2025-12-25T12:00:00Z",
"device": {
"id": "urn:uuid:019c0049-6e8c-745c-adb1-5b03f8ad50c4",
"name": "Audiobook Player (Sonos Era 300)"
},
"progression": 0.72370325,
"references": ["#t=849.250"]
}
Example 9: Progression in a Web Publication
{
"modified": "2026-02-01T16:00:00Z",
"device": {
"id": "https://reader.example.com",
"name": "Web Reader"
},
"progression": 0.1,
"references": ["https://example.com/chapter1#:~:text=It%20was%20expected"]
}
Successful interactions must either return a Progression Document or an empty payload (when a progression hasn’t been communicated to the service yet).
If the interaction returns a 401 Unauthorized code, the payload must contain an OPDS Authentication Document.
For any other error, the payload must contain a Problem Details Object with a type and title.
This document defines a list of values for that implementations are strongly advised to follow.
Example 10: Problem Details Object
{
"type": "https://registry.opds.io/error#progression-date",
"title": "A more recent progression point is already available."
}
| HTTP Verb | Expected behavior |
|---|---|
GET |
Client requests the last-known progression from the server. If this information is more up-to-date than what the client has, it requests to the user if they’d like to jump to the new progression. |
| HTTP Status Code | Payload |
|---|---|
200 OK |
Progression Document or an empty payload |
| HTTP Verb | Expected behavior |
|---|---|
PUT |
Client sends the last-known progression to the server. Server determines whether the progression should be updated and returns a progression. |
| HTTP Status Code | Payload |
|---|---|
200 OK |
Progression Document |
201 Created |
Progression Document |
| HTTP Status Code | Type | Title |
|---|---|---|
400 Bad Request |
https://registry.opds.io/error#progression-invalid-payload | Progression could not be updated due to an invalid payload. |
403 Forbidden |
https://registry.opds.io/error#progression-incorrect-user | Progression could not be updated for the current user. |
403 Forbidden |
https://registry.opds.io/error#progression-locked | Progression can no longer be updated for this publication. |
409 Conflict |
https://registry.opds.io/error#progression-date | A more recent progression point is already available. |
A JSON Schema is available under version control at https://github.com/opds-community/drafts/blob/master/schema/progression.schema.json
For the purpose of validating an OPDS Progression Document, use the following URL: https://drafts.opds.io/schema/progression.schema.json