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

# Limits and spend

> What your organization can run out of, the two headers that report it, and how to read the cost of a stream.

Your own provider keys have no money ceiling. Managed Keys spends a prepaid balance, so it can run out.

Two response headers report what you have left. `GET /v1/limits` reports the whole picture in one call.

## Your own keys have no money ceiling

We set no request allowance and no monthly cap. You hold no balance to draw down. See [pricing and billing](/billing).

One ceiling applies. Your organization runs a fixed number of flex races at a time. Past that number we run the request on the standard tier. You lose the discount, not the answer. The report calls that number `own_keys.flex_race_slots`.

## What Managed Keys can run out of

| Ceiling             | What it counts                                                                                       | At the ceiling                                                                          |
| ------------------- | ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| Prepaid balance     | Cash first, then promo credits.                                                                      | [`insufficient_balance`](/errors#insufficient_balance), status `402`.                   |
| Daily spend ceiling | Spend settled today, plus today's requests in flight. The window is a UTC day.                       | [`spend_velocity_exceeded`](/errors#spend_velocity_exceeded), status `429`.             |
| Managed concurrency | Your managed requests in flight.                                                                     | [`rate_limit_exceeded`](/errors#rate_limit_exceeded), status `429`, with `Retry-After`. |
| Shared pool rate    | Requests a minute on a pool every managed organization shares. Today that is Workers AI and Foundry. | [`rate_limit_exceeded`](/errors#rate_limit_exceeded), status `429`.                     |

A risk review can pause managed requests on top of those four. It returns [`account_under_review`](/errors#account_under_review). Your own key routes keep working.

Four more limits cover every organization. Three count requests a minute from one organization, from one key, and from one IP address. The fourth counts failed authentication attempts from one IP address. We also refuse a body over 50,000,000 bytes as [`request_too_large`](/errors#request_too_large).

The report names each per-minute limit with its window and its scope. It leaves the number out, because Cloudflare counts each one in every location it runs in and one number wouldn't be a budget you could plan against. Back off for the seconds in `Retry-After` instead.

## Two response headers report your spend

An own-keys response carries them once its routes resolve, and a managed response carries them from the balance hold on.

Three responses have neither header: one we turned away earlier, the model catalog, and a managed request whose balance we couldn't read. We leave the headers off rather than guess.

| Header                            | What it says                                                                                                                                                         |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `x-flexinference-spend-remaining` | The word `unlimited` when no money ceiling applies. Otherwise a signed micro-USD integer. It is the smaller of your balance and what the daily ceiling still allows. |
| `x-flexinference-spend-as-of`     | When we read that number, in epoch milliseconds. It only comes with a number, since `unlimited` needs no freshness mark.                                             |

We read both as we admitted this request. The number covers what you had left before this request settled its own cost.

A negative number means we turn away every managed request. Adding money repairs a negative balance. A negative daily remainder recovers at the next UTC midnight or with a raised ceiling, never with a top-up.

Read these headers on traffic you already send. Polling the endpoint before every request costs a round trip and tells you no more than the header did.

## The limits endpoint

`GET /v1/limits` takes your FlexInference key. It reports the ceilings your organization runs under. It reads the records that admit your requests, so it never claims room we'd turn away. We never cache the answer.

```bash theme={null}
curl https://api.flexinference.com/v1/limits \
  -H "Authorization: Bearer $FLEXINFERENCE_API_KEY"
```

```json theme={null}
{
  "object": "limits",
  "as_of": 1769558400123,
  "own_keys": {
    "unlimited": true,
    "flex_race_slots": {
      "limit": 40,
      "scope": "organization",
      "on_exceed": "degrade_to_standard"
    }
  },
  "managed": {
    "providers": ["anthropic", "openai"],
    "serving": "ok",
    "paused_reason": null,
    "binding": "daily_spend",
    "spend_remaining_micro_usd": 41200000,
    "currency": "USD",
    "balance": {
      "remaining_micro_usd": 94880000,
      "cash_micro_usd": 84880000,
      "credit_micro_usd": 10000000,
      "reserved_micro_usd": 120000
    },
    "daily_spend": {
      "limit_micro_usd": 250000000,
      "used_micro_usd": 208800000,
      "remaining_micro_usd": 41200000,
      "window": "utc_day",
      "resets_at": 1769644800
    },
    "concurrency": {
      "limit": 10,
      "scope": "organization",
      "on_exceed": "refuse"
    },
    "ramp_week": 1,
    "ramp_defaults": {
      "concurrency": 10,
      "daily_spend_micro_usd": 250000000
    },
    "override_in_force": {
      "concurrency": false,
      "daily_spend": false
    },
    "rates": []
  },
  "abuse_limits": {
    "counted_per_cloudflare_location": true,
    "request_body_bytes": 50000000,
    "rates": [
      {
        "name": "organization_requests",
        "scope": "organization",
        "window_seconds": 60,
        "limit": null,
        "on_exceed": "refuse"
      },
      {
        "name": "api_key_requests",
        "scope": "api_key",
        "window_seconds": 60,
        "limit": null,
        "on_exceed": "refuse"
      },
      {
        "name": "client_ip_requests",
        "scope": "client_ip",
        "window_seconds": 60,
        "limit": null,
        "on_exceed": "refuse"
      },
      {
        "name": "failed_authentications",
        "scope": "client_ip",
        "window_seconds": 60,
        "limit": null,
        "on_exceed": "refuse"
      }
    ]
  }
}
```

Every money field is a micro-USD integer. One USD is 1,000,000 of them.

| Field                               | What it says                                                                                                                                                              |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `as_of`                             | Epoch milliseconds. The balance's own clock when we read a balance, and ours when we didn't.                                                                              |
| `own_keys.unlimited`                | Always `true`.                                                                                                                                                            |
| `own_keys.flex_race_slots`          | How many flex races run at a time. Passing the number costs the discount, not the answer.                                                                                 |
| `managed`                           | `null` when no provider serves on managed keys.                                                                                                                           |
| `managed.serving`                   | `ok`, or `paused` in each of the three states that turn every managed request away.                                                                                       |
| `managed.paused_reason`             | Which state. One of `account_under_review`, `spend_velocity_exceeded`, or `insufficient_balance`. It is `null` while serving reads `ok`.                                  |
| `managed.binding`                   | Which ceiling bites first. One of `balance`, `daily_spend`, `paused`, or `exempt`.                                                                                        |
| `managed.spend_remaining_micro_usd` | The number the `x-flexinference-spend-remaining` header carries.                                                                                                          |
| `managed.balance`                   | `remaining_micro_usd` is cash plus credit. That is the quantity we compare to zero. `reserved_micro_usd` is money your in-flight requests hold, and we don't subtract it. |
| `managed.daily_spend`               | The ceiling, what today has used, and what is left. `resets_at` is the next UTC midnight in epoch seconds.                                                                |
| `managed.concurrency`               | How many managed requests your organization runs at a time.                                                                                                               |
| `managed.ramp_week`                 | Which week of the account-age schedule you sit in. Week 0 covers an account that has never topped up.                                                                     |
| `managed.ramp_defaults`             | What that week alone gives you. One concurrency number and one daily ceiling.                                                                                             |
| `managed.override_in_force`         | One flag per ramped ceiling. `true` means an admin set that number, so the weekly schedule won't move it.                                                                 |
| `managed.rates`                     | The per-minute limits on the shared pools this organization serves on.                                                                                                    |
| `abuse_limits`                      | The limits every organization shares, plus the body cap in bytes.                                                                                                         |

The last three fields say why your concurrency number and your daily ceiling read as they do. An exempt organization has no ceiling to explain, so all three read `null`.

A paused balance reports the pause in place of a number. No positive figure can then read as permission to send.

These numbers hold at `as_of` and promise nothing about your next request. Another request moves them, and so does a settlement, a top-up, or a refund.

A missing or wrong key returns `401` with [`invalid_api_key`](/errors#invalid_api_key). When we can't read one of these records, the endpoint returns `503` with [`limits_unavailable`](/errors#limits_unavailable). It refuses rather than hand you a cached figure, which could claim room your next request wouldn't get. Requests keep working either way.

## Cost inside a stream

A response you didn't stream reports its cost twice, in the `x-flexinference-cost` header and the `usage.cost` block. A streamed response can't use the header, because we send headers before the answer exists and we don't know the cost then.

Send `include_cost: true` to move the cost inside the stream.

```json theme={null}
{
  "model": "gpt-5.5",
  "start_within": "00h-00m-30s",
  "stream": true,
  "include_cost": true,
  "input": "Summarize this contract."
}
```

The cost then goes in the usage frame the endpoint already sends. A `usage.routing` block sits beside it and names the route that ran the request.

```json theme={null}
"usage": {
  "input_tokens": 412,
  "output_tokens": 128,
  "cost": { "total_micro_usd": 1840, "currency": "USD" },
  "routing": {
    "provider": "openai",
    "requested_provider": "openai",
    "tier": "flex",
    "reason": "flex_won",
    "fallback_attempts": 0,
    "mode": "byok"
  }
}
```

The switch stays off by default. A stream you didn't ask this of matches what the provider sent, byte for byte.

`/v1/chat/completions` makes the usage frame itself opt-in at OpenAI. Send `"stream_options": {"include_usage": true}` as well. Without it the cost has no frame to go in.

A managed request reports what the provider charged us. An own-keys request reports the provider's list price at the tier that ran it. A request we can't price reports no `cost` at all. Read a missing block as nothing to report, not as zero.

Two routing headers come on every response either way. They are `x-flexinference-served-provider` and `x-flexinference-routing-reason`. A streaming caller who skips `include_cost` still sees which route ran the request and why. See [reading the outcome](/deadline-routing#reading-the-outcome).

`include_cost` never reaches the provider. We remove it from the body before we forward the request.
