```yaml
product: AlterLab
title: "Spend Limits & Usage Controls — Budget Management API"
comparison_context: "AlterLab is an alternative to Firecrawl, ScrapingBee, and Bright Data."
source_url: https://alterlab.io/docs/guides/spend-limits
```

Guide

# 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

All budget values use **microcents** (1,000,000 = $1.00). This gives you sub-cent precision for fine-grained cost control.

Set spend limits directly from the API Keys page in your dashboard. Each key can have its own budget cap.

Monitor your API usage in real time with detailed breakdowns by tier, domain, and time period.

## How It Works

1

### 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.

2

### 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.

3

### 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

GET

`/api/v1/api-keys/{key_id}/limits`

Returns the current spend limit configuration and usage status for an API key.

Bash

```
curl https://api.alterlab.io/api/v1/api-keys/{key_id}/limits \
  -H "Authorization: Bearer your_session_token"
```

Response:

JSON

```
{
  "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

PUT

`/api/v1/api-keys/{key_id}/limits`

Create or update spend limits for an API key. At least one of `budget_limit_microcents` or `request_limit` must be provided.

Bash

```
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

DELETE

`/api/v1/api-keys/{key_id}/limits`

Remove all spend limits from an API key. Returns 204 No Content.

Bash

```
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

Both per-key and account limits are checked on every request. If either limit is exceeded, the request is blocked. For example, a key with a $50/month cap under an account with a $200/month cap will stop at $50 for that key, but other keys can continue until the account total reaches $200.

### Get Account Limits

GET

`/api/v1/account/limits`

Bash

```
curl https://api.alterlab.io/api/v1/account/limits \
  -H "Authorization: Bearer your_session_token"
```

Response:

JSON

```
{
  "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

PUT

`/api/v1/account/limits`

Create or update account-level spend limits. Same request body as per-key limits.

Bash

```
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

DELETE

`/api/v1/account/limits`

Remove account-level spend limits. Returns 204 No Content.

Bash

```
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

Open **Settings → Connected Apps** to see each app's current spend, its cap, the reset period, and the next reset time. The `resets_at` field holds the same next reset time in the API.

### List OAuth Grant Limits

GET

`/api/v1/oauth-grants/limits`

Returns 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.

Bash

```
curl https://api.alterlab.io/api/v1/oauth-grants/limits \
  -H "Authorization: Bearer your_session_token"
```

Response:

JSON

```
{
  "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.

JSON

```
{
  "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

Counters reset automatically at the end of each period (daily, weekly, or monthly). The `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

GET

`/api/v1/api-keys/{key_id}/usage`

Returns total requests, success/failure counts, total spend, and top domains for a key.

Bash

```
curl "https://api.alterlab.io/api/v1/api-keys/{key_id}/usage?days=30" \
  -H "Authorization: Bearer your_session_token"
```

Response:

JSON

```
{
  "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

GET

`/api/v1/api-keys/{key_id}/usage/timeseries`

Returns daily request counts and spend for charting and trend analysis. Missing days are filled with zeros.

Bash

```
curl "https://api.alterlab.io/api/v1/api-keys/{key_id}/usage/timeseries?days=7" \
  -H "Authorization: Bearer your_session_token"
```

Response:

JSON

```
{
  "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

GET

`/api/v1/api-keys/{key_id}/usage/by-tier`

See which scraping tiers your key is using and their success rates. Useful for optimizing cost by identifying expensive tier escalations.

Bash

```
curl "https://api.alterlab.io/api/v1/api-keys/{key_id}/usage/by-tier?days=30" \
  -H "Authorization: Bearer your_session_token"
```

Response:

JSON

```
{
  "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

GET

`/api/v1/usage/by-key`

Compare usage across all API keys in your workspace. Shows per-key totals and account-wide aggregates.

Bash

```
curl "https://api.alterlab.io/api/v1/usage/by-key?days=30" \
  -H "Authorization: Bearer your_session_token"
```

Response:

JSON

```
{
  "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

Python

```
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

TYPESCRIPT

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

[Cloud Storage Export](https://alterlab.io/docs/guides/cloud-storage)[Organizations & Teams](https://alterlab.io/docs/guides/organizations)

Last updated: June 2026