Reference
Artifact Anchoring
Prove an artifact existed exactly as-is at a moment in time, and make any later tampering detectable. A contract, an invoice, a medical prescription, an insurance claim, an image, an audio recording: you hash it locally, register only the sha256, and the registration joins the same tamper-evident audit chain as Fidacy's payment verdicts, checkpointed to the Bitcoin blockchain. The file itself never leaves your machine.
What this is, and what it is not
Anchoring answers one question with cryptographic force: has this exact content changed since it was registered? If the hash of the file in front of you matches the anchored record, the content is byte-for-byte what it was then, and the Bitcoin checkpoint puts a floor under “then” that no one, including Fidacy, can quietly rewrite. That is what a dispute, an audit or a fraud investigation actually needs from a document trail.
It is not content analysis. Fidacy does not read, scan or judge the artifact, and cannot: it only ever sees the hash. That is also why it is safe for regulated content. A prescription or a claim file carries heavy PII; the sha256 of it carries none.
Register an artifact
Authenticated with your engine API key (scope assess:write). Hash the file locally, then:
curl -s https://api.fidacy.com/v1/artifacts \
-H "Authorization: Bearer $FIDACY_ENGINE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sha256": "'"$(shasum -a 256 contract.pdf | cut -d\ -f1)"'",
"kind": "contract",
"label": "MSA-2026-014"
}'kind is one of contract, invoice, prescription, claim, document, image, audio, video, conversation, custom. label is an optional short reference (an invoice number, a case id). Do not put PII in it.
The response is your receipt:
{
"artifactId": "c2e3e05f-…",
"kind": "contract",
"sha256": "9f2a…",
"subject": "agent:default",
"ts": "2026-07-03T08:17:41.512Z",
"digest": "e3b0…",
"audit": { "seq": 140, "hash": "189a990b…" },
"anchor": { "status": "queued" },
"receipt": "<compact JWS, EdDSA>"
}receipt. It is a signed JWS over the canonical registration payload, verifiable offline against the engine JWKS at /.well-known/jwks.json, exactly like a verdict's riskPayloadJws.The anchor lifecycle
- ·
queued: the registration is on the hash chain, waiting for the next checkpoint run. - ·
anchoring: a checkpoint covering your record was submitted to the OpenTimestamps calendars. - ·
confirmed: the checkpoint's Merkle root is in a Bitcoin block. Rewriting your record now means rewriting Bitcoin.
Check status any time:
The second form answers the verification question directly: has this exact content been anchored by my account? Hash the file you were handed, look it up. No match where you expected one means the file changed since anchoring. That mismatch is the tampering signal.
Verify offline, without trusting Fidacy
The receipt is reproducible from public parts:
- ·The chain digest is
sha256(JCS({v:"fidacy.artifact.v1", artifactId, kind, sha256, subject, ts}))(JCS = RFC 8785 canonical JSON). Recompute it from the receipt fields and compare withdigest. - ·The receipt JWS verifies against the public JWKS (EdDSA, by
kid), same recipe as Verify a Payload. - ·The audit record at
audit.seqcarries that digest inside the global hash chain, and its checkpoint's Merkle root is in a public Bitcoin transaction. The inclusion proof is available via the anchor API, and the whole chain head is public.
Conversation receipts
A chatbot session is an artifact too, and for insurers, hospitals and banks it is the one that ends up in disputes. The @fidacy/session SDK hashes every message into a running chain locally (the transcript never leaves your infrastructure), anchors the final digest at session close with kind: conversation, and gives you a verify link to hand the customer.
import { createSession } from "@fidacy/session";
const session = createSession({ label: "case-4711" });
session.add("user", "I want to file a claim for water damage.");
session.add("assistant", "I can help. When did it happen?");
const receipt = await session.anchor({ apiKey: process.env.FIDACY_ENGINE_API_KEY });
session.verifyUrl(); // https://fidacy.com/verify?sha256=… ← give this to the customerThe transcript digest recipe is public (documented in the package README): anyone holding the exported transcript recomputes the hash offline with digestTranscript(messages) and checks it on the verify page. Editing one character of one message breaks the match.
Public verification API
The consumer side needs no account and no key. Both endpoints are open and CORS-enabled; the verify page is built on them.
Returns whether the hash was anchored, plus kind, timestamp, chain position and Bitcoin checkpoint state per record. No org, label or subject data is ever exposed.
Body { "receipt": "<compact JWS>" }. Verifies the EdDSA signature against the JWKS, recomputes the digest recipe for internal consistency, and returns the current anchor state of the covered chain record. A forged or altered receipt returns { "valid": false }.
From an agent (MCP and OpenClaw)
The @fidacy/mcp server (0.1.15+) and the native OpenClaw plugin (0.1.9+) ship two tools: anchor_artifact and check_artifact. Both take a file path, hashed locally with streaming SHA-256 so even a large video never loads into memory, or a precomputed sha256. Your agent can anchor the contract it just generated, or verify the invoice it was just handed, as a single tool call.
# the agent side of a dispute-proof document flow
anchor_artifact { "path": "./contracts/msa-2026-014.pdf", "kind": "contract", "label": "MSA-2026-014" }
# … months later, when the counterparty presents "the same" contract:
check_artifact { "path": "./inbox/msa-2026-014.pdf" }
# NOT FOUND → the bytes changed since anchoring. That is your answer.