# Check credits

> How much your API key can still spend, from /v1/balance or the OpenAI legacy subscription endpoint.

Shows how much your API key can still spend right now and which limit decides that. Amounts are US dollars as JSON numbers with up to 6 decimals. `GET /v1/dashboard/billing/subscription` returns the same number in the OpenAI legacy format, for clients such as Cherry Studio.

## Method and path

`GET /v1/balance`

`GET /v1/dashboard/billing/subscription`

Base URL `https://api.relayvia.dev/v1`. Send the key as `Authorization: Bearer sk-...`.

## Common parameters

No parameters. The key in the header decides whose data is returned.

## Differences from the original API

- Read-only and free: it is not billed, not logged and does not count toward model request limits. It has its own limit of 60 requests per minute per key (429 `rate_limited`). Disabled or expired keys get 401. `Authorization: Bearer`, `x-api-key` and `x-goog-api-key` all work.
- `remaining_usd` is the smallest of what is left on the key's limit, the team member's limit, the account spend limit and the account's credits, so it can be 0 or negative. `limited_by` says which one: `key`, `member`, `budget` or `wallet`.
- The legacy endpoint returns `remaining_usd + key.used_total_usd` as all three limits, so the usual hard limit minus total usage gives `remaining_usd`. `access_until` is the key's expiry in Unix seconds, 0 when it never expires.

## Request examples

**cURL**

```bash
curl https://api.relayvia.dev/v1/balance \
  -H "Authorization: Bearer sk-..."
```

**Python**

```python
import requests

resp = requests.get("https://api.relayvia.dev/v1/balance", headers={"Authorization": "Bearer sk-..."})
print(resp.json())
```

**JavaScript**

```javascript
const resp = await fetch("https://api.relayvia.dev/v1/balance", {
  headers: { Authorization: "Bearer sk-..." },
});
console.log(await resp.json());
```

## Response examples

| Field | Type | Description |
| --- | --- | --- |
| `remaining_usd` | `number` | US dollars this key can still spend now: the smallest remaining amount of the items below. Can be 0 or negative. |
| `limited_by` | `string` | Which item decides `remaining_usd`: `key`, `member`, `budget` or `wallet`. |
| `key` | `object` | The key's credit limit: `unlimited`, `period` (`none`, `daily`, `weekly` or `monthly`), `limit_usd`, `used_usd`, `remaining_usd`, `resets_at`, plus `used_total_usd` (all-time usage) and `expires_at`. Limit fields are null when unlimited. |
| `member` | `object` | The credit limit of the team member who owns the key, with the same fields; `period` is `total` or `monthly`. |
| `budget` | `object \| null` | The tightest account spend limit, or null when none is set. |
| `company.available_usd` | `number` | The account's available credits; can be negative. The console header shows the same number. |

**Response**

```json
{
  "object": "balance",
  "remaining_usd": 42.5,
  "limited_by": "key",
  "key": {
    "unlimited": false,
    "period": "monthly",
    "limit_usd": 50,
    "used_usd": 7.5,
    "remaining_usd": 42.5,
    "resets_at": "2026-12-01T00:00:00Z",
    "used_total_usd": 31.2,
    "expires_at": null
  },
  "member": {
    "unlimited": true,
    "period": "total",
    "limit_usd": null,
    "used_usd": 31.2,
    "remaining_usd": null,
    "resets_at": null
  },
  "budget": null,
  "company": {
    "available_usd": 812.345678
  }
}
```

**OpenAI legacy format**

```json
{
  "object": "billing_subscription",
  "has_payment_method": true,
  "soft_limit_usd": 73.7,
  "hard_limit_usd": 73.7,
  "system_hard_limit_usd": 73.7,
  "access_until": 0
}
```

## Errors this endpoint returns

| HTTP | code | When |
| --- | --- | --- |
| `401` | `invalid_api_key` | The API key does not exist, is disabled or has expired. |
| `403` | `forbidden` | The key may not use this model, the source IP is not on the allowlist, or the account is disabled. |
| `429` | `rate_limited` | Too many requests: per IP, per key, per account, or too many requests in progress at once. |

Every code, its fixed message and what to do are on the [error codes](https://relayvia.dev/docs/errors) page.
