Getting Started
You will have a working authorization request running locally before the end of this guide.
Veritrellis evaluates a policy, returns a signed permit when the action is allowed, and requires you to verify that permit before your code executes the action. No valid permit, no execution.
Prerequisites
- Node.js 22 or later
- pnpm 9 or later
- Docker (recommended) or a local PostgreSQL instance
- A WorkOS account for admin authentication
1. Install and boot the stack
pnpm install
pnpm docker:up
pnpm docker:wait
pnpm db:migrate
pnpm seed
pnpm dev
pnpm seed prints a workspace ID and a sandbox API key. Keep those — you will use them in the next step.
After pnpm seed you will see something like:
Workspace: ws_01HXXX...
API key: vt_sandbox_01HYYY...
2. Send your first authorization request
Paste the values from pnpm seed into the request below:
curl -sS http://localhost:3001/v1/authorize \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"environment": "sandbox",
"action_type": "issue_refund",
"resource_ref": "cus_123",
"payload": {
"customer_id": "cus_123",
"amount": 50,
"currency": "EUR",
"reason": "customer request"
}
}'
What to expect
The seeded policy grants refunds up to €100 directly and requires human approval above that threshold:
| Amount | Decision | Response includes |
|---|---|---|
<= 100 | allowed | permit JWT |
> 100 | pending_approval | request_id for polling |
A direct-allow response looks like this:
{
"decision": "allowed",
"request_id": "req_01HXXX...",
"permit": "eyJhbGciOiJFUzI1NiJ9..."
}
3. Verify the permit before executing
Never skip this step. A permit that cannot be verified should halt execution.
import { verifyPermit } from "@veritrellis/sdk-node";
const claims = await verifyPermit({
permitJwt: result.permit,
workspaceId: process.env.VERITRELLIS_WORKSPACE_ID!,
issuer: "https://api.veritrellis.ai"
});
// claims.action_type === "issue_refund"
// claims.sub === "req_01HXXX..."
// Execute your action here — only when claims are valid
verifyPermit checks the signature via the workspace JWKS endpoint, validates the issuer, confirms audience context, and rejects expired permits. It throws on any verification failure.
4. Handle a pending-approval response
When decision is pending_approval, poll until the request resolves:
curl -sS "http://localhost:3001/v1/permits/REQUEST_ID" \
-H "Authorization: Bearer YOUR_API_KEY"
| Status code | Meaning |
|---|---|
200 | Approved — response includes permit |
202 | Still waiting for approval |
409 | Terminal state with no permit (denied or expired) |
5. Open the admin app
http://127.0.0.1:3000 — complete onboarding to create a workspace, review policies, approve pending requests, and inspect audit events.
The seeded workspace runs in the sandbox environment. All behavior is identical to production except that permit JWTs are issued against sandbox JWKS. Keep environment: "sandbox" in your API requests while testing.
Next steps
- Node SDK guide — full
createClient,authorizeRequest, and middleware reference - Policy and permits — decision model, approval flows, permit claims
- REST API overview — base URL, authentication, and endpoint inventory
- Connectors — integrate HubSpot, Intercom, or Zendesk