> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blobhub.io/llms.txt
> Use this file to discover all available pages before exploring further.

# blobhub blob revisions

> Every revision of a blob, newest first, with the latest marked and each phase shown

`blob revisions` lists every revision a blob has, newest first, marks the latest, and shows each one's phase and
status. It is what turns a `REVISION_NOT_WRITABLE` failure into something self-diagnosing: the command that
refused you named a phase, and this is where you see which revisions are in which.

## Synopsis

```bash theme={null}
blobhub blob revisions <org>/<blob>
```

| Argument | Default  | Description                                          |
| -------- | -------- | ---------------------------------------------------- |
| `blob`   | required | Blob as `<org>/<name>`, or a bare name with `--org`. |

The command has no flags of its own. `--org` and `--json` are
[global](/cli/configuration#global-flags), so they go **before** the subcommand.

## What it does

1. Parses the reference, exactly as [`blob show`](/cli/blob/show) does.
2. Fetches the blob record. **Required, not enrichment**: the listing itself does not report which revision is
   the latest, so the `*` marker comes from the record's `latest_revision_id`.
3. Lists the revisions.
4. Reads the blob's limits to decide whether the listing may have truncated. That read needs an `admin` key, so it
   usually fails; it degrades silently and the check is simply skipped.
5. Sorts newest first by `created_at` and prints one row per revision. The platform returns index order, which is
   neither documented nor useful, and the reason to run this command is almost always to find a recent revision.

```text theme={null}
  REVISION                               PHASE     STATUS      CREATED                    COMMENT
* 9f2c1e84-3a77-4d10-b6e5-0c8a1f5d92b4   draft     ready       2026-07-14T09:12:03+00:00  add the refund branch
  1b6d4a09-52ee-4c31-8f77-a3d90b7e6c15   commit    ready       2026-06-30T16:40:55+00:00  v3
  c74e0b2d-8f19-4a63-9d02-5e1b8c47af38   snapshot  ready       2026-06-02T11:05:18+00:00
```

An empty listing prints **nothing at all** — not even the header — and exits `0`. A bare column header over no
rows is noise a pipeline has to filter back out.

Under `--json` the payload carries `blob` and `revisions`, each entry holding `id`, `phase`, `status`,
`created_at`, `comment`, `parent_id` and the boolean `latest`. `parent_id` is in the JSON only; the rendered
table leaves it out.

## Phases, and which of them a command will accept

| Phase      | Read | Write |
| ---------- | ---- | ----- |
| `draft`    | yes  | yes   |
| `managed`  | yes  | yes   |
| `commit`   | yes  | no    |
| `snapshot` | no   | no    |

Both columns additionally require the revision's status to be `ready`, which is what the `STATUS` column is for.

This table is why the command exists in the shape it does. The platform's own rejection for an unusable phase is
a `400 bad request` whose message does not mention the revision at all, so the CLI pre-checks the phase before
it writes anything and reports `REVISION_NOT_WRITABLE` locally, naming the phase it found. When you get that
code, this listing is the answer to "then which revision *can* I write to?" — the phase column is right there,
and `*` marks the one a manifest's `revision: latest` resolves to.

## The truncation advisory

`REVISION_LIST_TRUNCATED` is raised when the number of revisions returned has reached the blob's configured
`revisions_per_blob` maximum. The platform cannot page this listing, so a blob at its cap may be missing
revisions that were silently dropped — nothing in the API reports it, which is why the CLI infers it from the
count.

The check runs **only when the limit is readable**, which needs an `admin`-scoped key. With the `read` or `write`
keys the platform recommends for automation, the limit read fails, the check is skipped, and the command stays
silent rather than guessing. See [`blobhub blob limits`](/cli/blob/limits) for why that is, and for what else it
explains.

Like every advisory, it goes to stderr, is suppressed by `--quiet` and whenever stderr is not a TTY, and never
changes the exit code.

## Errors

| Code                                                           | When                                                                                                                                                          |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BLOB_REFERENCE_INVALID`                                       | The reference is empty, carries more than one `/`, has an empty org before the `/`, has no blob name, or is a bare name with no `--org` and no `BLOBHUB_ORG`. |
| `BLOB_NOT_ACCESSIBLE`                                          | The blob record is absent, not visible to this key, or the key was rejected outright — one `403` covers all of it.                                            |
| `AUTH_INVALID`                                                 | The revision listing itself was rejected. Rare: the blob record is fetched first, so a bad key normally surfaces on the row above.                            |
| `CREDENTIALS_NOT_FOUND`                                        | No API key from flags, environment, or credentials file.                                                                                                      |
| `PROFILE_NOT_FOUND`                                            | `BLOBHUB_PROFILE` names a profile that is not stored.                                                                                                         |
| `INSECURE_CREDENTIALS_PERMISSIONS`                             | `credentials.yaml` is readable by group or other.                                                                                                             |
| `API_RATE_LIMITED`, `API_TRANSIENT_ERROR`, `API_NETWORK_ERROR` | A call failed after its retries.                                                                                                                              |
| `REVISION_LIST_TRUNCATED`                                      | Advisory, on stderr: the listing has reached the configured maximum. The exit code stays `0`.                                                                 |

The revisions route is gated on `read`, not `admin` — and that was confirmed against the deployed API with a
non-admin key, not merely read off the handler. It matters: if it needed `admin`, this command would be useless
to exactly the keys the platform tells automation to use, and the one command that explains a phase failure
would be unavailable to the automation hitting it.

## See also

* [`blobhub blob show`](/cli/blob/show) — the blob record, and the latest revision only.
* [`blobhub blob limits`](/cli/blob/limits) — the `admin`-only read this command degrades around.
* [Error codes](/cli/error-codes) — every code above, and the advisories alongside them.
* [List Revisions](/rest-api/blobs/list-revisions) — the route behind the listing.
* [Commit Revision](/rest-api/revisions/commit-revision) — how a `draft` becomes a `commit`.
