# bee-check report format (spec v1)
This document defines the JSON shape that `bee-check --output json`
emits and that `bee-check-web` will consume. Implementations in other
languages should match this exactly so reports are portable.
## Top-level
```jsonc
{
"reference": "c79394...bdc36a", // 64- or 128-hex Swarm reference
"status": "retrievable", // see Status below
"vantages": [ /* VantageResult, see below */ ],
// Added in bee-check 0.3.0 — additive, no spec_version bump.
// Both empty/absent when not used.
"gateways": [ /* GatewayResult, see below */ ],
"resolution": { /* Resolution, see below */ },
"chunks": [ /* ChunkProbe, see below */ ], // omitted when --per-chunk not used
// Added in bee-check 0.5.0 — additive, no spec_version bump.
"cold_downloads": [ /* ColdDownloadResult, see below */ ], // omitted when --cold not used
"spec_version": 1
}
```
### Status
```jsonc
"retrievable" // every vantage returned IsRetrievable=true
"unretrievable" // every vantage either returned IsRetrievable=false or errored
"partial" // mixed: some retrievable, some not
"error" // every vantage produced an error (no retrievability answer at all)
```
Exit code is `0` when at least one vantage returned `retrievable=true`,
`2` otherwise.
## VantageResult
One per `--bee` URL, ordered by URL (lex).
```jsonc
{
"bee_url": "http://localhost:1633",
"retrievable": true, // or false, or null when the call errored
"elapsed_ms": 3004,
"error": null, // omitted when null; non-null string when the call failed
// Added in bee-check 0.2.0 — additive, no spec_version bump.
// All three optional; absent if the corresponding GET /addresses
// or GET /health call failed for the vantage.
"overlay": "7179856eb3c28642983d0e1b7f264693e407a2738593dec9fd59f2ee29046c9a",
"bee_version": "2.7.2-rc1-868c1d52",
"proximity_to_root": 3
}
```
A vantage with `retrievable: null` AND `error: "..."` indicates the
`/stewardship/{ref}` call itself failed (network, 404, timeout, etc.).
A vantage with `retrievable: false` and no `error` means Bee said the
reference is not retrievable from that node's view.
`overlay` is the probed Bee's overlay address from `GET /addresses`.
The first 2 hex chars identify the node's neighborhood.
`bee_version` is the `version` field from `GET /health`.
`proximity_to_root` is the proximity order between the probe node's
overlay and the reference being checked — higher means the probe is
closer to where the chunk is stored; `0` means the probe is not in
the chunk's neighborhood at all.
## ChunkProbe
Emitted only when `--per-chunk` is used. One per chunk reachable from
the root manifest, up to `MAX_CHUNKS` (1000 in v1).
```jsonc
{
"address": "1a2b3c...ef",
"neighborhood": "1a", // first 2 hex chars (PO 0-7 → first byte)
"per_vantage": {
"http://localhost:1633": {
"found": true,
"elapsed_ms": 412,
"error": null,
// Added in bee-check 0.2.0 — optional.
"proximity": 4
},
"https://b.example": {
"found": false,
"elapsed_ms": 5012,
"error": "404: chunk not found",
"proximity": 0
}
}
}
```
`proximity` (when present) is the proximity order between that
vantage's overlay and **this specific chunk's** address. Higher is
better; this is the per-chunk analog of `proximity_to_root` on the
vantage. Lets you see "this chunk's neighborhood is 0x1a; my probes
were at PO 0 and PO 3 from it" — i.e. neither probe is in the chunk's
neighborhood, which explains a miss without needing to inspect the
network.
The chunk list is **post-order BFS from the root**, deduplicated, and
capped. If the root chunk isn't a parseable manifest, the chunk list is
just `[<root>]`.
## GatewayResult
Added in bee-check 0.3.0. One per `--gateway` URL, ordered by URL.
```jsonc
{
"url": "https://api.gateway.ethswarm.org",
"retrievable": true, // 2xx HTTP status → true; 4xx/5xx → false; network err → null
"elapsed_ms": 412,
"status_code": 200, // omitted when the call errored at network layer
"error": null // non-null when status_code is omitted
}
```
Gateway probes call `HEAD {url}/bzz/{reference}/` and interpret the
HTTP status as a coarse retrievability signal: a public gateway only
returns 2xx if it could resolve and forward the content through the
network. Aggregates into the same top-level `status` as vantages —
"retrievable through any vantage or any gateway" is enough to call
the reference retrievable.
## Resolution
Added in bee-check 0.3.0. Present when the user supplied a mutable
input (a Swarm feed reference) and bee-check resolved it before
probing. Currently one variant:
```jsonc
{
"kind": "feed",
"owner": "1234...abcd", // 40-hex Ethereum address
"topic": "5678...beef", // 64-hex feed topic
"resolved_reference": "c79394...bdc36a"
}
```
The CLI accepts `feed:OWNER:TOPIC` (or `feed:OWNER/TOPIC`) as a
positional input and resolves via `GET /feeds/{owner}/{topic}` on
the first `--bee` URL. The top-level `reference` field is then the
**resolved** chunk reference; the original input is recoverable
from `resolution`.
## ChunkStats (0.4.0+)
Populated alongside `chunks` (i.e. when `--per-chunk` was used).
Pure post-processing — no extra network calls.
```jsonc
"chunk_stats": {
"per_vantage": {
"http://localhost:1633": {
"total": 42,
"found": 40,
"missing": 2,
"elapsed_p50_ms": 120,
"elapsed_p95_ms": 540,
"elapsed_max_ms": 800
}
},
"per_neighborhood": {
"1a": {
"total": 10, "found": 10, "missing": 0,
"elapsed_p50_ms": 200, "elapsed_p95_ms": 1100,
"elapsed_max_ms": 1400
}
}
}
```
Latencies are computed over `found == true` chunks only. `elapsed_*`
fields are absent when no chunk in that bucket was found.
The per-neighborhood roll-up keys on the first 2 hex chars of the
chunk address (PO 0-7 = first byte). Reveals patterns like "every
chunk in neighborhood 0x4a is slow regardless of which vantage" —
useful for distinguishing storer-node problems from probe-side ones.
## ColdDownloadResult (0.5.0+)
Emitted only when `--cold` is used. One entry per Bee URL (probed
via `GET /bytes/{ref}`) and one per gateway URL (probed via
`GET /bzz/{ref}/`). The body is streamed to EOF and discarded;
`bytes_downloaded` is the total received, `elapsed_ms` is wall-clock
for the entire transfer.
```jsonc
{
"url": "http://localhost:1633",
"endpoint": "/bytes/{ref}", // or "/bzz/{ref}/" for gateways
"success": true,
"bytes_downloaded": 4096,
"elapsed_ms": 312,
"status_code": 200, // omitted on transport error
"error": null // present on 4xx/5xx or stream error
}
```
Cold-download is informational and does NOT contribute to the
top-level `status` aggregate (which remains vantages + gateways).
It exists to expose end-to-end transport behavior — for instance,
a vantage that walks the chunk graph fine via stewardship but
serves bytes slowly, or a gateway that 200s a HEAD but errors mid-
stream on a full GET.
## VantageResult.target_proximity (0.4.0+)
When the CLI was invoked with `--target-overlay HEX`, each vantage
also reports its proximity order to that target overlay, and the
`vantages` array is sorted closest-first. Useful for "from a node
near neighborhood X, is this retrievable?" questions.
## Compatibility
- `spec_version` lets consumers refuse reports they don't understand.
- New fields may be added in a minor revision; consumers MUST ignore
fields they don't recognize.
- Renames or removals bump `spec_version`.
## Implementation notes for other consumers
- **bee-check-web** consumes this shape. It also accepts user-uploaded
JSON files in this format, so users can share a report by attaching
the file rather than re-running the probe.
- **CLI piping**: `bee-check ... --output json | jq '.status'` is the
canonical scripting pattern. Don't add CLI flags whose effect can't
be inferred from the JSON.