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

# Usage

# Usage and limits

Every AI verb in the API can be refused by a usage limit — post
generation, image generation, and the knowledge/source ingests that
summarise or transcribe. There are two:

| Limit                                   | Error                                                      | Period                  | Scope                                       |
| --------------------------------------- | ---------------------------------------------------------- | ----------------------- | ------------------------------------------- |
| Weekly AI budget — the primary one      | [`usage_limit_exceeded`](./errors/usage_limit_exceeded.md) | Resets Monday 00:00 UTC | One project's budget, or the workspace pool |
| Daily API AI-spend cap — an abuse valve | [`spend_cap_exceeded`](./errors/spend_cap_exceeded.md)     | Resets 00:00 UTC        | The workspace's API traffic                 |

`GET /v1/usage` reports both **before** either fires, so a client
never has to discover a limit by spending a job on it.

***

## `GET /v1/usage`

**Scope:** `workspace:read` · **Rate-limit bucket:** read

```bash theme={null}
curl -s https://api.scripe.io/v1/usage?projectId=proj_a1b2c3d4e5f6g7h8 \
  -H "Authorization: Bearer scripe_sk_live_…" \
  -H "Scripe-Api-Version: 2026-08-10"
```

### Response

```json theme={null}
{
  "data": {
    "plan": "BUSINESS",
    "canGenerate": true,
    "blockedBy": null,
    "ai": {
      "scope": "ai_project",
      "percentUsed": 42,
      "unlimited": false,
      "enforcement": "block",
      "weekStart": "2026-08-10",
      "resetsAt": "2026-08-17T00:00:00.000Z",
      "project": {
        "id": "proj_a1b2c3d4e5f6g7h8",
        "name": "Lisa Holzinger",
        "percentUsed": 42,
        "unlimited": false
      },
      "workspacePool": { "percentUsed": 7, "unlimited": false }
    },
    "storage": {
      "usedBytes": 10032669,
      "limitBytes": 665719930880,
      "percentUsed": 0,
      "usedAssets": 9,
      "assetLimit": 120000
    },
    "apiSpend": {
      "bucketDate": "2026-08-14",
      "capCents": 10000,
      "spentCents": 16,
      "remainingCents": 9984
    }
  }
}
```

### Read `canGenerate` first

`canGenerate` is `false` exactly when the next AI job would be refused,
and `blockedBy` names the limit responsible (`weekly_ai_budget` or
`daily_api_spend_cap`). It is worth preferring over the raw meters
because two things about them are easy to get wrong:

* A meter at 100% only *refuses* when `ai.enforcement` is `block`. The
  other modes (`off`, `shadow`, `warn`) meter without blocking.
* The daily cap compares `spent + the job's estimate` against the cap,
  not `spent` against the cap — so a workspace with 2¢ of headroom is
  already blocked for a 5¢ post generation.

`canGenerate` considers usage limits only. A call can still fail for a
missing scope or a plan that does not include the feature.

### Why AI is a percentage and storage is bytes

The weekly AI budget is denominated in provider cost, so the number
that means something to a customer is *how much of the allowance is
gone* — the same figure the Scripe dashboard's usage card shows.
Storage is a plain quantity and is reported in bytes; the daily API cap
is reported in cents because it already appears that way in the
`spend_cap_exceeded` error body and in the published per-plan table.

### Project vs pool

With `projectId` the answer is about that project's weekly budget and
`ai.project` names it. Without one, `ai.project` is `null` and the
answer covers the workspace pool.

A **company page** has no budget of its own — it spends from the
workspace pool — so passing a company page's `projectId` reports the
pool, and `ai.scope` says `ai_workspace_pool`. That routing is the same
one the gate performs, so this read and the refusal cannot disagree.

### Field reference

| Path                                        | Type            | Notes                                          |
| ------------------------------------------- | --------------- | ---------------------------------------------- |
| `plan`                                      | string          | The workspace's plan at request time.          |
| `canGenerate`                               | boolean         | Would the next AI job be accepted?             |
| `blockedBy`                                 | string \| null  | `weekly_ai_budget` \| `daily_api_spend_cap`.   |
| `ai.scope`                                  | string          | Which budget governs the next job.             |
| `ai.percentUsed`                            | integer         | 0-100 of that budget. Always 0 when unlimited. |
| `ai.enforcement`                            | string          | `off` \| `shadow` \| `warn` \| `block`.        |
| `ai.weekStart` / `ai.resetsAt`              | string          | The current usage week and when it rolls over. |
| `ai.project`                                | object \| null  | Present only when the request named a project. |
| `ai.workspacePool`                          | object          | The pool meter, always reported.               |
| `storage.limitBytes` / `storage.assetLimit` | integer \| null | `null` = unlimited.                            |
| `apiSpend.remainingCents`                   | integer \| null | Today's headroom; `null` = unlimited.          |

## Related

* [`usage_limit_exceeded`](./errors/usage_limit_exceeded.md)
* [`spend_cap_exceeded`](./errors/spend_cap_exceeded.md)
* [Jobs](./jobs.md) — every AI verb runs as one.
