Curovana Documentation Audit
Curovana ships two parallel webs of "docs" — a marketing site at www.curovana.com and the simulator app at sim.curovana.com — and they disagree with each other on legal terms, feature counts, contact addresses, and even the AMR statistics that anchor the company's mission. The simulator's SPA returns a 404 body for most of the routes a developer or agent would expect (/docs, /api, /support, /faq, /pricing), and an unauthenticated /api/health endpoint quietly publishes the production stack. There is no llms.txt, no OpenAPI spec, and no developer documentation of any kind.
1. Two contradictory legal regimes for the same product (critical)
Location: sim.curovana.com/privacy + /terms vs www.curovana.com/privacy + /terms
Problem: The simulator subdomain and the marketing site each publish their own Privacy Policy and Terms of Service, and they do not agree on jurisdiction, rights, retention, or contact:
sim.curovana.com/privacy(Last updated: January 21, 2026) is framed entirely under India's DPDP Act, 2023, names a Grievance Officer atsupport@curovana.com, and gives concrete retention windows ("Account data: …plus 3 years after account deletion", "Session data: …2 years").www.curovana.com/privacy(Last updated: March 2026) is framed under GDPR ("compliance with applicable privacy regulations including GDPR"), routes toprivacy@curovana.com, omits retention numbers entirely, and never mentions a Grievance Officer or DPDP rights such as "Nominate another person to exercise your rights."sim.curovana.com/terms§4.2 says "New accounts require administrator approval. We reserve the right to approve, reject, or suspend accounts at our discretion." The www/termshas no equivalent clause, so a user who reads only the marketing terms before signing up has no warning that registration is gated.sim/terms§13 declares Indian governing law and exclusive Indian jurisdiction;www/termshas no governing-law statement at all.- Contacts diverge:
simlegal pages route everything (privacy, grievance, support, terms) tosupport@curovana.com.www/privacyroutes toprivacy@curovana.com;www/termsroutes tolegal@curovana.com— neither inbox is mentioned anywhere else on either site.
Consequence: A medical user (or institution) reading the marketing site believes they are signing up under GDPR with no admin gate and a 12-month liability cap, then lands on the simulator under Indian DPDP, with admin approval required and Grievance Officer escalation. A regulator reviewing the policies will find the same data subject (the same trainee) governed by mutually exclusive frameworks. For a clinical-education product handling identifiable health-professional data, this is the kind of contradiction that voids the consent it tries to capture.
The fix: Pick one canonical Privacy Policy and one canonical ToS, host them once, and have both subdomains link to the canonical URL. Reconcile the regulatory framing (DPDP and/or GDPR — but state which actually applies and on what basis), restore the §4.2 admin-approval clause on the public-facing terms, and converge to a single legal contact (legal@curovana.com) and a single privacy contact (privacy@curovana.com) referenced everywhere.
2. Unauthenticated /api/health leaks production stack and vendor map (critical)
Location: https://sim.curovana.com/api/health
Problem: The endpoint responds without auth and returns:
{"status":"ok","timestamp":"2026-05-06T00:17:38.659Z","nodeVersion":"v20.20.1","environment":"production","uptime":"54h 18m 11s","uptimeMs":195491590,"database":true,"secrets":{"openai":true,"anthropic":true,"elevenlabs":true,"database":true,"resend":true,"googleOAuth":true},"activeSessions":0}
This publishes: exact Node minor version (v20.20.1), build environment, host uptime (useful for inferring deploy cadence and last-restart windows for CVE applicability), DB-up boolean, current concurrent-session count, and — most consequentially — a full map of which third-party secrets are configured. It tells any visitor that the platform is built on OpenAI + Anthropic + ElevenLabs + Resend + Google OAuth.
Consequence: Two distinct harms. (a) Reconnaissance: Node version + uptime + environment is a starter pack for targeted CVE scanning. (b) Vendor disclosure: the AI stack and email/auth providers are not advertised in any user-facing material — this endpoint is the only place the dependency list exists, and competitors, scrapers, and security researchers all see it. activeSessions even leaks a real-time usage signal (it currently reads 0, which during the public beta is itself an embarrassing disclosure).
The fix: Health endpoints for load balancers should return {"status":"ok"} and nothing else. Move the diagnostic payload behind auth (/api/health/detailed requiring an admin token), strip nodeVersion, secrets, uptime, and activeSessions from the public response, and add the route to robots.txt for good measure.
3. Simulator SPA returns a hard-coded 404 body with HTTP 200 for a long list of advertised routes (significant)
Location: sim.curovana.com/docs, /help, /faq, /pricing, /changelog, /api, /support, /forgot-password, /register, /dashboard, /cases, /simulator, /blog, /contact
Problem: Every one of those URLs returns the literal string:
404 Page Not Found
Did you forget to add the page to the router?
but the HTTP status is 200. Some of these are routes the rest of the product actively links to: the login page exposes a "Forgot Password" modal that ought to deep-link to /forgot-password; www.curovana.com's footer link labelled "Pricing" points to /products because /pricing 404s; /support exists on www but not on sim; /register is a tab inside /login but the standalone URL dies; and a developer reasonably probing /api or /docs is told the page doesn't exist while the server still claims success.
Consequence: Every search engine and every coding agent crawling the site indexes a page titled "404 Page Not Found" with body "Did you forget to add the page to the router?" as a successful response. Deep-links from email password resets, blog posts, or institutional intranets break silently. A user who bookmarks sim.curovana.com/dashboard after login can never return to it. The Did you forget to add the page to the router? text is a developer-facing error message that should never reach users.
The fix: (a) Return HTTP 404 (not 200) from the SPA fallback. (b) Replace the "Did you forget to add the page to the router?" debug copy with a real not-found page that links back to /. (c) Audit every cross-link — /forgot-password, /register, the footer "Pricing" link — and either implement the route or rewrite the link. (d) Either build a real /docs and /api or remove any external mention of them.
4. Marketing homepage publishes placeholder zeros and a clinically alarming vitals widget (significant)
Location: https://www.curovana.com/
Problem: The marketing homepage's hero vitals widget renders with HR 29 bpm, SPO2 0 %, RESP 0 /min, NIBP 0 mmHg (and the values have been observed unstable across reloads). The "Impact of AMR & Our Solution" section directly below ships unfilled stat templates: 0.00M Deaths linked to AMR annually, 0% Inappropriate prescriptions, 0/100 Avg stewardship score, 0+ Clinical scenarios. The same site's /about page renders the same statistics with real numbers: 4.95M, 50%, 10M. The homepage of a clinical-simulation product is therefore both (a) self-contradicting against /about and (b) showing a patient with an HR of 29 (severe bradycardia), 0 % SpO2, and 0 mmHg blood pressure as a marketing visual.
Consequence: First impressions for a paying institution arrive on a page where the company can't keep its own headline statistics straight, and the credibility hook — "AI patients. Real physiology." — is undermined by a vitals panel showing values incompatible with life. Press, prospective customers, and search engines snapshot the homepage; the broken numbers are what they cite.
The fix: Treat the homepage as production. Wire the 0.00M / 0% / 0/100 / 0+ placeholders to the same source the /about page uses (4.95M / 50% / —/ 30+), or hard-code them. For the vitals widget, either drive it from a fixed scripted scenario (e.g. the Priya Mehta case shown on the sim homepage: HR 92, BP 148/90, SpO2 97 %, Temp 37.1, RR 22) or guard the render so it never paints a zero/null state.
5. Feature counts contradict across the four surfaces a buyer reads in sequence (significant)
Location: sim.curovana.com/ vs www.curovana.com/products vs www.curovana.com/clinical-intelligence
Problem: The same product is described with mutually exclusive numbers on adjacent pages:
- Modes.
sim.curovana.com/(the in-app homepage): "8 modes: simulator, StepWiser, exam prep, scenario forge, case discussions, tutor, flashcards, random cases."www.curovana.com/clinical-intelligence: "Three Simulation Modes — Standard / Voice / Advanced Voice."www.curovana.com/products: "Text, voice, and advanced voice modes" (3). A buyer who reads the marketing site sees 3 modes; a user who actually logs in sees 8. - Drugs. Within a single page (
sim.curovana.com/) the hero says "1000+ DRUGS MODELED" in the under-the-hood stats and "103+ medications" two scroll-lengths below. A 10× self-contradiction on one page. - Specialties / domains.
sim.curovana.com/says "14 CLINICAL DOMAINS";www.curovana.com/clinical-intelligencesays "14 Medical Specialties" and lists 14 names. These match in count but mismatch in label, and the listed 14 don't appear anywhere onsim, so a buyer cannot verify the claim from inside the product. - Scenarios.
simsays "30 curated scenarios."www/productsandwww/clinical-intelligencesay "30+".www/homepage says "0+". (See Issue 4.)
Consequence: Sales calls and procurement reviews stall the moment someone reads two pages. An institution buying based on "3 modes" discovers 8 (or vice-versa) and asks whether the other 5 are deprecated, beta, or fictional. For agents and crawlers there is no canonical answer to "how many modes does Curovana have?" — the highest-ranked source on each phrase contradicts the others.
The fix: Stand up a single feature-count source of truth (a JSON or MDX fragment) and inline it everywhere those numbers appear. Decide whether the public-facing answer is "3 simulation modes" (Standard/Voice/Advanced Voice — interaction styles) or "8 modes" (simulator/StepWiser/exam prep/etc. — product surfaces) and use distinct labels for the two concepts. Reconcile 1000+ vs 103+ drugs to a single, dated number.
6. No agent- or developer-readable surface at all (significant)
Location: site-wide
Problem: Curovana markets itself as a 10-engine clinical pipeline with institutional licensing, but provides nothing a coding agent or integrating developer can parse:
- No
llms.txtorllms-full.txtat either domain. - No OpenAPI / Swagger spec.
/api,/docs,/changelogall return the broken 404 body (Issue 3).- The only programmatic endpoint discoverable is
/api/health(Issue 2), which leaks internals but documents nothing. - The
/supportpage promises "FAQ (Coming Soon)" while a four-question FAQ already lives on/products;/faq404s on both subdomains.
Consequence: An institution evaluating Curovana for LMS / SSO / SCORM integration has no way to discover endpoints, auth model, rate limits, or data schemas without a sales call. Coding agents (Claude Code, Cursor, etc.) asked "how do I authenticate against Curovana?" have nothing to retrieve and will either hallucinate or refuse. For a platform whose homepage tagline is "Building the safety layer for healthcare AI," the absence of a machine-readable surface is itself the audit finding.
The fix: Publish (a) https://www.curovana.com/llms.txt listing the canonical pages and their purposes; (b) an OpenAPI spec at /api/openapi.json even if only covering health, auth, and session endpoints; (c) a real /docs index that links the privacy/terms/products/clinical-intelligence pages plus institutional integration notes; (d) move the existing four-item FAQ off /products and onto /faq, and update the /support "Coming Soon" copy.
What they do well
- The
/clinical-intelligencepage is the one place where the product story is concretely structured: 10-engine pipeline, named specialties, three interaction modes, AWaRe scoring tiers (Access / Watch / Reserve). - The login-page "Required Acknowledgement" is clear, candid about AI failure modes, and non-evasive about the educational-only scope — better than most clinical AI products manage.
- The simulator's
/aboutpage exposes a version string (1.0.0) and environment, which is the right instinct (just don't do it on/api/healthtoo).
Top 3 recommendations
- Collapse the two legal regimes into one canonical Privacy Policy and one canonical ToS, served from a single URL and linked from both subdomains; reconcile DPDP vs GDPR framing and restore the admin-approval clause on the public terms.
- Strip
/api/healthto{"status":"ok"}and gate the diagnostic payload behind admin auth — today it publishes your Node version and entire vendor stack to the open internet. - Fix the SPA 404 (return HTTP 404, replace the developer-facing copy) and stand up the routes the rest of the site links to:
/forgot-password,/register,/pricing,/faq,/docs, plus anllms.txtand an OpenAPI spec so agents and integrators have something to read.