Spend Limits & Usage Controls
Set budget caps per API key or account, monitor usage by domain and tier, and protect against unexpected costs with automatic overage blocking.
Balance & Microcents
How It Works
Configure
Set a budget cap (microcents) and/or request limit on individual API keys or your entire account. Choose a reset period: daily, weekly, or monthly.
Enforce
Every scrape request is checked against active limits before processing. If a limit would be exceeded, the request is rejected with a 429 status and a detailed error message.
Monitor
Query real-time usage data per key — daily timeseries, tier breakdowns, top domains, and cross-key comparisons. Counters reset automatically at the end of each period.
Per-Key Limits
Assign budget caps and request limits to individual API keys. Useful for separating production, staging, and development workloads or enforcing per-team budgets.
Get Key Limits
/api/v1/api-keys/{key_id}/limitsReturns the current spend limit configuration and usage status for an API key.
curl https://api.alterlab.io/api/v1/api-keys/{key_id}/limits \
-H "Authorization: Bearer your_session_token"Response:
{
"api_key_id": "550e8400-e29b-41d4-a716-446655440000",
"api_key_name": "Production Key",
"has_limits": true,
"limits": {
"budget_limit_microcents": 50000000,
"request_limit": 10000,
"reset_period": "monthly",
"enabled": true,
"current_spend_microcents": 12340000,
"current_request_count": 2450,
"current_period_start": "2026-03-01T00:00:00Z",
"resets_at": "2026-04-01T00:00:00Z",
"budget_percent_used": 24.7,
"requests_percent_used": 24.5
}
}Set Key Limits
/api/v1/api-keys/{key_id}/limitsCreate or update spend limits for an API key. At least one of budget_limit_microcents or request_limit must be provided.
curl -X PUT https://api.alterlab.io/api/v1/api-keys/{key_id}/limits \
-H "Authorization: Bearer your_session_token" \
-H "Content-Type: application/json" \
-d '{
"budget_limit_microcents": 50000000,
"request_limit": 10000,
"reset_period": "monthly",
"enabled": true
}'| Parameter | Type | Required | Description |
|---|---|---|---|
| budget_limit_microcents | integer | No* | Budget cap in microcents (1,000,000 = $1.00). null = no budget limit. |
| request_limit | integer | No* | Max requests per period. null = no request limit. |
| reset_period | string | No | daily, weekly, or monthly (default) |
| enabled | boolean | No | Whether this limit is active (default: true) |
* At least one of budget_limit_microcents or request_limit is required.
Remove Key Limits
/api/v1/api-keys/{key_id}/limitsRemove all spend limits from an API key. Returns 204 No Content.
curl -X DELETE https://api.alterlab.io/api/v1/api-keys/{key_id}/limits \
-H "Authorization: Bearer your_session_token"Account Limits
Set an account-wide budget cap that applies across all API keys. Account limits act as a safety net — even if individual keys have no per-key limits, the account limit prevents total spend from exceeding your budget.
Dual Enforcement
Get Account Limits
/api/v1/account/limitscurl https://api.alterlab.io/api/v1/account/limits \
-H "Authorization: Bearer your_session_token"Response:
{
"user_id": "a0e1f2d3-b4c5-6789-a0b1-c2d3e4f5a6b7",
"has_limits": true,
"limits": {
"budget_limit_microcents": 200000000,
"request_limit": null,
"reset_period": "monthly",
"enabled": true,
"current_spend_microcents": 45670000,
"current_request_count": 9134,
"current_period_start": "2026-03-01T00:00:00Z",
"resets_at": "2026-04-01T00:00:00Z",
"budget_percent_used": 22.8,
"requests_percent_used": null
}
}Set Account Limits
/api/v1/account/limitsCreate or update account-level spend limits. Same request body as per-key limits.
curl -X PUT https://api.alterlab.io/api/v1/account/limits \
-H "Authorization: Bearer your_session_token" \
-H "Content-Type: application/json" \
-d '{
"budget_limit_microcents": 200000000,
"reset_period": "monthly",
"enabled": true
}'Remove Account Limits
/api/v1/account/limitsRemove account-level spend limits. Returns 204 No Content.
curl -X DELETE https://api.alterlab.io/api/v1/account/limits \
-H "Authorization: Bearer your_session_token"OAuth Grant Limits
Every app you connect with OAuth (Claude Desktop, Cursor, or any other MCP client) gets its own grant, and every grant has a spend cap from the moment you approve it. The cap applies to that app only. Requests from the app stop when it reaches its cap, while your API keys and other apps keep working.
Reset periods
- Default: new grants start with a budget cap that resets daily.
- Daily: resets 24 hours after the current period started.
- Weekly: resets 7 days after the current period started.
- Monthly: resets on the same day of the next month (or the last day of a shorter month).
See consumption in your dashboard
resets_at field holds the same next reset time in the API.List OAuth Grant Limits
/api/v1/oauth-grants/limitsReturns your active OAuth grants with their cap status. This endpoint requires a dashboard session, so a connected app cannot read or raise its own cap.
curl https://api.alterlab.io/api/v1/oauth-grants/limits \
-H "Authorization: Bearer your_session_token"Response:
{
"grants": [
{
"grant_id": "5b1e7c2a-9d3f-4e8a-b6c1-2f0a9e4d7c13",
"client_id": "mcp_client_8f2a",
"client_name": "Claude Desktop",
"scope": "scrape",
"created_at": "2026-03-10T09:12:00Z",
"last_used_at": "2026-03-14T16:40:00Z",
"has_limits": true,
"limits": {
"budget_limit_microcents": 25000000,
"request_limit": null,
"reset_period": "daily",
"enabled": true,
"current_spend_microcents": 3120000,
"current_request_count": 1560,
"current_period_start": "2026-03-14T09:12:00Z",
"resets_at": "2026-03-15T09:12:00Z",
"budget_percent_used": 12.5,
"requests_percent_used": null
}
}
]
}Overage Protection
When a request would exceed an active limit, AlterLab returns a 429 Too Many Requests response with details about which limit was hit.
{
"error": "spend_limit_exceeded",
"limit_type": "key_budget",
"current_value": 50000000,
"limit_value": 50000000,
"reset_at": "2026-04-01T00:00:00Z",
"message": "API key budget limit reached. Current spend: $50.0000, limit: $50.0000. Resets at 2026-04-01T00:00:00+00:00."
}| limit_type | Meaning |
|---|---|
| key_budget | Per-key budget cap reached |
| key_requests | Per-key request limit reached |
| account_budget | Account-wide budget cap reached |
| account_requests | Account-wide request limit reached |
Automatic Reset
resets_at field in the limit status tells you exactly when the next reset occurs. No manual intervention needed.Usage Monitoring
Query real-time usage data for any API key. All usage endpoints accept a days query parameter (1–90, default 30) to control the lookback period.
Usage Summary
/api/v1/api-keys/{key_id}/usageReturns total requests, success/failure counts, total spend, and top domains for a key.
curl "https://api.alterlab.io/api/v1/api-keys/{key_id}/usage?days=30" \
-H "Authorization: Bearer your_session_token"Response:
{
"api_key_id": "550e8400-...",
"api_key_name": "Production Key",
"total_requests": 2450,
"successful_requests": 2380,
"failed_requests": 70,
"total_spend_microcents": 12340000,
"top_domains": [
{ "domain": "example.com", "requests": 1200, "spend_microcents": 6000000 },
{ "domain": "shop.example.org", "requests": 800, "spend_microcents": 4000000 }
],
"period_start": "2026-02-22T00:00:00Z",
"period_end": "2026-03-24T00:00:00Z"
}Daily Timeseries
/api/v1/api-keys/{key_id}/usage/timeseriesReturns daily request counts and spend for charting and trend analysis. Missing days are filled with zeros.
curl "https://api.alterlab.io/api/v1/api-keys/{key_id}/usage/timeseries?days=7" \
-H "Authorization: Bearer your_session_token"Response:
{
"api_key_id": "550e8400-...",
"days": 7,
"granularity": "day",
"data": [
{ "date": "2026-03-18", "requests": 320, "spend_microcents": 1600000 },
{ "date": "2026-03-19", "requests": 410, "spend_microcents": 2050000 },
{ "date": "2026-03-20", "requests": 0, "spend_microcents": 0 },
{ "date": "2026-03-21", "requests": 380, "spend_microcents": 1900000 },
{ "date": "2026-03-22", "requests": 290, "spend_microcents": 1450000 },
{ "date": "2026-03-23", "requests": 500, "spend_microcents": 2500000 },
{ "date": "2026-03-24", "requests": 150, "spend_microcents": 750000 }
]
}Tier Breakdown
/api/v1/api-keys/{key_id}/usage/by-tierSee which scraping tiers your key is using and their success rates. Useful for optimizing cost by identifying expensive tier escalations.
curl "https://api.alterlab.io/api/v1/api-keys/{key_id}/usage/by-tier?days=30" \
-H "Authorization: Bearer your_session_token"Response:
{
"api_key_id": "550e8400-...",
"days": 30,
"tiers": [
{
"tier": "1",
"tier_name": "Basic HTTP",
"requests": 1800,
"successful": 1750,
"failed": 50,
"spend_microcents": 3600000,
"success_rate": 97.2
},
{
"tier": "2",
"tier_name": "Premium Proxy",
"requests": 400,
"successful": 380,
"failed": 20,
"spend_microcents": 4000000,
"success_rate": 95.0
},
{
"tier": "4",
"tier_name": "Penetrator",
"requests": 250,
"successful": 240,
"failed": 10,
"spend_microcents": 4740000,
"success_rate": 96.0
}
]
}Cross-Key Comparison
/api/v1/usage/by-keyCompare usage across all API keys in your workspace. Shows per-key totals and account-wide aggregates.
curl "https://api.alterlab.io/api/v1/usage/by-key?days=30" \
-H "Authorization: Bearer your_session_token"Response:
{
"keys": [
{
"api_key_id": "550e8400-...",
"api_key_name": "Production Key",
"total_requests": 2450,
"successful_requests": 2380,
"failed_requests": 70,
"total_spend_microcents": 12340000
},
{
"api_key_id": "661f9511-...",
"api_key_name": "Staging Key",
"total_requests": 120,
"successful_requests": 115,
"failed_requests": 5,
"total_spend_microcents": 600000
}
],
"account_total_spend_microcents": 12940000,
"account_total_requests": 2570,
"period_start": "2026-02-22T00:00:00Z",
"period_end": "2026-03-24T00:00:00Z"
}Python Example
import alterlab
client = alterlab.AlterLab(api_key="your_api_key")
# Set a $50/month budget limit on a key
key_id = "550e8400-e29b-41d4-a716-446655440000"
client.request(
"PUT",
f"/api/v1/api-keys/{key_id}/limits",
json={
"budget_limit_microcents": 50_000_000, # $50.00
"request_limit": 10_000,
"reset_period": "monthly",
"enabled": True,
},
)
# Check current usage
usage = client.request("GET", f"/api/v1/api-keys/{key_id}/usage?days=30")
spend = usage["total_spend_microcents"] / 1_000_000
print(f"Spend: ${spend:.2f}")
print(f"Requests: {usage['total_requests']}")
# Get daily timeseries for charting
timeseries = client.request(
"GET", f"/api/v1/api-keys/{key_id}/usage/timeseries?days=7"
)
for day in timeseries["data"]:
day_spend = day["spend_microcents"] / 1_000_000
print(f" {day['date']}: {day['requests']} requests, ${day_spend:.2f}")
# Compare all keys
comparison = client.request("GET", "/api/v1/usage/by-key?days=30")
total = comparison["account_total_spend_microcents"] / 1_000_000
print(f"Account total: ${total:.2f} across {len(comparison['keys'])} keys")Node.js Example
import AlterLab from "alterlab";
const client = new AlterLab({ apiKey: "your_api_key" });
const keyId = "550e8400-e29b-41d4-a716-446655440000";
// Set a $50/month budget limit on a key
await client.request("PUT", `/api/v1/api-keys/${keyId}/limits`, {
body: {
budget_limit_microcents: 50_000_000, // $50.00
request_limit: 10_000,
reset_period: "monthly",
enabled: true,
},
});
// Check current usage
const usage = await client.request(
"GET",
`/api/v1/api-keys/${keyId}/usage?days=30`
);
const spend = usage.total_spend_microcents / 1_000_000;
console.log(`Spend: $${spend.toFixed(2)}`);
console.log(`Requests: ${usage.total_requests}`);
// Get tier breakdown to optimize costs
const tiers = await client.request(
"GET",
`/api/v1/api-keys/${keyId}/usage/by-tier?days=30`
);
for (const tier of tiers.tiers) {
const tierSpend = tier.spend_microcents / 1_000_000;
console.log(
` ${tier.tier_name}: ${tier.requests} requests, $${tierSpend.toFixed(2)}, ${tier.success_rate}% success`
);
}
// Compare all keys
const comparison = await client.request("GET", "/api/v1/usage/by-key?days=30");
const total = comparison.account_total_spend_microcents / 1_000_000;
console.log(`Account total: $${total.toFixed(2)}`);