Integration Guide
How to commit artifacts, verify proofs, and integrate BitGraph into your application. Connecting an AI agent instead? See MCP. Building a no-code workflow? See Zapier and Make.
Quick start: commit via API
Hash your artifact locally, then send only the digest to the BitGraph endpoint:
# 1. Hash your file
DIGEST=$(openssl dgst -sha256 -binary myfile.pdf | base64)
# 2. Send to BitGraph endpoint
curl -X POST https://bitgraph.ing/api/commit \
-H "Content-Type: application/json" \
-d '{
"digests": [{
"digestB64": "'$DIGEST'",
"hashAlg": "sha256"
}],
"chainId": "bitgraph:main",
"metadata": {
"source": "my-app"
}
}'TypeScript / JavaScript
// Hash locally
const bytes = new Uint8Array(await file.arrayBuffer());
const hashBuf = await crypto.subtle.digest("SHA-256", bytes);
const digestB64 = btoa(String.fromCharCode(...new Uint8Array(hashBuf)));
// Commit through the BitGraph endpoint (with optional attribution)
const resp = await fetch("https://bitgraph.ing/api/commit", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
digests: [{ digestB64, hashAlg: "sha256" }],
chainId: "bitgraph:main",
attribution: { name: "Jane Doe", title: "Project Photo" },
metadata: { source: "my-app", fileName: file.name },
}),
});
const [proof] = await resp.json();
// proof is a complete BitGraphProof JSON object
console.log(proof.commit.counter);
console.log(proof.slotAllocation); // causal slot record
console.log(proof.attribution); // signed creator metadataBatch commit
Send multiple digests in one request. The enclave allocates a slot and commits each digest sequentially. If using actor-bound proofs (passkey), all proofs in the batch receive actor identity.
const resp = await fetch("https://bitgraph.ing/api/commit", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
digests: [
{ digestB64: digest1, hashAlg: "sha256" },
{ digestB64: digest2, hashAlg: "sha256" },
{ digestB64: digest3, hashAlg: "sha256" },
],
chainId: "bitgraph:main",
attribution: { name: "Jane Doe" },
metadata: { source: "my-app", batchId: "abc123" },
}),
});
const proofs = await resp.json();
// proofs[0], proofs[1], proofs[2] - one per digestVerify a proof
import { verify } from "@mikeargento/bitgraph";
const result = await verify({
proof: myProof,
bytes: originalFileBytes,
trustAnchors: {
requireEnforcement: "measured-tee",
allowedMeasurements: ["ac813febd1ac4261..."],
requireAttestation: true,
requireAttestationFormat: ["aws-nitro"],
},
});
if (result.valid) {
console.log("Proof verified successfully");
} else {
console.error("Verification failed:", result.reason);
}Verify over HTTP
For callers that cannot run a verifier: no-code automation platforms, shell scripts, anything without a JavaScript runtime. It delegates to the same package, so this endpoint and the offline verifier cannot disagree.
DIGEST=$(openssl dgst -sha256 -binary myfile.pdf | base64)
curl -X POST https://bitgraph.ing/api/verify \
-H "Content-Type: application/json" \
-d '{"digest": "'$DIGEST'"}'
# {
# "verified": true,
# "status": "valid",
# "artifactBinding": "checked",
# "onRecord": true,
# "counter": "7910",
# "epochId": "...",
# "proof": { ... }
# }Send proof to check a proof you are carrying rather than whatever the ledger currently holds, and both together to check that the proof describes that exact file. Add allowedMeasurements to reject anything not signed by a specific enclave build. The digest may be hex or base64, either form.
Read artifactBinding, not just verified. checked means the digest you sent matches the one inside the proof. not-checked means the proof is sound but nothing tied it to a file, which is what you get from a proof with no digest alongside it. mismatch means the proof is genuine and is for different bytes. A verdict from the service that issued the proof is a convenience; the proof comes back whole so you can redo the check yourself, which is the result that counts.
Enclave info
# Get enclave public key and measurement
curl https://nitro.occproof.com/key
# Response:
# {
# "publicKeyB64": "...",
# "measurement": "ac813febd1ac4261...",
# "enforcement": "measured-tee"
# }Important notes
- • Files are never uploaded. Only the SHA-256 digest crosses the network.
- • Commit via bitgraph.ing. The site endpoint records every causal position of a file for later lookup. Committing to the enclave host directly skips that index, and your recordings will not be discoverable by digest.
- • The proof is portable. Store it alongside the artifact or in a separate system.
- • Verification is offline. No API calls needed to verify. Just the public key and original bytes.
- • Pin measurements. For production, always pin allowedMeasurements and require attestation.
- • Track counters. Store the last accepted counter value to prevent replay.
- • Causal slots. Every proof includes a pre-allocated slot that proves the enclave committed to a counter position before seeing the artifact hash.
- • Attribution is signed. Name, title, and message in the attribution field are covered by the Ed25519 signature and cannot be tampered with.