# Usage

What this key has spent against its plan. The same counters the rate limiter and the caps read. `daily` is the limit that is enforced per key, held against each key on its own: `limitPerKey`, what the busiest key has left, and `resetsAt`, the next midnight UTC. `currentMonth` is the plan's allowance, enforced for the whole account: calls served this month (`used`), `limit`, `remaining` and `resetsAt`, midnight UTC on the 1st. To slow down before a 429 you do not need to call this: every response already carries what is left of the day and the month as `response.rateLimit` (`dailyRemaining`, `dailyReset`, `monthlyRemaining`, `monthlyReset`). Use this to reconcile and to see every key at once, and remember it is itself a request. A 304 costs a rate-limit slot but spends neither the day nor the month, which is why a caching client sees these numbers rise more slowly than its request count.

Source: https://docs.gunspec.io/en/sdk/usage

## client.usage.get()

`GET /v1/me/usage`

Auth: API key required  
Tier: Explorer+

Current usage for the calling key.

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `month` | string | no | Billing month to report on, formatted YYYY-MM |
| `days` | integer | no | Trailing window in days, as an alternative to month |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object | The response payload. |
| `data.currentMonth` | object | Totals for the reported period, meaning the current billing month, or the trailing window when `days` is given. |
| `data.currentMonth.used` | integer | Requests served in the reported period across every key on the account. Calls a limit refused with a 429 are not counted: they spent nothing, and this is the figure the monthly allowance is enforced against. |
| `data.currentMonth.limit` | integer | Requests your plan allows in the period. Enforced: once `used` reaches it every call is refused with `MONTHLY_CAP_EXCEEDED` until `resetsAt`. |
| `data.currentMonth.remaining` | integer | Requests left in the period, never below zero. |
| `data.currentMonth.percentage` | number | Share of records, 0 to 100. |
| `data.currentMonth.resetsAt` | string | When the monthly counter returns to zero: midnight UTC on the first of the next month, for every plan. The same instant as `X-Monthly-Reset`. |
| `data.daily` | object | What is left of today, against the limit that is enforced. Each key is counted and limited on its own. |
| `data.daily.limitPerKey` | integer \| null | Requests one key may make per UTC day on this plan. The limit applies to each key separately, which is why there is no account total to compare it with. Null when the plan has no daily ceiling. |
| `data.daily.usedToday` | integer | Requests made today (UTC) across every key on the account. Not comparable with `limitPerKey` unless the account has one key: each key is held to the limit on its own. |
| `data.daily.busiestKeyToday` | object \| null | The key nearest its daily limit, or null when no key has made a request today. |
| `data.daily.resetsAt` | string | When every daily counter returns to zero: the next midnight UTC. The same instant as `X-Daily-Reset`. |
| `data.mcp` | object | Usage through the hosted MCP server, a subset of the requests above. |
| `data.mcp.usedThisMonth` | integer | Calls made through the MCP server in the reported month. Already counted in `currentMonth.used`, never on top of it. |
| `data.mcp.usedToday` | integer | MCP calls today (UTC) across every key on the account. |
| `data.mcp.dailyLimitPerKey` | integer | MCP calls one key may make per UTC day on this plan. The limit applies to each key separately. |
| `data.mcp.busiestKeyToday` | object \| null | The key nearest its daily MCP limit, or null when no key has made an MCP call today. |
| `data.mcp.resetsAt` | string | When the daily MCP counters return to zero: the next midnight UTC. |
| `data.progress` | object | Your standing. Experience is earned per call and weighted by what the call is: resolving a name, asking what fits a firearm or comparing two records is worth several times a page of a list, because the point is integration depth rather than traffic. Earned by an SDK, the MCP server, a script or a request tool; a browser earns nothing, since the reference has a Try It button and a page left open should not outrank a production service. A `304` earns nothing, on the same reasoning that it spends no quota, and a call that failed earns nothing either. |
| `data.progress.xp` | integer | Experience earned across every key on the account, for its whole life. |
| `data.progress.xpToday` | integer | Experience earned today (UTC). |
| `data.progress.dailyXpCap` | integer | The most one key can earn in a UTC day. A ceiling rather than a target: reaching it every day is not how the levels are meant to be climbed. |
| `data.progress.level` | integer | Your level, derived from `xp` alone. Nothing else moves it. |
| `data.progress.levelStartsAt` | integer | The experience this level began at. |
| `data.progress.nextLevelAt` | integer | The experience the next level begins at. |
| `data.progress.streakDays` | integer | Consecutive days you have called the API, counting today. A day you did not call breaks it, though yesterday still counts as unbroken so a timezone does not cost you a streak. Reported, never rewarded: no experience is paid for showing up. |
| `data.progress.daysActive` | integer | Days you have called the API at all, over the last two years. |
| `data.progress.operationsUsed` | integer | Documented operations you have called at least once. Counted from the request log by the nightly job, so an operation you called for the first time today appears tomorrow. |
| `data.progress.operationsAvailable` | integer | Documented operations there are to call, counted from this document rather than written down, so it cannot fall behind a route added today. |
| `data.endpointCredits` | object | Calls to endpoints above your plan, attached to the account so every key draws on the same balance. Every new account starts with a one-time grant covering any endpoint up to Studio, and the team can give more. A call spent this way is served exactly as the endpoint's own plan would be (full fields, that plan's paging depth), is marked with an `X-Endpoint-Credit: spent` header, and still counts against your plan's per-minute and daily limits. A call that fails, or answers `304`, is given back. |
| `data.endpointCredits.remaining` | integer | Calls left across every credit that can still be spent. |
| `data.endpointCredits.credits` | object[] | Every credit the account has had, newest first, spent ones included. |
| `data.dailyBreakdown` | object[] | Requests per day over the reported period, oldest first. Days with no traffic are omitted. |
| `data.dailyBreakdown[].date` | string | The day, `YYYY-MM-DD` in UTC. |
| `data.dailyBreakdown[].count` | integer | How many records fall in this bucket. |
| `data.dailyBreakdown[].mcpCount` | integer | Of `count`, the requests made through the MCP server. |
| `data.perKey` | object[] | Requests per API key over the reported period. |
| `data.perKey[].keyId` | string | Id of the API key. The key itself is never returned. |
| `data.perKey[].keyName` | string | The label you gave the key. |
| `data.perKey[].count` | integer | How many records fall in this bucket. |
| `data.perKey[].mcpCount` | integer | Of `count`, the requests made through the MCP server. |
| `data.perKey[].mcpToday` | integer | MCP calls this key made today (UTC), the figure its daily MCP limit is held against. |
| `data.perKey[].today` | integer | Requests this key made today (UTC), the figure its daily limit is held against. Counts calls the limit refused. |
| `data.perKey[].remainingToday` | integer \| null | Requests this key has left today, never below zero. Null when the plan has no daily ceiling. |
| `data.keyCount` | integer | How many API keys the account holds. |
| `data.tier` | object | The allowances of the plan the account is on. |
| `data.tier.name` | string | Display name, as the maker writes it. |
| `data.tier.requestsPerMonth` | integer | Monthly request allowance on this plan, enforced for the whole account. |
| `data.tier.requestsPerDay` | integer \| null | Requests each key may make per UTC day on this plan: the limit that is enforced. Null when the plan has no daily ceiling. |
| `data.tier.rateLimit` | integer | Requests per minute this plan allows. |
| `data.tier.mcpCallsPerDay` | integer | MCP calls each key may make per UTC day on this plan. |

```json
{
  "success": true,
  "data": {
    "currentMonth": {
      "used": 1284,
      "limit": 25000,
      "remaining": 23716,
      "percentage": 5.1,
      "resetsAt": "2026-10-01T00:00:00.000Z"
    },
    "daily": {
      "limitPerKey": 5000,
      "usedToday": 1840,
      "busiestKeyToday": {
        "keyId": "key_01H8...",
        "keyName": "Production",
        "used": 1670,
        "remaining": 3330,
        "percentage": 33
      },
      "resetsAt": "2026-09-18T00:00:00.000Z"
    },
    "mcp": {
      "usedThisMonth": 312,
      "usedToday": 41,
      "dailyLimitPerKey": 2500,
      "busiestKeyToday": {
        "keyId": "key_01H8...",
        "keyName": "Claude Desktop",
        "used": 38,
        "percentage": 2
      },
      "resetsAt": "2026-09-18T00:00:00.000Z"
    },
    "progress": {
      "xp": 4210,
      "xpToday": 180,
      "dailyXpCap": 500,
      "level": 10,
      "levelStartsAt": 4050,
      "nextLevelAt": 5000,
      "streakDays": 12,
      "daysActive": 96,
      "operationsUsed": 31,
      "operationsAvailable": 145
    },
    "endpointCredits": {
      "remaining": 50,
      "credits": [
        {
          "id": "9f2c1e0a-5b7d-4c1e-8a3f-2d6b9e4c7a10",
          "source": "welcome",
          "operations": [
            "get /v1/firearms/{id}"
          ],
          "maxTier": "studio",
          "callsGranted": 50,
          "callsUsed": 12,
          "callsRemaining": 38,
          "expiresAt": "2026-12-31T00:00:00.000Z",
          "status": "active",
          "createdAt": "2026-09-10 08:30:00"
        }
      ]
    },
    "dailyBreakdown": [
      {
        "date": "2026-09-10",
        "count": 2187,
        "mcpCount": 64
      }
    ],
    "perKey": [
      {
        "keyId": "key_01H8...",
        "keyName": "Production",
        "count": 1603,
        "mcpCount": 210,
        "mcpToday": 38,
        "today": 1670,
        "remainingToday": 3330
      }
    ],
    "keyCount": 2,
    "tier": {
      "name": "Studio",
      "requestsPerMonth": 150000,
      "requestsPerDay": 10000,
      "rateLimit": 300,
      "mcpCallsPerDay": 2500
    }
  }
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/me/usage?month=2026-08' \
  --header 'X-API-Key: your_key'
```
