Netlify Documentation Audit
One-line state of the docs: a broad, actively-maintained platform reference that reads well for humans but leaks legacy identifiers, scatters hard limits across unrelated pages, buries silent-footgun caveats, and ships an agent-facing surface (llms.txt, MCP, skills) whose own links don't agree with each other.
1. Function limits (timeout, memory, payload) are absent from the Functions docs and scattered to billing and async pages (critical)
Location: /build/functions/overview/ ; /build/functions/get-started/ ; /build/functions/usage-and-billing/ ; /build/async-workloads/limitations/
Problem: Edge Functions has a dedicated /build/edge-functions/limits/ page (code size 20 MB, memory 512 MB, CPU 50 ms, header timeout 40 s). Serverless Functions has no equivalent. The Functions overview and get-started pages contain no limits section at all. The only place memory is stated is the billing page ("The default memory allocation for Netlify Functions is 1024 MB… up to 4096 MB"), and the 6 MB payload limit only surfaces on the Async Workloads limitations page ("Given the 6 MB limit for Netlify functions…"). Function execution timeout is not stated anywhere in the scraped Functions content.
Consequence: A developer evaluating whether their workload fits Netlify Functions cannot find the payload ceiling, memory defaults, or execution timeout from the Functions docs. They learn the 6 MB payload limit only if they happen to read the Async Workloads page — a feature they may not use. Agents indexing the Functions docs will report "no documented limits," which is false.
The fix: Create /build/functions/limits/ mirroring the Edge Functions limits page (timeout, default + max memory, payload size, concurrency), and link it from the Functions overview. Consolidate the numbers currently stranded on the billing and async-workloads pages.
2. The MCP server link advertised to agents redirects to a page with no dedicated MCP content (critical)
Location: /build/build-with-ai/netlify-mcp-server/ (redirects to /build/build-with-ai/agent-setup-guides/agent-setup-overview/) ; /llms.txt
Problem: The canonical MCP server URL https://docs.netlify.com/build/build-with-ai/netlify-mcp-server/ is confirmed by both fetch methods to 301/302-redirect to the generic "Agent setup overview" page. The destination page then itself renders a link reading "Learn more about Netlify's MCP server." — i.e., the page you were redirected to in search of MCP details tells you to go learn more about the MCP server. There is no longer a dedicated MCP server reference page at the advertised path. (The scraped llms.txt excerpt is truncated and does not show the exact link label, but the redirect and the circular destination link are both verbatim in the page content.)
Consequence: The MCP server is the integration point explicitly built for AI agents, and its advertised link resolves to a stub that circularly points back at the topic. An agent following the docs to configure MCP lands on overview prose, not a spec.
The fix: Either restore a dedicated MCP server page at the advertised URL or update the link target to point directly at the real reference, and remove the self-referential "Learn more about Netlify's MCP server" link from the destination page.
3. The "site" vs "project" rename is half-finished and contradicts itself in the same sentence (significant)
Location: /api-and-cli-guides/cli-guides/get-started-with-cli/ ; /build/caching/caching-overview/ ; /api-and-cli-guides/api-guides/get-started-with-api/
Problem: The UI was renamed from "Site"/"Site ID" to "Project"/"Project ID", but the API and env vars were not. The CLI guide tells you to "copy the value for Project ID. (Also known as Site ID.)" and then in the very next step assign it to NETLIFY_SITE_ID. The caching page contains the worst of it: "checking the Project ID or Project name (Also known as Site ID in the Netlify API and formerly as Site ID and Site name in the Netlify UI.)". Meanwhile the REST API guide uses site_id and /sites/{site_id} exclusively (the site_slug variant appears on the caching page).
Consequence: A developer (or an agent) reading the UI sees "Project ID," searches the API docs for "project," finds nothing, and has no programmatic confirmation that Project ID == Site ID == the value NETLIFY_SITE_ID expects. The IDs are in fact the same value, but the reconciliation is buried in an inline parenthetical instead of stated as a first-class concept, so the mapping is easy to miss.
The fix: Add a single canonical "Project ID / Site ID" identifier note at the top of the API and CLI getting-started pages stating plainly: UI label = "Project ID", API field = site_id, env var = NETLIFY_SITE_ID, all the same value. Stop relying on inline asides to carry a platform-wide rename.
4. Async Workloads silently breaks if you set path or schedule inline — and there's no way to invoke one directly (significant)
Location: /build/async-workloads/limitations/
Problem: Async Workloads run on top of serverless functions, which normally take path/schedule in their inline config. The limitations page states the opposite for workloads — but only in prose buried under "Functions configuration": "Because the Async Workloads system will handle all event routing, do not set the path or schedule inline configuration for a serverless function. At this time, there is no way to invoke Async Workload functions directly without using the AsyncWorkloadClient or the router API." The recommended pattern (a separate function that calls client.send()) follows in the same paragraph.
Consequence: A developer who reuses the standard Functions snippet — which prominently sets export const config: Config = { path: "/..." } — and adds it to an Async Workload gets a route that silently never works, with no error explaining why. This is exactly the "agents fail silently" failure mode: the config key is valid for ordinary functions and invalid here, and nothing flags the difference at deploy time.
The fix: Promote this caveat out of prose into a callout/warning at the top of the Async Workloads docs, and add it to the Functions configuration reference as a note ("path/schedule are ignored for Async Workload functions — invoke via client.send() instead").
5. The Functions AI example won't run as copied — hardcoded model and no credential setup (significant)
Location: /build/functions/overview/
Problem: The headline function example instantiates new OpenAI() and calls client.responses.create({ model: "gpt-5-mini", … }). There is no mention of an OPENAI_API_KEY environment variable, no note that the model name is a placeholder, and no link to where the key is configured. The model string gpt-5-mini is hardcoded into a sample meant to demonstrate the platform.
Consequence: A developer or agent copies the snippet, deploys it, and the function throws at runtime because no API key is configured — an error that has nothing to do with Netlify and isn't anticipated anywhere on the page. Copy-paste completeness fails: a required external credential is invisible.
The fix: Add the required OPENAI_API_KEY (or AI Gateway) setup step alongside the example, mark gpt-5-mini as a substitutable placeholder, and note the example depends on an external provider account.
6. REST API docs have no structured error/status-code reference (significant)
Location: /api-and-cli-guides/api-guides/get-started-with-api/
Problem: The API guide documents auth, rate limits, and the X-RateLimit-* headers, but error handling is reduced to a few scattered facts: async requests over 30 s are terminated, deploys are capped at 3/min and 100/day, cache purges return 429, and a hook is deleted if its endpoint returns 410 Gone. There is no consolidated table of error response shapes, HTTP status codes, or error body schema for the general API.
Consequence: Developers cannot write reliable error handling without trial and error, and agents have nothing parseable to branch on. "What does a 4xx body look like? How do I distinguish a rate-limit from an auth failure programmatically?" is unanswerable from the docs.
The fix: Add an "Errors" section to the API guide with the standard error response JSON shape and a status-code table (401/403/404/422/429/5xx), ideally cross-linked to the OpenAPI spec's shared response schemas.
7. Sample API responses ship stale, misleading values (significant)
Location: /api-and-cli-guides/api-guides/get-started-with-api/#deploys
Problem: The Get sites response example contains "admin_url": "https://api.netlify.com/sites/synergy" — the admin URL points at the API host (api.netlify.com), not the app dashboard. Timestamps are 2013-09-17, and a separate endpoint documents the custom media type application/vnd.bitballoon.v1.raw (BitBalloon being Netlify's former name).
Consequence: Sample payloads are what agents and SDK authors pattern-match against. An admin_url rooted at api.netlify.com teaches consumers to construct or expect the wrong dashboard host, and the vnd.bitballoon media type reads like a typo to anyone who doesn't know the company's history — leaving developers unsure whether it's still valid.
The fix: Refresh the sample payloads with current host values and recent timestamps, and add a one-line note explaining that application/vnd.bitballoon.v1.raw is the (still-valid) legacy media type if it remains supported.
8. "Available here" references render with no link (significant)
Location: /build/functions/usage-and-billing/
Problem: Critical limit information is gated behind phantom links: "Functions are billed by request count… Limits per plan are available here." renders as plain text with no inline URL in the documentation output.
Consequence: The per-plan request limits — the exact numbers a developer on a Legacy plan needs to avoid an automatic upgrade to "the next level or package" (i.e., a bigger bill) — are described as existing "here" but "here" goes nowhere. The reader is told a limit exists and simultaneously denied the value.
The fix: Replace every "available here" with an explicit, resolvable link, or inline the per-plan limit table directly on the billing page.
9. Setup navigation paths render as unlinked, run-on breadcrumbs (significant)
Location: /api-and-cli-guides/api-guides/get-started-with-api/ ; /api-and-cli-guides/cli-guides/get-started-with-cli/ ; /build/caching/caching-overview/
Problem: The steps that tell you where to click are written as bare UI breadcrumbs with no separators and no link. The PAT instructions read "Go to Applications Personal access tokens" on both the API and CLI guides, with no URL to the destination. The caching page is worse: its purge-by-site instructions split the navigation path around a long parenthetical — "checking the Project ID or Project name (Also known as Site ID in the Netlify API and formerly as Site ID and Site name in the Netlify UI.) General Project details Project information" — so the breadcrumb "Project configuration → General → Project details → Project information" is broken in half by the disclaimer.
Consequence: A developer can't tell whether "Applications Personal access tokens" is one menu item or two, and there's no link to jump there. On the caching page the navigation path is interrupted mid-stream, so the click sequence to find your Site ID is genuinely hard to reconstruct. An agent reading the same flattened text inherits the ambiguity with nothing to resolve it.
The fix: Render setup navigation as a linked breadcrumb with explicit separators (e.g., "Applications → Personal access tokens") and link to the destination where one exists. On the caching page, move the "also known as Site ID" parenthetical out of the middle of the navigation path.
10. OpenAPI spec version (2.55.0) contradicts the /api/v1/ paths it documents (minor)
Location: https://open-api.netlify.com/ vs /api-and-cli-guides/api-guides/get-started-with-api/
Problem: The OpenAPI reference is titled "Netlify's API documentation (2.55.0)" and that number is the API version, yet every documented endpoint is rooted at /api/v1/. The API guide adds that on backward-incompatible changes "we'll bump the version marker," implying the path version is the source of truth.
Consequence: A developer who reads "2.55.0" as the API version may attempt to construct version-specific URLs or assume v1 is outdated. The relationship between the spec's semver and the URL's v1 is never explained.
The fix: Add one sentence to the spec intro and the API guide clarifying that the URL version (v1) is stable and 2.55.0 is the spec/release revision, not a path component.
11. The ".md version of any page" feature is advertised only on some pages (minor)
Location: /build/edge-functions/limits/ and /build/async-workloads/limitations/ vs docs home, API guide, CLI guide
Problem: The Edge Functions limits and Async Workloads limitations pages open with "Markdown versions of this page are available by appending .md to the URL." This agent-friendly capability is not mentioned on the docs home, the API guide, or the CLI guide.
Consequence: A feature explicitly useful to agents and scrapers is discoverable only by landing on one of the few pages that happen to advertise it. Agents indexing from the home page or API guide will never learn .md exists.
The fix: Surface the .md affordance globally (e.g., in the docs footer or alongside the llms.txt reference) rather than per-page, so it's discoverable from any entry point.
12. HIPAA/Trust Center link points to a different domain (minor)
Location: /build/edge-functions/limits/
Problem: The HIPAA compliance note links to https://trust-center.netlify-corp.com — a netlify-corp.com domain distinct from the netlify.com everything else lives on.
Consequence: Compliance and security links are exactly where an unfamiliar domain raises a red flag; a careful developer or security reviewer may distrust or block the link, assuming it's mis-typed or unofficial.
The fix: Host the Trust Center on a netlify.com subdomain, or add a brief note confirming netlify-corp.com is an official Netlify domain.
13. The sql engine is attributed to "Waddler" in the API reference and "Drizzle ORM" in the skills table (minor)
Location: /build/data-and-storage/netlify-database/api/ vs /build/build-with-ai/agent-setup-guides/agent-setup-overview/
Problem: The Database API reference says the sql tagged-template function is "based on the Waddler open-source module" (linked at waddler.drizzle.team), while the agent-skills table describes netlify-db as offering "Drizzle ORM integration." The two are related — Waddler is a Drizzle-team project — but a tagged-template SQL library and Drizzle ORM are not the same tool, and the docs never connect the names.
Consequence: A developer choosing a query layer can't tell whether Netlify Database ships a tagged-template SQL helper, a full ORM, or both, and which the recommended @netlify/database path actually provides.
The fix: State the relationship explicitly on the Database page — e.g., note that sql is built on Waddler (a Drizzle-team project) and clarify how that relates to the "Drizzle ORM integration" the skills table advertises — so the two names don't read as unrelated or interchangeable.
14. PUT and PATCH on /sites/{site_id} are documented with identical descriptions (minor)
Location: /api-and-cli-guides/api-guides/get-started-with-api/#deploys
Problem: Both verbs get the same one-line description: "PATCH /api/v1/sites/{site_id} updates some attributes on a site." and "PUT /api/v1/sites/{site_id} updates some attributes on a site." The only differentiator stated is that a PUT with Content-Type: application/zip behaves like a deploy — nothing distinguishes the two for ordinary attribute updates.
Consequence: A developer can't tell whether PUT does a full replace and PATCH a partial merge (the conventional REST distinction), or whether they're genuinely interchangeable. The choice affects whether omitted fields get cleared, which is exactly the kind of silent data difference that bites in production.
The fix: Document the semantic difference between the two verbs (full replace vs partial update, and how omitted fields are treated), or state explicitly that they are equivalent for this endpoint.
What they do well
- Edge Functions limits page is a model section — code size, memory, CPU time, header timeout, and feature limitations all in one parseable place. It's exactly what the Serverless Functions docs are missing.
- Real agent-facing infrastructure — llms.txt, an installable skills repo (
npx skills add netlify/context-and-tools), and a fully-rendered Redoc OpenAPI spec show genuine investment in machine consumption. - Honest legacy/maintenance docs — the Next.js v4 runtime page clearly enumerates what differs from the current adapter (Pages Router only, On-demand Builders, ipx, no tag/path revalidation) instead of pretending the old path doesn't exist.
Top 3 recommendations
- Give Serverless Functions a real limits page (timeout, memory, payload, concurrency) and pull the numbers currently stranded on the billing and async-workloads pages onto it.
- Finish the site→project rename as one canonical identifier note, stated up front in the API and CLI guides, instead of inline parentheticals that contradict the field names a line later.
- Fix the agent surface and surface its footguns: repair the redirecting MCP link, complete the AI function example with its required credential, and promote the Async Workloads
path/schedulecaveat into a callout — the places agents are most likely to fail silently.