You are most likely reading this because something is missing: a panel that says you need a different plan, a button that is not there, a recommendation block that renders nothing, or a search box on your published site that returns no results at all. A plan gate is not a permission problem, and Leed does not gate everything the same way — which is why “nothing happened” is sometimes the correct gated behavior rather than a fault.
This page describes the five things a gate can actually look like, the error that sits behind the visible ones, and the handful of gates that are deliberately silent.
Plan gates are not permission errors
Two different systems can stop you, and they have different fixes and different people to ask.
| Permission | Plan gate | |
|---|---|---|
| The question it answers | Who are you? Your role and any overrides on this resource | What does this workspace pay for? |
| HTTP status | 403 | 402 |
| Who fixes it | Someone with the Administrator role, on Settings → Team | Someone who holds billing access, on Settings → Plans & billing |
| Applies to | One person | Everyone in the workspace |
The two are additive: a plan gate never grants access, and a role never buys a feature. If you can see a surface but it refuses to save, check which of the two you are looking at before asking for the wrong thing. Roles and permissions covers the role side, and billing and developer access covers who in your workspace is allowed to change the plan at all.
The upgrade prompt
Every gated surface in the CMS renders the same component, so the prompt looks and reads the same wherever you meet it. It comes in three shapes:
- a panel that replaces the surface entirely — the whole screen becomes the prompt;
- a banner above or inside a surface that otherwise still works, used where part of a screen is gated and the rest is not;
- a coming soon variant, reserved for capabilities that are gated and not built yet, which reads “
is coming soon ” and “Arriving on theplan. ”
The copy is generated from the feature and the plan it needs, so it is always specific:
Campaign planner is available on the Growth plan Upgrade to the Growth plan to unlock campaign planner for your team.
What sits under that sentence depends on whether you can act on it:
- If you hold billing access, you get an Upgrade plan button that goes to
Settings → Plans & billing. - If you do not, you get the plain sentence “Ask your account admin to upgrade your plan.” and no button.
Navigation does not disappear
Nothing vanishes from the interface because of your plan. Rail tabs, settings cards and menu entries render the same on Free as on Enterprise; it is the destination that renders the upgrade state when you arrive. So a section you cannot use is still discoverable, and the prompt inside it tells you what it costs.
The one thing your plan does hide is the Billing & plan settings card itself — and that is a permission, not a plan gate. It is hidden from people without billing access on every tier, Enterprise included.
The error behind the prompt
Behind every visible gate is one JSON body, shared by feature gates, quota checks and the analytics window alike. If you are reading the network tab, scripting against the API or debugging an MCP client, this is the shape to match on.
{
"error": "upgrade_required",
"reason": "feature_gated",
"feature": "campaignPlanner",
"requiredTier": "growth",
"currentTier": "free"
}A quota refusal carries the same envelope with a different reason and two extra numbers. Here, a Free workspace asked for analytics reaching 90 days back against a 30-day window:
{
"error": "upgrade_required",
"reason": "quota_exceeded",
"feature": "analyticsRetention",
"currentTier": "free",
"quota": 30,
"used": 90
}| Field | Always present? | Meaning |
|---|---|---|
error | Yes | Always the literal string upgrade_required |
reason | Yes | feature_gated (the plan does not include this capability) or quota_exceeded (it does, and you have used it up) |
feature | Yes | A capability name such as campaignPlanner — or, on a quota denial, a quota kind: contacts or analyticsRetention |
requiredTier | On feature_gated; optional on quota_exceeded | The lowest plan that includes it |
currentTier | Yes | The workspace’s plan right now |
quota | On quota_exceeded only | Your allowance — a count, or a number of days for retention |
used | On quota_exceeded only | What you used, or how far back you asked |
Note that feature on a quota denial is not a plan feature. contacts and analyticsRetention ride this body because it is the one shape every denial emits, but they are meters rather than capabilities — usage and limits covers all three of them, including the marketing-email allowance.
A 400 is not a gate
One error is reliably misread as a plan gate and is not one. When you set a custom documentation theme, code theme or font name, the bare name must match ^[a-z0-9]{1,32}$ — lowercase letters and digits only, no dashes, at most 32 characters. A malformed name is a 400 with the message “a custom name must be lowercase letters and numbers only, at most 32 characters”, and it is a 400 on every plan, Enterprise included, because the shape is checked before the plan is consulted at all.
So leedai is accepted and leed-ai is rejected, and the rejection has nothing to do with what you pay. There is a plan gate on the same field — naming a custom theme is a Starter capability — but it fires only when you introduce a new custom value. Re-sending the value you already have, clearing it, or switching between built-in themes passes on every tier, which is why a downgraded workspace can still open Settings without being refused. The naming rules themselves live with custom documentation themes.
The five ways a gate can behave
Under the hood there are nine distinct enforcement points. What a person can actually observe collapses to five, and knowing which one you are looking at is the difference between “I need a bigger plan” and “this product is broken”.
flowchart TD
A[You do something] --> R{Does your role<br/>allow it?}
R -->|No| F403[403 — permission denied<br/>Ask an administrator]
R -->|Yes| P{Does your plan<br/>include it?}
P -->|Yes| OK[It works]
P -->|No| K{Where are you?}
K -->|A CMS screen| B1[Upgrade prompt<br/>e.g. campaign planner, short links]
K -->|A CMS editor control| B2[Hidden control<br/>e.g. site layouts, email templates]
K -->|A record you can read| B3[Withheld data<br/>e.g. transcripts, reader history]
K -->|Your published site| B4[Empty result or 404<br/>e.g. recommendations, live search]
K -->|Your site build| B5[Skipped at build<br/>e.g. auto-linking, footer badge]
| What you see | Where it happens | Real examples | What to do |
|---|---|---|---|
| Upgrade prompt | CMS screens | Campaign planner, dynamic CTAs, short links, recommendation settings, gated analytics metrics, sending a marketing email | Read the plan it names; upgrade, or send that sentence to whoever holds billing access |
| Hidden control | CMS editors | Custom theme and font name fields, site layouts, email templates | Nothing is broken — the editing UI is not rendered below its plan |
| Withheld data | A record that still loads | Transcripts and extracted document text, per-reader history on a contact profile | The record is intact and stored; only part of the response is removed |
| Empty or not found | Your published site’s endpoints | Recommendations return 200 [], dynamic CTA slots return 200 {}, live documentation search returns 404 | Expected below the plan — a visitor must never see a billing error |
| Skipped at build | Your site build | Auto-linking, the live-search client, the “Powered by Leed” footer badge | The site builds successfully without the feature; it appears at the next build after an upgrade |
Which capability sits behind which behavior is listed feature by feature in feature availability by plan.
- In the CMS
- On your published site
- In the API and MCP clients
You get a prompt or you get nothing rendered. Gated screens replace themselves with the upgrade panel, gated sub-sections carry a banner, and gated editing controls are simply absent. Reads are almost never gated — a downgraded workspace can still see its own data, which is what makes cleaning up after a downgrade possible.
Your visitors never see a plan message. The endpoints that power recommendations and dynamic CTAs return empty successful responses, and live documentation search returns 404 so the surface looks like it does not exist rather than like a billing problem. Your plan is read on every request, so a plan change takes effect on your live site immediately, without republishing.
You get an HTTP 402 with the upgrade_required body above. Match on error === "upgrade_required" rather than on the message, and branch on reason to tell a missing capability from an exhausted allowance. Both MCP services are free on every plan, so an MCP client is never refused for billing reasons — a 402 reaching an MCP client comes from the gated capability it called, not from MCP access itself.
For developers: which routes gate, and which stay open below the gate
Gates are placed on writes, not on reads, and specifically so that a workspace that drops a plan can still tidy up after itself.
| Surface | Blocked below its plan | Still allowed on every plan |
|---|---|---|
| Distribution channels (page Workflows) | Creating a channel, enabling one, or changing its configuration | Reading them, switching one off, and deleting one — a plain {"enabled": false} update is never gated |
| Content-level access overrides | Creating a page-type or label override | Existing overrides keep working; per-page and contact overrides are ungated; deleting an override always works |
| Custom theme and font names | Introducing a new custom value | Echoing back the stored value, clearing it, and switching between built-in themes |
| Campaign planner | Every /campaigns route | The plan calendar is deliberately left ungated, so the calendar view keeps working |
| Assets | Nothing — upload, transcription and extraction run on every tier | The whole pipeline; only the transcript and extracted text are stripped from the response below Starter |
An unknown identifier is resolved before the plan is consulted, so asking about something that does not exist returns 404 rather than leaking a 402 about a resource you cannot see.
Gates you will not see at all
The silent set deserves naming, because a quiet gate is the one that makes people think Leed is broken.
- Recommendations return an empty list on your published site. The recommendation block renders nothing at all.
- Dynamic CTAs return an empty payload, so the CTA slot stays blank.
- Live documentation search returns
404— at the edge and at the API — so it reads as “there is no search here” rather than as a payment error. This is deliberate: a visitor’s browser must never receive a billing error from your site. - Transcripts and extracted document text are stripped out of the asset response while the “a transcript exists” flag survives. That is why an asset page can honestly tell you a transcript is there and still not show it to you.
- Per-reader history is withheld from a contact’s profile while the profile itself loads normally. Identified contacts are a Free capability; their per-reader timeline is not.
- Auto-linking is skipped when your site builds. The build succeeds and says nothing in the foreground.
- An ejectable documentation header or footer is not offered. Both templates require Starter, and
leed site ejectneither lists nor ejects a template above your plan — a developer meets an absence, not a refusal. The eject command explains what the list contains.
One surface breaks the rule that every gated CMS screen renders a prompt: the click-count overlay in the page editor refuses below Growth and renders nothing at all — no panel, no banner, no explanation. That is a known defect rather than intended design, and it is recorded in known limitations.
A gentler example of the same mixed state is the editor’s Workflows tab, where a locked channel stays visible with its plan named in the row’s detail text, next to channels you can use:
A locked channel that is already switched on can still be switched off. That is deliberate — see page workflows.
If you cannot upgrade
Most people who hit a gate cannot buy their way past it, because billing access is held by one or two people in a workspace.
Whoever holds billing access goes to Settings → Plans & billing, where the plan chooser and checkout live — managing your subscription walks through the screen, and plans and tiers is the shorter argument for what each rung buys. Administrators have that access already; anyone else needs the billing override, which an Administrator grants per person on Settings → Team, as described in billing and developer access.