Documentation
5-minute quickstart
Meter your first user in five minutes. You need a ProtAI account and an API key — both free.
1. Install the SDK
JavaScript / TypeScript
npm install @protai/sdkPython
pip install protai2. Create an API key
In the dashboard, create a project, open API Keys, and create a key. It starts with ptk_ and is shown once — copy it immediately. Send it as Authorization: Bearer <key>.
3. Define a meter
Open Meters and create one — e.g. slug tokens, unit “Tokens”, monthly quota 100. The slug is what you reference in code.
4. Wrap your AI call
Three lines. Check before you spend, report after:
import { ProtAI } from "@protai/sdk";
const protai = new ProtAI(process.env.PROTAI_API_KEY!);
const check = await protai.check(userId, "tokens");
if (!check.allowed) return showUpgrade(check); // reason: 'insufficient' | 'killed'
const usage = await openai.chat.completions.create({ /* ... */ });
await protai.report(userId, "tokens", usage.usage.total_tokens);5. Set your guardrails
Open Alerts and add an 80% threshold — you'll be emailed before a user burns through quota. If spend ever runs away, the kill-switch on the project overview denies every check instantly.
Method reference
Base URL: https://protai.co.uk (use http://localhost:3000 locally). All requests need the Authorization: Bearer ptk_… header. Rate limit: 100 requests/minute per key.
checkPOST /api/v1/checkCall before spending tokens on a user. Returns whether the spend is allowed under their balance, quota, and your kill-switch.
| end_user_id | string — your user's ID (any stable identifier) |
| meter | string — meter slug, e.g. "tokens" |
| units | number, optional — default 1 |
reportPOST /api/v1/reportCall after the AI call completes, with what was actually spent. Deducts from the user's balance and writes a ledger entry.
| end_user_id | string |
| meter | string — meter slug |
| units | number — actual units consumed |
balanceGET /api/v1/balance?end_user_id=&meter=Read the current credit state for a user on a meter. Useful for rendering “you have X left” UI.
| end_user_id | query string |
| meter | query string — meter slug |
Response shapes
// check → 200
{ "allowed": true, "balance": 4820, "quota": 10000 }
// or, when denied:
{ "allowed": false, "balance": -120, "quota": 10000, "reason": "insufficient" }
// or when the kill-switch is on:
{ "allowed": false, "balance": 4820, "quota": 10000, "reason": "killed" }
// report → 200
{ "balance": 2980 }
// balance → 200
{ "balance": 2980, "quota": 10000, "period": "2026-10" }Overage behaviors
Each meter decides what happens when a user exceeds their monthly quota:
Hard block
check() returns allowed: false with reason insufficient. Show an upgrade prompt. Best for free tiers.
Allow + alert
Usage continues (balance can go negative) and you're emailed immediately. Best for paying customers you never want to interrupt mid-task.
Selling credit packs
Define packs in the dashboard (Credit Packs), then sell them from your own backend — call the pack checkout endpoint with your ProtAI API key and redirect the buyer to the returned Stripe URL. Completed purchases credit their balance automatically:
curl -X POST https://protai.co.uk/api/v1/packs/checkout \
-H "Authorization: Bearer ptk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"pack_id":"PASTE_PACK_ID","meter_slug":"tokens",
"end_user_id":"user_123"}'
// → { "url": "https://checkout.stripe.com/…", "session_id": "cs_…" }No SDK? Use plain HTTP
Any language can call the API directly:
curl -X POST https://protai.co.uk/api/v1/check \
-H "Authorization: Bearer ptk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"end_user_id":"user_123","meter":"tokens","units":1}'Ready to meter your first user?
Create a free account