Skip to content
6.8M+ active NPIs · NPPES
fonteum
Research
PricingDocs
Request a pilot →
Chain reference

Verify the chain. Any language. No credentials.

Fonteum’s attestation chain is a Certificate-Transparency-style cryptographic chain over every snapshot we attest. Every link is Ed25519-signed, references the previous link’s hash, and is verifiable from inputs alone with the published public key. This page is the canonical reference for verifiers.

← Chain index Underlying snapshot attestations → Live metadata JSON →

Chain semantics

What the chain proves.

Every chain_links row is one signed link:

  • link_index — monotonically increasing bigint, starting at 0 (genesis).
  • prev_hash— 64-char lowercase hex SHA-256 of the prior link’s content_hash. Genesis prev_hash is "00".repeat(32).
  • attestation_id — bigint reference to the underlying snapshot_attestations row this link attests over.NULL for genesis only.
  • attestation_content_hash — echoed from snapshot_attestations.content_hash. Same zero-pad as prev_hash for genesis.
  • content_hash — SHA-256 over the canonical serialization (next section). Locked once written.
  • signature — Ed25519 signature ofcontent_hashusing the chain’s private key.
  • public_key_id — identifier for the signing key. Phase 1 uses a single key (rotation is Phase 2 — see Public-key publication below).
  • signed_at — ISO 8601 timestamp the link was signed. Part of the canonical content-hash payload.

A verifier walks link_index 0..head, recomputes eachcontent_hash, verifies eachsignature against the published public key, and checks prev_hash[N] == content_hash[N-1]. Any tamper anywhere in the chain breaks at least one of these three checks.

Atomic chain extension: each new link is appended via the extend_chain SECURITY DEFINER plpgsql function which performs INSERT chain_links + UPDATE chain_state head pointer in one transaction. The chain head pointer never lags the disk row.

Canonical content-hash serialization

Frozen contract.

The content_hash is SHA-256 over the following UTF-8 byte string. This format is FROZEN — changing it breaks every external verifier:

contentHash = SHA256(
  String(linkIndex)        || "||" ||
  prevHash                 || "||" ||
  attestationIdStr         || "||" ||   // "null" for genesis
  attestationContentHash   || "||" ||
  signedAtIso
)
  • linkIndex — base-10 string, no leading zeros (e.g. "0", "123").
  • prevHash, attestationContentHash — 64-char lowercase hex SHA-256.
  • attestationIdStr — base-10 string for non-genesis links; literal "null" for genesis (attestation_id IS NULL only at link_index=0).
  • signedAtIso — ISO 8601 with millisecond precision and trailing "Z" (e.g. "2026-05-09T17:42:31.123Z").
  • "||"— the literal two-character separator (U+007C twice). Not escaped inside any field because no field can contain "||" by construction.
Genesis link

link_index = 0.

The genesis link anchors the chain. It is created once, post-deploy, by the operator. Its values are fixed by spec:

  • link_index = 0
  • prev_hash = "00".repeat(32) (64 zero hex chars)
  • attestation_id = NULL (no underlying attestation)
  • attestation_content_hash = "00".repeat(32)
  • content_hash = canonical SHA-256 over the above + signed_at
  • signature = Ed25519 over content_hash

The genesis link’s attestation_id serializes to the literal string "null" in the canonical content-hash payload. This guarantees genesis cannot collide with any future link that has attestation_id = 0.

Public-key publication

Single key, two equivalent surfaces.

The chain’s Ed25519 public key is published at two endpoints, both serving the same value (canonical source: chain_state.public_key):

  • https://fonteum.com/.well-known/chain-public-key — text/plain hex (64 lowercase hex chars + trailing newline). RFC-blessed location for automated discovery.
  • https://fonteum.com/api/v1/chain → public_key field. Same value as a JSON field alongside chain metadata.

Phase 1 uses a single signing key. Key rotation is deferred to a separate wave (§sprint3-chain-key-rotation) which will introduce multi-key support with overlapping validity windows so verifiers can transition gracefully. Until rotation lands, the published public_key_id on every link points to the same key.

API surface

Three reads, one verify.

  • GET /api/v1/chain — chain head + total + published public key.
  • GET /api/v1/chain/[link_index] — full record for one link. Cached public, max-age=31536000, immutable (chain links are immutable once signed).
  • GET /.well-known/chain-public-key — text/plain hex public key.
  • POST /api/v1/chain/verify — accepts a chain link JSON in the body, returns { valid, errors[] }. Verifies content_hash, signature, and prev_hash linkage to the prior on-disk link.
Verifier — Node 20+

Two checks, no DB access.

// Node 20+ — npm i @noble/ed25519
import { createHash } from 'node:crypto';
import { verifyAsync } from '@noble/ed25519';

const link = await fetch('https://fonteum.com/api/v1/chain/123').then((r) => r.json());
const meta = await fetch('https://fonteum.com/api/v1/chain').then((r) => r.json());

// 1. Re-derive content_hash via the canonical serialization.
const payload =
  String(link.link_index) + '||' +
  link.prev_hash          + '||' +
  (link.attestation_id === null ? 'null' : String(link.attestation_id)) + '||' +
  link.attestation_content_hash + '||' +
  link.signed_at;
const recomputed = createHash('sha256').update(payload, 'utf8').digest('hex');
console.log('content_hash matches:', recomputed === link.content_hash);

// 2. Verify the Ed25519 signature.
const hexToBytes = (h) => Uint8Array.from(h.match(/.{2}/g).map((b) => parseInt(b, 16)));
const valid = await verifyAsync(
  hexToBytes(link.signature),
  hexToBytes(link.content_hash),
  hexToBytes(meta.public_key),
);
console.log('valid:', valid);
Verifier — Python 3.10+

stdlib + cryptography.

# Python 3.10+ — pip install cryptography requests
import hashlib, requests
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
from cryptography.exceptions import InvalidSignature

link = requests.get('https://fonteum.com/api/v1/chain/123').json()
meta = requests.get('https://fonteum.com/api/v1/chain').json()

# 1. Re-derive content_hash via the canonical serialization.
attestation_id_str = 'null' if link['attestation_id'] is None else str(link['attestation_id'])
payload = '||'.join([
    str(link['link_index']),
    link['prev_hash'],
    attestation_id_str,
    link['attestation_content_hash'],
    link['signed_at'],
])
recomputed = hashlib.sha256(payload.encode('utf-8')).hexdigest()
print('content_hash matches:', recomputed == link['content_hash'])

# 2. Verify the Ed25519 signature.
public_key = Ed25519PublicKey.from_public_bytes(bytes.fromhex(meta['public_key']))
try:
    public_key.verify(bytes.fromhex(link['signature']), bytes.fromhex(link['content_hash']))
    print('valid: True')
except InvalidSignature:
    print('valid: False')
Verifier — Go 1.21+

stdlib only.

// Go 1.21+ (stdlib only)
package main

import (
	"crypto/ed25519"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"net/http"
)

type ChainLink struct {
	LinkIndex              int    `json:"link_index"`
	PrevHash               string `json:"prev_hash"`
	AttestationID          *int   `json:"attestation_id"`
	AttestationContentHash string `json:"attestation_content_hash"`
	ContentHash            string `json:"content_hash"`
	Signature              string `json:"signature"`
	SignedAt               string `json:"signed_at"`
}

type ChainMeta struct {
	PublicKey string `json:"public_key"`
}

func mustGet(url string, out any) {
	res, err := http.Get(url)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	if err := json.NewDecoder(res.Body).Decode(out); err != nil {
		panic(err)
	}
}

func main() {
	var link ChainLink
	var meta ChainMeta
	mustGet("https://fonteum.com/api/v1/chain/123", &link)
	mustGet("https://fonteum.com/api/v1/chain", &meta)

	// 1. Re-derive content_hash.
	attID := "null"
	if link.AttestationID != nil {
		attID = fmt.Sprintf("%d", *link.AttestationID)
	}
	payload := fmt.Sprintf("%d||%s||%s||%s||%s",
		link.LinkIndex, link.PrevHash, attID,
		link.AttestationContentHash, link.SignedAt,
	)
	sum := sha256.Sum256([]byte(payload))
	recomputed := hex.EncodeToString(sum[:])
	fmt.Println("content_hash matches:", recomputed == link.ContentHash)

	// 2. Verify the Ed25519 signature.
	pubBytes, _ := hex.DecodeString(meta.PublicKey)
	sigBytes, _ := hex.DecodeString(link.Signature)
	msgBytes, _ := hex.DecodeString(link.ContentHash)
	valid := ed25519.Verify(ed25519.PublicKey(pubBytes), msgBytes, sigBytes)
	fmt.Println("valid:", valid)
}

Compliance posture

Methodology · Corrections log · Editorial policy

fonteum

Healthcare provider data, traced to source.


PLATFORM

  • Data platform
  • Pricing
  • FHIR API docs
  • For health-tech

RESEARCH

  • Research hub
  • Nursing homes
  • Methodology
  • Methodology changelog

COMPANY

  • About
  • Press
  • Contact
  • Trust & integrity

LEGAL

  • Privacy policy
  • Editorial policy
  • Corrections log

© 2026 FONTEUM RESEARCH · DATA SNAPSHOT MAY 8, 2026 · BUILT WITH CARE

  • X
  • LINKEDIN
  • PRESS