Skip to content

Fetch a record

GET /v1/records/{record_id} answers one record of any of the five types — the bytes exactly as the business sealed them — and everything needed to check it. One id per call: there is no batch fetch, no list and no export.

samples/typescript/fetch-and-verify.ts
// Fetch one record, then check it without trusting the response: the receipt offline against
// MasterDB's key set, the seal through the public verify endpoint, the business's certificate offline.
//
// MASTERDB_ANCHORS_FILE the trust anchors (JSON array of root JWKs); the pinned sandbox anchors by default
import assert from 'node:assert/strict';
import { createPrivateKey } from 'node:crypto';
import { readFileSync } from 'node:fs';
import { SANDBOX, createEd25519Signer, createPublicClient, createRetrievalClient } from '@masterdb/client';
import { KeySet, SANDBOX_ANCHORS, recordBytes, sha256Tagged, verifyCertificate, verifyReceipt } from '@masterdb/verifier';
const baseUrl = process.env.MASTERDB_API_URL ?? SANDBOX.retrieval;
const signer = createEd25519Signer(createPrivateKey(readFileSync(process.env.MASTERDB_KEY_FILE as string)));
const client = createRetrievalClient({ baseUrl, signer });
const anchors = process.env.MASTERDB_ANCHORS_FILE ? JSON.parse(readFileSync(process.env.MASTERDB_ANCHORS_FILE, 'utf8')) : SANDBOX_ANCHORS;
// A product of Garnet Mill, a fictional Irish business in the sandbox corpus.
const recordId = 'mdb_xmomas3i3kzkdwyqpfoxou5rea';
// Read the body as text: the record's bytes are a span of it, and a seal covers exactly those bytes.
const res = await client.GET('/v1/records/{record_id}', { params: { path: { record_id: recordId } }, parseAs: 'text' });
if (res.error) throw new Error(`fetch refused: ${JSON.stringify(res.error)}`);
const text = res.data as unknown as string;
const bytes = recordBytes(text);
const response = JSON.parse(text);
// 1. The receipt: MasterDB's signed statement of what it served you. Verified offline, from the anchors.
const keys = await KeySet.fetch(baseUrl, { anchors, sandbox: true });
const receipt = verifyReceipt(response.receipt, keys);
assert.equal(receipt.rows[0]?.id, recordId);
assert.equal(receipt.rows[0]?.adl_origin, sha256Tagged(bytes), 'the receipt names the hash of the bytes you received');
console.log('receipt', receipt.retrieval_id, 'served', receipt.served_at, 'in', receipt.region, 'sandbox:', receipt.sandbox);
// 2. The seal: who published these exact bytes, and when. The public verify endpoint needs no account,
// and asks for the record itself, never a bare id.
const publicApi = createPublicClient({ baseUrl });
const check = await publicApi.POST('/v1/verify', {
body: { record_base64: Buffer.from(bytes).toString('base64'), seal: response.seal, sidecar: response.sidecar },
});
if (check.error) throw new Error(check.error.code);
assert.equal(check.data.seal.valid, true);
console.log('seal valid, sealed at', check.data.seal.sealed_at, 'checks', JSON.stringify(check.data.seal.checks));
// 3. The certificate the seal names: the business's verified identity, signed by MasterDB's issuance key.
const cert = await publicApi.GET('/v1/certificates/{uuid}', { params: { path: { uuid: response.business_uuid } } });
if (cert.error) throw new Error(cert.error.code);
const verified = verifyCertificate(cert.data.certificate, keys);
assert.equal(verified.cert_id, check.data.seal.cert_id);
assert.equal(verified.status, 'active');
console.log('certificate', verified.cert_id, verified.status, String(verified.payload['legal_name']));
{
"record_id": "mdb_xmomas3i3kzkdwyqpfoxou5rea",
"business_uuid": "6c1658dd-fa53-4f12-8a18-6eee69f5ca99",
"type": "products",
"published_at": "2026-10-01T00:00:00.000Z",
"record": { "schema": "masterdb/products/1", "business_product_id": "GARNET-00001", "…": "…" },
"seal": { "…": "the business's DSSE seal" },
"sidecar": { "…": "MasterDB's signed sidecar" },
"ai_policy": { "version": 1, "record": { "schema": "masterdb/ai_policy/1", "ai_policy_schema": 2, "answer": true, "…": "…", "blocked": { "adult_sexual": false, "alcohol": true, "…": "…" } }, "seal": { "…": "…" } },
"provenance": { "certificate_url": "https://…/v1/certificates/6c1658dd-…", "projection_version": "products/…", "log_leaf": "sha256:…" },
"receipt": { "payloadType": "application/vnd.masterdb.receipt.v3+json", "…": "…" }
}
Member What it is
record The sealed bytes, verbatim. MasterDB writes the stored bytes into the response without re-serialising them. To check the seal, hash the span of the response body that is this member’s value — recordBytes(text) in TypeScript, record_bytes(body) in Python — never a re-serialisation of the parsed object.
seal The business’s seal over those bytes: a DSSE envelope (Path B), or the batch envelope with this record’s leaf index and inclusion proof (Path A).
sidecar MasterDB’s signed statement of what it checked at publish: the resolved scope, the certificate and AI policy version in force, where the record came from, and, for records with an address, the geocoded coordinate — never written into the business’s bytes.
ai_policy The business’s sealed AI policy record in force now: {version, record, seal}, or {version: 0, record: null, seal: null} if it has never sealed one — what proves a row’s ai_policy_bits. See AI policy.
represent Business & Brand files only: the texts the business wrote about how it wants to be represented.
provenance Where to find the business’s certificate, which projection version made the record’s rows, and the seal’s leaf in the transparency log.
receipt MasterDB’s signed statement that it served you this record, naming the hash of its bytes and the AI policy version applied.

A record from a business that blocked your group, a withdrawn record, a deleted record, a record that never existed, a malformed id, and an id of a type that is not fetchable all answer the same 404, with the same problem body (its instance echoes the path you asked for), and no sooner than 20 ms after the request arrived — so none can be told from another. See Blocking is invisible.

A fetch that returns a record is one query; a 404 is not billed. What you may do with the record is governed by the AI-company Terms (the version in force on the receipt) and by the business’s sealed AI policy: among the Terms’ conditions, a record is used once, in one conversation, and is not cached or used for training.