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.