Overview
Anchora supports four anchoring strategies. The strategy you pick determines which chain(s) your record's Merkle root gets written to. All strategies share the same POST /v1/anchor API — switching strategy is a Settings change, not a code change.
The four strategies
1. Public — Polygon (default)
Anchors to Polygon Amoy (testnet) or Polygon Mainnet. Records can be independently verified on Polygonscan. Cost ~$0.000007 per record thanks to Merkle tree batching (256 records per on-chain transaction).
Best for: B2C apps, AI-content provenance, public attestations, anything where third parties need to verify without your help.
2. Private — Hyperledger Fabric (BYO mode)
Anchors to your own Hyperledger Fabric network. You run the peers, orderer, and CA. Anchora deploys the anchora-anchor chaincode on your channel and authenticates via your X.509 identity. No gas fees, data never leaves your network.
Best for: Banking, healthcare, defense, regulated consortiums. Any workflow where data sovereignty is non-negotiable.
3. Hybrid — Both at once
Anchors the same Merkle root to BOTH your private Fabric network AND a public EVM chain (Polygon by default) in a single batch. Internal compliance team sees the Fabric anchor; regulators or external auditors see the Polygon anchor. Same hash. Two independent attestations.
Best for: Regulated workflows that need internal control AND external verifiability. Banks, pharma, gov.
4. Custom — Any EVM RPC, any Fabric profile
Manual configuration. Point at Ethereum Mainnet, Sepolia, Besu, Quorum, or any custom EVM RPC. Or any Fabric channel + MSP combination. For advanced deployments.
Webhook delivery
Webhooks now carry chain provenance so receivers can branch on the chain type without re-querying the API.
New headers
X-Anchora-Event: ANCHORED
X-Anchora-Hash: <full hash>
X-Anchora-Package: SEPARATED | IN_PLACE | MANAGED
X-Anchora-Chain: evm | fabric ← NEW
X-Anchora-Network: polygon-amoy | fabric-byo | ... ← NEW
X-Anchora-Retry-Attempt: 0..5
EVM body example
{
"type": "ANCHORED",
"hash": "6e35efbd84a333a63e4155abdea2b8ed7e373144efb0ea52a057aa88dca2caa7",
"recordId": "507f1f77bcf86cd799439011",
"chainType": "evm",
"networkId": "polygon-amoy",
"blockNumber": 38235356,
"transactionHash": "0xd8f21871c197f1942e105ab304e2930db2c18baeb1e26a897f5d48dcaaa1597b",
"batchId": 116,
"anchoredAt": "2026-05-12T11:00:44.940Z",
"merkleProof": [],
"metadata": {}
}
Fabric body example
Note the differences: blockNumber is explicit null (Fabric has no block heights via fabric-gateway), transactionHash is the raw Fabric txID (no 0x), and batchId is a string.
{
"type": "ANCHORED",
"hash": "63e33ef9eb4b58c8f2ecd54e9ea3d1e15b8f488c3d22df8447f8951f0e2706e2",
"recordId": "507f1f77bcf86cd799439012",
"chainType": "fabric",
"networkId": "fabric-byo",
"blockNumber": null,
"transactionHash": "95cfed3ad9d5c49af57f4045cbf119e1308cb5217c11f929ed3475c7904c48d4",
"batchId": "7",
"anchoredAt": "2026-05-12T11:21:10.736Z",
"merkleProof": ["0x70bdd5472143f6773e2c0c194b75cf03307f72236d1dfdfc2ebf0a49ce0930be"],
"metadata": {}
}
Hybrid body example
A Hybrid record's webhook carries BOTH chain anchors in a single delivery — primary fields at top level, secondary inside dualAnchor.
{
"type": "ANCHORED",
"hash": "e90e818fbf...",
"chainType": "fabric",
"networkId": "fabric-byo",
"batchId": "4",
"transactionHash": "aea1e2167553e7e3...",
"blockNumber": null,
"merkleProof": [],
"dualAnchor": {
"chainType": "evm",
"networkId": "polygon-amoy",
"batchId": 114,
"blockNumber": 38228377,
"transactionHash": "0x6bc51454f711b1348e49ad...",
"merkleProof": [],
"anchoredAt": "..."
}
// ... + standard fields
}
Verification response /v1/verify
For Hybrid records, /v1/verify returns independent verification verdicts for both chains.
{
"success": true,
"verified": true,
"status": "VERIFIED",
"blockchainVerified": true,
"chainType": "fabric",
"networkId": "fabric-byo",
"batchId": "4",
"onChainMerkleRoot": "0xe90e818...",
"dualAnchor": {
"verified": true,
"chainType": "evm",
"networkId": "polygon-amoy",
"batchId": 114,
"onChainMerkleRoot": "0xe90e818..."
}
}
Reason codes inside dualAnchor: reader-unavailable (chain reader not configured) or batch-not-found (secondary anchor never completed). Use these to distinguish “couldn't check” from “actively tampered” — verified: null means unknown, verified: false means tampered.
Reliability features
Dual-anchor retry
If the secondary chain fails to anchor at batch time (RPC blip, timeout), the worker retries hourly up to 5 attempts. Primary chain anchor stands; record remains valid; secondary back-fills on success. Once filled, a webhook with the complete shape is delivered.
Cert expiry monitoring
Fabric X.509 certs eventually expire. Anchora monitors certExpiresAt on every project and emails the organization owner at 30 / 7 / 1 days before expiry. Re-import a fresh cert in Project Settings → Blockchain to re-arm the warnings.
Backward compatibility
Pre-existing EVM customers see no breaking changes. All old API fields are preserved. New fields (chainType, networkId, dualAnchor, X-Anchora-Chain, X-Anchora-Network) are additive only — old webhook receivers that ignore them keep working.