Product · Receipt Verifier
TestingFree · public · no authDon't take our word for it.
Check the signature yourself, with your own tools.
Run npx @synoi/verify <receipt_id> to re-run the signature math on your own machine; it fetches the receipt and key from our gateway, which proves the signature is internally consistent. To trust no one, verify an exported bundle or check the signature in your own code against a key you hold out of band: then nothing is sent to us. Prefer a quick lookup instead? Paste a receipt ID at verify.synoi.systems and the gateway confirms it for you server-side today. That is a convenience, not an independent reperformance.
Anatomy of a Decision Receipt
Every field in the schema is documented. The signed body is verifiable.
The receipt below is a sample of the canonical body returned by the verifier. The signature is computed over the byte-exact canonical JSON encoding of this body. Every field is annotated. None of it is proprietary; the format spec is open and standards-based.
version 1
receipt_id rcpt_8b3c9f12...
tenant_id acme-prod
action_class tool.deploy
action_desc terraform apply
risk_level high
decision allow
mode enforce
approver a.rivera
approval_surface mobile
elapsed_ms 14_312
model claude-opus-4-7
oid_hex a3f8c21d9b4e...
recorded_at 2026-05-14T14:32:01Z
signature
3a9f2b1c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a (Ed25519 + ML-DSA-65)
receipt_id
Globally-unique. Embeds in the verify URL. Never reused across tenants.
action_class · action_desc · risk_level
What was attempted, in human-readable form. Tenant policy decides the risk class; the receipt reflects the policy decision.
decision
One of: allow · deny · hitl_approved · hitl_denied · modify. The exit status of the governance evaluation.
approver · approval_surface
If HITL was required, who approved it and on what surface (mobile / slack / sms / desktop / email).
oid_hex
The content-addressed Object Identifier (OID): SHA-256 of the canonical body. Same content, same OID, across providers and time.
signature
Hybrid Ed25519 (RFC 8032) + ML-DSA-65 (NIST FIPS 204) over the canonical JSON encoding. Public key published. Verify offline with any standard library.
Why a public verifier matters
Verifiability is only credible when it doesn't require trusting the vendor.
Third-party verifiability
An auditor, a customer, or a regulator can check any receipt without a SynOI account, an API key, or a sales call. Verification is a public key plus standard math, run offline against a key you hold (bundle mode or your own Ed25519 library). There is no SaaS in the verification path.
Offline checking
The published public key is small and stable. Auditors can mirror it once, then verify receipts offline forever after. The signature mathematics doesn't require the issuer to be online.
Standards-based crypto
Ed25519 (RFC 8032) and ML-DSA-65 (NIST FIPS 204). Any major language ecosystem has libraries for Ed25519: Rust, Go, Python, Node, Java, C++, Swift, .NET. We don't invent the math.
Tamper-evident forever
The signature is over the canonical encoding. Any mutation (even whitespace) invalidates it. A receipt that verifies today verifies in five years, with the same key, regardless of what's happened to SynOI in the interim.
Survives vendor risk
The pitch is honest about this: if SynOI is acquired, pivots, or vanishes, the receipts your team produced under SynOI's governance keep verifying. The crypto doesn't care who owns the company.
Independent of receipt issuer
The verifier doesn't know about SynOI specifically. Any party can publish an Ed25519 + ML-DSA-65 public key pair and issue compatible receipts. The protocol is open; the verifier is a reference implementation, not a moat.
Verify in your own code
Three languages, three libraries, all standard.
Receipts are hybrid-signed: BOTH the classical Ed25519 signature and the post-quantum ML-DSA-65 signature must verify. The snippets below show the classical Ed25519 half over the canonical JSON (RFC 8785 JCS) body, for illustration in your own language. For a complete hybrid check in one step, use the reference library: npx @synoi/verify <receipt_id> or @synoi/verify-core in your own code.
Node · @noble/ed25519 (classical half)
import { ed25519 } from '@noble/curves/ed25519'
const body = canonicalJson(receipt) // RFC 8785 JCS
const sig = receipt.signature.ed25519
const pubKey = await fetchSynoIKey()
const ok = ed25519.verify(sig, body, pubKey)
// Full verification also requires the ML-DSA-65 signature to pass;
// see @synoi/verify-core for the hybrid check.Python · cryptography (classical half)
from cryptography.hazmat.primitives.asymmetric.ed25519 \ import Ed25519PublicKey body = canonical_json(receipt) # RFC 8785 JCS sig = receipt['signature']['ed25519'] pub = fetch_synoi_key() Ed25519PublicKey.from_public_bytes(pub).verify(sig, body) # Full verification also requires the ML-DSA-65 signature to pass; # use the reference verifier for the hybrid check.
Rust · ed25519-dalek (classical half)
use ed25519_dalek::{Signature, VerifyingKey, Verifier};
let body = canonical_json(&receipt); // RFC 8785 JCS
let sig = Signature::from_bytes(&receipt.signature.ed25519);
let pk = VerifyingKey::from_bytes(&fetch_key())?;
pk.verify(&body, &sig)?;
// Full verification also requires the ML-DSA-65 signature to pass;
// use the reference verifier for the hybrid check.The SynOI public key is published today at gateway.synoi.systems/verify/pubkey and rotates on a documented schedule. Old keys remain valid for receipts they signed; the rotation policy is documented in /security. A canonical well-known path at oid.synoi.systems is planned, not yet deployed.
Verifiability you don't have to take our word for.
The crypto is free, standard, and runs without us: @synoi/verify or any Ed25519 + ML-DSA-65 library gives you the answer yourself. Or use verify.synoi.systems for a quick lookup by receipt ID, confirmed server-side today, then point a real workflow at the gateway and check your own receipts.