Scalio ships an impressive agent-facing scaffold (llms.txt, OpenAPI, RFC 9727 API catalog, agent skills, site-wide markdown content negotiation) around a documentation surface that is four pages long, still contains its template's "replace this page" placeholders, and contradicts its own machine-readable spec.
1. The entire docs surface is an unedited template scaffold, shipped to production (critical)
Problem: The docs landing page ends with a template author's note rendered live to users: "These docs are a starting scaffold. Expand each guide with your product's exact workflows, screenshots, and examples." Both guide pages end the same way — the photoshoots guide closes with "Replace this page with your product's exact photoshoot workflow, supported inputs, and example outputs" and the reels guide with "Replace this page with your product's exact video workflows, supported formats, and platform-specific guidance." The complete docs index at /docs/llms.txt confirms the whole surface is four pages: index, quickstart, and two guides. The string "starting scaffold" is visible in the served HTML, not just the markdown source.
Consequence: Every substantive page tells the reader it is a placeholder. A developer (or agent) looking for supported input formats, output resolutions, credit costs per generation, or export options finds none of it — the guides are generic card grids with no product-specific facts. Trust in everything else on the domain drops accordingly.
The fix: Either finish the guides (concrete workflows, supported inputs/formats, credit costs, limits, screenshots) and delete the scaffold notes, or take /docs down until it documents the real product. Shipping the template's TODO notes is worse than shipping nothing.
2. /api/waitlist is documented on the API docs page but missing from the OpenAPI spec the page tells you to use (critical)
Problem: The human-readable API docs page lists three endpoints — /api/contact, /api/waitlist (required: email, brandName, phone; optional: brandUrl, numberOfPhotos, source, campaign), and /api/health — and instructs integrators: "Use the machine-readable specification when generating a client or integration" and "Start with the OpenAPI document for the exact schema." But the OpenAPI document at /.well-known/openapi.json contains only /api/contact and /api/health. /api/waitlist is absent entirely, and the spec's own description ("lead-capture endpoints... to submit a contact request") doesn't acknowledge it either.
Consequence: Anyone who follows the page's own instruction — generate a client from the spec — gets a client that cannot join the waitlist, one of only two write endpoints the product exposes. Agents that discover the API via /.well-known/api-catalog → openapi.json (the advertised path in llms.txt) never learn the endpoint exists. The seven waitlist fields have no machine-readable schema anywhere, so their types and validation rules are guesswork.
The fix: Add /api/waitlist to openapi.json with a WaitlistRequest schema matching the fields on /api-docs/, and update the spec's info.description to cover both lead-capture endpoints.
3. Two different web-app entry points: docs say studio.scalio.app, everything else says web.scalio.app (significant)
Problem: The quickstart's step 1 is "Head to studio.scalio.app and sign in (or create an account)", and the docs index card links "Open Studio" to https://studio.scalio.app. The homepage ("Web: https://web.scalio.app"), and the use-scalio agent skill ("open the web app at https://web.scalio.app/login to sign up or sign in") point at a different host. Both hosts are live and serve sign-in pages, and neither surface mentions the other.
Consequence: A user or agent following the docs lands on a different application than one following the marketing site or the published agent skill. It is impossible to tell from the documentation whether these are two products, one product with a legacy URL, or an error — and an account created on one may not exist on the other.
The fix: Pick one canonical web-app URL, use it in the quickstart, docs index, homepage, and agent skills, and redirect the deprecated host.
4. The docs describe a different product than the one being sold (significant)
Problem: The docs index defines Scalio as an image/video generation tool: "Upload a few product or garment images and generate a full catalog of high-converting visuals." The homepage sells a much larger product — "It posts... It makes Reels... It gets you found... It advertises... It answers... It protects your reputation" — and the pricing page bills for social media posting (30 posts/month), stories, AI customer replies, a Website Builder, and Google Business Profile tools for up to 5 locations. None of those paid features appear anywhere in /docs; the complete docs index (/docs/llms.txt) lists only photoshoots and reels/ads.
Consequence: A paying Professional customer (₹1,999/$49.99 per month) has zero documentation for most of what they bought: how AI replies work, what the monthly "usage allowance" on replies is, how website hosting behaves, how Google Business Profile integration is configured. Agents asked about these features find nothing to cite.
The fix: Add guides for each billed capability — posting/calendar, stories, AI replies (including the usage allowance), Website Studio, and Google Business Profile tools — or scope the docs title to the feature subset they actually cover.
5. Root llms.txt never links the docs, and the advertised llms-full.txt convention only half-exists (significant)
Problem: The root /llms.txt "Key pages" section lists fourteen marketing pages (Home, Product Studio, Reel Maker, Pricing, Blog, Contact...) but does not link https://scalio.app/docs or /docs/llms.txt at all. Meanwhile /llms-full.txt at the root returns HTTP 404, while /docs/llms-full.txt exists (4,926 bytes). The docs pages themselves point agents to /docs/llms.txt as "the complete documentation index."
Consequence: An agent that starts at the standard discovery point — the root llms.txt — can enumerate every marketing page and the API well-knowns but never discovers that product documentation exists. The two llms indexes describe disjoint worlds: one all marketing, one all docs.
The fix: Add the /docs section (or at least /docs/llms.txt) to the root llms.txt, and either publish a root /llms-full.txt or stop implying the convention exists at the root.
6. The contact endpoint's success and error contract is an empty object (significant)
Problem: The spec's 200 response for POST /api/contact is {"schema": {"type": "object"}} — no properties, no example. The skill file's entire success contract is one sentence: "A 200 response means the message was delivered." The only error shape is {"error": string} for 400 ("Missing required fields") and 500. There is no documentation of rate limits, abuse protection, field length limits, or phone/email validation rules on a public, unauthenticated POST endpoint that Scalio explicitly invites third-party agents to call on users' behalf.
Consequence: An agent cannot distinguish "delivered" from "accepted and silently dropped," cannot know whether retrying a 500 double-sends the message, and cannot anticipate throttling. Invalid phone formats or over-long messages fail in ways the spec doesn't describe.
The fix: Document the actual 200 response body (or a confirmation id), add a 429 with rate-limit semantics, and state validation rules (formats, max lengths) in the ContactRequest schema.
7. OpenAPI documents /api/health without the trailing slash the server requires (minor)
Problem: The spec's path is /api/health with a single documented response, 200. A live GET to https://scalio.app/api/health returns HTTP 308; only https://scalio.app/api/health/ returns the documented 200 with {"status":"ok","service":"scalio-lp"}. The API catalog's status link already uses the trailing-slash form, so the two machine-readable files disagree about the same endpoint's path.
Consequence: Clients generated from the spec that don't auto-follow redirects (or monitoring probes that treat non-200 as down) report the healthy service as failing.
The fix: Normalize on one path — either serve 200 at /api/health or document /api/health/ in the spec, and document the 308 if it stays.
8. "Website Studio" vs "Website Builder", and two unreconciled pricing models for the same feature (minor)
Problem: The feature page calls it "Website Studio" and prices it in credits: "Website Studio uses 10 credits to create a site and 10 credits per month to keep it live." The pricing comparison table calls the same row "Website Builder" and prices it by plan: "Not included" on Starter, "1 website" on Professional. The raw pricing HTML contains both names. Nothing explains whether a Starter user can spend their 60 monthly credits on a website or not.
Consequence: A customer can't determine before buying whether websites are plan-gated, credit-priced, or both — and searching docs for one feature name misses the page using the other.
The fix: Use one feature name everywhere and add one sentence to both pages reconciling the credit cost with the plan gating.
What they do well
Genuinely strong agent-facing plumbing: RFC 9727 API catalog, OpenAPI 3.1 at a well-known URI, published agent skills with digests, and site-wide Accept: text/markdown content negotiation that actually works (verified on / and /pricing/).
Both llms.txt files are clean, well-described, and accurately summarize the pages they index.
The contact-scalio skill documents required vs optional fields consistently with the OpenAPI schema, with a realistic example payload.
Top 3 recommendations
Replace the scaffold docs with real product documentation — concrete workflows, supported inputs/outputs, credit costs, and limits — and remove the "replace this page" template notes from production.
Add /api/waitlist to openapi.json so the machine-readable spec matches the API docs page that tells integrators to rely on it.
Pick one canonical web-app URL (studio.scalio.app vs web.scalio.app) and one website feature name, and use them consistently across docs, marketing, and agent skills.
Fixed
0
Skip
1
Fail
2
Failing pages
https://scalio.app/.well-known/openapi.json
https://scalio.app/api-docs/
Summary
11 verifiable items across Scalio's public API documentation surface: 8 PASS, 1 SKIP, 2 FAIL. Scalio's docs contain no conventional code snippets (the /docs guides are UI walkthroughs), so verification targeted the machine-readable artifacts and documented API behaviors: the OpenAPI 3.1 spec, the RFC 9727 API catalog, the agent-skills index and its sha256 digests, the contact-scalio example payload, and the site-wide Accept: text/markdown content-negotiation claim.
Failures: (1) GET /api/health executed exactly as pathed in openapi.json returns HTTP 308, not the sole documented 200 — only the trailing-slash form /api/health/ (used by the api-catalog) returns 200; (2) /api-docs/ returns text/html to Accept: text/markdown despite that very page (and llms.txt) claiming "Every page supports the Accept: text/markdown request header."
Required credentials
None. No credentials were provided and none of the public endpoints require authentication. The one skipped item (live POST /api/contact) was skipped for side-effect reasons, not missing credentials.
GET https://scalio.app/api/health as pathed in the spec
FAIL
Returns HTTP 308 (permanent redirect), empty body; spec documents only a 200 response. Diagnosis: server requires a trailing slash (/api/health/ returns the documented 200); the api-catalog already uses the slash form, so the two machine-readable files disagree. Redirect-following clients succeed, but strict clients and monitors validating against the spec see an undocumented status. Suggested solution: document the path as /api/health/ in openapi.json, or serve 200 at /api/health.
Valid JSON; contains all three required fields (name, phone, message) and only fields defined in the OpenAPI ContactRequest schema
9
Live POST https://scalio.app/api/contact with the example body
SKIP
Side-effectful as written: the docs state "A 200 response means the message was delivered," so executing would deliver a fabricated contact message ("Priya Sharma") to the Scalio team; the skill also provides no complete request command (partial fragment)
Returns text/html; charset=utf-8. The page states "Every page supports the Accept: text/markdown request header for a token-efficient version" — and is itself the only sampled page that does not honor it. Suggested solution: add /api-docs/ to the content-negotiation middleware or scope the claim.