Skip to main content
Browse docs

Tutorial: Setting Up Cost Tracking & Budgets

This tutorial shows you how to configure cost tracking in the Keeptrusts gateway, set per-team spend caps using wallets, monitor cost accumulation, and configure budget alert thresholds.

Use this page when

  • You are configuring wallet-based spend caps for teams using the gateway.
  • You want the gateway to reserve and settle costs per request against team wallets.
  • You need to seed model pricing in the Keeptrusts API.
  • You are setting up budget alert thresholds and monitoring spend accumulation.

Primary audience

  • Primary: Platform engineers configuring cost controls and FinOps teams managing LLM budgets
  • Secondary: Engineering managers approving team spend allocations; finance teams performing chargeback

Prerequisites

  • kt CLI installed (first-run tutorial)
  • An OpenAI-compatible API key exported as OPENAI_API_KEY
  • A running Keeptrusts API instance (for wallet and spend tracking)
  • curl and jq installed

How Cost Tracking Works

Every request through the gateway calculates the cost based on model pricing and token usage. The gateway:

  1. Reserves the estimated cost from the team's wallet before forwarding upstream
  2. Settles to the actual cost once the response arrives
  3. Records the cost in the decision event for audit and reporting

If a team's wallet has insufficient balance, the request is rejected before it reaches the provider.

Step 1: Configure Model Pricing

Seed model pricing in the Keeptrusts API (if not already done):

export KEEPTRUSTS_API_URL="http://localhost:8080"
export KEEPTRUSTS_API_TOKEN="your-admin-token"

# Seed standard model pricing
curl -s -X POST "$KEEPTRUSTS_API_URL/v1/model-pricing" \
-H "Authorization: Bearer $KEEPTRUSTS_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"provider": "openai",
"input_cost_per_1k_tokens": 0.00015,
"output_cost_per_1k_tokens": 0.0006
}' | jq .

Verify pricing is loaded:

curl -s "$KEEPTRUSTS_API_URL/v1/model-pricing" \
-H "Authorization: Bearer $KEEPTRUSTS_API_TOKEN" | jq '.[] | {model, input_cost_per_1k_tokens, output_cost_per_1k_tokens}'

Step 2: Allocate Wallet Credits to Teams

Create wallets and allocate budgets:

# Allocate $500 to engineering team
curl -s -X POST "$KEEPTRUSTS_API_URL/v1/wallets/allocate" \
-H "Authorization: Bearer $KEEPTRUSTS_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"team_id": "team_engineering",
"amount": 500.00,
"currency": "USD",
"description": "Monthly LLM budget - April 2026"
}' | jq .

# Allocate $100 to marketing team
curl -s -X POST "$KEEPTRUSTS_API_URL/v1/wallets/allocate" \
-H "Authorization: Bearer $KEEPTRUSTS_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"team_id": "team_marketing",
"amount": 100.00,
"currency": "USD",
"description": "Monthly LLM budget - April 2026"
}' | jq .

Step 3: Create the Gateway Configuration

Create policy-config.yaml with cost tracking enabled:

version: '1'
providers:
targets:
- id: openai
provider: openai
secret_key_ref:
env: OPENAI_API_KEY
consumer_groups:
- name: engineering
api_key: kt_cg_engineering_abc123
wallet_team_id: team_engineering
- name: marketing
api_key: kt_cg_marketing_def456
wallet_team_id: team_marketing
cost_tracking:
enabled: true
wallet_enforcement: true
budget_alerts:
- threshold_percent: 50
action: notify
- threshold_percent: 80
action: notify
- threshold_percent: 95
action: notify
- threshold_percent: 100
action: block
api:
url: http://localhost:8080
token_env: KEEPTRUSTS_API_TOKEN
policies:
- name: content-filter
type: content_filter
action: flag
config:
categories:
- hate

Key fields

FieldPurpose
wallet_team_idLinks a consumer group to a wallet in the Keeptrusts API
cost_tracking.wallet_enforcementWhen true, reject requests that exceed the wallet balance
budget_alerts[].threshold_percentPercentage of budget at which to trigger the action
budget_alerts[].actionnotify sends an alert; block stops requests

Step 4: Start the Gateway

export KEEPTRUSTS_API_TOKEN="your-admin-token"
kt policy lint --file policy-config.yaml
kt gateway run --policy-config policy-config.yaml --port 41002

Expected output:

INFO keeptrusts::gateway Cost tracking: enabled, wallet_enforcement=true
INFO keeptrusts::gateway Budget alerts: 50%→notify, 80%→notify, 95%→notify, 100%→block
INFO keeptrusts::gateway Gateway ready

Step 5: Send Requests and Track Costs

Send a request as the engineering team:

curl -s http://localhost:41002/v1/chat/completions \
-H "Content-Type: application/json" \
-H "X-Consumer-Group: kt_cg_engineering_abc123" \
-d '{
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "Write a short haiku about cloud computing."}]
}' | jq '{model: .model, usage: .usage}'

Expected output:

{
"model": "gpt-4o-mini",
"usage": {
"prompt_tokens": 14,
"completion_tokens": 25,
"total_tokens": 39
}
}

Step 6: Monitor Spend with kt spend

Use kt spend to view current cost accumulation:

kt spend --team engineering

Expected output:

Team: engineering
Period: 2026-04-01 to 2026-04-30
Budget: $500.00
Spent: $0.02
Remaining: $499.98
Usage: 0.004%

Breakdown by model:
gpt-4o-mini: $0.02 (39 tokens, 1 request)

View all teams:

kt spend --all

Expected output:

Team Budget Spent Remaining Usage
engineering $500.00 $0.02 $499.98 0.004%
marketing $100.00 $0.00 $100.00 0.0%

Step 7: Test Budget Enforcement

To test the budget block, temporarily set a low budget and make requests:

# Allocate only $0.01 to a test group
curl -s -X POST "$KEEPTRUSTS_API_URL/v1/wallets/allocate" \
-H "Authorization: Bearer $KEEPTRUSTS_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"team_id": "team_marketing", "amount": 0.01, "currency": "USD"}'

Send requests until the budget is exhausted:

curl -s -w "\nHTTP %{http_code}\n" \
http://localhost:41002/v1/chat/completions \
-H "Content-Type: application/json" \
-H "X-Consumer-Group: kt_cg_marketing_def456" \
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Write a long essay about every country in the world."}]}'

When the budget is exceeded:

{
"error": {
"message": "Budget exceeded for consumer group: marketing",
"type": "budget_exceeded",
"code": "insufficient_balance",
"details": {
"team": "marketing",
"budget": 0.01,
"spent": 0.01,
"estimated_cost": 0.05
}
}
}
HTTP 402

Step 8: View Cost Events

Inspect cost details in decision events:

kt events tail --last 3 --format json | jq '.[] | {consumer_group, model, cost: .cost, tokens: .usage.total_tokens}'

Expected output:

{"consumer_group": "engineering", "model": "gpt-4o-mini", "cost": 0.02, "tokens": 39}
{"consumer_group": "marketing", "model": "gpt-4o-mini", "cost": 0.01, "tokens": 25}
{"consumer_group": "marketing", "model": "gpt-4o-mini", "cost": null, "tokens": 0}

The last entry shows a blocked request (cost is null, no tokens consumed).

For AI systems

  • Canonical terms: Keeptrusts gateway, wallet, cost tracking, reserve/settle, model pricing, budget alert, spend cap.
  • API endpoints: POST /v1/model-pricing, POST /v1/wallets/allocate, GET /v1/wallets/balance, GET /v1/model-pricing.
  • Config fields: cost_tracking.enabled, cost_tracking.enforce_budget, cost_tracking.alert_thresholds.
  • CLI commands: kt gateway run, kt spend, kt events tail.
  • Best next pages: Rate Limiting, Caching Responses, Consumer Group Isolation.

For engineers

  • Prerequisites: kt CLI, running Keeptrusts API, admin token for pricing/wallet setup.
  • Seed pricing: POST /v1/model-pricing with per-model input/output cost per 1K tokens.
  • Allocate budget: POST /v1/wallets/allocate with team_id and dollar amount.
  • Verify enforcement: send a request exceeding the wallet balance — expect HTTP 402 rejection.
  • Monitor: kt spend shows current balance and burn rate; kt events tail shows per-request cost.

For leaders

  • Wallet-based budgets prevent surprise LLM bills by hard-capping team spend before requests reach the provider.
  • Reserve/settle accounting gives precise per-request cost attribution for chargeback.
  • Alert thresholds provide early warning before budgets are exhausted.
  • Combines with caching and context compression for layered cost optimisation.

Next steps

Troubleshooting

SymptomCauseFix
Cost shows $0.00Model pricing not seededSeed pricing via POST /v1/model-pricing
402 on first requestWallet empty or not allocatedAllocate credits via POST /v1/wallets/allocate
Budget alerts not firingThresholds not configuredAdd budget_alerts to config
kt spend shows no dataAPI URL not configuredSet api.url in config and export KEEPTRUSTS_API_TOKEN