---
title: "Docs"
description: "Publish and yank versions of a doc set, read them without a token, and follow the revision a docs reader serves."
order: 10
---

Publish and yank versions of a doc set, read them without a token, and follow the revision a docs reader serves.

## `GET /api/v1/docs/readers`

The docs readers of the projects you can see, with the revision each one serves and how its last call went.

| Status | Means | Body |
| --- | --- | --- |
| 200 | Done | [DocReadersResponse](#docreadersresponse) |
| 401 | No token, or a token that is not valid |  |

## `GET /api/v1/docs/revision`

The current docs revision and every publish and yank after the one you name. A docs reader also polls it, with its three headers, to say which revision it serves.

| Parameter | In | Type | About |
| --- | --- | --- | --- |
| `since` (optional) | query | integer or null | The revision the caller already has; 0 or left out lists every change. |
| `x-ops-docs-reader` (optional) | header | string or null | A reader's poll: its project |
| `x-ops-docs-secret` (optional) | header | string or null | A reader's poll: its secret |
| `x-ops-docs-served` (optional) | header | integer or null | A reader's poll: the revision it serves |

| Status | Means | Body |
| --- | --- | --- |
| 200 | Done | [DocRevisionResponse](#docrevisionresponse) |
| 401 | A reader's poll whose secret does not match |  |
| 422 | A reader's poll missing a header, or serving a revision ops has not reached |  |
| 429 | Too many reads from this address; wait a minute |  |

## `GET /api/v1/docs/revisions/{revision}/pickups`

When each docs reader picked up one revision, and how long it took after the publish or yank.

| Parameter | In | Type | About |
| --- | --- | --- | --- |
| `revision` | path | integer |  |

| Status | Means | Body |
| --- | --- | --- |
| 200 | Done | [DocRevisionPickupsResponse](#docrevisionpickupsresponse) |
| 401 | No token, or a token that is not valid |  |
| 404 | No such revision |  |

## `GET /api/v1/docs/sets`

Every doc set, with its newest version and how many versions it has. Narrow it by project or kind. No token needed.

| Parameter | In | Type | About |
| --- | --- | --- | --- |
| `project` (optional) | query | string or null | Only this project's sets. |
| `kind` (optional) | query | string or null | Only sets of this kind: `package` or `service`. |

| Status | Means | Body |
| --- | --- | --- |
| 200 | Done | [DocSetsResponse](#docsetsresponse) |
| 422 | Not a kind |  |
| 429 | Too many reads from this address; wait a minute |  |

## `GET /api/v1/docs/sets/{set}/versions`

One doc set and all its versions, newest first, yanked ones included. No token needed.

| Parameter | In | Type | About |
| --- | --- | --- | --- |
| `set` | path | string |  |

| Status | Means | Body |
| --- | --- | --- |
| 200 | Done | [DocVersionsResponse](#docversionsresponse) |
| 404 | No such set |  |
| 429 | Too many reads from this address; wait a minute |  |

## `GET /api/v1/docs/sets/{set}/versions/{version}`

One version of a doc set, with the list of its pages and images. No token needed.

| Parameter | In | Type | About |
| --- | --- | --- | --- |
| `set` | path | string |  |
| `version` | path | string |  |

| Status | Means | Body |
| --- | --- | --- |
| 200 | Done | [DocVersionDetail](#docversiondetail) |
| 404 | No such set or version |  |
| 429 | Too many reads from this address; wait a minute |  |

## `PUT /api/v1/docs/sets/{set}/versions/{version}`

Publish a docs folder as one version of a doc set. The body is the folder as a plain tar. A version never changes: the same bytes again change nothing, and other bytes are refused.

| Parameter | In | Type | About |
| --- | --- | --- | --- |
| `set` | path | string |  |
| `version` | path | string |  |
| `project` (optional) | query | string or null | The project a service set's first version is published for. Needed only then; any other set refuses one that is not its own. |
| `source` (optional) | query | string or null | `push` (default) or `publish` (a package publish run's `docs` step). |

**Body:** `application/x-tar` bytes. The docs folder as a plain tar

| Status | Means | Body |
| --- | --- | --- |
| 200 | The same bytes again: nothing changed | [DocPublishResponse](#docpublishresponse) |
| 201 | Published | [DocPublishResponse](#docpublishresponse) |
| 401 | No token, or a token that is not valid |  |
| 403 | Not allowed to publish in the set's project |  |
| 409 | That version is published with other content |  |
| 413 | Larger than the body limit |  |
| 422 | The folder, the name or the version is refused | [DocRefusal](#docrefusal) |

## `GET /api/v1/docs/sets/{set}/versions/{version}/archive`

The docs folder of one version, exactly as it was published, as a plain tar. Yanked versions are still served. No token needed.

| Parameter | In | Type | About |
| --- | --- | --- | --- |
| `set` | path | string |  |
| `version` | path | string |  |

| Status | Means | Body |
| --- | --- | --- |
| 200 | The docs folder as a plain tar (application/x-tar) |  |
| 404 | No such set or version |  |
| 429 | Too many reads from this address; wait a minute |  |
| 503 | The archive could not be read |  |

## `POST /api/v1/docs/sets/{set}/versions/{version}/yank`

Yank one version, so readers stop showing it. Its archive stays readable.

| Parameter | In | Type | About |
| --- | --- | --- | --- |
| `set` | path | string |  |
| `version` | path | string |  |

| Status | Means | Body |
| --- | --- | --- |
| 200 | Done | [DocYankResponse](#docyankresponse) |
| 401 | No token, or a token that is not valid |  |
| 403 | Not allowed to publish in the set's project |  |
| 404 | No such set or version |  |

## `GET /api/v1/projects/{slug}/docs/refreshes`

The project's docs reader and the last 50 revisions it picked up, with how long each took.

| Parameter | In | Type | About |
| --- | --- | --- | --- |
| `slug` | path | string |  |

| Status | Means | Body |
| --- | --- | --- |
| 200 | Done | [DocRefreshesResponse](#docrefreshesresponse) |
| 401 | No token, or a token that is not valid |  |
| 403 | Your role does not allow this |  |

## Types

### DocReadersResponse

| Field | Type | About |
| --- | --- | --- |
| `readers` | array of [DocReaderView](#docreaderview) |  |
| `revision` | integer | The revision now, to compare each reader's with. |

### DocRevisionResponse

The revision now and every change after `since`, oldest first.

| Field | Type | About |
| --- | --- | --- |
| `changes` | array of [DocChange](#docchange) |  |
| `revision` | integer |  |
| `since` | integer |  |

### DocRevisionPickupsResponse

What a publish run or a deploy shows under its `docs` step.

| Field | Type | About |
| --- | --- | --- |
| `at` | string |  |
| `readers` | array of [DocRevisionPickup](#docrevisionpickup) |  |
| `revision` | integer |  |

### DocSetsResponse

| Field | Type | About |
| --- | --- | --- |
| `sets` | array of [DocSetView](#docsetview) |  |

### DocVersionsResponse

A set and its versions, newest published first.

| Field | Type | About |
| --- | --- | --- |
| `set` | [DocSetView](#docsetview) |  |
| `versions` | array of [DocVersionView](#docversionview) |  |

### DocVersionDetail

One version with its manifest: every page and image, so an index never opens the archive.

| Field | Type | About |
| --- | --- | --- |
| `archive` | string | The path the archive is read from. |
| `digest` | string |  |
| `kind` | string |  |
| `manifest` | [Manifest](#manifest) |  |
| `published_at` | string |  |
| `set` | string |  |
| `size_bytes` | integer |  |
| `source` | string |  |
| `version` | string |  |
| `yanked` | boolean |  |
| `yanked_at` (optional) | string or null |  |

### DocPublishResponse

What a publish did. `created` is false for the same bytes pushed again, which changes nothing; `revision` is then the revision the version was first published at.

| Field | Type | About |
| --- | --- | --- |
| `created` | boolean |  |
| `digest` | string |  |
| `images` | integer |  |
| `kind` | string |  |
| `pages` | integer |  |
| `project` (optional) | string or null |  |
| `published_at` | string |  |
| `revision` | integer |  |
| `set` | string |  |
| `size_bytes` | integer |  |
| `version` | string |  |

### DocRefusal

A refused docs folder: every problem found, each naming its page.

| Field | Type | About |
| --- | --- | --- |
| `error` | string |  |
| `refusals` | array of string |  |

### DocYankResponse

What a yank did. Yanking a yanked version changes nothing and answers the same.

| Field | Type | About |
| --- | --- | --- |
| `revision` | integer | The revision the yank bumped to, or the current one when it was yanked already. |
| `set` | string |  |
| `version` | string |  |
| `yanked_at` | string |  |

### DocRefreshesResponse

A project's reader and its refreshes, newest first; `reader` null when the project declares none.

| Field | Type | About |
| --- | --- | --- |
| `reader` (optional) | null or [DocReaderView](#docreaderview) |  |
| `refreshes` | array of [DocRefresh](#docrefresh) |  |

### DocReaderView

One docs reader, and what it last said it serves.

| Field | Type | About |
| --- | --- | --- |
| `call_error` (optional) | string or null |  |
| `call_ms` (optional) | integer or null |  |
| `called_at` (optional) | string or null | The last call ops made to it, how long it took, and why it failed. |
| `path` | string |  |
| `pickup_ms` (optional) | integer or null | Milliseconds from the bump of `served_revision` to the reader serving it. |
| `project` | string |  |
| `served_at` (optional) | string or null |  |
| `served_revision` (optional) | integer or null | The revision it serves, as it last reported; null before it ever answered. |
| `service` | string |  |

### DocChange

One bump of the revision.

| Field | Type | About |
| --- | --- | --- |
| `action` | string | `published` or `yanked`. |
| `at` | string |  |
| `digest` | string |  |
| `kind` | string |  |
| `revision` | integer |  |
| `set` | string |  |
| `version` | string |  |

### DocRevisionPickup

When one reader first served a revision (or a newer one).

| Field | Type | About |
| --- | --- | --- |
| `picked_up_at` (optional) | string or null | null while it has not. |
| `pickup_ms` (optional) | integer or null | Milliseconds after the bump. |
| `project` | string |  |

### DocSetView

One set as the listing shows it.

| Field | Type | About |
| --- | --- | --- |
| `kind` | string | `package` or `service`. |
| `latest` (optional) | string or null | The newest published version that is not yanked; null before the first. |
| `name` | string |  |
| `packages` | array of string | The published package names it follows (a module: its crate and its layer). |
| `project` (optional) | string or null | The project that owns it. |
| `updated_at` (optional) | string or null | When its newest version was published. |
| `versions` | integer | How many versions it has, yanked ones included. |

### DocVersionView

One version as a set's listing shows it.

| Field | Type | About |
| --- | --- | --- |
| `digest` | string | SHA-256 of the archive, lowercase hex: a reader's cache key. |
| `images` | integer |  |
| `pages` | integer |  |
| `published_at` | string |  |
| `size_bytes` | integer |  |
| `source` | string | `publish` (a package publish run), `deploy` (a production deploy) or `push`. |
| `version` | string |  |
| `yanked` | boolean |  |
| `yanked_at` (optional) | string or null |  |

### Manifest

| Field | Type | About |
| --- | --- | --- |
| `images` | array of [ManifestImage](#manifestimage) | Every image, by path. |
| `pages` | array of [ManifestPage](#manifestpage) | Every Markdown page, by path. |

### DocRefresh

One refresh of a reader: a revision it picked up.

| Field | Type | About |
| --- | --- | --- |
| `picked_up_at` | string |  |
| `pickup_ms` | integer |  |
| `revision` | integer |  |
| `via` | string | `call` (its answer to ops's call) or `poll` (its own poll). |

### ManifestImage

| Field | Type | About |
| --- | --- | --- |
| `path` | string |  |
| `size` | integer |  |

### ManifestPage

| Field | Type | About |
| --- | --- | --- |
| `description` (optional) | string or null |  |
| `order` (optional) | integer or null | The front matter's `order`; pages without one sort after those with one, by path. |
| `path` | string | Inside the docs folder, `/` separated, `guides/install.md`. |
| `size` | integer | Bytes of the Markdown file. |
| `title` | string |  |
