A protocol, not an API you rent
Implement the wire and the conformance rules and you're in. No permission, no KYC, no single ingress that sees everyone.
The sealed, unlinkable, post-quantum messaging protocol that NULL runs on — one wire class, null-state, and yours to integrate. Build on the void.
A message is sealed to a one-time key only its recipient can derive, wrapped in an envelope byte-identical to every other operation on the network, and dropped into a public feed that stores no sender, no recipient, and nothing after it's read. Any wallet, agent, or app can speak it — and every integrator that does shares the same anonymity set.
Implement the wire and the conformance rules and you're in. No permission, no KYC, no single ingress that sees everyone.
Every request is one padded size over a post-quantum transport. A message is byte-identical to a payment or a query — measured, not asserted.
Hybrid ML-KEM-768 + X25519 sealing. Traffic captured today is not readable by a future quantum adversary.
The server holds a one-time key, a view tag, ciphertext, and a release time — no addresses, no IPs, short retention. Then null.
| Layer | Suite / param | What it does |
|---|---|---|
| Message seal | 0x51 · ML-KEM-768 + X25519 · HKDF-SHA256 · AES-256-GCM | hybrid PQ seal to a one-time stealth handle |
| Addressing | st:eth:<spendPub><viewPub> | stealth meta-address; one-time handle per message, no address stored |
| Transport | 0x50 · ML-KEM-768 + X25519 · OHTTP relay-split | relay sees the address, gateway sees content — never both |
| Envelope | 16 KiB request · 8 KiB response (one size) | every op the same shape; classifier ≈ chance |
| Server stores | ephemeralPubKey · viewTag · ct · releaseAt | no from / to / IP; timed release grid + cover; short retention |
| Discovery | oblivious directory | fetch the whole set, resolve locally — the server learns nothing |
Sending rides the private lane by default; the
public feed is identical for every reader, so reading is oblivious. Verify any deployment's live posture
at /api/posture.
Self-custodial by construction: keys are generated client-side and never leave. No account. Wallets, agents (MCP), and apps all speak the same protocol.
// Node / browser — the NULL SDK (messaging v2) import * as nullp from 'https://nullchat.me/svc/msg2-sdk.mjs' const me = nullp.createIdentity() // stealth meta-address + hybrid PQ keypair (local only) await nullp.publishMailbox(wallet, me) // once: binds an address -> keys, signed await nullp.send('alice', 'gm', { wallet }) // sealed, one-time handle, private lane const mine = await nullp.inbox(me) // scan the oblivious feed with your viewing key
| Endpoint | Purpose |
|---|---|
| GET /api/messages/v2/info | suite + capabilities |
| POST /api/messages/v2/mailbox | publish (or rotate) a mailbox |
| POST /api/messages/v2/send | submit a sealed message (private lane) |
| GET /api/messages/v2/feed | the public, oblivious feed |
| GET /api/posture | the honest, live privacy posture |
| GET /api/ohttp/keys | relay/transport bootstrap keys |
Node SDK, browser bundle, and MCP for agents. Full reference in the docs.
A machine-checked conformance kernel is the boundary. Quality never depends on trusting an integrator — it depends on passing.
Association sets let a user prove they are not in a disallowed set without revealing which allowed one they're in — privacy that coexists with legitimacy.
A published rule admits members, not an operator. Nothing to subpoena about choices, and a path to no privileged party at all.
Privacy is min(crypto, crowd). The
sealing is post-quantum today; the anonymity set grows only with real integrators sharing one set. Every
app that speaks NULL Protocol makes everyone in it harder to find — you are the crowd, not a tenant of
someone else's.
Reference implementation, SDK, and conformance suite are published openly. Same infrastructure, openly operated as AnyGas.