{"openapi":"3.1.0","info":{"title":"Luna API","description":"Luna is a baby tracker for feeds, sleep, nappies, solids and routines, shared between parents and invited caregivers.\n\nThis REST API is the same one the Luna web app uses. Every request is scoped to **one family**: the family is resolved from the bearer token (or session cookie) and there is no way to address another family's data.\n\n## Authentication\n\n* **Bearer token** (`Authorization: Bearer <token>`) — the way agents and scripts should call the API. Create one in the app (Settings → Connect an assistant) or `POST /api/vega/token` from a signed-in session. Tokens are stored hashed and can carry `read` or `read`+`write` scopes.\n* **Session cookie** (`luna_session`) — what the browser uses after `POST /login` or `POST /api/vega/onboard`.\n\nOnly `GET /api/health` and `POST /api/vega/onboard` are reachable without credentials. Unauthenticated calls to anything else return `401 {\"error\": \"unauthorized\"}`.\n\n## Conventions\n\n* Timestamps are ISO 8601 in the family's local time (`YYYY-MM-DDTHH:MM:SS`); omit `ts` to log \"now\". Future timestamps are rejected.\n* Volumes are millilitres, weights kilograms, lengths centimetres. Families with `units: imperial` still store metric.\n* Errors are JSON `{\"error\": \"<code or message>\"}` with a 4xx status.\n* Luna is not a medical device: nothing here diagnoses, assesses symptoms or advises on medication.\n\n## Other ways in\n\n* **MCP connector** at `https://getmyluna.app/mcp` (streamable HTTP, same bearer token) — 23 tools, resources and prompts for Meta Muse, Claude Code and any MCP client. Manifest: `/.well-known/luna-connector.json`.\n* **Agent instructions**: `/llms.txt`. **Developer portal**: `/developers`. **CLI**: `/cli/luna.py`.\n","termsOfService":"https://getmyluna.app/terms","contact":{"name":"Luna support","url":"https://getmyluna.app/contact","email":"hello@getmyluna.app"},"version":"1.1.0"},"servers":[{"url":"https://getmyluna.app","description":"Production"}],"paths":{"/.well-known/luna-connector.json":{"get":{"tags":["Discovery"],"summary":"MCP connector manifest","description":"Machine-readable description of the MCP server: URL, auth, tools, resources, prompts.","operationId":"connector_manifest","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","description":"Connector manifest: name, version, mcp_url, auth, tools[], resources[], prompts[], privacy_url, terms_url.","required":["name","version","mcp_url","auth","tools"],"additionalProperties":true}}}}},"security":[]}},"/llms.txt":{"get":{"tags":["Discovery"],"summary":"Agent instructions (llms.txt)","description":"When to use Luna and how to call it, in the llms.txt format. Also at `/.well-known/agent-instructions.md`.","operationId":"llms_txt","responses":{"200":{"description":"Success","content":{"text/plain":{"schema":{"type":"string"}}}}},"security":[]}},"/api/analytics":{"post":{"tags":["Analytics"],"summary":"Record a product analytics event","description":"Allowlisted event names only; no PII. Public so the marketing pages can call it.","operationId":"record_analytics_event","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsRequest"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[]}},"/api/vega/onboard":{"post":{"tags":["Account"],"summary":"Create a family account","description":"Public sign-up: creates a new family (tenant) and its first admin caregiver, and sets a session cookie. Every later call is scoped to this family. Returns `409` if the email is already registered.","operationId":"create_account","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardRequest"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Email already registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[]}},"/api/health":{"get":{"tags":["Discovery"],"summary":"Health check","description":"Always `{\"ok\": true}` when the app is serving. No auth.","operationId":"health","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}}},"security":[]}},"/api/me":{"get":{"tags":["Discovery"],"summary":"Who am I","description":"The username, family id and role the current credentials resolve to. Useful for confirming a bearer token works.","operationId":"whoami","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/growth-summary":{"get":{"tags":["Account"],"summary":"Operator growth summary","description":"Admin only. Aggregate, non-PII sign-up and activity counts.","operationId":"growth_summary","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GrowthSummaryResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-requires-role":"admin"}},"/api/vega/export":{"get":{"tags":["Account"],"summary":"Export the family's data","description":"Admin only. Everything the family has logged as one JSON document (served as a download). Excludes password and token hashes.","operationId":"export_family","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-requires-role":"admin"}},"/api/vega/log":{"post":{"tags":["Tracker"],"summary":"Log an event","description":"Append a feed, sleep/wake, nappy, solid meal, note, supplement or measurement. Validates ranges (milk 0–500 ml, weight 0.5–30 kg, length 40–120 cm) and rejects future timestamps. Returns the saved event, the refreshed live status, and a soft `warning` if the time conflicts with a recorded sleep span.","operationId":"log_event","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogEventRequest"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogEventResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/food/suggestions":{"get":{"tags":["Tracker"],"summary":"Recently logged foods","description":"Foods logged in the last 14 days, most recent first — handy for autocomplete.","operationId":"food_suggestions","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Maximum number of foods to return.","default":12,"title":"Limit"},"description":"Maximum number of foods to return."}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FoodSuggestionsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/event/edit":{"post":{"tags":["Tracker"],"summary":"Edit an event","description":"Change editable fields (ts, ml, foods, note, meal_type, kind, author) on one event by id.","operationId":"edit_event","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventEditRequest"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventMutationResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/event/delete":{"post":{"tags":["Tracker"],"summary":"Delete an event","description":"Remove one event by id.","operationId":"delete_event","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventIdRequest"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventMutationResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/event/react":{"post":{"tags":["Tracker"],"summary":"React to an event","description":"Add an emoji reaction from the current caregiver to an event.","operationId":"react_to_event","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventReactRequest"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventMutationResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/recipes":{"post":{"tags":["Tracker"],"summary":"Save a recipe","description":"Store a named ingredient list so it can be logged as one solid meal.","operationId":"save_recipe","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecipeRequest"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecipeResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/undo":{"post":{"tags":["Tracker"],"summary":"Undo the last event","description":"Removes the most recently logged event. Returns `removed: null` when the log is empty.","operationId":"undo_last_event","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UndoResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/live":{"get":{"tags":["Insights"],"summary":"Live status","description":"Asleep/awake, hunger state, next feed estimate, last nappy, today's totals and any alert — derived from the log right now.","operationId":"live_status","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiveStatus"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/stats":{"get":{"tags":["Insights"],"summary":"Historical stats (legacy)","description":"Always `{}` for public families; kept for compatibility with older clients.","operationId":"stats","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/patterns":{"get":{"tags":["Insights"],"summary":"Patterns and weekly review","description":"Sleep patterns, 14-day totals, today's events, and — once solids have started — 7-day nutrient tallies, targets and the allergen grid.","operationId":"patterns","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatternsResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/today":{"get":{"tags":["Tracker"],"summary":"Today's events","description":"Shortcut for `GET /api/vega/events` with today's date.","operationId":"today_events","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventsResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/events":{"get":{"tags":["Tracker"],"summary":"Events for a day","description":"All events for `date` (YYYY-MM-DD), oldest first. Defaults to today.","operationId":"list_events","parameters":[{"name":"date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Day to list, YYYY-MM-DD. Defaults to today (family-local).","examples":["2026-09-20"],"title":"Date"},"description":"Day to list, YYYY-MM-DD. Defaults to today (family-local)."}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventsResponse"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/measurements":{"get":{"tags":["Insights"],"summary":"Growth measurements","description":"All logged weight and length events, oldest first.","operationId":"measurements","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeasurementsResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/profile":{"get":{"tags":["Profile"],"summary":"Child profile and family settings","description":"Name, date of birth, computed age, region, units, timezone and member count.","operationId":"get_profile","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Profile"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]},"post":{"tags":["Profile"],"summary":"Update profile or settings","description":"Admin only. Any subset of fields; setting `region` also sets `units` unless given.","operationId":"update_profile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileUpdateResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-requires-role":"admin"}},"/api/vega/token":{"post":{"tags":["Tokens"],"summary":"Create a bearer token","description":"Mints a token for agents, scripts or the MCP connector. The plaintext is returned **once**. Re-minting with the same `label` replaces that token; different labels coexist. Optional body — omit it for a full-access token labelled with your username.","operationId":"create_token","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenRequest"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/tokens":{"get":{"tags":["Tokens"],"summary":"List tokens","description":"Every token issued for this family (never the secret).","operationId":"list_tokens","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokensResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/token/revoke":{"post":{"tags":["Tokens"],"summary":"Revoke a token","description":"Immediately stops that token (and any assistant using it).","operationId":"revoke_token","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenRevokeRequest"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/vega/family":{"get":{"tags":["Account"],"summary":"List family members and open invites","description":"Caregivers in this family. Open invite links are included for admins only.","operationId":"get_family_access","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FamilyAccessResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]},"delete":{"tags":["Account"],"summary":"Delete the family permanently","description":"Admin only. Deletes the family, every event, note, token, invite and connector state. Cannot be undone; `confirm` must match the family's name exactly.","operationId":"delete_family","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FamilyDeleteRequest"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FamilyDeleteResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-requires-role":"admin"}},"/api/vega/invite":{"post":{"tags":["Account"],"summary":"Create a caregiver invite link","description":"Admin only. A 48-hour invite link a partner, grandparent or nanny uses at `/join` to get their own login for this family.","operationId":"create_invite","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-requires-role":"admin"}},"/api/vega/invite/revoke":{"post":{"tags":["Account"],"summary":"Revoke an invite","description":"Admin only. Invalidates an unused invite code.","operationId":"revoke_invite","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteRevokeRequest"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"x-requires-role":"admin"}},"/api/ask":{"post":{"tags":["Ask Luna"],"summary":"Ask Luna (Luna Plus)","description":"A question answered from this family's own log, in Luna's non-clinical lane. Requires Luna Plus (`402 payment_required` otherwise) and is subject to daily/monthly limits (`429 usage_limit_reached`). Prefix the question with `remember:` to save a note instead.","operationId":"ask_luna","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskRequest"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Luna Plus required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Usage limit reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/ask/notes":{"get":{"tags":["Ask Luna"],"summary":"Notes Luna remembers","description":"Durable notes saved for this family.","operationId":"list_notes","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotesResponse"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}},"/api/ask/notes/delete":{"post":{"tags":["Ask Luna"],"summary":"Forget a note","description":"Delete one remembered note by its `ts`.","operationId":"delete_note","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NoteDeleteRequest"}}},"required":true},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}]}}},"components":{"schemas":{"AskResponse":{"properties":{"answer":{"type":"string","title":"Answer"},"reply":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reply","description":"Same as `answer` (legacy key)."},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model","description":"`null` when a guardrail answered without the model."},"context_used":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Context Used"},"guardrail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Guardrail","examples":["clinical_escalation"]},"usage_limit":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Usage Limit"},"saved_notes":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Saved Notes"}},"type":"object","required":["answer"],"title":"AskResponse"},"ErrorResponse":{"properties":{"error":{"type":"string","title":"Error","description":"Machine-readable code (e.g. `unauthorized`, `not_found`) or a short message.","examples":["unauthorized"]},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message","description":"Optional human-readable detail."}},"type":"object","required":["error"],"title":"ErrorResponse","description":"Every error is a JSON object with an `error` code or message."},"Event":{"properties":{"id":{"type":"string","title":"Id","description":"8-hex-char id, unique within the family.","examples":["af73aec9"]},"ts":{"type":"string","title":"Ts","description":"ISO 8601 local timestamp.","examples":["2026-09-20T09:49:53"]},"type":{"type":"string","enum":["milk","sleep","wake","nappy","poop","solid","note","supplement","weight","length"],"title":"Type"},"author":{"type":"string","title":"Author","description":"Username of whoever logged it (or `app`).","default":"app"},"ml":{"anyOf":[{"type":"integer","maximum":500.0,"minimum":0.0},{"type":"null"}],"title":"Ml","description":"`milk` only: millilitres (0 for a breastfeed)."},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind","description":"`nappy`: wet|dirty|both|dry. `supplement`: vitd|iron|multivitamin."},"foods":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Foods","description":"`solid` only: what was eaten."},"meal_type":{"anyOf":[{"type":"string","enum":["meal","snack"]},{"type":"null"}],"title":"Meal Type","description":"`solid` only."},"kg":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Kg","description":"`weight` only."},"cm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cm","description":"`length` only."},"ug":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ug","description":"`supplement` only: micrograms."},"note":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Note"},"reactions":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Reactions","description":"Emoji reactions from caregivers."}},"type":"object","required":["id","ts","type"],"title":"Event","description":"One logged event. Fields beyond `id`/`ts`/`type`/`author` depend on `type`."},"EventMutationResponse":{"properties":{"status":{"type":"string","const":"ok","title":"Status"},"event":{"anyOf":[{"$ref":"#/components/schemas/Event"},{"type":"null"}]},"removed":{"anyOf":[{"$ref":"#/components/schemas/Event"},{"type":"null"}]},"live":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Live"}},"type":"object","required":["status"],"title":"EventMutationResponse"},"EventsResponse":{"properties":{"events":{"items":{"$ref":"#/components/schemas/Event"},"type":"array","title":"Events"}},"type":"object","required":["events"],"title":"EventsResponse"},"ExportResponse":{"properties":{"exported_at":{"type":"string","title":"Exported At"},"family":{"additionalProperties":true,"type":"object","title":"Family"},"profile":{"additionalProperties":true,"type":"object","title":"Profile"},"events":{"items":{"$ref":"#/components/schemas/Event"},"type":"array","title":"Events"},"week_plan":{"additionalProperties":true,"type":"object","title":"Week Plan"},"recipes":{"additionalProperties":true,"type":"object","title":"Recipes"},"snapshots":{"additionalProperties":true,"type":"object","title":"Snapshots"},"notes":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Notes"}},"type":"object","required":["exported_at","family","profile","events","week_plan","recipes","snapshots","notes"],"title":"ExportResponse","description":"Full family export (also served as a download in the app). Excludes password/token hashes."},"FamilyAccessResponse":{"properties":{"members":{"items":{"$ref":"#/components/schemas/FamilyMember"},"type":"array","title":"Members"},"can_manage_invites":{"type":"boolean","title":"Can Manage Invites"},"invites":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Invites","description":"Open invites (admin only; otherwise empty)."}},"type":"object","required":["members","can_manage_invites","invites"],"title":"FamilyAccessResponse"},"FamilyDeleteResponse":{"properties":{"ok":{"type":"boolean","title":"Ok"},"deleted":{"type":"string","title":"Deleted","description":"The deleted family id."}},"type":"object","required":["ok","deleted"],"title":"FamilyDeleteResponse"},"FamilyMember":{"properties":{"id":{"type":"string","title":"Id"},"email":{"type":"string","title":"Email"},"username":{"type":"string","title":"Username"},"role":{"type":"string","enum":["admin","member"],"title":"Role"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","email","username","role","created_at"],"title":"FamilyMember"},"FoodSuggestionsResponse":{"properties":{"suggestions":{"items":{"type":"string"},"type":"array","title":"Suggestions","description":"Recently logged foods, most recent first."}},"type":"object","required":["suggestions"],"title":"FoodSuggestionsResponse"},"GrowthSummaryResponse":{"properties":{},"additionalProperties":true,"type":"object","title":"GrowthSummaryResponse","description":"Non-PII aggregate counts; admin only."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"InviteResponse":{"properties":{"code":{"type":"string","title":"Code"},"join_url":{"type":"string","title":"Join Url","examples":["https://getmyluna.app/join?code=…"]},"expires_at":{"type":"string","title":"Expires At"},"expires_in_hours":{"type":"integer","title":"Expires In Hours"}},"type":"object","required":["code","join_url","expires_at","expires_in_hours"],"title":"InviteResponse"},"LiveStatus":{"properties":{"now":{"type":"string","title":"Now"},"asleep":{"type":"boolean","title":"Asleep"},"night_sleep":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Night Sleep"},"awake_minutes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Awake Minutes"},"alert_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Alert Level"},"alert_msg":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Alert Msg"},"hungry_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hungry State","description":"e.g. `not_yet`, `hungry_soon`, `overdue`, `dream_feed`, `unknown`."},"next_feed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Feed At"},"last_milk_ml":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Last Milk Ml"},"ml_today":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ml Today"},"feeds_today":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Feeds Today"},"last_poop_hours_ago":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Last Poop Hours Ago"},"poop_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Poop Status"},"expected_bedtime_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expected Bedtime At"},"next_nap_window_at":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Next Nap Window At"},"daily_milk_target_ml":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Daily Milk Target Ml"},"supplement_log":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Supplement Log"}},"type":"object","required":["now","asleep"],"title":"LiveStatus","description":"Current state derived from the log. Additional keys may appear; the ones below are stable."},"LogEventResponse":{"properties":{"status":{"type":"string","const":"ok","title":"Status"},"event":{"$ref":"#/components/schemas/Event"},"live":{"additionalProperties":true,"type":"object","title":"Live","description":"The refreshed live-status block (same shape as `GET /api/vega/live`)."},"unknown_foods":{"items":{"type":"string"},"type":"array","title":"Unknown Foods","description":"`solid` foods with no nutrient data."},"warning":{"anyOf":[{"$ref":"#/components/schemas/Warning_"},{"type":"null"}],"description":"Soft conflict, e.g. a feed logged inside a recorded sleep span. The event was still saved."}},"type":"object","required":["status","event","live"],"title":"LogEventResponse"},"MeResponse":{"properties":{"user":{"type":"string","title":"User","description":"Username."},"family_id":{"type":"string","title":"Family Id"},"role":{"type":"string","enum":["admin","member"],"title":"Role"}},"type":"object","required":["user","family_id","role"],"title":"MeResponse"},"MeasurementsResponse":{"properties":{"measurements":{"items":{"$ref":"#/components/schemas/Event"},"type":"array","title":"Measurements","description":"`weight` and `length` events, oldest first."}},"type":"object","required":["measurements"],"title":"MeasurementsResponse"},"Note":{"properties":{"ts":{"type":"string","title":"Ts"},"text":{"type":"string","title":"Text"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"}},"type":"object","required":["ts","text"],"title":"Note"},"NotesResponse":{"properties":{"notes":{"items":{"$ref":"#/components/schemas/Note"},"type":"array","title":"Notes"}},"type":"object","required":["notes"],"title":"NotesResponse"},"OkResponse":{"properties":{"ok":{"type":"boolean","title":"Ok","default":true,"examples":[true]}},"type":"object","title":"OkResponse"},"OnboardResponse":{"properties":{"ok":{"type":"boolean","title":"Ok"},"redirect":{"type":"string","title":"Redirect","examples":["/vega"]}},"type":"object","required":["ok","redirect"],"title":"OnboardResponse"},"PatternsResponse":{"properties":{"patterns":{"additionalProperties":true,"type":"object","title":"Patterns"},"daily_totals":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Daily Totals"},"today":{"items":{"$ref":"#/components/schemas/Event"},"type":"array","title":"Today"},"nutrients_7d":{"additionalProperties":true,"type":"object","title":"Nutrients 7D"},"nutrients_today":{"additionalProperties":true,"type":"object","title":"Nutrients Today"},"nutrient_targets":{"additionalProperties":true,"type":"object","title":"Nutrient Targets"},"allergens_today":{"additionalProperties":true,"type":"object","title":"Allergens Today"},"allergen_grid":{"additionalProperties":true,"type":"object","title":"Allergen Grid"},"baby_name":{"type":"string","title":"Baby Name"},"dob":{"type":"string","title":"Dob"},"age_months":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Age Months"},"age_display":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Age Display"},"flags":{"additionalProperties":true,"type":"object","title":"Flags","examples":[{"solids_started":false}]}},"type":"object","required":["patterns","daily_totals","today","nutrients_7d","nutrients_today","nutrient_targets","allergens_today","allergen_grid","baby_name","dob","age_months","age_display","flags"],"title":"PatternsResponse","description":"Everything the dashboard renders. Solid-food blocks are empty until `flags.solids_started` is true."},"Profile":{"properties":{"baby_name":{"type":"string","title":"Baby Name"},"dob":{"type":"string","title":"Dob","description":"YYYY-MM-DD"},"gender":{"type":"string","title":"Gender","default":""},"family_name":{"type":"string","title":"Family Name","default":""},"timezone":{"type":"string","title":"Timezone","description":"IANA zone.","default":"Europe/London"},"region":{"type":"string","enum":["uk","us"],"title":"Region","default":"uk"},"units":{"type":"string","enum":["metric","imperial"],"title":"Units","default":"metric"},"age_months":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Age Months"},"age_display":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Age Display"},"solids_started":{"type":"boolean","title":"Solids Started","default":false},"member_count":{"type":"integer","title":"Member Count","default":1},"age_band_targets":{"additionalProperties":true,"type":"object","title":"Age Band Targets"}},"type":"object","required":["baby_name","dob"],"title":"Profile"},"ProfileUpdateResponse":{"properties":{"ok":{"type":"boolean","title":"Ok"},"profile":{"additionalProperties":true,"type":"object","title":"Profile"}},"type":"object","required":["ok","profile"],"title":"ProfileUpdateResponse"},"RecipeResponse":{"properties":{"status":{"type":"string","const":"ok","title":"Status"},"recipe":{"additionalProperties":true,"type":"object","title":"Recipe"}},"type":"object","required":["status","recipe"],"title":"RecipeResponse"},"TokenInfo":{"properties":{"id":{"type":"string","title":"Id"},"label":{"type":"string","title":"Label"},"username":{"type":"string","title":"Username"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","label","username","scopes","created_at"],"title":"TokenInfo"},"TokenResponse":{"properties":{"token":{"type":"string","title":"Token","description":"Shown once; store it securely."},"luna_url":{"type":"string","title":"Luna Url"},"mcp_url":{"type":"string","title":"Mcp Url","examples":["https://getmyluna.app/mcp"]},"label":{"type":"string","title":"Label"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"}},"type":"object","required":["token","luna_url","mcp_url","label","scopes"],"title":"TokenResponse"},"TokensResponse":{"properties":{"tokens":{"items":{"$ref":"#/components/schemas/TokenInfo"},"type":"array","title":"Tokens"}},"type":"object","required":["tokens"],"title":"TokensResponse"},"UndoResponse":{"properties":{"status":{"type":"string","const":"ok","title":"Status"},"removed":{"anyOf":[{"$ref":"#/components/schemas/Event"},{"type":"null"}],"description":"`null` when there was nothing to undo."},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"},"live":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Live"}},"type":"object","required":["status"],"title":"UndoResponse"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"Warning_":{"properties":{"type":{"type":"string","title":"Type","examples":["asleep_at_time"]},"message":{"type":"string","title":"Message"},"sleep_span":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Sleep Span"}},"type":"object","required":["type","message"],"title":"Warning_"},"LogEventRequest":{"description":"Body for `POST /api/vega/log`. Provide the fields that make sense for `type`.","properties":{"type":{"enum":["milk","sleep","wake","nappy","poop","solid","note","supplement","weight","length"],"examples":["milk"],"title":"Type","type":"string"},"ts":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"ISO 8601 local time; defaults to now. Cannot be in the future.","examples":["2026-09-20T14:30:00"],"title":"Ts"},"ml":{"anyOf":[{"maximum":500,"minimum":0,"type":"integer"},{"type":"null"}],"default":null,"description":"`milk`: millilitres, 0–500. Use 0 (or omit) for a breastfeed.","examples":[150],"title":"Ml"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"`nappy`: wet|dirty|both|dry. `supplement`: vitd|iron|multivitamin.","examples":["wet"],"title":"Kind"},"foods":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"default":null,"description":"`solid`: foods eaten.","examples":[["scrambled egg","toast"]],"title":"Foods"},"meal_type":{"anyOf":[{"enum":["meal","snack"],"type":"string"},{"type":"null"}],"default":null,"description":"`solid` only.","title":"Meal Type"},"kg":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"description":"`weight`: kilograms, 0.5–30.","examples":[8.45],"title":"Kg"},"cm":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"description":"`length`: centimetres, 40–120.","examples":[72.5],"title":"Cm"},"ug":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"description":"`supplement`: micrograms.","examples":[10],"title":"Ug"},"note":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Free text, up to 300 characters.","title":"Note"},"author":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Defaults to the calling user's username.","title":"Author"},"timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"IANA zone if `ts` is in a different zone from the family's.","title":"Timezone"}},"required":["type"],"title":"LogEventRequest","type":"object"},"EventEditRequest":{"properties":{"id":{"examples":["af73aec9"],"title":"Id","type":"string"},"changes":{"additionalProperties":true,"description":"Editable fields only: ts, ml, foods, note, meal_type, kind, author.","examples":[{"ml":180}],"title":"Changes","type":"object"}},"required":["id","changes"],"title":"EventEditRequest","type":"object"},"EventIdRequest":{"properties":{"id":{"examples":["af73aec9"],"title":"Id","type":"string"}},"required":["id"],"title":"EventIdRequest","type":"object"},"EventReactRequest":{"properties":{"id":{"examples":["af73aec9"],"title":"Id","type":"string"},"emoji":{"examples":["❤️"],"title":"Emoji","type":"string"}},"required":["id","emoji"],"title":"EventReactRequest","type":"object"},"RecipeRequest":{"properties":{"name":{"examples":["lentil dahl"],"title":"Name","type":"string"},"ingredients":{"examples":[["red lentils","carrot","coconut milk"]],"items":{"type":"string"},"title":"Ingredients","type":"array"}},"required":["name","ingredients"],"title":"RecipeRequest","type":"object"},"ProfileUpdateRequest":{"description":"Any subset of fields; admin only.","properties":{"baby_name":{"anyOf":[{"maxLength":80,"type":"string"},{"type":"null"}],"default":null,"title":"Baby Name"},"dob":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"YYYY-MM-DD, not in the future, within 0–5 years.","title":"Dob"},"gender":{"anyOf":[{"enum":["girl","boy","female","male","other","unknown","prefer_not_to_say",""],"type":"string"},{"type":"null"}],"default":null,"title":"Gender"},"family_name":{"anyOf":[{"maxLength":120,"type":"string"},{"type":"null"}],"default":null,"title":"Family Name"},"timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"IANA zone, e.g. `America/New_York`.","title":"Timezone"},"region":{"anyOf":[{"enum":["uk","us"],"type":"string"},{"type":"null"}],"default":null,"description":"Sets `units` to match unless `units` is given.","title":"Region"},"units":{"anyOf":[{"enum":["metric","imperial"],"type":"string"},{"type":"null"}],"default":null,"title":"Units"}},"title":"ProfileUpdateRequest","type":"object"},"OnboardRequest":{"properties":{"email":{"examples":["sam@example.com"],"title":"Email","type":"string"},"password":{"minLength":6,"title":"Password","type":"string"},"username":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Defaults to the part of the email before `@`.","title":"Username"},"baby_name":{"examples":["Isla"],"maxLength":80,"title":"Baby Name","type":"string"},"dob":{"description":"YYYY-MM-DD","examples":["2025-06-01"],"title":"Dob","type":"string"},"family_name":{"anyOf":[{"maxLength":120,"type":"string"},{"type":"null"}],"default":null,"title":"Family Name"},"gender":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Gender"},"timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"IANA zone; default `Europe/London`.","title":"Timezone"},"region":{"anyOf":[{"enum":["uk","us"],"type":"string"},{"type":"null"}],"default":null,"description":"Default `uk`.","title":"Region"},"units":{"anyOf":[{"enum":["metric","imperial"],"type":"string"},{"type":"null"}],"default":null,"title":"Units"},"acquisition":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"default":null,"description":"Optional first-touch attribution (utm_source etc.).","title":"Acquisition"}},"required":["email","password","baby_name","dob"],"title":"OnboardRequest","type":"object"},"TokenRequest":{"properties":{"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Re-minting the same label replaces that token. Defaults to your username.","examples":["Muse"],"title":"Label"},"scopes":{"anyOf":[{"items":{"enum":["read","write"],"type":"string"},"type":"array"},{"type":"null"}],"default":null,"description":"Default: both.","examples":[["read","write"]],"title":"Scopes"}},"title":"TokenRequest","type":"object"},"TokenRevokeRequest":{"properties":{"id":{"description":"Token id from `GET /api/vega/tokens`.","title":"Id","type":"string"}},"required":["id"],"title":"TokenRevokeRequest","type":"object"},"InviteRevokeRequest":{"properties":{"token":{"description":"The invite code.","title":"Token","type":"string"}},"required":["token"],"title":"InviteRevokeRequest","type":"object"},"FamilyDeleteRequest":{"properties":{"confirm":{"description":"Must equal the family's name exactly.","examples":["The Lopez family"],"title":"Confirm","type":"string"}},"required":["confirm"],"title":"FamilyDeleteRequest","type":"object"},"AskRequest":{"properties":{"question":{"description":"Prefix with `remember:` to save a note instead of asking.","examples":["How did feeding go this week?"],"title":"Question","type":"string"}},"required":["question"],"title":"AskRequest","type":"object"},"NoteDeleteRequest":{"properties":{"ts":{"description":"The note's `ts`, which is its identifier.","title":"Ts","type":"string"}},"required":["ts"],"title":"NoteDeleteRequest","type":"object"},"AnalyticsRequest":{"properties":{"name":{"description":"One of the allowlisted event names.","examples":["cta_click"],"title":"Name","type":"string"},"props":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"default":null,"title":"Props"}},"required":["name"],"title":"AnalyticsRequest","type":"object"}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"opaque","description":"Token from Settings → Connect an assistant or `POST /api/vega/token`. Scopes: `read`, `write`."},"sessionCookie":{"type":"apiKey","in":"cookie","name":"luna_session","description":"Browser session set by `POST /login` or `POST /api/vega/onboard`."}}},"tags":[{"name":"Discovery","description":"Health, identity and machine-readable descriptions of Luna."},{"name":"Account","description":"Sign-up, family members, invites and account deletion."},{"name":"Tokens","description":"Bearer tokens for agents, scripts and the MCP connector."},{"name":"Tracker","description":"Log and read the family's events: feeds, sleep, nappies, solids, notes, measurements, supplements."},{"name":"Insights","description":"Live state, patterns, weekly nutrition/allergen records and growth measurements derived from the log."},{"name":"Profile","description":"The child's profile and family settings (region, units, timezone)."},{"name":"Ask Luna","description":"Luna Plus AI summaries grounded in the family's own log, plus the notes Luna remembers."},{"name":"Analytics","description":"Allowlisted, non-PII product analytics."}],"externalDocs":{"description":"Developer portal","url":"https://getmyluna.app/developers"}}