Quickstart
TokenGuard is an OpenAI-compatible proxy. Replace your OpenAI API key with a TokenGuard key — no other code changes required. Every request is logged and your budgets are enforced automatically.
- Sign up and create a project in the dashboard.
- Copy the
tg_live_…key shown after creation. - Set
OPENAI_API_KEY=tg_live_…in your app. - Set
OPENAI_BASE_URL=https://tokenguard.eu/proxy/openai/v1in your app. - Send requests as normal — TokenGuard handles the rest.
Create a project
A project is the unit of access control in TokenGuard. Each project has its own API key, daily budget, monthly budget, fallback model, and alert email.
- Go to Dashboard → Projects.
- Click New project.
- Set a name, daily budget (USD), and monthly budget (USD).
- Optionally set a fallback model and alert email.
- Click Create project — your key is shown once.
Copy your key
The full API key is shown only once immediately after project creation or key regeneration. Copy it and store it securely. The dashboard shows only a prefix (e.g. tg_live_abc123…).
You can regenerate the key at any time from the project detail page. The old key is immediately invalidated.
Proxy endpoint
The proxy is OpenAI-compatible. Use the same request body as you would for OpenAI.
Base URL
https://tokenguard.eu/proxy/openai/v1Authentication
Pass your TokenGuard key in the x-tokenguard-key header. Do not put it in Authorization: Bearer … — that slot can carry your upstream OpenAI key if you manage keys per-project.
Supported endpoints
POST https://tokenguard.eu/proxy/openai/v1/chat/completionsMulti-provider
TokenGuard proxies OpenAI, Anthropic Claude, and Google Gemini — all through the same project key, budget, and dashboard.
OpenAI
curl -X POST https://tokenguard.eu/proxy/openai/v1/chat/completions \
-H "Content-Type: application/json" \
-H "x-tokenguard-key: tg_live_YOUR_KEY" \
-d '{
"model": "gpt-4o-mini",
"messages": [{ "role": "user", "content": "Hello" }]
}'Anthropic Claude
curl -X POST https://tokenguard.eu/proxy/anthropic/v1/messages \
-H "Content-Type: application/json" \
-H "x-tokenguard-key: tg_live_YOUR_KEY" \
-d '{
"model": "claude-3-5-haiku-latest",
"max_tokens": 300,
"messages": [{ "role": "user", "content": "Hello" }]
}'Google Gemini
curl -X POST https://tokenguard.eu/proxy/gemini/v1beta/models/gemini-2.0-flash/generateContent \
-H "Content-Type: application/json" \
-H "x-tokenguard-key: tg_live_YOUR_KEY" \
-d '{
"contents": [{ "parts": [{ "text": "Hello" }] }]
}'Provider keys. Each provider key can be set per-project (encrypted at rest) or via a backend environment variable fallback (OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY).
Cost estimates. Token counts and costs are approximations based on public pricing. Actual charges may differ due to promotions, batch discounts, or API updates. Always verify with your provider's billing dashboard.
Fallback model. The fallback model applies across all providers. If you set a fallback that belongs to a different provider than the original request, the proxy will forward it and let the target provider respond.
Environment variables
Update these two variables in your application — nothing else changes.
# .env
OPENAI_API_KEY=tg_live_YOUR_KEY_HERE
OPENAI_BASE_URL=https://tokenguard.eu/proxy/openai/v1The OpenAI SDK and most wrappers (LangChain, LlamaIndex, etc.) respectOPENAI_BASE_URL. No code changes needed.
Node.js example
Using the official OpenAI Node SDK:
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'tg_live_YOUR_KEY_HERE',
baseURL: 'https://tokenguard.eu/proxy/openai/v1',
defaultHeaders: {
'x-tokenguard-key': 'tg_live_YOUR_KEY_HERE',
},
});
const response = await client.chat.completions.create({
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: 'Say hello' }],
});
console.log(response.choices[0].message.content);curl example
curl -X POST https://tokenguard.eu/proxy/openai/v1/chat/completions \
-H "Content-Type: application/json" \
-H "x-tokenguard-key: tg_live_YOUR_KEY_HERE" \
-d '{
"model": "gpt-4o-mini",
"messages": [{ "role": "user", "content": "Say hello" }]
}'Budget behavior
TokenGuard enforces daily and monthly spend limits per project.
- Under 80% — requests flow normally to the configured model.
- 80–100% — if a fallback model is configured, requests are automatically routed to it instead.
- Over 100% — proxy returns
HTTP 429with a descriptive error body:{ "error": { "code": "BUDGET_EXCEEDED", "message": "Daily spend limit reached" } } - Reset — daily budgets reset at UTC midnight; monthly budgets reset on the 1st of each month.
Fallback model
Set a fallback model in the project settings. When spend crosses 80% of either the daily or monthly budget, TokenGuard automatically routes new requests to the fallback model instead of the requested model.
Example: primary model gpt-4o, fallback gpt-4o-mini. At 80% budget the proxy silently switches to mini — your app keeps working, your bill shrinks.
The usage log records both originalModel and finalModel and flags requests with wasFallback: true.
Team & Workspaces
TokenGuard supports multi-user team workspaces. Each workspace has its own projects, budget, API keys, and members. You can be a member of multiple workspaces.
- Owner — full control: rename, delete workspace, manage all members, invite anyone.
- Admin — can invite/cancel invites, manage non-owner members, view audit log.
- Member — read and use projects; cannot invite or manage team.
How invites work
- An owner or admin sends an invite from Dashboard → Team.
- If SMTP is configured, the invitee receives an email with a link.
- The invitee visits
/invites/TOKENand signs in (or creates an account). - After auth, they click Accept — they are added to the workspace immediately.
- Invites expire after 7 days. Expired invites can be resent.
SMTP setup
Without SMTP, invite tokens still work — users can follow the invite link directly. Configure SMTP to deliver invite emails automatically.
# Backend .env
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USER=apikey
SMTP_PASS=SG.your_sendgrid_key
SMTP_FROM=noreply@yourdomain.com
FRONTEND_URL=https://yourdomain.comFRONTEND_URL is used to build the accept link in invite emails. Set it to your public frontend URL.
Role permissions
| Action | Owner | Admin | Member |
|---|---|---|---|
| View workspace | ✓ | ✓ | ✓ |
| Create/manage projects | ✓ | ✓ | ✓ |
| Invite members | ✓ | ✓ | ✗ |
| Cancel invites | ✓ | ✓ | ✗ |
| Change member role | ✓ | ✗ | ✗ |
| Remove members | ✓ | ✗ | ✗ |
| Rename workspace | ✓ | ✗ | ✗ |
| Delete workspace | ✓ | ✗ | ✗ |
| View audit log | ✓ | ✓ | ✗ |
| Manage billing | ✓ | ✗ | ✗ |
Audit log
Every significant workspace action is recorded in the audit log. Owners and admins can view it at Dashboard → Team → Audit log.
Tracked events:
workspace_createdworkspace_updatedworkspace_deletedmember_invitedinvite_acceptedinvite_cancelledmember_role_changedmember_removedbilling_plan_changedproject_createdprovider_keys_updated
Workspace deletion
Workspace deletion is owner-only and uses soft-delete. The workspace is flagged with a deletedAt timestamp — it disappears from all listings immediately, but data is retained in the database for recovery if needed.
- Cannot delete your only workspace — you must always have at least one.
- Your account is never deleted — only the workspace and its associated data.
- Confirmation required — type the exact workspace name to confirm in the UI.
Reporting
TokenGuard provides workspace-scoped analytics endpoints and a monthly digest email. All analytics require JWT authentication and respect workspace isolation.
Analytics endpoints
All routes under GET /api/analytics/* accept these query parameters:
from— ISO date string (defaults to 30 days ago)to— ISO date string (defaults to now)provider— filter byopenai,anthropic, orgeminiprojectId— scope to a single projectmodel— partial match on model name
GET /api/analytics/overviewKPI summary: spend today/month, request counts, top provider/model, budget risk projects, blocked count.
GET /api/analytics/trendsDaily time series: date, requests, spend, token counts, blocked requests, errors.
GET /api/analytics/providersPer-provider breakdown: spend, requests, tokens, avg latency, error rate, blocked count.
GET /api/analytics/modelsTop 20 models by spend with avg cost per request and latency.
GET /api/analytics/projectsPer-project: requests, spend, budget utilization %, blocked requests, last used.
CSV export
GET /api/analytics/export.csv returns a raw CSV of up to 10,000 usage log rows with columns: createdAt, workspace, project, provider, model, status, inputTokens, outputTokens, totalTokens, estimatedCostUsd, latencyMs, errorCode. Supports all filter params above. The export is also logged as an audit event.
You can also use the Export CSV button on the Analytics dashboard page.
Monthly digest
POST /api/analytics/monthly-digest/test (admin+ role required) generates a digest of the current month and sends it to the authenticated user's email if SMTP is configured. If SMTP is not configured, the JSON preview is returned with emailDelivery: "skipped".
The digest includes: total spend, total requests, top provider, top model, top project, budget warnings, blocked request count, and a recommended action.
Required SMTP variables
SMTP_HOST— mail server hostnameSMTP_PORT— defaults to 587SMTP_USER/SMTP_PASS— credentialsSMTP_FROM— sender address
Production checklist
- Set FRONTEND_URL — required for invite emails and CORS. Example:
https://app.yourdomain.com - Set SMTP_HOST — without it, invite emails are skipped (invite links still work).
- Set JWT_SECRET — use at least 64 random chars. Rotate to invalidate all sessions.
- Set ENCRYPTION_KEY — 64 hex chars (32 bytes). Required for encrypted provider keys.
- Set CORS_ORIGIN — set to your frontend domain, not
*. - Verify backup of DATABASE_URL — the database holds all usage logs, budgets, and audit events.
Security
- Keys are hashed — TokenGuard stores only a bcrypt hash of your API key. The full key is shown once and then gone.
- No OpenAI key stored in plaintext — per-project OpenAI keys are AES-256-GCM encrypted at rest.
- JWT sessions — dashboard auth uses short-lived JWTs. Rotate your
JWT_SECRETto invalidate all sessions instantly. - Budget limits as a blast radius control — even if a key leaks, spend is capped at your configured limits.
- Deactivate instantly — from the project page you can deactivate a key in one click. Deactivated keys return
HTTP 401immediately.