API v1 · Resources
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 | Resets Monday 00:00 UTC | One project's budget, or the workspace pool |
| Daily API AI-spend cap — an abuse valve | spend_cap_exceeded | 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
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
{
"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.enforcementisblock. The other modes (off,shadow,warn) meter without blocking. - The daily cap compares
spent + the job's estimateagainst the cap, notspentagainst 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_exceededspend_cap_exceeded- Jobs — every AI verb runs as one.