Billing & spend caps
When the API stops spending.
Model-backed calls are metered and attributed to the key that made them. An organization can cap what its API keys are allowed to spend in a period — and when that cap is reached, the calls that would spend are refused rather than silently billed.
Which calls spend
The ones that run a model or a pipeline: interpret, generate (both the plan call and the approve call), conversation messages, and asking for an analyses run. Reads — the project list, metadata, source, live values, an analysis read, export polls — cost nothing and are never gated by the cap.
The one response to handle
| Error code (402) | Meaning & what to do |
|---|---|
api_spend_limit_reached | The org paused API usage after reaching its spend limit for the period. Not retryable — surface it to a human rather than backing off, because nothing changes until someone acts. |
{
"error": "api_spend_limit_reached",
"message": "This organization has reached its API spend limit for the period.",
"userMessage": "Your organization paused API usage after reaching its monthly API spend limit.",
"suggestedAction": "An org owner/admin can raise or remove the limit, or switch to \"Continue with overage billing\", in Settings → Spending Controls.",
"isRetryable": false,
"request_id": "req_8f2a1c9d4e5b6a7c8d9e0f12"
}from plcsai import ApiError
try:
result = client.interpret("prj_…", "Why is the filler stuck?")
except ApiError as e:
if e.error == "api_spend_limit_reached":
# Do not retry — an owner/admin has to raise the cap first.
notify_operator(e.user_message, e.suggested_action)
else:
raisetry
{
var result = await client.InterpretAsync("prj_…", "Why is the filler stuck?");
}
catch (PlcsApiException e) when (e.Error == "api_spend_limit_reached")
{
// Do not retry — an owner/admin has to raise the cap first.
NotifyOperator(e.UserMessage, e.SuggestedAction);
}Usage is reported, not billed, on the call itself. Every model-backed response carries a usage block summing the token counts across every model call that turn made — informational, so you can attribute cost per integration. It is not an invoice.
Per-project charges
Organizations billed per project confirm that charge when a machine is onboarded — which happens in the app or through a version-source connector, never over this API. There is no create-a-project verb here, so an API key cannot add a billable project and no acknowledgement handshake applies to it.
Saving a new version of an existing project (/versions) adds no billable project, on any plan.