This is a complete deployment walkthrough. By the end, you'll have:
- A running Visionality gateway on Render
- A Neon Postgres database with all 13 migrations applied
- A Vercel-hosted operator dashboard
- Your first Spend Token minted
- A real API call routed through the gateway and visible in the ledger
Estimated time: 28 minutes on a clean start. 45 minutes if you're configuring PII rules and allocation rules at the same time.
Prerequisites: a Render account, a Neon account, a Vercel account, and a Clerk account. All four have free tiers that cover everything in this walkthrough.
Step 1: Fork and clone the repository (3 min)
git clone https://github.com/servicevision/AICostControl
cd AICostControl
pnpm install
All packages install. The workspace has 19 packages but pnpm handles the graph — this should take under two minutes on a decent connection.
Step 2: Provision a Neon database (5 min)
In the Neon console:
- Create a new project:
visionality-prod(or your org name) - Create a database:
visionality - Copy the connection string from the "Pooled connection" tab — it looks like
postgres://user:[email protected]/visionality?sslmode=require - Create a second role for the application:
acc_app. In the Neon SQL editor:
CREATE ROLE acc_app WITH LOGIN PASSWORD 'your-strong-password';
GRANT CONNECT ON DATABASE visionality TO acc_app;
You'll use the acc_app role for the running application. The owner role runs migrations.
Step 3: Run migrations (3 min)
In your local clone, with the owner connection string:
DATABASE_URL="postgres://owner:password@.../visionality?sslmode=require" \
pnpm --filter @acc/db migrate
This runs all 13 migrations in order. The output ends with a confirmation that append-only enforcement is in place:
✓ Migration 0001_initial complete
...
✓ Migration 0011_revoke_on_audit complete
✓ Smoke check: UPDATE privilege absent on audit_log ✓
✓ 13 migrations applied, 0 errors
The smoke check is not optional — it's the deploy-time verification that your audit tables are genuinely append-only, not just supposed to be.
Step 4: Deploy the gateway to Render (8 min)
In the Render dashboard, create a new Web Service:
- Source: Your forked GitHub repo
- Root directory:
services/gateway - Build command:
pnpm install && pnpm build - Start command:
node dist/server.js - Instance type: Starter ($7/mo) is enough for the initial deployment
Environment variables:
DATABASE_URL=postgres://acc_app:password@.../visionality?sslmode=require
NODE_ENV=production
CLERK_SECRET_KEY=sk_live_...
ACC_VALIDATOR_HMAC=<random 32-byte base64url string>
For ACC_VALIDATOR_HMAC, generate a random value:
node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))"
Deploy. The first build takes 3–4 minutes. When it's live, the health endpoint responds:
curl https://your-gateway.onrender.com/healthz
# {"status":"ok","version":"...","db":"connected"}
If db shows connected, your Neon connection is working.
Step 5: Deploy the dashboard to Vercel (5 min)
In the Vercel dashboard, import the same repo:
- Root directory:
apps/dashboard-next - Framework: Next.js (auto-detected)
Environment variables:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_...
CLERK_SECRET_KEY=sk_live_...
DATABASE_URL=postgres://acc_app:password@.../visionality?sslmode=require
NEXT_PUBLIC_GATEWAY_URL=https://your-gateway.onrender.com
Deploy. Vercel builds Next.js fast — usually under 2 minutes. When it's done, your dashboard is live at your-project.vercel.app.
Sign in with Clerk. The first sign-in creates your operator account.
Step 6: Mint your first Spend Token (3 min)
In the dashboard, navigate to Spend Tokens → New Token.
Fill in:
- Organization: your org name
- Project: a project name (e.g.,
search-feature) - Allowed models:
claude-3-5-haiku-20241022(or whichever model you're testing with) - Spend limit:
5.00(USD — generous for a test) - TTL: 24 hours
Submit. The dashboard shows:
- Token ID:
st_... - Validator secret: shown once, copy it now
Copy both. The validator secret is hashed and stored — you can't retrieve it again.
Step 7: Route a real request through the gateway (2 min)
With the Anthropic SDK, change one environment variable in your test application:
ANTHROPIC_BASE_URL=https://your-gateway.onrender.com
Or test directly with curl:
curl -X POST https://your-gateway.onrender.com/v1/messages \
-H "Content-Type: application/json" \
-H "x-api-key: your-anthropic-key" \
-H "x-spend-token: st_..." \
-H "x-validator: your-validator-secret" \
-d '{
"model": "claude-3-5-haiku-20241022",
"max_tokens": 100,
"messages": [{"role": "user", "content": "Say hello in one sentence."}]
}'
The gateway intercepts the request, validates the Spend Token, reserves estimated cost, forwards to Anthropic, settles the actual cost, and returns the response.
Step 8: Verify in the dashboard (1 min)
In the dashboard, navigate to Request Explorer. Your request appears with:
- Timestamp
- Model used
- Token counts (input + output)
- Cost in USD
- Spend token ID
- Reserve and settle amounts
Navigate to Spend Tokens. Your token shows the remaining balance, reduced by the cost of your test request.
That's the full loop: request in → gateway validates → ledger records → dashboard shows.
Common issues
Gateway health check fails with db: disconnected
Check that your DATABASE_URL uses the acc_app role, not the owner role. The owner role may have a password that contains special characters requiring URL encoding.
402 on first request
Check that the model in your request matches the allowed model list in your Spend Token. Model names must be exact: claude-3-5-haiku-20241022, not claude-haiku.
Dashboard shows no data after a successful API call
Check that NEXT_PUBLIC_GATEWAY_URL in your Vercel env vars points to your Render service URL without a trailing slash.
Migrations fail on step 11
Step 11 is the REVOKE migration for append-only enforcement. It requires that the acc_app role exists before the migration runs. Confirm you created the role in Step 2 before running migrations.
What's next
You have a running gateway. From here:
- Allocation rules: In the dashboard, navigate to Settings → Allocation Rules and add a rule mapping your org/project to a GL code
- PII policy: Navigate to Settings → PII Policy and configure your project's detection mode (block, obfuscate, or log)
- Anomaly detection: Running automatically — check the Anomaly Inbox after a day of real traffic to see if any detectors fire
The deploy guide in the repository covers each of these in detail. For anything else, request a demo and we'll walk through it live.
Stuck on any step? Request a demo → and we'll deploy it together.