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

# Plan usage and funding

> Read coding plan windows and policy, identify what paid for a request, and handle a plan limit.

```http theme={"dark"}
GET https://api.runinfra.ai/v1/usage
```

Read the workspace's coding plan limits, credits after limits, and funding policy with a workspace API key. This endpoint is read-only. Use [GET /v1/credits](/docs/api-reference/credits) for the credit balance and budget, including when no coding plan exists.

## Request

```bash theme={"dark"}
curl https://api.runinfra.ai/v1/usage \
  -H "Authorization: Bearer $RUNINFRA_GATEWAY_KEY"
```

A legacy key scoped to a deployment or endpoint cannot read workspace finances. These keys, and internal canary keys, receive `403 usage_scope_violation`. Use a workspace key.

The endpoint has a separate limit of 60 reads per minute per key, in addition to the normal per-key request limit. Responses carry `Cache-Control: no-store`. A rate refusal returns `429 rate_limit_exceeded`; follow its retry headers. During a rate-limit store outage, both limits are counted per server. If the rate-limit store is not configured or the connection gate cannot evaluate the request, the response is `503 limiter_unavailable`.

## Response

This example shows a workspace without a coding plan. The identifier and observation time are illustrative.

```json theme={"dark"}
{
  "workspace_id": "00000000-0000-4000-8000-000000000001",
  "coding_plan": {
    "observed_at": "2026-09-23T12:00:00.000Z",
    "availability": "available",
    "current": null
  },
  "covers": ["chat", "embeddings", "rerank"],
  "order": ["plan", "credits", "standby", "refused"]
}
```

| Field | Meaning |
| - | - |
| `workspace_id` | The workspace authenticated by the key. |
| `coding_plan.observed_at` | ISO 8601 observation time for the plan snapshot, or `null` when unavailable. |
| `coding_plan.availability` | Snapshot availability: `available`, `stale`, or `unavailable`. Read this before using retained data. |
| `coding_plan.current` | Plan state, or `null` when there is no current plan state. |
| `covers` | Covered operation categories. `chat` includes chat completions, Messages, and Responses. This list does not promise that a particular model is available. |
| `order` | Funding order. Credits require the owner's choice and sufficient balance and cap; Standby covers chat only and must be available. |

### Current plan state

When `coding_plan.current` is present, it has these fields. All are required except `resumes_at`, `serving_until`, `can_keep`, `remedy_code` and `billing_frozen`; a required field can still be `null` where noted. This endpoint always returns them; they are optional only so that older cached snapshots still parse.

| Field | Meaning |
| - | - |
| `tier`, `interval` | `starter`, `pro`, or `team`; interval is `month`. |
| `status`, `tile_state`, `serving` | Payment status, display state, and whether the plan can currently serve. A retained plan record does not by itself mean the plan is serving. |
| `price_cents` | The plan's quoted monthly price, in US cents. |
| `cancel_at`, `renews_at` | ISO 8601 timestamps, or `null`. `renews_at` is set only while the plan is active and serving; it is `null` while payment is needed, canceling, paused, ended, or refund-closed. |
| `five_hour_limit_microcents` | The quoted 5-hour limit, including before its first window starts. |
| `plan_blocked_until` | Latest blocking plan reset as an ISO 8601 timestamp, counting pending commitments. `null` when no plan window blocks admission. Displayed window usage counts settled requests only. |
| `resumes_at` | Optional ISO 8601 timestamp for the earliest time requests can resume after a limit, considering plan resets, eligible Standby refills, and credits-period resets. Can be `null`. |
| `five_hour` | Window counters, or `null` before an admitted plan request starts the clock. |
| `week` | Weekly window counters. |
| `standby_day` | Daily Standby counters. Its `resets_at` is the refill time. Counters alone do not promise capacity or eligibility. |
| `included_month` | Plan usage counted in the billing period: `starts_at`, `resets_at`, and `used_microcents`. `null` when that period is unavailable. |
| `pending_change` | Scheduled tier change with `tier` and `effective_at`, or `null`. |
| `credits` | The credits-after-limits settings and counters described below. |
| `funding` | `null` on this policy read. It is not a receipt for a request. |
| `predicted_funding` | Availability for a nominal next covered chat request: `plan`, `credits`, `standby`, `refused`, or `null` when no prediction is available. The actual request can differ by key, cost, operation, or capacity. |
| `remedy_code` | Optional typed remedy behind `copy.remedy`: `enable_credits`, `raise_cap`, `add_funds`, `raise_key_limit`, `ask_owner`, `contact_support`, `wait_for_refill`, or `null`. Choose an action from this code rather than parsing display text. Null while `billing_frozen` is true. |
| `serving_until` | Optional. When the plan stops serving unless a payment succeeds: the payment grace deadline, or the scheduled cancellation when that is earlier. `null` while the plan is not serving. |
| `can_keep` | Optional. `true` while a scheduled cancellation can still be undone (**Keep plan**): `cancel_at` is in the future, the plan has no dispute hold or reversal fence, its subscription has had no payment dispute (a bank inquiry does not count), and it is not canceled, disputed, incomplete or refund-closed. After a payment dispute, `can_keep` stays `false`, even once the hold is released. |
| `billing_frozen` | Optional. `true` while an unpaid bill or a payment dispute freezes the account and blocks requests. Resolve an unpaid bill in Billing. For a payment dispute, contact support. A negative credit balance is not a billing freeze. Plan and credits settings cannot lift it. |
| `copy` | Server-written display text. `summary` and `policy` describe the current policy; `actual` is `null` on this endpoint. `remedy` supplies the available next step when one exists. |

Each window has `starts_at`, `resets_at`, `used_microcents`, `limit_microcents`, and `used_percent`. Body timestamps use ISO 8601. Percentages are integers clamped to 0 through 100. A request admitted before a limit can finish beyond it, so retain the exact counters when adding usage.

| `credits` field | Meaning |
| - | - |
| `enabled` | Whether the owner chose credits after plan limits. |
| `cap_cents` | Cap per billing period, in US cents. With `enabled` true, `null` means no cap; with `enabled` false, credits are off. |
| `balance_cents` | Workspace credit balance in US cents; it can be negative. |
| `month_spent_microcents` | Calculated credit charges after plan limits during the billing period. |
| `pending_max_holds_microcents` | Maximum costs committed to requests still in flight against that cap. |
| `resets_at` | ISO 8601 billing-period end, or `null` when unavailable. |

One cent is 1,000,000 microcents. One US dollar is 100,000,000 microcents. The credits cap after plan limits is separate from the workspace spend cap returned by `/v1/credits`.

## Response funding headers

Model API responses carry these headers only when a coding plan decision applied to the request. They come from the admission snapshot. A workspace without a plan receives none of them. Uncovered operations, **Credits only** keys, non-serving plans, and promotional zero-price requests use the ordinary pay-as-you-go path without plan headers.

| Header | Value |
| - | - |
| `x-runinfra-funding` | `plan`, `credits`, `standby`, or `refused`. Describes this request's funding decision. |
| `x-runinfra-plan` | `starter`, `pro`, or `team`. |
| `x-runinfra-plan-5h-used-percent` | Integer percent used, clamped to 0 through 100. Omitted if no 5-hour window has started. |
| `x-runinfra-plan-5h-resets-at` | Unix timestamp in seconds. Omitted if no 5-hour window has started. |
| `x-runinfra-plan-week-used-percent` | Integer weekly percent used, clamped to 0 through 100. |
| `x-runinfra-plan-week-resets-at` | Unix timestamp in seconds. |

These are response headers, not controls for selecting how a request is paid. They describe the request's admission state, not the counters after it finishes. An idempotent replay retains the original funding receipt.

## Calculated cost and plan value

On chat completions and Responses, `usage.cost` reports the calculated charge in US dollars. It is `0` when the plan or Standby paid. `usage.runinfra.cost_microcents` is the same calculated charge in integer microcents.

This illustrative usage fragment shows a request with a list value of 294,000 microcents paid by the plan:

```json theme={"dark"}
{
  "cost": 0,
  "runinfra": {
    "cost_microcents": 0,
    "plan_value_microcents": 294000,
    "paid_from": "plan"
  }
}
```

`usage.runinfra.plan_value_microcents` is the usage value counted at the applicable per-token rates. `usage.runinfra.paid_from` is `plan` or `standby`. Both fields are added only when the plan or Standby paid. A credit-funded response retains the ordinary cost fields; use `x-runinfra-funding` when present to identify credits after plan limits.

The calculated charge is not the final whole-cent credit debit for an individual request. Credit settlement carries fractional cents between requests, and the balance's debt floor can limit a debit. See [request cost and cached input](/docs/api-reference/chat-completions#the-cost-of-the-request-and-its-cached-input-on-its-usage) for streaming and replay details.

## Plan limit errors and Messages

When only running requests hold the rest of a limit, the request waits on the server for up to 30 seconds and then gets a retryable `429 plan_window_busy`. Messages and Responses keep it as a `429` `rate_limit_error`. When the plan is at a limit and neither credits nor Standby can serve the request, the OpenAI-compatible envelope returns `402 plan_limit_reached`. Its fields include the blocking window, reset time, `standby_blocker`, credit blocker, and a next step. It carries `x-should-retry: false` and no `Retry-After`. See the [complete error example](/docs/api-reference/errors#coding-plan-limit).

The Anthropic-compatible `/v1/messages` error envelope keeps `error.type: "billing_error"` and the message text, plus `request_id`. It does not preserve `error.code`, window fields, `standby_blocker`, or `fixes`. The message therefore states the product, blocking limit, reset time, Standby condition, and next step with its Billing URL.

On plan and Standby responses, the Messages success envelope adds `usage.cost` (`0`) and `usage.runinfra` (`cost_microcents`, `plan_value_microcents`, `paid_from`) to its token counts, in the JSON body and in the stream's final `message_delta`. Credit-funded and pay-as-you-go Messages responses report token counts only. Read the funding headers for which source paid, and use this endpoint for current plan state. See [Anthropic Messages](/docs/api-reference/anthropic-messages#coding-plan-funding).
