PLAN_RESTRICTED
The action needs a higher plan, such as buying credits on the Free plan.
What this means
[02]PLAN_RESTRICTED fires when an action needs a higher plan than you have. The main case is buying credits on Free: Free accounts can receive granted credits but can't buy them. The Serve analytics CSV export also returns it unless you're on Pro or Business.
When you'll see it
[03]HTTP 403. Body always includes code: "PLAN_RESTRICTED". Branch on code, never on the human-readable message — wording can change without notice; the code is the stable contract.
Example response
[04]{
"status": "error",
"code": "PLAN_RESTRICTED",
"message": "Credit top-ups require a paid plan. Upgrade to Starter or higher to purchase credits.",
"current_tier": "free"
}How to handle
[05]Upgrade at app.buildonto.dev/read/billing. Buying credits needs Starter or above. Retrying won't help.
Suggested handling in a Node client:
if (data.code === 'PLAN_RESTRICTED') {
// Surface upgrade CTA — never retry blindly.
return res.status(402).json({ error: 'Upgrade required', upgradeUrl: 'https://app.buildonto.dev/read/billing' });
}A paid plan used up its monthly credits and has no bought credits left.
The Authorization header is missing, malformed, or holds a key that isn't active.
See the full error index for the complete catalog with the handling switch statement covering every code at once.