Start here
SDKs
Public packages: @zerogrant/browser, @zerogrant/node, @zerogrant/react, @zerogrant/webhook-contracts (restricted npm org publish via Changesets / sdk-publish workflow). Locally: make pack-sdks dry-run. Secret keys stay on the server. Publishable keys and intent client_secret are what the browser may hold.
$ npm install @zerogrant/browser @zerogrant/node
install.sh
npm install @zerogrant/browser @zerogrant/node @zerogrant/webhook-contracts
# optional React bindings
npm install @zerogrant/reactNode (secret key)
server.ts
import { ZeroGrant } from "@zerogrant/node";
const zg = new ZeroGrant({
apiKey: process.env.ZEROGRANT_SECRET_KEY!, // zg_test_...
baseUrl: "https://api.zerogrant.io",
});
const intent = await zg.clearanceIntents.create({
customerReference: "demo_user",
purpose: "sandbox_clearance",
});
// intent.client_secret -> pass to browser Element (shown once)
await zg.policies.list();
await zg.complianceEvidence.download();
await zg.billing.invoices();Browser (publishable key)
client.ts
import { loadZeroGrant } from "@zerogrant/browser";
const zeroGrant = await loadZeroGrant(
process.env.NEXT_PUBLIC_ZEROGRANT_PUBLISHABLE_KEY!, // pk_test_...
{ apiBaseUrl: "https://api.zerogrant.io" },
);
const clearance = zeroGrant.elements.create("clearance", {
clientSecret: intentClientSecret,
onSucceeded: (result) => console.log(result),
});
clearance.mount("#zerogrant-clearance");Keys
Create secret and publishable keys in the dashboard (or POST /v1/api-keys). The secret plaintext is returned once at create time; list and evidence endpoints never re-expose it.
Element session routes: GET /v1/element/session, POST /v1/element/session/approve, POST /v1/element/session/decline (Bearer ci_secret_...). Publishable config: GET /v1/element/config.