> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Per-API-key usage limits and spend alerts

> See live usage per API key, set a per-minute rate limit and monthly request quota per key or as an org-wide default, and flag keys that cross a usage-alert threshold before they run away.

# Per-API-key usage limits and spend alerts

Every API key on your workspace now reports its own live usage, and you can bound each key independently: a requests-per-minute rate limit, a monthly request quota, and a usage-alert threshold that flags a key before it exhausts its quota. One noisy integration — or a leaked key — trips its own limit instead of spending the throughput your other keys depend on.

This is the per-key scoping mature communications APIs expose: the org-wide default applies to every key until you override a single key, and you can read live usage and headroom for each key at any time.

## Rate limits and monthly quotas

There are two independent controls per key — set either, both, or none:

* **Rate limit (requests per minute).** When a key crosses its per-minute window, that key alone receives `429 RATE_LIMIT_EXCEEDED` with a `Retry-After` hint. Your other keys are untouched.
* **Monthly request quota.** A hard ceiling per UTC month. Cross it and the key gets `429` with a monthly-quota code until the month resets on the 1st (UTC).

Defaults are generous — well-behaved keys never notice either control. They exist to contain one bad key: a stuck retry loop or a compromised credential is bounded to its own window instead of taking down every integration in the workspace.

Both dimensions are bounded by platform maximums (per key: **60,000 requests/minute**, **1,000,000,000 requests/month**); values above them are rejected at config time.

## The usage-alert threshold

Set a whole-percent alert threshold (1–100) to flag any key whose monthly-quota usage crosses it. `GET /api/v1/developer/governance` marks each key with `alerting: true` once its usage reaches the threshold, so a runaway key shows up in your console (and your polling) before it hits the hard quota.

The threshold is advisory — it does not block traffic. Blocking happens only at the rate limit or the quota.

## Read state and live usage

Owner / admin / developer scope.

```bash theme={null}
curl https://api.orbit.devotel.io/api/v1/developer/governance \
  -H "X-API-Key: dv_live_sk_..."
```

Response (one key shown):

```json theme={null}
{
  "data": {
    "org_default": {
      "requests_per_minute": 6000,
      "monthly_request_quota": 10000000
    },
    "alert_threshold_percent": 80,
    "bounds": {
      "max_requests_per_minute": 60000,
      "max_monthly_request_quota": 1000000000
    },
    "keys": [
      {
        "api_key_id": "key_abc123",
        "name": "production-backend",
        "key_prefix": "dv_live_sk_prod",
        "active": true,
        "effective_limits": {
          "requests_per_minute": 6000,
          "monthly_request_quota": 10000000
        },
        "override": null,
        "usage": {
          "requests_this_minute": 41,
          "requests_this_month": 812345
        },
        "monthly_quota": {
          "limit": 10000000,
          "used": 812345,
          "remaining": 9187655,
          "usage_percent": 8,
          "over_quota": false
        },
        "alerting": false
      }
    ],
    "keys_truncated": false
  }
}
```

Notes on fields:

* `effective_limits` is what actually gates the key — the per-key override when one exists, otherwise the org default.
* `override` is `null` when the key inherits the org default.
* `monthly_quota` is `null` when neither the key nor the org has a monthly quota set (usage is still reported; nothing blocks).
* `usage_percent` is floored — 79.9% reports `79` and does not prematurely trip an 80% threshold.
* The read hydrates at most 250 keys with live usage; `keys_truncated: true` tells you the list was cut.

## Set the org-wide default

```bash theme={null}
curl -X PUT https://api.orbit.devotel.io/api/v1/developer/governance/org \
  -H "X-API-Key: dv_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "requests_per_minute": 6000,
    "monthly_request_quota": 10000000,
    "alert_threshold_percent": 80
  }'
```

Send only the fields you want to change. Send `null` on a field to clear it (the key inherits the platform default). `alert_threshold_percent` accepts an integer from 1 to 100, or `null` to disable flagging.

The body must contain at least one field — an empty body is a `422`, not a silent no-op.

## Override a single key

```bash theme={null}
curl -X PUT https://api.orbit.devotel.io/api/v1/developer/governance/keys/{keyId} \
  -H "X-API-Key: dv_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{ "requests_per_minute": 1200, "monthly_request_quota": 500000 }'
```

Send `null` on a dimension to inherit the org default for that dimension; send both as `null` to remove the override entirely. A key you do not own returns `404` — the write can never be applied to another tenant's key.

## Constraints and behavior

* Writes take effect on the next request — there is no propagation lag.
* Both writes are audit-logged (`developer.api_governance.org_updated`, `developer.api_governance.key_updated`).
* Existing keys are unchanged until you set a limit — a key left unconfigured behaves exactly as before.
* Values of `0` are rejected (a zero cap would hard-block the key, which is never the intent; to disable a key, revoke it). Use `null` to clear instead.
* The rate/quota guards are fail-open on infrastructure errors: a cache blip never 429s or blocks a well-behaved key; only a real over-limit verdict does.

## Dashboard surface

The same controls live under **Developer → API governance** in the dashboard: live per-key usage bars, the org-wide default, per-key overrides, and the alert threshold — all reading and writing this exact API surface.
