Content Consumption Guide
The canonical consumer surface for reading Oak Chain content is the explorer family on each validator. Topology discovery, tree browsing, node detail, provenance, and event subscription all share a single response contract: a versioned envelope with cluster context plus a domain-specific payload.
Validators also expose a legacy diagnostic surface (/api/explore, /api/blob, /api/cid/*). Those endpoints remain available for on-box troubleshooting but are not part of the upstream consumer contract. See the API Reference for the full local surface and its live inventory.
Authentication
Validator HTTP endpoints can require a token in the standard Authorization header. Send the token itself, without a Bearer prefix.
Configuration:
- System property:
oak.validator.auth.token - Environment variable:
OAK_VALIDATOR_AUTH_TOKEN
If neither is set, the validator runs in POC mode: all endpoints accept unauthenticated requests. This is the default for local development clusters.
If a token is configured, every endpoint except /health, /health/{local,deep,cluster}, and /v1/ops/snapshots/{health,runtime,storage} requires it. Segment-transfer routes (/segments/*, /journal.log, /manifest) skip rate limiting but still need the token. A missing or wrong header, including one with a Bearer prefix, returns 401 Unauthorized.
curl -s -H "Authorization: ${OAK_VALIDATOR_AUTH_TOKEN}" \
"http://127.0.0.1:8090/v1/explorer/content/nav"
Response Envelope
Every source-class endpoint returns a JSON envelope with three guaranteed fields:
contractVersion: schema identifier (e.g.,explorer.content.v1,events.recent.v1,settlement.v1). Consumers should check this to detect schema evolution.generatedAtMs: wall-clock milliseconds when the response was assembled.- Domain-specific payload fields below.
Cluster-scoped responses additionally include a cluster block describing which cluster served the read (clusterId, displayName, scope, role, leader, transport). Errors use a separate envelope; see Error Responses.
Reading Content
Content reads follow a four-step pattern: discover topology, browse, read, verify provenance. All four endpoints share the explorer.content.v1 contract.
1. Discover topology
Start with the topology nav to learn which clusters exist, what each owns, and how to address them.
curl -s "http://127.0.0.1:8090/v1/explorer/content/nav" | jq .
Returns:
localCluster: the cluster this validator belongs to (clusterId,displayName,scope,browseRoot, ownership rules, leader URL).mountedNeighbors: read-only mounted clusters (lazy read fabric).outerNetwork: observed clusters beyond the local mount horizon.cacheHints: recommended cache strategies per scope (event-invalidated for local, TTL-based for remote).
2. Browse a cluster tree
Use the clusterId from topology nav to browse content under a path:
curl -s "http://127.0.0.1:8090/v1/explorer/content/clusters/local-localhost-8090/tree?path=/oak-chain" | jq .
Returns the cluster context plus the tree under the requested path.
3. Read a node
For full node detail at a specific path:
curl -s "http://127.0.0.1:8090/v1/explorer/content/clusters/local-localhost-8090/node?path=/oak-chain/74/2d/35/0xWALLET/Brand/content/page-173" | jq .
4. Inspect provenance
For provenance and authority facts at a path: signatures, on-chain settlement references, attribution chain, and the consensus terms under which the write was committed.
curl -s "http://127.0.0.1:8090/v1/explorer/content/clusters/local-localhost-8090/provenance?path=/oak-chain/74/2d/35/0xWALLET/Brand/content/page-173" | jq .
Reading Settlement
For on-chain settlement details by proposal id or transaction hash:
curl -s "http://127.0.0.1:8090/v1/settlement/proposals/{proposalId}" | jq .
curl -s "http://127.0.0.1:8090/v1/settlement/transactions/{transactionHash}" | jq .
Both carry the settlement.v1 contract.
Events
Backfill recent events
Source-class endpoint:
curl -s "http://127.0.0.1:8090/v1/events/recent?limit=50" | jq .
Contract: events.recent.v1. Default limit 50. Returns events[], count, hasMore, lastId. Optional filters: since (epoch milliseconds, exclusive), types, wallets, organizations, path. There is no cursor parameter; to page forward, pass the newest timestamp you have seen as since.
Event stats
curl -s "http://127.0.0.1:8090/v1/events/stats" | jq .
Contract: events.stats.v1. Returns connectedClients, eventBufferSize, totalEventsBroadcast.
Streaming
Each validator pushes content events as Server-Sent Events (SSE) at GET /v1/events/stream. The stream is validator-local: a validator emits an event when it applies a write to its own store. No upstream SSE stream is published. The edge gateway serves only /ops/v1/events/recent and /ops/v1/events/stats, so remote consumers poll /ops/v1/events/recent. The stream is classified as local-diagnostic.
curl -N -H "Authorization: ${OAK_VALIDATOR_AUTH_TOKEN}" \
"http://127.0.0.1:8090/v1/events/stream"
Drop the header when the validator runs without a token. A browser EventSource cannot send an Authorization header, so with a token set, connect from a server-side client.
Event format
The SSE event name is the event type, and the SSE id is the event id. The data fields id, type, and timestamp are always present; action, path, wallet, organization, message, ipfsCid, signature, size, and contentType appear when set.
event: content
id: 1767225600000
data: {"id":"1767225600000","type":"content","action":"write","path":"/oak-chain/74/2d/35/0x742d35cc.../PixelPirates/content/page-1767225600000-11111111","wallet":"0x742d35cc...","organization":"PixelPirates","timestamp":1767225600000,...}
contentdeletebinarywalletconsensus// Server-side, or a validator without a token (EventSource sends no Authorization header)
const es = new EventSource('http://127.0.0.1:8090/v1/events/stream?types=content,delete');
es.addEventListener('content', (event) => {
const { path, wallet } = JSON.parse(event.data);
console.log('Written:', path, 'by', wallet);
});
es.addEventListener('delete', (event) => {
console.log('Deleted:', JSON.parse(event.data).path);
});
Filters and resume
Optional query parameters: types, wallets, organizations (comma-separated lists), path (a prefix), and since (epoch milliseconds). On reconnect, the stream replays buffered events after the one named in the Last-Event-ID header, which a browser EventSource sends automatically.
Limits
/v1/events/recent and reconnect replayBinaries
The canonical consumer pattern for retrieving binaries does not call the validator. Read the CID from an explorer response, then fetch directly from the IPFS gateway:
// 1. Get CID from node detail
const meta = await fetch(
`http://127.0.0.1:8090/v1/explorer/content/clusters/${clusterId}/node?path=${encodeURIComponent(path)}`
);
const { properties } = await meta.json();
// Validator-hosted binaries carry the CID in the ipfsCid property
const cid = properties.find((p) => p.name === 'ipfsCid')?.value;
// 2. Fetch binary from IPFS gateway (no validator in the path)
const binary = await fetch(`https://ipfs.io/ipfs/${cid}`);
return binary.blob();
The validator's local /api/blob/{blobId}, /api/cid/{blobId}, /api/cid/reverse/{cid}, and /api/cid/gateway/{blobId} are diagnostic surfaces for operators and have no upstream replacement. See Binary Storage for the storage model and API Reference if you need the diagnostic surface for on-box debugging.
Error Responses
All endpoints return errors in a single JSON envelope:
{
"success": false,
"error": "Wallet not found",
"code": "not_found",
"status": 404,
"timestamp": 1715246700000
}
bad_requestunauthorizednot_foundrate_limitedservice_unavailableinternal_errorSuccessful responses use 200 OK for normal returns and 302 Found for the diagnostic CID gateway redirect.
Diagnostic Surfaces
The validator exposes legacy and diagnostic endpoints that are not part of the canonical consumer contract. They remain available for on-box debugging and operator workflows.
/api/explore?path=.../v1/explorer/content/clusters/{clusterId}/tree/api/blob/{blobId}/api/cid/{blobId}ipfsCid)/api/cid/reverse/{cid}/api/cid/gateway/{blobId}/v1/events/stream/ops/v1/events/recent via edge gatewaySee API Reference for the complete taxonomy.
Upstream Aggregation
Oak Chain is the canonical write/finality/provenance layer. Validators do not keep full-text or search indexes in consensus state, which keeps consensus deterministic and small. Discovery, search, and rich consumption should be built upstream: at the edge gateway, in dashboards, or in agentic read models that consume the validator's source-class endpoints.
Recommended upstream pipeline:
- Event intake
- Poll
/ops/v1/events/recent(edge gateway) for updates, or use the validator-local/v1/events/streamon-box. - Backfill with
/v1/events/recentusing thesincefilter.
- Canonical fetch
- Resolve affected paths with
/v1/explorer/content/clusters/{clusterId}/node. - Capture provenance with
/v1/explorer/content/clusters/{clusterId}/provenancewhen writes need attestation.
- Read-model indexing
- Build indexes and materialized views by cluster, namespace, and content type.
- Support search, faceting, recommendations, and explorer views in the upstream layer, not the validator.
- Enrich in the same layer: classify content, extract tags, topics, and relationships, and rank by tenant and wallet policy.
- Integrity checks
- For critical or disputed reads, re-verify against the validator's
provenanceendpoint. - Keep the upstream model eventually consistent but integrity-anchored.
- Serve
- Publish client-facing APIs behind
/ops/v1/*or a higher-level product contract, and keep validator URLs out of public client contracts.
Recommended Read Pattern
- Resolve topology with
/v1/explorer/content/nav(or cache it; it changes rarely). - Browse or list with
/v1/explorer/content/clusters/{clusterId}/tree. - Fetch node detail with
/v1/explorer/content/clusters/{clusterId}/node. - Resolve binaries by reading the CID from the node response and fetching from IPFS directly.
- Poll
/ops/v1/events/recentfor cache invalidation and freshness.
This gives stable cluster-scoped reads, deterministic node fetches, event-driven invalidation, and a binary path that does not pin throughput to validator capacity.
Source of Truth Rule
- Upstream services are for speed, search, and intelligence.
- Validator source-class endpoints are for canonical truth and verification.
- Local-diagnostic and internal endpoints are for operator workflows only.
- Never treat upstream indexes as authoritative for finality, provenance, or attribution semantics.
Consumer Types
API Clients / SDK Consumers
Use HTTP endpoints directly against the validator (/v1/explorer/content/*) for source truth, or against the edge gateway (/ops/v1/*) for the production-shaped contract. This is the default for web, mobile, and server consumers.
Edge Worker Read Models
Use route-specific fetches from validator source endpoints to shape dashboard or control-plane payloads. The edge worker translates raw source responses into the wrapped {version, generatedAt, clusterId, data} envelope used by /ops/v1/*.
AEM Connector Consumers
AEM 6.5 LTS author can mount Oak Chain content read-only at /oak-chain with the connector's opt-in mount; see AEM 6.5 LTS Integration. Even then, the explorer endpoints remain the authoritative public contract.
Consistency and Query Caveat
Oak Chain stores flexible JSON structures, but consumption quality depends on consistent property shapes per namespace.
If structure drifts, query and index behavior degrades and traversal limits can be hit. Keep namespace style guides stable.
See: