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"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/sdk";
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)}`);