---
title: "Open one node of the maintained record (traversal, sb.node.v1)"
method: GET
path: "/api/v1/node/{kind}/{hex}"
---

# Open one node of the maintained record (traversal, sb.node.v1)

`GET /api/v1/node/{kind}/{hex}`

## Request

- Base URL: `https://api.signalbureau.ai`
- URL: `https://api.signalbureau.ai/api/v1/node/{kind}/{hex}`
- Auth: none declared

To see how the record fits together, start at an entity or event (e.g. Hormuz) and traverse its maintained relationships; each step returns its relation type, receipts, standing and time. Walk the maintained record node to node. Returns ONE node in schema `sb.node.v1` — an entity (`e`), a situation or corroborated claim (`p`), or a co-mention relation (`r`) — with its identity, five separate standing records, the knowledge cutoff it was read at, provenance (`build`), and its neighbours folded: `children` (observations, each with its source url) and `relations` (situations, claims and co-mentions it takes part in), each as a count plus the first page of typed refs and a cursor. Follow any ref's id, or pass a cursor, to open the next level. Same object as the MCP tool `traverse`. The same door also answers by query at `GET /api/v1/node?id=…` with a full id (`sb:e/…`), a starting point by name (`entity:hormuz`, `event:strait-of-hormuz`) or a cursor alone. Free, no key, CORS-enabled. PUBLISHED LIMITS (also stated in every node's `limits`): one level per call (`depth` must be 1; there is no whole-graph dump); `pageSize` 1-50, default 10; members listed up to 50; 60 calls a minute per caller (runaway-loop protection, not a meter); one knowledge cutoff, the deploy's. THREE STATES, NEVER TWO: a level we read and found empty has `count: 0`; a level we could not read has `count: {state: "cannot-measure", reason}`; a level the projection cannot hold has `count: {state: "not-built", reason}`. An unknown id is a 404 with code `node_not_found`; a store we could not read is a 503 `cannot_measure` (the node may exist). Version 1 is PROJECTED from today's graphs (`build.plane`), not read from the maintained world state. Claim ids are provisional (a wording change mints a new id); relation ids use the proposed letter `r`. Edge-cached 5 minutes.

## Path parameters

- `kind` 'e' | 'p' | 'r', required
- `hex` string, required

## Query parameters

- `level` 'node' | 'children' | 'relations'
- `cursor` string
- `pageSize` integer
- `edgeKind` 'event' | 'claim' | 'co-mentioned'
- `depth` 1
- `asOf` string

## Response `200`

The node.

- object: sb.node.v1. Full JSON Schema: lib/schemas/sb.node.v1.json in the repository.
  - `schema` 'sb.node.v1', required
  - `id` string, required
  - `kind` 'entity' | 'relation' | 'event' | 'claim' | 'observation' | 'source' | 'watch' | 'reading', required
  - `grain` 'occurrence' | 'situation'
  - `label` object, required
    - `text` string
    - `locale` string
  - `identity` object: How the id was minted (anchor) and how strong it is.
  - `asOf` object, required: The one knowledge cutoff this node was read at. Every cursor carries it.
    - `knowledgeCutoff` string
    - `snapshot` string
  - `lens` object, required
    - `kind` 'public' | 'watch'
  - `build` object, required
    - `plane` 'projected' | 'maintained'
    - `builtFrom` string[]
    - `rule` string
  - `standing` object, required: Five separate records: evidence, admission, disposition, validity, measurement. Any may be {state, reason}.
  - `dimensions` object
  - `members` object[]
    - `role` string
    - `position` integer
    - `id` string
    - `label` string
    - `resolved` boolean
  - `receipt` object
  - `up` object[], required
    - `id` string, required
    - `kind` string, required
    - `label` string, required
    - `role` string
    - `relationKind` string
    - `members` integer
    - `url` string: Observation refs: the source document.
  - `upNote` string
  - `children` object, required
    - `count` union, required: An integer, or {state, reason} when the level could not be read (cannot-measure), was never measured (unknown) or needs the maintained world state (not-built). Never a zero standing in for blindness.
      - integer
      - object
        - `state` 'unknown' | 'cannot-measure' | 'not-applicable' | 'not-built', required
        - `reason` string, required
    - `byKind` object
    - `items` object[]
      - `id` string, required
      - `kind` string, required
      - `label` string, required
      - `role` string
      - `relationKind` string
      - `members` integer
      - `url` string: Observation refs: the source document.
    - `cursor` string, nullable: Opaque. Pass it back (with no other paging params) for the next page of this level. null when the level is complete.
    - `order` string
  - `relations` object, required
    - `count` union, required: An integer, or {state, reason} when the level could not be read (cannot-measure), was never measured (unknown) or needs the maintained world state (not-built). Never a zero standing in for blindness.
      - integer
      - object
        - `state` 'unknown' | 'cannot-measure' | 'not-applicable' | 'not-built', required
        - `reason` string, required
    - `byKind` object
    - `items` object[]
      - `id` string, required
      - `kind` string, required
      - `label` string, required
      - `role` string
      - `relationKind` string
      - `members` integer
      - `url` string: Observation refs: the source document.
    - `cursor` string, nullable: Opaque. Pass it back (with no other paging params) for the next page of this level. null when the level is complete.
    - `order` string
  - `edge` object, required
    - `state` 'continues' | 'source' | 'observation' | 'cannot-see' | 'withheld' | 'not-built'
    - `reason` string
    - `url` string
  - `links` object, required
    - `rest` string
    - `mcp` string
    - `page` string, nullable
  - `limits` object, required
    - `levelsPerCall` 1
    - `pageSize` integer
    - `maxPageSize` integer
    - `membersMax` integer
    - `statement` string
  - `actions` object[], required: The control panel: 14 verbs, each lit (with the next call) or dim (with the reason). Every verb only reads or declares a Watch.
    - `verb` string
    - `lit` boolean
    - `effect` 'read' | 'watch-declaration'
    - `layer` string
    - `call` string
    - `reason` string

## Other responses

- `400`: bad_id, bad_param, depth_limit, page_size_limit or bad_cursor — the message names the parameter and the accepted values.
- `404`: node_not_found: the id is well-formed and the store was read, and no such node exists at this cutoff.
- `409`: cursor_stale or as_of_unavailable: the walk would mix two knowledge cutoffs.
- `429`: slow_down: more than 60 calls in a minute from one caller; retry-after header set.
- `501`: kind_not_served: a valid id letter this version does not open (observations are leaves listed with their url; Watches wait on a ruling).
- `503`: cannot_measure: a store needed to answer could not be read; the node may exist. Retry shortly.

---

[API](https://skmtc.dev/sigb/apis/signal-bureau-api.md) · [All operations](https://skmtc.dev/sigb/apis/signal-bureau-api/llms.txt) · [OpenAPI document](https://skmtc.dev/sigb/apis/signal-bureau-api/revisions/290c9c6ca0d0?raw)
