Schematic Documentation Audit
The conceptual material and Stripe/entitlement coverage is genuinely strong, but the developer-facing surface has a pattern of dead URLs and broken examples at exactly the spots agents and humans land first — the OpenAPI page, the changelog, the Python SDK page, and /api-reference/overview all 404, and at least one quickstart code sample won't run.
1. Python SDK lives at a malformed URL while the canonical one 404s (critical)
Location: /developer_resources/sdks/python (dead) vs. /getting-started/developer-resources/sd-ks/python (live)
Problem: Every other SDK in the catalog follows the pattern /developer_resources/sdks/<lang> (React, Node.js, Vue, Angular, Go, Java, C#, React Native, JS, Next.js — entries 47–58 of sitemap.xml). Python is the lone exception: its page is at /getting-started/developer-resources/sd-ks/python — note the orphan getting-started/ prefix and the malformed sd-ks slug. The expected /developer_resources/sdks/python is a 404. The SDK overview page at /developer_resources/sdks/overview lists Python as available, but readers and agents that derive the URL from the pattern will land on a dead page.
Consequence: Anyone navigating by URL convention — including AI coding assistants doing path inference — finds nothing at the Python SDK page. The DataStream / async-client / Replicator-Mode capabilities (which look like Python's most differentiated features) become discoverable only via the sitemap or search.
The fix: Move the Python page to /developer_resources/sdks/python, redirect the malformed URL to it, and fix the sd-ks slug source (looks like a CMS auto-slug bug from "SDKs" → "sd-ks").
2. No OpenAPI / machine-readable spec exposed (critical)
Location: /api-reference/openapi (404), /api-reference/resources, /api-reference/* endpoint pages
Problem: /api-reference/openapi returns "This page does not exist." The closest substitute, /api-reference/resources, lists resource categories (API Keys, Environments, Plans, Companies, Users, Events, Features, Flags, Entitlements, Feature Usage, Account Members) but only as a category index — there is no exposed openapi.json, no swagger.json, no downloadable schema. The llms-full.txt and .md per-page outputs are mentioned, but neither is a parseable spec.
Consequence: For an entitlements platform whose pitch is "no engineering tickets," there is no machine-readable way for tools (Postman, code generators, MCP servers, Claude Code, Cursor) to discover endpoints, request shapes, or error schemas. SDK consumers have to read prose to figure out a curl call. This is especially odd given Schematic ships an MCP server (schematic-mcp) — which presumably consumes a spec internally that is not published.
The fix: Publish the OpenAPI spec at a stable URL (/api-reference/openapi.json), link it from the API reference index, and add it to llms.txt so agents can fetch it directly.
3. No public changelog for a billing-critical platform (critical)
Location: /changelog (404)
Problem: /changelog returns "This page does not exist." There is no other versioning page, no API version history, no breaking-change log in the scraped content.
Consequence: Schematic sits between a customer's product and their billing. When entitlement-evaluation logic ("most generous" policy, override expiry behavior, trial-conversion rules) or SDK methods (checkFlag vs checkFlagWithEntitlement vs checkFlags) change, customers have no audit trail. The useSchematicEntitlement hook, the initializeWithPlan API, the negative-quantity behavior — none of these are dated. Teams cannot answer "when did this start?" during an incident.
The fix: Publish a dated changelog with at least: SDK releases, API additions, behavior changes to entitlement evaluation, and breaking changes. Surface it in the top nav.
4. API reference has no overview, and API authentication has no dedicated page (significant)
Location: /api-reference/overview (404), /developer_resources/api-keys (404)
Problem: Two URLs the implied IA points to but that do not exist (separate from the dead OpenAPI/changelog/Python pages covered above):
/api-reference/overview— 404. The API reference section ships without an overview page;/api-reference/resourcesis a category index, not an introduction./developer_resources/api-keys— 404, despite an entire authentication concept that covers Secret, Publishable, and Readonly keys. The only page with a similar name is/developer_resources/key_management, which is about entity key mapping (Stripe customer IDs, application UUIDs), not API authentication keys — a confusing name collision.
Consequence: Developers clicking through to the API reference expecting an overview hit a 404; anyone looking for an "API keys" guide in the developer-resources tree (the obvious sibling of key_management) finds nothing — and key_management is about something else entirely.
The fix: Build /api-reference/overview (the API reference cannot reasonably ship without an intro) and /developer_resources/api-keys (auth deserves its own page distinct from entity-key management). Cross-link the two key_management / api-keys pages so the naming collision is explicit.
5. Two "Concepts" pages with overlapping content and no clear canonical (significant)
Location: /concepts and /developer_resources/concepts
Problem: Both pages exist and both define the same vocabulary — Features, Flags, Entitlements, Plans, Companies, Users, Events, Keys, Traits. The wording differs: /concepts says "Flags determine who gets access, when, and under what conditions"; /developer_resources/concepts says "Flags: Boolean gates implemented in code controlling resource accessibility." Same term, two different framings (business-level vs. implementation-level) presented as if both are authoritative.
Consequence: A developer reading one page builds a different mental model than a developer reading the other — especially around the Features-vs-Flags distinction (/developer_resources/concepts claims Features are "mapped one-to-one to flags"; /concepts calls Features capabilities with three types). For agents, the duplication doubles the chance of citing the less-precise version.
The fix: Pick one canonical concepts page. Either redirect the other to it, or split clearly into "Product concepts" (for GTM) and "Implementation model" (for engineers) and cross-link the two so they cannot drift.
6. SDK package name, repo name, and import name diverge with no callouts (significant)
Location: /developer_resources/sdks/nodejs, /getting-started/developer-resources/sd-ks/python, /playbooks/metering, GitHub SchematicHQ/schematic-node
Problem: Both server SDKs have package-name-vs-import mismatches with no explanation:
- Node.js: The npm install command is
npm install @schematichq/schematic-typescript-node. The corresponding GitHub repository isSchematicHQ/schematic-node— notschematic-typescript-node. Nothing in the SDK doc tells the reader this. - Python: The Python SDK page says
pip install schematichq, but the metering playbook example doesfrom schematic import Schematicand instantiatesSchematic(api_key=...). So the install name (schematichq), the import name (schematic), and the class naming used elsewhere (SchematicClienton Node) all diverge — and the Python page itself never tells the reader what to import.
Consequence: Developers who hit an SDK bug and search GitHub for the published package name will not find the Node repo. Python developers copying the playbook example won't be able to figure out the right import from the install command alone. Same hazard for agents trying to fetch source or scaffold code.
The fix: Rename the Node repo to match the package (or add an explicit "Source: github.com/SchematicHQ/schematic-node" callout on the Node.js SDK page). On the Python SDK page, state both the install name and the import name with a real example (pip install schematichq then from schematic import Schematic), and explain why they differ.
7. Rate-limit doc declares a concurrency limit but never states it (significant)
Location: /api-reference/rate_limiting
Problem: The rate-limit page lists "Concurrency limit: Active request restrictions apply (specific number not detailed in provided content)." The two other limits are stated (20/s write, 20/s read), but the concurrency cap — which is the one that surprises production workloads — is referenced without a value.
Consequence: Teams sizing batch jobs (the doc itself flags "Batched company/user upserts" from daily sync as the typical 429 cause) cannot plan worker counts. They will discover the limit by hitting it in production.
The fix: State the concurrency limit numerically. If it varies by plan or environment, say so and link to the limit per tier. The current phrasing — admitting a limit exists but not naming it — is worse than silence.
8. React SDK's SSR limitation is documented only on the quickstart page (significant)
Location: /quickstart/setup-sdk (states limitation), /developer_resources/sdks/react (does not)
Problem: "At this time, the React SDK only supports client-side rendering" appears in the quickstart setup page. The actual React SDK reference at /developer_resources/sdks/react shows a ReactDOM.render example and lists hooks — but never repeats the SSR caveat. A Next.js or Remix developer reading the SDK page in isolation has no idea the SDK won't work in a server component.
Consequence: Developers integrate <SchematicProvider> into a server-rendered Next.js app, ship it, then hit hydration or "window is not defined" errors. The Next.js framework is even listed as a supported SDK in /developer_resources/sdks/cross-platform-features, deepening the confusion.
The fix: Add a prominent "Client-side only" callout at the top of /developer_resources/sdks/react. Clarify on the Next.js page whether the limitation applies there too, and what the recommended pattern is (server checkFlag + client <SchematicProvider>).
9. Bulk flag check returns 201 Created for a non-creating operation (significant)
Location: /api-reference/features/check-flags vs /api-reference/features/check-flag
Problem: POST /flags/{key}/check (single) returns 200 OK. POST /flags/check (bulk) returns 201 Created. Neither endpoint creates a resource — both evaluate flags. The bulk endpoint's response shape ({ data: { flags: [...], plan: {...} }, params: {} }) confirms it returns evaluation data, not a created object.
Consequence: HTTP clients with status-code-based middleware (cache invalidation on 201, retry logic, logging) will treat the two semantically-identical operations differently. Agents generating client code from the doc will see two different "successful" expectations for the same logical action.
The fix: Return 200 OK from the bulk check endpoint (or, if you really want a 2xx code that distinguishes batch shape, document the reasoning). At a minimum, document the inconsistency.
10. Quickstart Python code sample uses a JavaScript boolean literal (significant)
Location: /quickstart/identifying-users
Problem: The "Advanced Backend Example with Traits (Python)" example writes:
client.companies.upsert_company(
keys={"demo-id": "demo-company"},
name="Acme Widgets, Inc.",
traits={
"city": "Atlanta",
"high_score": 25,
"is_active": true,
},
)
true is a JavaScript boolean literal. Python requires True (capitalized). This code raises NameError: name 'true' is not defined on first execution.
Consequence: A developer or agent who copy-pastes the quickstart's Python identify example — exactly the path the page is designed to encourage — gets a NameError from the runtime, not from Schematic. This is the kind of bug that erodes trust in every other code sample on the site.
The fix: Change true to True. Audit every other Python sample across the docs for the same class of error (likely produced by copying a JS/TS example and not adjusting the literal).
11. SDK capability matrix has unexplained omissions (significant)
Location: /developer_resources/sdks/cross-platform-features
Problem: The "Real-Time Updates Support" table lists JavaScript, React/Next.js, Vue, Go, C#, Node.js, Python, Java. Angular, React Native, and Ruby are simply not in the table. The Replicator-support table also omits React Native and Ruby. There is no "not supported" or "planned" annotation — they're just absent.
Consequence: A developer choosing the Angular SDK cannot tell whether real-time updates are unsupported, planned, in development, or just undocumented. Same for Ruby on Replicator. This is exactly the kind of capability matrix that agents will quote authoritatively while missing the absence.
The fix: Make every row explicit — ✅, ❌, "In development", or "Not planned." Don't omit. A blank cell in a capability matrix reads as a bug to humans and a hole to agents.
12. Webhook signature formula uses an unclear concatenation token (minor)
Location: /integrations/webhooks
Problem: The doc describes the signature as HMAC-SHA256(secret, rawBody + "+" + timestamp). The middle "+" is quoted as a string literal but the surrounding + are concatenation operators in the same pseudocode — readable to a careful reader as a literal + separator, but easy to misread as JS-style concatenation with no separator.
Consequence: Anyone implementing verification by hand (not using the SDK helpers) can produce a signature that fails verification, especially given the strong warning that "parsed or re-serialized bodies will not match the original signature."
The fix: Replace the formula with a pinned example — e.g., HMAC_SHA256(secret, raw_body || "+" || timestamp_unix_seconds) plus a worked example with a known input and the expected hex output. Reference SDK source if available.
13. "For developers" top-level page covers only AI tooling (minor)
Location: /for-developers
Problem: The /for-developers slug suggests a developer landing page. Its actual content is exclusively "AI Skills" and "Model Context Protocol (MCP)" — the page does not mention SDKs, the API reference, environments, webhooks, or any of the other developer concerns. Meanwhile, the real developer hub is split across /developer_resources/*, /api-reference/*, and /architecture/*.
Consequence: A developer hitting /for-developers is led to believe Schematic's developer story is "we have MCP." The actual SDK/API surface is elsewhere and discoverable mostly by side-nav.
The fix: Either rename the page (/ai-tools or /for-ai-agents) or expand it into a genuine developer landing page that fans out to SDKs, API reference, webhooks, architecture, and the AI tooling.
14. Typos and a grammar error on customer-facing pages (minor)
Location: Homepage Security card; /api-reference/pagination; /integrations/stripe-troubleshooting
Problem:
- Home card text: "Learn how Schematic safegaurds your billing data."
- Pagination doc: "list API methods use offset pagination through the
limitandoffsetparamaters." - Stripe troubleshooting: "The most common reason a customer can't change plans is that are no live plans that they can switch to." (Missing "there.")
Consequence: Small but visible on three pages closest to "security," "API basics," and "troubleshooting an active production issue" — all credibility-sensitive contexts. The Stripe-troubleshooting one is the worst: it's the first sentence under "Missing Change Plan Button," exactly when a customer is already frustrated.
The fix: Fix to "safeguards," "parameters," and "is that there are no live plans."
What they do well
llms-full.txtis present and well-structured; the per-page.mdsuffix trick is a clean agent-discoverable pattern.- Entitlement-evaluation semantics are unusually clear — the "most generous wins" rule, override-expiry edge cases, and trial-conversion behavior are documented with worked examples (the 500-call override + 1000-call plan = 1000 example is exactly the right level of specificity).
- The Stripe integration page draws clean boundaries — when a Stripe customer record gets created, which subscription statuses grant entitlements, what happens on company deletion. That kind of edge-case enumeration is rare and valuable.
Top 3 recommendations
- Publish the OpenAPI spec and a dated changelog. These are the two biggest holes — both for humans tracking changes and for agents discovering surface area. Both should exist before more SDK features ship.
- Fix the Python SDK URL, the Python code sample, and the install-vs-import mismatch.
/developer_resources/sdks/pythonshould resolve, the quickstart's"is_active": truemust becomeTrue, andpip install schematichq→from schematic import Schematicneeds to be stated explicitly somewhere. - Consolidate the two Concepts pages and make every SDK page state its own caveats. Right now the React SSR limitation lives on the quickstart page, the Node repo name lives on GitHub, and the concept model splits across two URLs. Every SDK and concept page should be readable in isolation.