Every number on this page is fixed in the product. It is the same on Free and on Enterprise, it does not appear on an invoice, and upgrading will not move it. When you hit one of these, the answer is in the last column of a table, not in a plan change.
How to tell which kind of limit you hit
You can tell the three kinds apart from the response alone, before you know anything about the feature.
- A 400 — or a form that refuses before it submits — is a fixed ceiling. It is on this page.
- A 402
upgrade_requiredis a plan quota or a feature gate. Those live on Usage and Limits and When a Feature Is Gated. - A 200 with nothing in it is neither. It is a gate that degrades silently instead of returning an error, and When a Feature Is Gated names the ones that behave that way.
flowchart LR
A["400, or the form<br/>refused to submit"] --> D["Fixed ceiling<br/>— this page"]
B["402 upgrade_required"] --> E["Plan quota or feature gate<br/>— Usage and Limits"]
C["200, but empty or<br/>missing data"] --> F["Silent degradation<br/>— When a Feature Is Gated"]
A -.- A1["Same on every tier.<br/>Upgrading changes nothing."]
B -.- B1["Body names the feature,<br/>your tier and the tier needed."]
C -.- C1["No error at all.<br/>The widget just never fills."]
Analytics
A single analytics query may span at most 365 days. The guard is shared by every analytics route — Know, page analytics, forms and short-code reporting — so none of them can drift from the others.
| Limit | Value | What happens when you hit it | What to do instead |
|---|---|---|---|
| Span of one analytics query | 365 days | 400 — Range cannot exceed 365 days | Split the question into two queries and add the results |
| Direction of the range | End must be after start | 400 — end must be after start | Reverse the dates |
Uploads and files
| Limit | Value | What happens when you hit it | What to do instead |
|---|---|---|---|
| Image upload size | Strictly under 10 MB | The upload modal refuses before the file is read, hashed or cropped | Compress or resize — Uploading Images |
| Image file type | png, jpeg, gif, webp, svg | The modal refuses with the accepted list | Convert the file, or upload it as a different kind of asset |
| Repository file size | 500 KB per file | leed site validate and leed site commit refuse the commit and name every oversized file | Move the asset into the CMS asset library instead of the repository |
| Repository file extensions | Media, archives, office documents and fonts are refused | The same refusal, listing the disallowed extensions | Upload it as an asset and reference it by URL |
| OpenAPI spec file | Under 25 MB | A hard error at generate time and again at upload — never a truncation | Split the spec, or trim examples out of it |
Both upload refusals are shown to you verbatim:
Image is 12.4MB. Images must be under 10MB.
Valid file types are: png,jpeg,gif,webp,svgTwo details worth knowing before you argue with the first one. The size in the message rounds up to a tenth of a megabyte, so a file one byte over reads as 10.1MB rather than 10.0MB. And the check is client-side only — it protects the upload modal, not the platform, so a caller working through the API is not stopped by it and should apply the same ceiling itself.
The 500 KB repository rule is the one number here that a self-hosting operator can change: the build reads FILE_VALIDATION_MAX_SIZE from the environment and interprets it in kilobytes, not bytes. It is not a per-workspace setting and there is no CMS control for it. The rest of the repository validation — the read-only files, the protected paths, the extension list — sits with it at File Validation Rules, and the CLI’s side of the refusal is leed site validate, commit and push.
Text field caps
| Limit | Value | What happens when you hit it | What to do instead |
|---|---|---|---|
| Social card title | 70 characters | The value is rejected on save | Write a shorter title — the card truncates in most feeds anyway |
| Social card description | 240 characters | Rejected on save | Shorten it |
| Page-type slug | 150 characters | Rejected on save | Shorten a segment; nested API roots count the separators too |
| Custom theme, code-theme and font name | 32 characters, ^[a-z0-9]{1,32}$ | 400 naming the field | Use lowercase letters and digits only, with no dashes |
| Form description | 400 characters | Rejected on save | Move the long copy onto the page around the form |
Batch and page-size ceilings
These are throughput mechanics rather than entitlements. Nothing here bills you, blocks you or shows an error — the work is split into more than one unit and proceeds. They matter mostly if you are calling Leed from a script or an MCP client and wondering why a result set stopped where it did.
Batch sizes and per-call page sizes
| Limit | Value | What happens when you hit it | What to do instead |
|---|---|---|---|
| Contact CSV fan-out | 10 contacts per queue message | The import lands progressively rather than all at once | Wait — the list fills in as the messages drain. Importing Contacts describes what you see |
| Marketing send fan-out | 100 recipients per batch message | The blast is chunked; recipients are reached over several invocations | Nothing; this is invisible except in timing |
| Engage segment membership | 1,000 members resolved per request | The scored list stops at 1,000 | Narrow the segment |
schedule_pages (Operator MCP) | 1–100 page ids per call | The call is rejected with a parameter error | Split the schedule into several calls; every page in one call shares one time slot |
| Operator MCP list tools | Page size 1–100 | The page size is rejected outside that band | Page through with offset |
| Operator MCP content search | Query 2–200 characters, limit 1–50 | Rejected outside those bands | Shorten the query or lower the limit |
| Docs MCP page fetch | 25 pages per call | Rejected above 25 | Fetch in batches of 25 |
| Docs MCP search results | 25 results maximum | The result list stops at 25 | Narrow the query |
Each MCP tool states its own parameter bounds; Operator MCP Tool Index points at the right tool’s table.
Rate limits
Three rate limiters are deployed, all of them fixed and none of them plan-scoped.
| Limit | Value | What happens when you hit it | What to do instead |
|---|---|---|---|
| Authentication endpoints | 10 requests / 60 s, keyed on your Authorization header or your IP | The request is refused until the window rolls | Wait a minute; nothing is lost |
| Contact detail reads | 60 requests / 60 s, keyed on the requesting user | The read is refused until the window rolls | Page through contacts instead of fetching them one at a time |
| Public site agent surface | 60 requests / 60 s, per IP | 429 with a JSON body | Back off and retry |
The agent surface is the only one of the three that answers with a body you can parse:
{ "error": "rate_limited" }The authentication limiter deliberately exempts the paths a CLI login walks — the device-code request, the device-code polling loop, the OAuth callback, sign-out and every already-authenticated session read — so signing in a terminal is never throttled mid-poll. Sign-in itself, and anything that handles a credential, stays limited.
These are deployment configuration rather than source constants: they are read per environment, and every environment currently agrees on the values above. Treat them as the current production numbers, not as an API contract.
Time limits
| Limit | Value | What happens when you hit it | What to do instead |
|---|---|---|---|
| CMS session | 7 days | You are signed out and returned to the sign-in screen | Sign in again; the session refreshes while you use it. Sessions, Connected Accounts and API Tokens |
| Magic link | 5 minutes | The link reports that it has expired | Request a new one |
| Emailed one-time code | 5 minutes | The code is refused | Request a new one |
| Device code (CLI and client authorization) | 5 minutes, polled every 5 seconds | The pending authorization lapses | Run the command again — Authorizing Devices and Clients |
| Build | 15 minutes | The deployment is marked failed as a safety net | Retry the deployment; a genuine 15-minute build is a content problem, not a slow build |
| Domain Connect re-check | Every 10 seconds, 12 times (2 minutes) | Polling stops and the button becomes manual | Click Check now once DNS has propagated |
| Scheduling horizon | 365 days ahead | A slot further out is not offered | Schedule closer in and revisit |
Display ceilings that are not limits at all
These are presentation and storage choices. Nothing is refused; you are simply not shown everything.
| Limit | Value | What happens when you hit it | What to do instead |
|---|---|---|---|
| Deployment history | Last 10 rows per column | Older deployments drop off the Deploy tab | Nothing is deleted; the history is trimmed for the screen only |
| Build error summary | 2,000 characters | The block you are shown is an extract | Treat a truncated block as a pointer, not the whole story — When a Deployment Fails decodes it |
| Visitor cookie lifetime | 1 year | Nothing; the cookie is refreshed as the visitor returns | Nothing |
The three that do move
These are the only numbers in Leed that change when your plan does. They are listed here so you can rule them out; the mechanics belong to Usage and Limits.
| Quota | Free | Starter | Growth | Enterprise | Documented in |
|---|---|---|---|---|---|
| Identified contacts | 250 | 1,000 | 10,000 | Unlimited | Usage and Limits |
| Marketing emails per month | 0 | 5,000 | 50,000 | Unlimited | Usage and Limits |
| Analytics retention | 30 days | 365 days | 730 days | Unlimited | Date Ranges and Retention |
The contacts number is a visibility cap applied when contacts are read, not a gate on capture. Forms keep accepting submissions past it and nothing is discarded; you see the oldest contacts up to your allowance until you upgrade. A denial on any of these three arrives as a 402 upgrade_required, and When a Feature Is Gated covers what happens next.
Limits that do not exist
Readers arrive looking for these, so it is worth saying plainly that they are not here. Leed imposes no traffic limit, no unique-visitor limit, no bandwidth limit, no storage limit, no seat limit and no page-count limit, on any plan. Editors and pages are unlimited on Free. If you are hunting for the number at which your site gets throttled or your team gets billed for another seat, there is no such number to find — the capabilities that are absent rather than capped are named at What Leed Does Not Do.