For AI labs
Compliance evidence that survives the audit.
At training-data ingestion, call one API per domain. Get back a record you can verify in standard-library Node.js — against the public Arweave network, without our code in the verify path.
Talk to integrations →The problem
At the moment of training, you need to be able to prove later — to a regulator, an auditor, a court — what you knew, and when you knew it, about each source’s opt-out status. An internal opt-out crawler produces records you generated yourself; a challenger can question those. robots.txt polling has no cryptographic timestamp and no proof of domain authority. Vendor-hosted registries without public anchoring depend on the vendor’s continued existence, honesty, and availability.
The registry produces evidence that holds up when none of those things are guaranteed.
What integration looks like
One HTTPS GET per unique domain in your training corpus. Standard-library Node.js to verify the response independently — three checks, ~30 lines, no SDK. One row in your audit log per lookup, retained for the maximum applicable statute of limitations. Total integration effort: one engineer, one to three days.
No SDK to install. No proprietary cryptography. Ed25519 per RFC 8032. SHA-256 per FIPS 180-4. Merkle inclusion proofs over SHA-256. Arweave for anchoring.
verifier.mjs
Real, working verifier. Production reference at /docs/verifier.
// Three independent checks. Standard library only. No Akaeon code.
import crypto from 'node:crypto'
const SPKI_HEADER = Buffer.from('302a300506032b6570032100', 'hex')
const sha256 = (b) => crypto.createHash('sha256').update(b).digest()
const r = await fetch(`https://api.akaeon.com/v1/lookup?domain=${domain}`).then(x => x.json())
const o = r.optouts[0]
// 1. Ed25519 signature on the registry's canonical message
const pk = crypto.createPublicKey({
key: Buffer.concat([SPKI_HEADER, Buffer.from(o.registry_signature.public_key, 'base64')]),
format: 'der', type: 'spki',
})
const sigOk = crypto.verify(null,
Buffer.from(o.registry_signature.canonical_message, 'utf8'),
pk,
Buffer.from(o.registry_signature.signature, 'base64'))
// 2. Merkle inclusion proof reconstructs the claimed root
let c = Buffer.from(o.merkle_inclusion.leaf_hash, 'hex'), i = o.merkle_inclusion.leaf_index
for (const s of o.merkle_inclusion.merkle_proof) {
const [l, ri] = (i & 1) === 0 ? [c, Buffer.from(s, 'hex')] : [Buffer.from(s, 'hex'), c]
c = sha256(Buffer.concat([Buffer.from([0x01]), l, ri]))
i >>= 1
}
const merkleOk = c.toString('hex') === o.merkle_inclusion.merkle_root
// 3. Arweave-anchored batch payload contains the same root
const ar = await fetch(o.merkle_inclusion.arweave_url).then(x => x.json())
const anchorOk = ar.merkle_root_sha256_hex === o.merkle_inclusion.merkle_root
console.log({ sigOk, merkleOk, anchorOk })The technical guarantees
Pricing
v1 honest answer: contact us. We expect to land on a per-lookup-volume tier structure with a free tier for non-commercial and research use. We want to set pricing in conversation with the first paying labs rather than guess.
What we ask in return
Honest audit-logging discipline — we cannot verify it, but the spec is designed to make it easy. Feedback on integration friction. A reference, if the integration goes well and you’re willing to give one.
Talk to integrations
For prioritization, include your company name, your role, and your expected query-per-second rate. We'll respond within two business days.