API REFERENCE5 endpoints · spec v0.1.0

The public endpoints

Generated from the same OpenAPI spec the API router is drift-tested against, so this page cannot lie. No key needed; IP rate limits apply. Conduct and licensing: the developer landing.

GET/public/ingredients/{id}/evidence

Public evidence rows for one ingredient. Identical to `getIngredientEvidence` EXCEPT that `evidence_grade` is omitted: letter grades are AI-assigned and stay off public surfaces until the deterministic grading rubric (#326) lands (claims posture, specs/428-web-marketing-site/design.md). Cited summaries + sources only. No auth; per-IP rate-limited.

200 Evidence rows for the ingredient (no grades) · 400 · 429 · 500

curl 'https://api.litmus.nomorro.com/public/ingredients/<ingredient-id>/evidence'

GET/public/ingredients/{id}/papers

Public quality-ranked research papers for one ingredient - same shape as `getIngredientPapers` (paper metadata, links, and the deterministic source-reliability rating are all publishable; nothing user-specific or AI-graded in this payload). Pass ?outcome=<uuid> to filter. No auth; per-IP rate-limited.

outcomequeryOutcome UUID; limits results to papers linked to that outcome.

200 Ranked papers for the ingredient · 400 · 429 · 500

curl 'https://api.litmus.nomorro.com/public/ingredients/<ingredient-id>/papers'

GET/public/products/search

Public catalog-only product search for the marketing site (#432). Same two-stage relevance ranking as `searchProducts` minus the user-dependent pieces (no private-library rows, no favorites boost), so the response is `ProductSummary` without user-specific fields. Limit clamps to 20. No auth; per-IP rate-limited.

qquery · requiredSearch query
limitqueryMax results. Server clamps to 20.

200 Search results, scored by relevance · 400 · 429 · 500

curl 'https://api.litmus.nomorro.com/public/products/search?q=...'

GET/public/starter-stacks

Public wrapper over the curated starter-stack recommender for the web quiz (#431). Same curated map, dimension aliasing, and general_wellness fallback as `getStarterStacks` - the web quiz is a thin client over this endpoint so app and web can't diverge. No auth; per-IP rate-limited (shared read-tier budget across /public/* GETs).

goalqueryGoal slug. Empty / unknown / typo → server falls back to `general_wellness` silently; the response's `goal` field echoes the resolved value.

200 Curated suggestions for the goal · 429 · 500

curl 'https://api.litmus.nomorro.com/public/starter-stacks'

POST/waitlist

Marketing-site waitlist signup. Public - no Cognito JWT (the gateway routes it without an authorizer), so `security` is empty here; abuse is bounded by per-IP rate limiting instead. Idempotent upsert keyed by case-insensitive email: a first signup returns 201, a repeat returns 200 with the row's `updated_at` (and `source`) refreshed. The response never echoes stored data.

200 Email was already on the waitlist (row refreshed; nothing echoed) · 201 Email added to the waitlist · 400 · 429 · 500

curl 'https://api.litmus.nomorro.com/waitlist'