Forseti docs
SDK quickstart
import { Forseti } from "@forseti/sdk";
const f = new Forseti();
const hash = await f.log({
id: crypto.randomUUID(),
timestamp: new Date().toISOString(),
agentId: "billing-agent",
organizationId: "<your org uuid>",
action: "approve.refund",
payload: { amount: 12.50, currency: "USD" },
});
// hash is a 64-char SHA-256 over the canonical JSON of the event.
// At batch time, the SDK builds a Merkle tree across N events and
// the batcher anchors the root to Chia DataLayer.Verify API
POST /v1/verify
curl -X POST https://api.forseti.<your-domain>/v1/verify \
-H 'authorization: Bearer forseti_<your-key>' \
-H 'content-type: application/json' \
-d '{
"leaf": "<sha256 of the event>",
"proof": { ... },
"expectedRoot": "<merkle root hex>"
}'GET /v1/event/:id/proof
curl https://api.forseti.<your-domain>/v1/event/<event-id>/proof \
-H 'authorization: Bearer forseti_<your-key>'Both endpoints are rate-limited per API key. The response includes an `x-ratelimit-remaining` header. Rate-limit window: 60 req / minute by default; tune via `RATE_LIMIT_PER_MIN` on the deployment.
Independent re-verification
The whole point of Forseti is that you don't need to trust us. Every Merkle root is anchored to a Chia DataLayer store via a `batch_update` transaction. Anyone with the store id can fetch the on-chain value with `chia data get_kv` and independently confirm the root. Forseti can vanish tomorrow and the audit trail still verifies.