Docs menu

API referenceLimits

Limits

What each plan allows, how a document is measured, and what a refusal costs.

The plan limits apply on the API, in the MCP server and in the editor's download. Separate renderer bounds also apply to every plan. A refusal names the limit it hit with a stable error code; the codes and what to do about each are on Errors and quota.

What each plan allows#

Limits on one document: how large it may be and how long it may take.

PlanMarkdownResourcesPagesRender time
Free512 KB1.5 MB2030 s
Starter2048 KB6 MB20060 s
Pro4096 KB12 MB1,00090 s
Scale8192 KB24 MB2,048120 s

Limits on the account: how much it may ask for, and how fast.

PlanDocuments per periodRequests per minuteConcurrent rendersImages linked from the web
Free10051Loaded
Starter1,000302Loaded
Pro10,0001205Loaded
Scale100,00060020Loaded

Requests per minute and concurrent renders are per account, not per key: every API key, the MCP server and the editor's download share them. A period starts each month at 00:00 UTC on the day the account signed up or, after a purchase, on the day of the purchase. GET /v1/usage reports your account's live limits and what is left of the period. Images linked from the web are loaded for signed-in accounts with documents left and never stored; images embedded in the document render on every plan. See how we load images.

How a document is measured#

Three budgets are checked before the render starts (the request body, the Markdown and the resources), so a document that does not fit costs nothing. Two more, the page count and the render time, can only be checked while or after the document is laid out.

The request body

The whole body is checked first, against a service ceiling the deployment derives from the largest plan it sells: that plan's Markdown and resources once base64 and JSON framing are counted, with headroom above it, so no document a plan sells reaches it. Over it the answer is 413 payload_too_large before the body is read; nothing is rendered and no document is spent.

A deployment may also hold the page count and the render time below what a plan sells. Where such a ceiling is what refused the document, the limit descriptor carries the service's number and plan: null, because no plan set it; a refusal against the plan's own number names that plan as usual.

The Markdown budget

The base64 payloads embedded in the document are split out of the Markdown before it is measured. What is left (the text, the syntax, the alt text and the URLs) is what counts against the plan's Markdown budget (512 KB on Free). A data: resource therefore never counts against the Markdown budget: it is charged to the resource budget instead.

The resource budget

The embedded base64 bytes and the bytes loaded for remote resources are counted together against the plan's resource budget (1.5 MB on Free). One resource may use the whole budget. Over it, the answer is 413 payload_too_large.

Two counts apply to every plan alike: at most 50 remote resources and 500 embedded resources in one document. Over either, the answer is 422 too_many_resources.

Pages and time

The page count is known only while the document is laid out. The renderer stops the layout when it passes the plan's page limit, and the answer is 422 too_many_pages. A render that outlasts the plan's render time is answered at once with 422 render_timeout, while the engine finishes the step it is on. Both return the document to your period.

The renderer has no page bound of its own. The only bound above the plan's page limit is the service's page ceiling: the deployment derives it from the largest plan it sells, with headroom above it, and may set it lower.

Strict and lenient#

A document may reference resources the service has to load. The JSON body's resources field decides what happens when one of them fails. The default is strict.

POST /v1/render
{ "markdown": "# Report\n\n![chart](https://example.com/chart.png)", "resources": "lenient" }
  • strict: a resource that cannot be loaded or cannot be read refuses the whole document with 422 resource_fetch_failed. The answer carries the failing resource's position in the document, never its URL. Use it when a missing resource makes the PDF wrong.
  • lenient: a failed resource is drawn as a placeholder and the rest of the document renders. The response says how many failed, in x-legivel-resources-failed (failed/total) and x-legivel-resources-failed-ids. Use it when a partial document is better than none.

On a plan that does not load remote resources, a strict document with remote references is refused 403 plan_required before any document is spent; lenient renders it with placeholders. Resources embedded in the document as data: URIs are always available, on every plan.

Renderer bounds#

A document within its plan budgets can exceed a renderer bound during preparation or rendering. The response is 413 payload_too_large with reason: preparation_limit. When the renderer identifies a known bound, renderer_bound names it. MCP reports the same name in _meta["legivel/renderer_bound"]. No limit descriptor is attached: the renderer reports no numeric value or plan for this refusal.

Bound namesMeaning and next step
OutOfMemory, MemoryLimit, PreparedMemoryLimitMemory was unavailable or a memory budget was reached. Reduce document complexity or resource sizes.
SourceLimit, SourceBytesLimit, PreparedBytesLimitA source or prepared-resource byte budget was reached. Use smaller resources.
ResourceCountLimitA resource count was reached. Reduce the number of resources.
ResourceDepthLimit, DepthLimitA nesting bound was reached. Reduce nested resource references or document structure.
ImageTooLarge, ImageTooManyPixels, ImageDimensionsTooLargeAn image size or pixel bound was reached. Reduce image dimensions or resolution.
ElementLimit, SvgWorkLimit, DecodedWorkLimitA structure or processing bound was reached. Simplify diagrams, repeated graphics or document structure.
ResourceLimit, InspectionLimit, CapacityAn internal resource, inspection or capacity bound was reached. Reduce document or resource complexity.

An unknown or unavailable name is omitted. The refusal still reports preparation_limit. These names do not establish a Markdown size ceiling. A larger plan does not raise these bounds. A refused render costs no document; make the input smaller or simpler before trying again.

What a refusal costs#

Only a PDF you receive is charged. A document is reserved from your period before the render starts and returned whenever the render does not produce the file:

  • Refused before anything is reserved, so nothing is charged: 403 plan_required, 429 rate_limited, 400 invalid_request, 400 empty_document, and the 413 payload_too_large or 422 too_many_resources raised against the document as sent: its body, its Markdown, its embedded resources and the resources it links.
  • Reserved and then returned: 422 too_many_pages, 422 render_timeout, 422 render_failed, 422 resource_fetch_failed, 422 signing_failed, a 503 that could not dispatch the render, and a 413 payload_too_large or 422 too_many_resources raised only once remote resources are loaded: their bytes, or the resources they in turn reference.
  • A replay, the same document under the same Idempotency-Key, renders again at no charge.

A returned document is recorded with the error code that caused it, and with the page count when the render got far enough to know one. The period counter is transactional, so a return is exact rather than eventual.

Raising a limit#

  • Move up a plan. Every number in the tables above rises with the plan. Change plan under Billing on the account page; the new limits apply to the next request.
  • Out of documents, not out of size. When the period's documents are used up the answer is 402 quota_exhausted; see Monthly quota.
  • Need more than the published plans. Higher volumes, longer renders and larger documents are arranged per account; write to support@legivel.com with the document sizes and the monthly volume you expect.

A document near the page limit is usually near the render time as well. Splitting a long report into sections renders faster and refuses less often, at the cost of one document per section.