---
title: Account & limits
description: GET /v1/key and GET /v1/generation in Clipia AI Gateway — check key limits and spend, exact request cost, rate-limit headers and the 429 response.
---

Clipia AI Gateway offers OpenAI-compatible endpoints to control your key and spend: `GET /v1/key` for key limits and usage, `GET /v1/generation` for the actual cost of a specific request. Billing runs in credits against the account balance.

## Key info (`GET /v1/key`)

<Method name="GET" path="/v1/key" />

```bash
curl https://api.clipia.ai/v1/key \
  -H "Authorization: Bearer $CLIPIA_API_KEY"
```

**Response `200`**

```json
{
  "data": {
    "label": "prod key",
    "usage": 1240.5,
    "limit": null,
    "limit_remaining": null,
    "rate_limit": { "requests": 120, "interval": "1m" }
  }
}
```

<TypeTable
  type={{
    label: { type: 'string', description: 'Key name set at creation.' },
    usage: { type: 'number', description: 'Credits spent by this key.' },
    limit: { type: 'number | null', description: 'Key budget in credits; null — no separate limit (bounded by the account balance).' },
    limit_remaining: { type: 'number | null', description: 'Remaining key budget in credits; null — no limit.' },
    'rate_limit.requests': { type: 'integer', description: 'Request limit per window.' },
    'rate_limit.interval': { type: 'string', description: 'Window length, e.g. "1m".' },
  }}
/>

## Request cost (`GET /v1/generation`)

Pass the `id` from a chat response (`chatcmpl-…`) to get the actual cost and token spend of an already-completed request.

<Method name="GET" path="/v1/generation?id={id}" />

```bash
curl "https://api.clipia.ai/v1/generation?id=chatcmpl-3f9a1c7e2b41" \
  -H "Authorization: Bearer $CLIPIA_API_KEY"
```

**Response `200`**

```json
{
  "data": {
    "id": "chatcmpl-3f9a1c7e2b41",
    "model": "claude-opus-5",
    "provider_name": "Clipia",
    "streamed": false,
    "total_cost": 0.046,
    "tokens_prompt": 28,
    "tokens_completion": 64,
    "finish_reason": "stop",
    "created_at": "2026-06-26T12:00:00Z"
  }
}
```

`total_cost` is the actual cost of the request in credits. This is handy for auditing spend per call, independently of the `usage` field in the chat response.

## Limits

Each key is limited by requests per minute (RPM, default **120**) and, optionally, by tokens per minute (TPM) and a credit budget. Exceeding RPM/TPM is rejected with `429`; exhausting the budget with `402`.

### Response headers

<TypeTable
  type={{
    'x-ratelimit-remaining-requests': { type: 'integer', description: 'Requests remaining in the current window.' },
    'x-ratelimit-remaining-tokens': { type: 'integer', description: 'Tokens remaining in the current window (if a TPM limit is set).' },
    'Retry-After': { type: 'integer (seconds)', description: 'Sent on 429: how many seconds before you may retry.' },
  }}
/>

### 429 response

```http
HTTP/1.1 429 Too Many Requests
Retry-After: 12
Content-Type: application/json
```

```json
{
  "error": {
    "message": "Rate limit exceeded. Try again later.",
    "type": "rate_limit_error",
    "param": null,
    "code": "rate_limit_exceeded"
  }
}
```

<Callout type="info" title="Respect Retry-After">
On `429`, wait the number of seconds given in `Retry-After` before retrying — it is more reliable than a fixed delay. Key limits can be raised in the [developer console](/developer).
</Callout>

<Callout type="warn" title="Verify against the live response">
The exact shape of `GET /v1/key` and `GET /v1/generation`, as well as the set of rate-limit headers, may differ — verify against the live API. Limit values are configurable per key.
</Callout>
