{"openapi":"3.1.0","info":{"title":"Indi Agent API - First Principles","version":"0.1.0"},"paths":{"/metrics":{"get":{"summary":"Metrics","description":"Endpoint that serves Prometheus metrics.","operationId":"metrics_metrics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/transcription/":{"post":{"tags":["transcription"],"summary":"Transcribe","description":"Transcribe audio file using Deepgram API\n\nArgs:\n    audio_file: Audio file to transcribe (supports various formats)\n    request: FastAPI request object for authentication\n\nReturns:\n    TranscriptionResponse with transcript text, confidence and metadata","operationId":"transcribe_transcription__post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_transcribe_transcription__post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranscriptionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/messages/{message_id}/attachment/thumbnail":{"get":{"tags":["chat"],"summary":"Get Attachment Thumbnail","description":"Get a sized thumbnail URL for a chat message attachment.\n\nLazy uploads base64 attachment to storage on first request, then mints a\nsized image URL (assets Worker on R2, else imgproxy) for efficient mobile\ndisplay. Falls back to a raw signed URL if minting fails.\n\nAuthentication: JWT required\nRLS: User must have access to the message","operationId":"get_attachment_thumbnail_chat_messages__message_id__attachment_thumbnail_get","parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","title":"Message Id"}},{"name":"index","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Attachment index (default: first)","default":0,"title":"Index"},"description":"Attachment index (default: first)"},{"name":"width","in":"query","required":false,"schema":{"type":"integer","maximum":2048,"minimum":1,"description":"Thumbnail width","default":400,"title":"Width"},"description":"Thumbnail width"},{"name":"height","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":2048,"minimum":1},{"type":"null"}],"description":"Thumbnail height (omit for a square: height = width)","title":"Height"},"description":"Thumbnail height (omit for a square: height = width)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/messages/{message_id}/attachment/video":{"get":{"tags":["chat"],"summary":"Get Attachment Video","description":"Return a short-lived signed URL for a video attachment on a chat message.\n\nCompanion to the thumbnail endpoint, which returns the poster image. This\nreturns the video file itself so the frontend can stream it in a modal\nplayer.\n\nPath scope validation mirrors the thumbnail route: we fetch the video's\ndocument_id, look up the document's child_id via the user-RLS'd client,\nand reject any `file_url` that falls outside `private/{child_id}/source/`.\n\nAuthentication: JWT required. RLS: user must have access to the message.","operationId":"get_attachment_video_chat_messages__message_id__attachment_video_get","parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","title":"Message Id"}},{"name":"index","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Attachment index","default":0,"title":"Index"},"description":"Attachment index"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/children":{"get":{"tags":["children"],"summary":"List Children","description":"List all children for the current user.\n\nLightweight endpoint returning only identifiers and avatars.\nShared across web and mobile clients.\n\nAuthentication: JWT required\nRLS: Automatically enforced - own children + family unit","operationId":"list_children_children_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChildrenListResponse"}}}}}},"post":{"tags":["children"],"summary":"Create Child","description":"Create a new child profile.\n\nRequired: name, date_of_birth\nOptional: age, gender, pronouns, diagnosis, conditions, diagnosed,\n          stage, initial_concerns\n\nAuthentication: JWT required\nAuthorization: RLS enforced - child linked to authenticated user\n\nReturns:\n    Created child profile with generated child_id","operationId":"create_child_children_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__children__profile__CreateChildRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChildResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/children/pending-clinic":{"get":{"tags":["children"],"summary":"List Pending Clinics","description":"The children whose asserted clinic has not been connected yet.\n\nDeclared before the POST because it is the static path and that one is dynamic - the\ntwo could not collide (different methods, different segment counts) but the convention\nis worth keeping visible.\n\n\"Not connected yet\" is an ``organisation_child_access`` row for the same pair. That is\nwhat Ashleigh's manual pairing writes, and a clinic that has reached the child has\nnothing left to ask for. Nothing clears ``pending_organisation_id`` - it is a billing\nsignal and stays true - so resolution is read from the access table rather than from\nthe absence of the stamp.\n\nA TYPED clinic is a ``clinic_sales_leads`` row with no email, and it is listed only\nwhile there is nothing from that practice on the child's care team. There is no pairing\nto wait on - the practice is not on indi - so once the parent has added their contact\nthere is nothing left to ask; the row stays, for the queue.\n\nEither shape is listed only while nothing from that practice is on the child's care\nteam - a member whose organisation is this practice, trimmed and case-insensitive, the\nsame test the completing UPDATE's ILIKE applies, so a contact that answers the ask here\nis a contact that reached the lead there. It is the parent's own act that answers the\nask, whichever way the clinic was named.\n\nONE per child. The finder lets a parent type a practice and then pick one from the\nsearch (the add sheet writes its lead on Save, not on Continue), and home has one\nactivation row to ask from, so two asks for one child is one the parent can never\nclear. The stamp wins - it is the answer they continued with - and among typed leads\nthe newest does, the same order ``complete_clinic_lead`` writes to, so the row this\nnames is the row the address lands on. The other leads stay in the queue untouched.","operationId":"list_pending_clinics_children_pending_clinic_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PendingClinicsResponse"}}}}}}},"/children/{child_id}/pending-clinic":{"post":{"tags":["children"],"summary":"Set Pending Clinic","operationId":"set_pending_clinic_children__child_id__pending_clinic_post","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","title":"Child Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PendingClinicResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/children/{child_id}/next-session":{"get":{"tags":["children"],"summary":"Get Next Session","description":"The clinic's next booking for this child, for the onboarding session step.\n\nRead from `provider_appointments`, where the sweep stores the practitioner\nas a name rather than as prose in a mirrored `detail`. That table is the\nclinic's (its RLS is org-only), so it is read on the service client, scoped\nto one child the caller has just been shown to see. Only the day, zone and\nthe practitioner's first name leave: nothing else about the booking does.","operationId":"get_next_session_children__child_id__next_session_get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Child Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/children/{child_id}/tracks":{"post":{"tags":["children"],"summary":"Add Child Tracks","description":"Create the parent's own tracks on a child that already exists.\n\nA clinic-claimed child skips the child form, so this is the same seeding\n`POST /children` does, for the one journey that never reaches it. RLS\n(`tracks_family_insert`) makes the parent the author and a family member\nthe only caller. A name the parent already has a live track for is skipped,\nso a retry whose answer was lost never makes a second one. Only the\nparent's OWN tracks count: a clinician's \"Sleep\" on the same child is the\ntrack this step exists to give the parent an alternative to, so it never\ncancels their pick.","operationId":"add_child_tracks_children__child_id__tracks_post","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Child Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddTracksRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/children/{child_id}":{"patch":{"tags":["children"],"summary":"Update Child","description":"Update an existing child profile.\n\nPartial update - only provided fields are changed.\nAt least one field must be provided.\n\nAuthentication: JWT required\nAuthorization: RLS enforced - user must own child\n\nReturns:\n    Updated child profile","operationId":"update_child_children__child_id__patch","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateChildRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChildResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["children"],"summary":"Get Child","description":"Get a child profile by ID.\n\nAuthentication: JWT required\nAuthorization: RLS enforced - user must own child\n\nReturns:\n    Child profile with inbox_email","operationId":"get_child_children__child_id__get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChildResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/children/{child_id}/favourite-thing":{"put":{"tags":["children"],"summary":"Set Favourite Thing","description":"Record a child's \"favourite thing\" as a parent observation.\n\nThin transport wrapper over `capture_favourite_thing` - the append-only\ndedup + canonical L4 projection/embedding live in that shared helper so\nthis REST route and the GraphQL `setFavouriteThing` mutation stay\nbyte-identical. A blank value is a success no-op (`note_id: null`).\n\nAuthentication: JWT required\nAuthorization: RLS enforced - user must own child","operationId":"set_favourite_thing_children__child_id__favourite_thing_put","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FavouriteThingRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/children/{child_id}/profile-picture":{"post":{"tags":["children"],"summary":"Upload Profile Picture","description":"Upload/replace child profile picture.\n\nAuthentication: JWT required via Authorization header\nRLS: User must own the child (enforced by Supabase)\n\nArgs:\n    child_id: UUID of child\n    file: Image file (JPEG, PNG, WebP, HEIC)\n\nReturns:\n    Profile picture URL and signed imgproxy URL\n\nRaises:\n    400: Invalid file type or size\n    404: Child not found or not owned by user\n    500: Upload failed","operationId":"upload_profile_picture_children__child_id__profile_picture_post","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_profile_picture_children__child_id__profile_picture_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["children"],"summary":"Get Profile Picture","description":"Get signed imgproxy URL for child profile picture.\n\nAuthentication: JWT required via Authorization header\nRLS: User must own the child (enforced by Supabase)\n\nArgs:\n    child_id: UUID of child\n    width: Target width (optional)\n    height: Target height (optional)\n    format: Output format (jpeg/webp/avif/png, default: webp)\n    quality: Image quality 1-100 (default: 85)\n\nReturns:\n    Signed imgproxy URL with expiry\n\nRaises:\n    404: Child not found, no profile picture or access denied\n    400: Invalid transformation parameters\n    500: URL generation failed","operationId":"get_profile_picture_children__child_id__profile_picture_get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"width","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":4096,"minimum":1},{"type":"null"}],"title":"Width"}},{"name":"height","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":4096,"minimum":1},{"type":"null"}],"title":"Height"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"webp","title":"Format"}},{"name":"quality","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":85,"title":"Quality"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/children/{child_id}/emergency-profile/share":{"get":{"tags":["children","emergency-profile"],"summary":"Get Emergency Profile Share Url","description":"Signed URL for the completed emergency-profile PDF snapshot.\n\nAuthentication: JWT required. RLS: caller must have access to the child.","operationId":"get_emergency_profile_share_url_children__child_id__emergency_profile_share_get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__children__emergency_profile_share__DownloadUrlResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/care-team/pending-matches":{"get":{"tags":["care-team-match"],"summary":"Pending Matches","description":"Return opted-in care-team auto-matches for the authenticated caller.\n\nSee ``list_pending_matches_for_email`` for the discovery filter; this\nhandler is the request-shaped wrapper that runs the auth + email\nresolution and surfaces the response model.\n\nAuthentication: JWT required.","operationId":"pending_matches_care_team_pending_matches_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PendingMatchesResponse"}}}}}}},"/care-team/accept-match":{"post":{"tags":["care-team-match"],"summary":"Accept Match","description":"Accept a per-child auto-match.\n\nAuthentication: JWT required.","operationId":"accept_match_care_team_accept_match_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptMatchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptMatchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/care-team/decline-match":{"post":{"tags":["care-team-match"],"summary":"Decline Match","description":"Decline a per-child auto-match.\n\nAuthentication: JWT required.","operationId":"decline_match_care_team_decline_match_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeclineMatchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Decline Match Care Team Decline Match Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/care-team/{care_team_member_id}/dismiss-match":{"post":{"tags":["care-team-match"],"summary":"Dismiss Match","description":"Parent dismisses an \"already on indi\" match suggestion (\"not involved\").\n\nStamps the durable ``suggestion_dismissed_at`` tombstone so the nudge is\nnever re-surfaced for this contact (checked before every enqueue + fan-out,\nnever cleared by reconcile). This is the PARENT-side counterpart to the\nworker-side ``/decline-match``: ownership is enforced by RLS (the caller must\nown the child the contact is on), so the user client suffices - a non-owner's\nSELECT/UPDATE simply sees no row.\n\nIdempotent: re-dismissing a dismissed row returns ``{success, idempotent}``.\n404 when the contact is unknown or not the caller's.\n\nAuthentication: JWT required.","operationId":"dismiss_match_care_team__care_team_member_id__dismiss_match_post","parameters":[{"name":"care_team_member_id","in":"path","required":true,"schema":{"type":"string","title":"Care Team Member Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Dismiss Match Care Team  Care Team Member Id  Dismiss Match Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/care-team/worker/children":{"get":{"tags":["care-team-landing"],"summary":"Worker Children","description":"List children the caller has care-team access to.\n\nWidens the role filter for ``account_type='village_free'`` callers\n(the canonical free-tier care-team member) and narrows it for everyone\nelse. See the module docstring for the two caller shapes and the\nfamily-OR-leak rationale.\n\nAuthentication: JWT required.","operationId":"worker_children_care_team_worker_children_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkerChildrenResponse"}}}}}}},"/care-team/invite":{"post":{"tags":["care-team-invite-canonical"],"summary":"Invite To Care Team","description":"Invite a person to a child's care team by email.\n\nCaller must be a family member of the child OR a clinician with active\naccess. The server branches on the recipient's account type:\n\n- active clinician → grant + clinician care team row (connected_clinician)\n- non-clinician account → canonicalize + worker care team row + synthetic\n  claimed invite code (connected_worker)\n- no account → create care team row + active invite code, dispatch email\n  (invite_sent)\n\nIdempotent on (email, child_id): a re-invite returns ``already_on_team``\nwith the existing ids. When ``care_team_member_id`` is supplied (the\nConnect surfaces always know it), the RPC matches the existing contact by\nthat id first - so adding or correcting a saved contact's email re-invites\nthe same record instead of forking a duplicate.","operationId":"invite_to_care_team_care_team_invite_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__care_team_invite_canonical__routes__InviteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__care_team_invite_canonical__routes__InviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/care-team/recommend-clinic":{"post":{"tags":["care-team"],"summary":"Recommend Clinic","description":"Send a recommendation email to a clinic about indi.","operationId":"recommend_clinic_care_team_recommend_clinic_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecommendClinicRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecommendClinicResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/care-team/batch":{"get":{"tags":["care-team"],"summary":"Get Care Team Batch","description":"Get care teams for several children in one round-trip.\n\nCollapses the account-page / todos-page per-child fan-out (#6324):\na fixed number of `.in_(\"child_id\", ...)` queries instead of\nO(children) requests. `child_ids` is comma-separated UUIDs.\n\nAuthentication: JWT required\nRLS: children the caller can't access are omitted, not errored","operationId":"get_care_team_batch_care_team_batch_get","parameters":[{"name":"child_ids","in":"query","required":true,"schema":{"type":"string","minLength":36,"title":"Child Ids"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchCareTeamResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/care-team/{child_id}":{"get":{"tags":["care-team"],"summary":"Get Care Team","description":"Get all care team members for a child.\n\nReturns the child's care team with role and contact information.\n\nAuthentication: JWT required\nRLS: User must have family access to the child","operationId":"get_care_team_care_team__child_id__get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChildCareTeamResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["care-team"],"summary":"Add Care Team Member","description":"Add a new care team member to a child.\n\nCreates the member record and links it to the child.\n\nAuthentication: JWT required\nRLS: User must have family access to the child","operationId":"add_care_team_member_care_team__child_id__post","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddCareTeamMemberRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CareTeamMemberResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/care-team/add-batch":{"post":{"tags":["care-team"],"summary":"Add Care Team Batch","description":"Add multiple care team members to a child in one request.\n\nEach member is processed independently - successful entries are persisted\neven when others fail (partial failure). Returns per-member results so the\nclient can surface inline errors and allow retrying only failed entries.\n\nFor each successfully added member:\n- Email is checked against clinician_profiles (Branch A = match, Branch B = no match)\n- Branch A results include clinician_name and clinic_name\n\nWhen send_inbox_emails=True, dispatches inbox sharing emails to selected\n(or all) successfully added members.\n\nAuthentication: JWT required\nRLS: User must have family access to the child","operationId":"add_care_team_batch_care_team_add_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddBatchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddBatchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/care-team/send-welcome-emails":{"post":{"tags":["care-team"],"summary":"Send Welcome Emails","description":"Send Branch B welcome emails for care team members.\n\nCalled after the parent previews and approves the email content.\nBranch A emails (share code to known clinicians) are auto-sent during\nbatch add, so this endpoint only handles Branch B (welcome emails to\nnon-indi members).\n\nAuthentication: JWT required","operationId":"send_welcome_emails_care_team_send_welcome_emails_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendWelcomeEmailsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendWelcomeEmailsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/care-team/lookup-email":{"post":{"tags":["care-team"],"summary":"Lookup Email","description":"Check if an email belongs to an active clinician on indi.\n\nUsed by the care team wizard to show real-time feedback as the parent\nenters a team member's email. Wraps the existing lookup_clinician_by_email\nhelper used during batch add.\n\nAuthentication: JWT required","operationId":"lookup_email_care_team_lookup_email_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LookupEmailRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LookupEmailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/care-team/{child_id}/{junction_id}":{"put":{"tags":["care-team"],"summary":"Update Care Team Member","description":"Update a care team member.\n\nUpdates both member data and role information.\n\nAuthentication: JWT required\nRLS: User must have family access to the child","operationId":"update_care_team_member_care_team__child_id___junction_id__put","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"junction_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Junction Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCareTeamMemberRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CareTeamMemberResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["care-team"],"summary":"Remove Care Team Member","description":"Remove a care team member from a child.\n\nRemoves the junction record. If this is a connected clinician,\nalso revokes their portal access via clinician_child_access.\n\nAuthentication: JWT required\nRLS: User must have family access to the child","operationId":"remove_care_team_member_care_team__child_id___junction_id__delete","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"junction_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Junction Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/care-team-members/{junction_id}":{"patch":{"tags":["care-team"],"summary":"Patch Care Team Member","description":"Update a care-team-member row scoped to one junction.\n\nAuthentication: JWT required.\n\nAuthorization: enforced by RLS - the caller must have family access\nto a child whose ``child_care_team`` row matches ``junction_id``.\nCross-family callers see the row as not-found (RLS hides it from the\nSELECT we use to discover ``care_team_member_id``); we surface that\nas a 404 rather than 403 to avoid leaking that the junction exists.","operationId":"patch_care_team_member_care_team_members__junction_id__patch","parameters":[{"name":"junction_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"Junction id (child_care_team.id)","title":"Junction Id"},"description":"Junction id (child_care_team.id)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchCareTeamMemberRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchCareTeamMemberResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/todos":{"get":{"tags":["todos"],"summary":"List All Todos","description":"List all todos across all children for the authenticated user.\n\nAuthentication: JWT required\nRLS: family members only; the family filter is for speed, not access","operationId":"list_all_todos_todos_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/TodoWithChildResponse"},"type":"array","title":"Response List All Todos Todos Get"}}}}}}},"/todos/{child_id}":{"get":{"tags":["todos"],"summary":"List Todos","description":"List all todos for a child.\n\nAuthentication: JWT required\nRLS: User must own the child","operationId":"list_todos_todos__child_id__get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TodoResponse"},"title":"Response List Todos Todos  Child Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["todos"],"summary":"Create Todo","description":"Create a new todo for a child.\n\nAuthentication: JWT required\nRLS: User must own the child","operationId":"create_todo_todos__child_id__post","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTodoRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/todos/{child_id}/deleted":{"get":{"tags":["todos"],"summary":"List Deleted Todos","description":"List soft-deleted todos for a child.\n\nAuthentication: JWT required\nRLS: deleted rows are family-only (`20260427100000`)","operationId":"list_deleted_todos_todos__child_id__deleted_get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TodoResponse"},"title":"Response List Deleted Todos Todos  Child Id  Deleted Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/todos/{child_id}/{todo_id}":{"put":{"tags":["todos"],"summary":"Update Todo","description":"Update a todo.\n\nAuthentication: JWT required\nRLS: User must own the child","operationId":"update_todo_todos__child_id___todo_id__put","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"todo_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Todo Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTodoRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["todos"],"summary":"Delete Todo","description":"Soft-delete a todo.\n\nAuthentication: JWT required\nRLS: User must own the child","operationId":"delete_todo_todos__child_id___todo_id__delete","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"todo_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Todo Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/todos/{child_id}/{todo_id}/toggle":{"patch":{"tags":["todos"],"summary":"Toggle Todo","description":"Toggle a todo's completed status.\n\n`surface` (query) records where the toggle originated - 'home' (home\nwidget), 'tasks_page' (full tasks page), or 'unknown' - so analytics can\nseparate home-surface engagement from the full page.\n\nAuthentication: JWT required\nRLS: User must own the child","operationId":"toggle_todo_todos__child_id___todo_id__toggle_patch","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"todo_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Todo Id"}},{"name":"surface","in":"query","required":false,"schema":{"type":"string","default":"unknown","title":"Surface"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/todos/{child_id}/{todo_id}/history":{"get":{"tags":["todos"],"summary":"Get Todo History","description":"Get event history for a todo.\n\nAuthentication: JWT required\nRLS: User must own the child","operationId":"get_todo_history_todos__child_id___todo_id__history_get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"todo_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Todo Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/todos/{child_id}/{todo_id}/restore":{"post":{"tags":["todos"],"summary":"Restore Todo","description":"Restore a soft-deleted todo.\n\nAuthentication: JWT required\nRLS: family only - deleted rows are family-readable (`20260427100000`)\nand the family UPDATE policy doesn't check is_deleted","operationId":"restore_todo_todos__child_id___todo_id__restore_post","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"todo_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Todo Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/todos/{child_id}/{todo_id}/revert/{event_id}":{"post":{"tags":["todos"],"summary":"Revert Todo","description":"Revert a todo to the state captured in a specific event's snapshot.\n\nAuthentication: JWT required\nRLS: User must own the child","operationId":"revert_todo_todos__child_id___todo_id__revert__event_id__post","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"todo_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Todo Id"}},{"name":"event_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/calendar-events":{"get":{"tags":["calendar-events"],"summary":"List All Calendar Events","description":"List all calendar events across all children for the authenticated user.","operationId":"list_all_calendar_events_calendar_events_get","parameters":[{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"To"}},{"name":"tags","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tags"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventWithChildResponse"},"title":"Response List All Calendar Events Calendar Events Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/calendar-events/{child_id}":{"get":{"tags":["calendar-events"],"summary":"List Calendar Events","description":"List calendar events for a child.","operationId":"list_calendar_events_calendar_events__child_id__get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"To"}},{"name":"tags","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tags"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventResponse"},"title":"Response List Calendar Events Calendar Events  Child Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["calendar-events"],"summary":"Create Calendar Event","description":"Create a new calendar event for a child.","operationId":"create_calendar_event_calendar_events__child_id__post","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCalendarEventRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarEventResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/calendar-events/{child_id}/deleted":{"get":{"tags":["calendar-events"],"summary":"List Deleted Calendar Events","description":"List soft-deleted calendar events for a child. RLS: family only (`20260427100000`).","operationId":"list_deleted_calendar_events_calendar_events__child_id__deleted_get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventResponse"},"title":"Response List Deleted Calendar Events Calendar Events  Child Id  Deleted Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/calendar-events/{child_id}/{event_id}":{"put":{"tags":["calendar-events"],"summary":"Update Calendar Event","description":"Update a calendar event.","operationId":"update_calendar_event_calendar_events__child_id___event_id__put","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"event_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Event Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCalendarEventRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarEventResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["calendar-events"],"summary":"Delete Calendar Event","description":"Soft-delete a calendar event.","operationId":"delete_calendar_event_calendar_events__child_id___event_id__delete","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"event_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/calendar-events/{child_id}/{event_id}/history":{"get":{"tags":["calendar-events"],"summary":"Get Calendar Event History","description":"Get event history for a calendar event.","operationId":"get_calendar_event_history_calendar_events__child_id___event_id__history_get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"event_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarEventHistoryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/calendar-events/{child_id}/{event_id}/restore":{"post":{"tags":["calendar-events"],"summary":"Restore Calendar Event","description":"Restore a soft-deleted calendar event.","operationId":"restore_calendar_event_calendar_events__child_id___event_id__restore_post","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"event_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarEventResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/calendar-events/{child_id}/{event_id}/todos":{"post":{"tags":["calendar-events"],"summary":"Link Todo","description":"Link a todo to a calendar event.","operationId":"link_todo_calendar_events__child_id___event_id__todos_post","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"event_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Event Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/calendar-events/{child_id}/{event_id}/todos/{todo_id}":{"delete":{"tags":["calendar-events"],"summary":"Unlink Todo","description":"Unlink a todo from a calendar event.","operationId":"unlink_todo_calendar_events__child_id___event_id__todos__todo_id__delete","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"event_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Event Id"}},{"name":"todo_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Todo Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/feed/{token}.ics":{"get":{"tags":["feed"],"summary":"Get Ical Feed","description":"Serve an iCal feed for a user's family calendar.\n\nThis endpoint is public - the token in the URL *is* the credential.\nReturns 404 for invalid/revoked tokens to avoid leaking endpoint existence.","operationId":"get_ical_feed_feed__token__ics_get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","minLength":20,"title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/feed/token":{"get":{"tags":["feed"],"summary":"List Feed Tokens","description":"List the current user's active feed tokens.","operationId":"list_feed_tokens_feed_token_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedTokenListResponse"}}}}}},"post":{"tags":["feed"],"summary":"Create Feed Token","description":"Generate a new feed token for the current user.","operationId":"create_feed_token_feed_token_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedTokenResponse"}}}}}}},"/feed/token/{token_id}":{"delete":{"tags":["feed"],"summary":"Revoke Feed Token","description":"Revoke a feed token (deactivate it).","operationId":"revoke_feed_token_feed_token__token_id__delete","parameters":[{"name":"token_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Token Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Revoke Feed Token Feed Token  Token Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/reactions":{"post":{"tags":["reactions"],"summary":"Add Reaction","description":"Add a reaction to a timeline item.","operationId":"add_reaction_reactions_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddReactionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReactionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/reactions/{reaction_id}":{"delete":{"tags":["reactions"],"summary":"Remove Reaction","description":"Remove a reaction. RLS ensures users can only delete their own.","operationId":"remove_reaction_reactions__reaction_id__delete","parameters":[{"name":"reaction_id","in":"path","required":true,"schema":{"type":"string","title":"Reaction Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/comments":{"post":{"tags":["comments"],"summary":"Add Comment","operationId":"add_comment_comments_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentCreateBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["comments"],"summary":"List Comments","operationId":"list_comments_comments_get","parameters":[{"name":"child_id","in":"query","required":true,"schema":{"type":"string","title":"Child Id"}},{"name":"item_type","in":"query","required":true,"schema":{"type":"string","title":"Item Type"}},{"name":"item_id","in":"query","required":true,"schema":{"type":"string","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/comments/{comment_id}":{"delete":{"tags":["comments"],"summary":"Delete Comment","operationId":"delete_comment_comments__comment_id__delete","parameters":[{"name":"comment_id","in":"path","required":true,"schema":{"type":"string","title":"Comment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/notifications":{"get":{"tags":["notifications"],"summary":"List Notifications","description":"List notifications for the current user.","operationId":"list_notifications_notifications_get","parameters":[{"name":"unread_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Unread Only"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"types","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated notifications.type filter, e.g. 'notify.tagged,comment.added' (the clinic tag feed).","title":"Types"},"description":"Comma-separated notifications.type filter, e.g. 'notify.tagged,comment.added' (the clinic tag feed)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/notifications/unread-count":{"get":{"tags":["notifications"],"summary":"Unread Count","description":"Return unread notification count for the current user.","operationId":"unread_count_notifications_unread_count_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnreadCountResponse"}}}}}}},"/notifications/read-all":{"patch":{"tags":["notifications"],"summary":"Mark All Read","description":"Mark all unread notifications as read.","operationId":"mark_all_read_notifications_read_all_patch","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkAllReadResponse"}}}}}}},"/notifications/read-matching":{"patch":{"tags":["notifications"],"summary":"Mark Matching Read","description":"Mark the caller's rows about what they opened read.","operationId":"mark_matching_read_notifications_read_matching_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadMatching"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/notifications/{notification_id}/read":{"patch":{"tags":["notifications"],"summary":"Mark Read","description":"Mark a single notification as read.","operationId":"mark_read_notifications__notification_id__read_patch","parameters":[{"name":"notification_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Notification Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/notifications/preferences":{"patch":{"tags":["notifications"],"summary":"Update Notification Preferences","description":"Upsert the caller's notification preferences.\n\nFor each (category, channel) pair in `body.preferences`, set the row's\ncolumn. Unknown categories/channels are silently dropped (whitelist).\nOmitted channels on an INSERT pick up the table's column defaults, which\nmatch `pref_allows()`'s coded defaults by design.","operationId":"update_notification_preferences_notifications_preferences_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateNotificationPreferencesRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateNotificationPreferencesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/reminders/daily":{"get":{"tags":["reminders"],"summary":"Get Daily Reminder","description":"The caller's schedule, or `null` if they have never set one up.\n\n`null` is what hides the settings section: the home card is the entry\npoint, and settings is for management.","operationId":"get_daily_reminder_reminders_daily_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/DailyReminder"},{"type":"null"}],"title":"Response Get Daily Reminder Reminders Daily Get"}}}}}},"put":{"tags":["reminders"],"summary":"Put Daily Reminder","description":"Create or update the schedule, then drop any push already queued for today.\n\nThe second half is not optional. Changing the time or switching off mid-day\nmust not leave an already-enqueued push to land at the old time - the parent\nturned it off and it went off anyway is the worst version of this feature.","operationId":"put_daily_reminder_reminders_daily_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDailyReminderRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DailyReminder"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/check-ins/{check_in_id}/recipient":{"patch":{"tags":["check-ins"],"summary":"Update Check In Recipient","operationId":"update_check_in_recipient_check_ins__check_in_id__recipient_patch","parameters":[{"name":"check_in_id","in":"path","required":true,"schema":{"type":"string","title":"Check In Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecipientActionBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecipientActionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/push-tokens":{"post":{"tags":["push-tokens"],"summary":"Register Push Token","description":"Register or re-activate an Expo push token for the current user.","operationId":"register_push_token_push_tokens_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterTokenRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterTokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["push-tokens"],"summary":"Deregister Push Token","description":"Deactivate a push token for the current user (soft delete).","operationId":"deregister_push_token_push_tokens_delete","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeregisterTokenRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeregisterTokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/att-events":{"post":{"tags":["att-events"],"summary":"Record Att Event","description":"Record one ATT priming-screen funnel event for the current user.","operationId":"record_att_event_att_events_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttEventRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttEventResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/logs/mobile":{"post":{"tags":["logs"],"summary":"Ingest Mobile Logs","description":"Accept a batch of mobile log entries and forward them via stdout.\n\nAuth is enforced by the global JWT middleware before we get here;\n`request.state.user_id` is guaranteed present on this path. The\ntype annotation below documents that invariant without introducing\na runtime check that duplicates the middleware.","operationId":"ingest_mobile_logs_logs_mobile_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MobileLogBatch"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__logs__routes__IngestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/artefacts/{child_id}":{"get":{"tags":["artefacts"],"summary":"List Artefacts","description":"List artefacts for a child.\n\nRLS enforces access: owner, family member or clinician.","operationId":"list_artefacts_artefacts__child_id__get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"include_hidden","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Hidden"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtefactListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/artefacts/{child_id}/{artefact_id}/download":{"get":{"tags":["artefacts"],"summary":"Get Artefact Download Url","description":"Get signed download URL for an artefact's file.\n\nWhen the artefact has a stored PDF (``file_url`` set), returns a\nsigned URL directly. When ``file_url`` is NULL (markdown-only\nartefact), renders the PDF on-the-fly, uploads to temp storage,\nand returns a signed URL for that.\n\nAuthentication: JWT required\nRLS: User must have access via family membership, ownership or clinician access.","operationId":"get_artefact_download_url_artefacts__child_id___artefact_id__download_get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"artefact_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Artefact Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__artefacts__routes__DownloadUrlResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/artefacts/{child_id}/{artefact_id}/preview":{"get":{"tags":["artefacts"],"summary":"Get Artefact Preview","description":"Render artefact content as branded HTML for iframe embedding.","operationId":"get_artefact_preview_artefacts__child_id___artefact_id__preview_get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"artefact_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Artefact Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/artefacts/{child_id}/{artefact_id}/render-pdf":{"post":{"tags":["artefacts"],"summary":"Render Artefact As Pdf","description":"Render artefact content as a branded PDF on-the-fly.","operationId":"render_artefact_as_pdf_artefacts__child_id___artefact_id__render_pdf_post","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"artefact_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Artefact Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/artefacts/{child_id}/{artefact_id}":{"delete":{"tags":["artefacts"],"summary":"Hide Artefact","description":"Soft-hide an artefact (set is_hidden = true)\n\nAuthentication: JWT required\nRLS: User must own the artefact via message (child_id on message)","operationId":"hide_artefact_artefacts__child_id___artefact_id__delete","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"artefact_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Artefact Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/artefacts/share":{"post":{"tags":["artefacts"],"summary":"Share Artefacts","description":"Share artefacts via email.\n\nAuthentication: JWT required\nRLS: User must be family member of the child.","operationId":"share_artefacts_artefacts_share_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareArtefactsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareArtefactsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/status":{"get":{"tags":["documents"],"summary":"Get Documents Status","description":"Unified document status endpoint - handles single or multiple IDs.\n\nOne endpoint, one pattern. Returns same format for 1 or N documents.\n\nQuery Parameters:\n    ids: Single UUID or comma-separated UUIDs\n         Examples: \"uuid1\" or \"uuid1,uuid2,uuid3\"\n\nReturns:\n    Object containing:\n    - documents: Array of document status objects (always array, even for single)\n    - summary: Statistics (total, pending, processing, completed, failed counts)","operationId":"get_documents_status_documents_status_get","parameters":[{"name":"ids","in":"query","required":true,"schema":{"type":"string","title":"Ids"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/preview-url":{"get":{"tags":["documents"],"summary":"Get Document Preview Url","description":"Mint a short-lived signed URL for previewing a stored document file.\n\nReplaces appweb's Next ``/api/documents/preview`` proxy: the browser fetches\nthis (Bearer JWT) and uses the returned URL directly as an <img>/link source.\nAccess to the private ``documents`` bucket is gated at mint time by\n``_authorize_document_preview`` - the R2 backend presigns without storage-RLS,\nso the old create-signed-url gate no longer holds. TTL matches the old route (1h).","operationId":"get_document_preview_url_documents_preview_url_get","parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","minLength":1,"title":"Url"}},{"name":"bucket","in":"query","required":false,"schema":{"enum":["documents","public-documents"],"type":"string","default":"documents","title":"Bucket"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewUrlResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/{child_id}":{"get":{"tags":["documents"],"summary":"List Child Documents","description":"List documents and artefacts for a child.\n\nAuthentication: JWT required\nRLS: User must own the child or have clinician access\n\nQuery params:\n    source: Filter by source (all, upload, email, chat, artefacts)\n    content_type: Filter by content type (all, documents, media).\n                  media = images + videos; documents = everything else.\n    include_processing: Include documents with status='processing' (default: false)\n                        Staged attachments have status='processing' until chat succeeds.\n    include_hidden: Include hidden documents (default: false)\n                    Hidden documents are kept out of Records (email artefacts,\n                    attachments of a deleted email, email documents whose\n                    ingestion failed for good).\n    limit: Number of documents per page (1-100, default: 20)\n    offset: Number of documents to skip (default: 0)\n    search: Search query to filter by title, filename, summary or description","operationId":"list_child_documents_documents__child_id__get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"enum":["all","upload","email","chat"],"type":"string"},{"type":"null"}],"default":"all","title":"Source"}},{"name":"content_type","in":"query","required":false,"schema":{"anyOf":[{"enum":["all","documents","media"],"type":"string"},{"type":"null"}],"title":"Content Type"}},{"name":"include_processing","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Processing"}},{"name":"include_hidden","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Hidden"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Search"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedDocumentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["documents"],"summary":"Delete Child Document","description":"Delete a document. Storage, the timeline card, embeddings and extracted notes follow the row.\n\nStorage cleanup, the L4 ``timeline_entries`` projection and the\n``child_notes`` extracted from the document are DB triggers on\n``documents``; embeddings and ingestion_jobs are FK CASCADE; chat_messages /\nemail_attachments references are FK SET NULL. Migration 20261007060803\nlists what the delete does and does not reach.\nThe timeline cleanup used to live here instead, and this was one of three\nhandlers that delete a documents row - the other two never got it, including\nthe ``deleteDocumentsBatch`` mutation every client actually calls, which is\nhow a deleted record kept an undeletable card on the child's timeline.\n``trigger_cleanup_document_timeline_entry`` (20260831072639) owns it now, in\nthe same transaction as the row.\n\nIdempotent: a delete for a row that's already gone (or never visible to this\ncaller via RLS) returns 200 with ``deleted: False`` plus ``already_deleted: True``\nwhen the caller is a family member. The client's stated intent - \"this should\nnot exist\" - is satisfied either way. This protects callers whose previous\nattempt timed out server-side but actually committed (the prod 2026-05-27\ncase for document 1e23ffad-bbe3-43b3-b2c0-f7bc3fe6b939). A ``document_id``\nthat is not a syntactic uuid reaches that same answer rather than a 500 -\nit addresses no row by construction (#8840).\n\nAuthentication: JWT required\nAuthorization: RLS - family members of the child can delete (see\n    ``Family members can delete documents`` policy, migration\n    ``20251212110001_family_unit_invites.sql``). On the idempotent retry\n    path the user-client DELETE matched nothing and so proves nothing about\n    the caller, hence the explicit family check before answering anything\n    other than \"not found\".\n\nBody:\n    document_id: UUID of the document to delete\n\nResponse:\n    ``{\"success\": True, \"deleted\": True}`` when the document row was\n    deleted, or ``{\"success\": True, \"deleted\": False, \"already_deleted\":\n    True}`` on the idempotent retry path. Existing clients only check\n    ``success``; the extra markers are purely informational for debugging.","operationId":"delete_child_document_documents__child_id__delete","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteDocumentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/{child_id}/{document_id}/thumbnail":{"get":{"tags":["documents"],"summary":"Get Document Thumbnail","description":"Generate a signed, sized URL for a document thumbnail.\n\nAuthentication: JWT required\nRLS: User must have access to the document (family member or uploader)\n\nArgs:\n    child_id: UUID of child\n    document_id: UUID of document\n    width: Target width (default: 96 for 2x retina of 48px display)\n    height: Target height (omit to keep the aspect ratio)\n    format: Output format (jpeg/webp/avif/png, default: webp)\n    quality: Image quality 1-100 (default: 80)\n\nReturns:\n    Signed thumbnail URL with expiry","operationId":"get_document_thumbnail_documents__child_id___document_id__thumbnail_get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"document_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Document Id"}},{"name":"width","in":"query","required":false,"schema":{"type":"integer","maximum":4096,"minimum":1,"default":96,"title":"Width"}},{"name":"height","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":4096,"minimum":1},{"type":"null"}],"title":"Height"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"webp","title":"Format"}},{"name":"quality","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":80,"title":"Quality"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/{child_id}/{document_id}":{"get":{"tags":["documents"],"summary":"Get Document Detail","description":"Get document detail.\n\nAuthentication: JWT required\nRLS: User must have access via family membership or document ownership","operationId":"get_document_detail_documents__child_id___document_id__get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"document_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Document Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["documents"],"summary":"Update Document","description":"Update document description or summary metadata.\n\nAuthentication: JWT required\nRLS: User must have access via family membership or document ownership","operationId":"update_document_documents__child_id___document_id__patch","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"document_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Document Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDocumentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/{child_id}/bulk-upload-urls":{"post":{"tags":["documents"],"summary":"Create Bulk Upload Urls","description":"Mint presigned Storage upload URLs for a bulk document upload.\n\nThe browser PUTs each file's bytes straight to Storage (no request-size\nceiling), then POSTs the returned paths as job metadata. Access is gated by\n``_require_upload_access``: on R2 the presign is a local HMAC that no RLS\nsees, so Storage's INSERT policies only ever held on the Supabase backend.","operationId":"create_bulk_upload_urls_documents__child_id__bulk_upload_urls_post","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkUploadUrlsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkUploadUrlsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/{child_id}/{document_id}/download":{"get":{"tags":["documents"],"summary":"Get Document Download Url","description":"Get signed download URL for a document.\n\nAuthentication: JWT required\nRLS: User must have access via family membership or document ownership\n\nReturns signed URL for direct download. Blocks quarantined files.\n\n``playback`` opts into the normalised MP4 for a transcoded video. It is\nopt-in because this is also the *file download* endpoint - \"save to disk\"\non web, clinic and mobile all resolve here, and those want the bytes the\nparent actually uploaded, under the name and MIME they uploaded them with.\nHanding a re-encode to a clinician exporting a record would be silent data\nsubstitution, so only the viewers that want to *play* the file ask for it.","operationId":"get_document_download_url_documents__child_id___document_id__download_get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"document_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Document Id"}},{"name":"playback","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Playback"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__documents__routes__DownloadUrlResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/{child_id}/{document_id}/docx":{"get":{"tags":["documents"],"summary":"Download Document Docx","description":"Download a clinician-authored markdown document as a .docx.\n\nMarkdown (``content``) is the source of truth; the .docx is generated on the\nfly. RLS scopes access via the user client. Only ``source == 'clinician'``\ndocuments qualify - parent/agent docs keep the PDF download path.","operationId":"download_document_docx_documents__child_id___document_id__docx_get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"document_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Document Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/{child_id}/{document_id}/unlock":{"post":{"tags":["documents"],"summary":"Unlock Document","description":"Unlock a password-protected PDF and re-queue it for processing.\n\nThe password decrypts the stored file in-request; the decrypted bytes\noverwrite the stored object, the document resets to ``pending`` and\nre-enqueues. The password is never logged, echoed or written to any table,\njob, or trace - it lives only in the request body and local variables.\n\nRLS: the user-scoped client proves ownership / family access. Keyed off\n``document_id`` so it is path-agnostic (works for a doc uploaded via chat,\nRecords, clinic, email or mobile).","operationId":"unlock_document_documents__child_id___document_id__unlock_post","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"document_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Document Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnlockDocumentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/share":{"post":{"tags":["documents"],"summary":"Share Documents","description":"Share documents via email with proper family member access control.\n\nAuthentication: JWT required\nRLS: User must be family member of the child to share their documents","operationId":"share_documents_documents_share_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareDocumentsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareDocumentsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/{child_id}/bulk":{"post":{"tags":["documents"],"summary":"Create Bulk Upload Job","description":"Create a bulk_upload_jobs record for pre-uploaded files.\n\nFiles are already in storage (uploaded browser-direct); this only stages the\njob the worker picks up. Every path must be one ``bulk-upload-urls`` minted\nfor this child. Whether the caller may upload to the child is the\n``bulk_upload_jobs`` INSERT policy's call, the same three arms as\n``_require_upload_access``; its refusal (42501) is the 403.","operationId":"create_bulk_upload_job_documents__child_id__bulk_post","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkUploadCreateRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/documents/{child_id}/bulk/{job_id}/status":{"get":{"tags":["documents"],"summary":"Get Bulk Upload Job Status","description":"Return current status for a bulk upload job. The client polls this while\nthe worker processes files. RLS scopes reads to the caller's own jobs.","operationId":"get_bulk_upload_job_status_documents__child_id__bulk__job_id__status_get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"job_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/records/{child_id}":{"get":{"tags":["records"],"summary":"List Child Records","description":"Merged, date-sorted feed of every record kind for a child.\n\nAuthentication: JWT required. Family members see all family records; a\nnon-family caller sees only the documents and drafts they wrote (the\nDocuments tab's gate). For documents the gate enforces it, since RLS\nadmits clinicians. For drafts RLS agrees since #11702's migration, and the\ngate keeps the api right in any environment that migration hasn't reached.\n\nFinalised clinic reports join the feed only when asked (`include=report`,\nor `kind=report`), which only appweb sends: without it the response is\nexactly what installed mobile builds already read\n(`tests/api/records/test_report_opt_in.py` pins it byte for byte).","operationId":"list_child_records_records__child_id__get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Child Id"}},{"name":"kind","in":"query","required":false,"schema":{"enum":["all","document","draft","email","outbox","media","report"],"type":"string","default":"all","title":"Kind"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Search"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"include","in":"query","required":false,"schema":{"anyOf":[{"const":"report","type":"string"},{"type":"null"}],"title":"Include"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordsFeedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/mobile/latest-conversations":{"get":{"tags":["read","mobile"],"summary":"Get Latest Conversations","description":"Get all children with their latest conversation data.\n\nMobile-optimized endpoint for child profiles list with conversation previews.\nReturns compact payload with essential fields only.","operationId":"get_latest_conversations_read_mobile_latest_conversations_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__read__mobile__latest_conversations__LatestConversationsResponse"}}}}}}},"/read/mobile/timeline":{"get":{"tags":["read","mobile"],"summary":"Get Timeline","description":"Fetch paginated timeline events for a child.\n\nAuthentication: JWT required via Authorization header\nRLS: Automatically enforced through user_client isolation","operationId":"get_timeline_read_mobile_timeline_get","parameters":[{"name":"child_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by specific child","title":"Child Id"},"description":"Filter by specific child"},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Filter events by year","title":"Year"},"description":"Filter events by year"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Items per page","default":10,"title":"Page Size"},"description":"Items per page"},{"name":"group_by","in":"query","required":false,"schema":{"type":"string","description":"Aggregation period: day, week, month","default":"day","title":"Group By"},"description":"Aggregation period: day, week, month"},{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter from date (YYYY-MM-DD)","title":"Start Date"},"description":"Filter from date (YYYY-MM-DD)"},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to date (YYYY-MM-DD)","title":"End Date"},"description":"Filter to date (YYYY-MM-DD)"},{"name":"tz_offset","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Client timezone offset in minutes (JS getTimezoneOffset)","title":"Tz Offset"},"description":"Client timezone offset in minutes (JS getTimezoneOffset)"},{"name":"user_timezone","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"IANA timezone (e.g. Australia/Sydney). Overrides tz_offset","title":"User Timezone"},"description":"IANA timezone (e.g. Australia/Sydney). Overrides tz_offset"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimelineResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/web/bio-panel":{"get":{"tags":["read","web"],"summary":"Get Bio Panel","description":"Fetch all children profiles with complete bio data for the current user.\n\nReturns all data needed for the Child Bio Panel component in a single call.\n\nAuthentication: JWT required via Authorization header\nRLS: Automatically enforced through user_client isolation","operationId":"get_bio_panel_read_web_bio_panel_get","parameters":[{"name":"selected_child_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional child ID to mark as selected","title":"Selected Child Id"},"description":"Optional child ID to mark as selected"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BioPanelResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/web/child/{child_id}/latest-conversation":{"get":{"tags":["read","web"],"summary":"Get Latest Conversation","description":"Get the most recent conversation ID for a child.\n\nReturns the latest conversation_id if exists, otherwise None.\nUsed for \"continue chatting\" flows in web UI.","operationId":"get_latest_conversation_read_web_child__child_id__latest_conversation_get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","title":"Child Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LatestConversationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/web/latest-conversations":{"get":{"tags":["read","web"],"summary":"Get Latest Conversations","description":"Get all children with their most recent conversation IDs.\n\nReturns all child profiles with their latest conversation_id.\nUsed for \"Family\" tab and chat selection screens.","operationId":"get_latest_conversations_read_web_latest_conversations_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__read__web__latest_conversations__LatestConversationsResponse"}}}}}}},"/read/web/timeline":{"get":{"tags":["read","web"],"summary":"Get Timeline","description":"Fetch paginated timeline events for a child.\n\nAuthentication: JWT required via Authorization header\nRLS: Automatically enforced through user_client isolation","operationId":"get_timeline_read_web_timeline_get","parameters":[{"name":"child_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by specific child","title":"Child Id"},"description":"Filter by specific child"},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Filter events by year","title":"Year"},"description":"Filter events by year"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Items per page","default":10,"title":"Page Size"},"description":"Items per page"},{"name":"group_by","in":"query","required":false,"schema":{"type":"string","description":"Aggregation period: day, week, month","default":"day","title":"Group By"},"description":"Aggregation period: day, week, month"},{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter from date (YYYY-MM-DD)","title":"Start Date"},"description":"Filter from date (YYYY-MM-DD)"},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to date (YYYY-MM-DD)","title":"End Date"},"description":"Filter to date (YYYY-MM-DD)"},{"name":"tz_offset","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Client timezone offset in minutes (JS getTimezoneOffset)","title":"Tz Offset"},"description":"Client timezone offset in minutes (JS getTimezoneOffset)"},{"name":"user_timezone","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"IANA timezone (e.g. Australia/Sydney). Overrides tz_offset","title":"User Timezone"},"description":"IANA timezone (e.g. Australia/Sydney). Overrides tz_offset"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimelineResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/observations/{observation_id}/delete":{"patch":{"tags":["observations"],"summary":"Delete Observation","description":"Soft-delete an observation (set is_deleted=true).\n\nThin transport wrapper over ``perform_observation_delete`` (shared with the\nGraphQL ``deleteObservation`` mutation). RLS is the single authorization\ngate; orphan timeline ghosts can be cleared by family members. See the\nshared helper for the two-leg behaviour.\n\nAuthentication: JWT required via Authorization header\nRLS: Parents (family members) and clinicians (with child access)\ncan soft-delete observations. Orphan timeline ghosts can be\ncleared by family members.","operationId":"delete_observation_observations__observation_id__delete_patch","parameters":[{"name":"observation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Observation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/observations/quick-note":{"post":{"tags":["observations"],"summary":"Create Quick Note","description":"Create an observation via quick capture (voice/text from home screen).\n\nThin transport wrapper over ``perform_quick_note_capture`` (shared with the\nGraphQL ``createQuickNote`` mutation). Saves with ``category=\"other\"`` and\nfans out timeline projection, embedding, AI categorize and worker→parent\nnotify-on-entry side effects - see the shared helper.","operationId":"create_quick_note_observations_quick_note_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuickNoteBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/messages":{"get":{"tags":["chat"],"summary":"Get User Messages","description":"Get paginated messages for user's single conversation (derived from JWT)\n\nSingle-conversation model: each user has one conversation.\nDefault: newest messages first (page 1 = most recent). Set oldest_first=true for chronological.","operationId":"get_user_messages_chat_messages_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Messages per page","default":50,"title":"Page Size"},"description":"Messages per page"},{"name":"oldest_first","in":"query","required":false,"schema":{"type":"boolean","description":"Order by oldest first (default: newest first)","default":false,"title":"Oldest First"},"description":"Order by oldest first (default: newest first)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedMessagesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/attachments/signed-upload":{"post":{"tags":["chat"],"summary":"Create Signed Upload","description":"Issue Supabase Storage signed upload URLs for a video + its poster.\n\nAuthentication: JWT required (user must have access to child_id via RLS on documents).","operationId":"create_signed_upload_chat_attachments_signed_upload_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedUploadBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedUploadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/chat/preferences":{"patch":{"tags":["chat"],"summary":"Update Chat Preferences","description":"Merge mutation-approval toggles into the parent's chat preferences.\n\n`true` adds the mutation to the whitelist, `false` removes it. Callers\nonly send the keys they know about - existing entries are preserved.","operationId":"update_chat_preferences_chat_preferences_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateChatPreferencesRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateChatPreferencesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/web/child/{child_id}/emails":{"get":{"tags":["read","web","emails"],"summary":"Emails","description":"List emails for a child with pagination. Hides thread replies, sorts by received_at.","operationId":"emails_read_web_child__child_id__emails_get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","title":"Child Id"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Pagination cursor (received_at timestamp)","title":"Cursor"},"description":"Pagination cursor (received_at timestamp)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Number of emails to return","default":20,"title":"Limit"},"description":"Number of emails to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/web/child/{child_id}/emails/{email_id}":{"get":{"tags":["read","web","emails"],"summary":"Email","description":"Get email detail and mark as read.","operationId":"email_read_web_child__child_id__emails__email_id__get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","title":"Child Id"}},{"name":"email_id","in":"path","required":true,"schema":{"type":"string","title":"Email Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["read","web","emails"],"summary":"Delete Email","description":"Cascade-hide an email and all its side effects (documents, notes, timeline entries).","operationId":"delete_email_read_web_child__child_id__emails__email_id__delete","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","title":"Child Id"}},{"name":"email_id","in":"path","required":true,"schema":{"type":"string","title":"Email Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailDeleteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/web/child/{child_id}/emails/{email_id}/read":{"post":{"tags":["read","web","emails"],"summary":"Mark Read","description":"Mark an email as read.","operationId":"mark_read_read_web_child__child_id__emails__email_id__read_post","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","title":"Child Id"}},{"name":"email_id","in":"path","required":true,"schema":{"type":"string","title":"Email Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/clinic/catchup/read":{"post":{"tags":["read","clinic"],"summary":"Mark Client Read","description":"Mark one client read as of the feed's `as_of`.","operationId":"mark_client_read_read_clinic_catchup_read_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkRead"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkReadResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/clinic/catchup/restore":{"post":{"tags":["read","clinic"],"summary":"Restore Client Read","description":"Undo a mark: the stamp goes back to what `read` returned as previous.","operationId":"restore_client_read_read_clinic_catchup_restore_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Restore"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/clinic/catchup/read-all":{"post":{"tags":["read","clinic"],"summary":"Mark All Clients Read","description":"Mark Home's list read. Only ids in the caller's default scope are touched,\nso a clinic-wide child is never stamped; the rest are dropped silently.","operationId":"mark_all_clients_read_read_clinic_catchup_read_all_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkAllRead"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkAllResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/clinic/catchup/restore-all":{"post":{"tags":["read","clinic"],"summary":"Restore All Read","description":"Undo Mark all read, child by child; each reports whether it went back.","operationId":"restore_all_read_read_clinic_catchup_restore_all_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreAll"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreAllResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/clinic/clients/duplicate-check":{"post":{"tags":["read","clinic"],"summary":"Check Client Duplicates","description":"Which of these candidate clients the caller's clinic already holds.\n\nAuthentication: JWT required via Authorization header\nRLS: Enforced through user_client isolation - the RPC is SECURITY INVOKER, so\n``child_profiles`` policy is what decides which children it can match against.","operationId":"check_client_duplicates_read_clinic_clients_duplicate_check_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DuplicateCheckRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DuplicateCheckResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/clinic/clients-page":{"get":{"tags":["read","clinic"],"summary":"Get Clients Page Data","description":"Paginated BFF endpoint for the clients page.\n\nOne RPC decides which rows and how many; enrichment runs over that page only.\n\nAuthentication: JWT required via Authorization header\nRLS: Enforced through user_client isolation","operationId":"get_clients_page_data_read_clinic_clients_page_get","parameters":[{"name":"include_archived","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Archived"}},{"name":"include_pms_hidden","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Pms Hidden"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":1,"maxLength":200},{"type":"null"}],"title":"Search"}},{"name":"therapist_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Therapist Id"}},{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"deprecated":true,"title":"Sort"},"deprecated":true}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientsPageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/clinic/fca-draft":{"post":{"tags":["read","clinic"],"summary":"Generate Fca Draft","description":"Draft the full FCA document from a child's record.\n\nAuthentication: JWT required. Authorization: clinician_child_access.\nRead-only - generates on demand, persists nothing.","operationId":"generate_fca_draft_read_clinic_fca_draft_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FcaDraftRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FcaDraftResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/clinic/fca-draft/docx":{"post":{"tags":["read","clinic"],"summary":"Fca Draft Docx","description":"Convert an FCA draft's markdown to a downloadable .docx.\n\nThe draft is never persisted (generation is read-only), so the markdown is\nposted in the body rather than read from a row. Gated to any signed-in\ncaller - the markdown originates client-side from a draft this user just\ngenerated; no child scope, since nothing is read back from indi's data.","operationId":"fca_draft_docx_read_clinic_fca_draft_docx_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FcaDraftDocxRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/clinic/new-updates":{"get":{"tags":["read","clinic"],"summary":"Get Clinic New Updates","description":"Observations and check-ins across this clinician's caseload since their last visit per child.\n\nA check-in is in the set so a parent's reply on it (a comment on the\ncheck-in's own entry) resurfaces it; the clinician's own, unanswered, is\nheld out by the function's own-post rule (`20261009021338`). A document\ncomes in only with `documents`, and only through a comment (#14447).\n\nThe join, cutoff comparison, per-child cap and unread count all happen in a\nsingle SECURITY INVOKER SQL pass (`get_clinic_new_updates`) - RLS still gates\n`child_profiles`, `timeline_entries`, and `user_timeline_read_state`.","operationId":"get_clinic_new_updates_read_clinic_new_updates_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Max entries per child","default":5,"title":"Limit"},"description":"Max entries per child"},{"name":"include_digest","in":"query","required":false,"schema":{"type":"boolean","description":"Attach today's Haiku catch-up digest","default":false,"title":"Include Digest"},"description":"Attach today's Haiku catch-up digest"},{"name":"documents","in":"query","required":false,"schema":{"type":"boolean","description":"Include documents brought back by comments (#14447). Sent by the catch-up surfaces only.","default":false,"title":"Documents"},"description":"Include documents brought back by comments (#14447). Sent by the catch-up surfaces only."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewUpdatesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/clinic/past-updates":{"get":{"tags":["read","clinic"],"summary":"Get Clinic Past Updates","description":"What this clinician has already read that was posted in [from, to), with\nthe summary made that day, for Past summaries (#14540).\n\n`get_clinic_read_updates` is the feed's unread rule turned round, in the\nfeed's own columns, so it is shaped and enriched as the feed is. Not\nmentions: they count unread tags. Not fail-soft: an error must read as an\nerror, never as a day with nothing read in it.","operationId":"get_clinic_past_updates_read_clinic_past_updates_get","parameters":[{"name":"from","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"Start of the local day","title":"From"},"description":"Start of the local day"},{"name":"to","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"End of the local day, exclusive","title":"To"},"description":"End of the local day, exclusive"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewUpdatesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/clinic/new-updates/{child_id}":{"get":{"tags":["read","clinic"],"summary":"Get Clinic Child Updates Page","description":"The next page of one child's unread updates, for the catch-up modal.\n\nThe feed's own RPC narrowed to this child (`p_child_id`) at `offset + limit`,\nso the page shares the feed's scope, unread window and total order exactly.\nThat caps paging at the RPC's 50 per child; past it the modal points at the\nchild's timeline.","operationId":"get_clinic_child_updates_page_read_clinic_new_updates__child_id__get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Child Id"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"exclusiveMaximum":50,"default":5,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":5,"title":"Limit"}},{"name":"documents","in":"query","required":false,"schema":{"type":"boolean","description":"Include documents brought back by comments (#14447). Sent by the catch-up surfaces only.","default":false,"title":"Documents"},"description":"Include documents brought back by comments (#14447). Sent by the catch-up surfaces only."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChildUpdatesPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/clinic/catchup-digest":{"get":{"tags":["read","clinic"],"summary":"Get Clinic Catchup Digest","description":"Today's catch-up digest for one client, fetched on its own so the feed's\nlist view renders without waiting on Haiku. Cache hit is instant; a cold\nmiss generates inline (~7s). `child_id` comes from the client, so access is\ngated here (the feed path relies on its own RLS instead).","operationId":"get_clinic_catchup_digest_read_clinic_catchup_digest_get","parameters":[{"name":"child_id","in":"query","required":true,"schema":{"type":"string","description":"Child to summarise","title":"Child Id"},"description":"Child to summarise"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatchupDigestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/clinic/prep":{"post":{"tags":["read","clinic"],"summary":"Generate Prep Summary","description":"Generate a clinical session prep summary for a child.\n\nFetches all timeline data within the specified period and generates\nan LLM summary to help clinicians prepare for their next session.\n\nAuthentication: JWT required via Authorization header\nAuthorization: Verified via clinician_child_access table","operationId":"generate_prep_summary_read_clinic_prep_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrepRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrepResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/clinic/quiet-clients":{"get":{"tags":["read","clinic"],"summary":"Get Quiet Clients","description":"At most ten quiet families with a check-in state she can act on.","operationId":"get_quiet_clients_read_clinic_quiet_clients_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuietClientsResponse"}}}}}}},"/read/clinic/timeline":{"get":{"tags":["read","clinic"],"summary":"Get Clinic Timeline","description":"Fetch paginated timeline events for a client that the clinician has access to.\n\nReturns observations, milestones and appointments grouped chronologically -\nthe clinical spine (``CLINIC_ENTRY_TYPES``) - plus the documents a clinician\nuploaded. The family's own uploads stay the Records tab's job; email and\ntask entries are family-only at the source and are\nadditionally blocked for clinicians in RLS.\nClinician must have an active (non-expired) access grant for this child.\n\nAuthentication: JWT required via Authorization header\nAuthorization: Verified via clinician_child_access table","operationId":"get_clinic_timeline_read_clinic_timeline_get","parameters":[{"name":"child_id","in":"query","required":true,"schema":{"type":"string","description":"Child ID to fetch timeline for","title":"Child Id"},"description":"Child ID to fetch timeline for"},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Filter events by year","title":"Year"},"description":"Filter events by year"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Items per page","default":10,"title":"Page Size"},"description":"Items per page"},{"name":"group_by","in":"query","required":false,"schema":{"type":"string","description":"Aggregation period: day, week, month","default":"day","title":"Group By"},"description":"Aggregation period: day, week, month"},{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter from date (YYYY-MM-DD)","title":"Start Date"},"description":"Filter from date (YYYY-MM-DD)"},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to date (YYYY-MM-DD)","title":"End Date"},"description":"Filter to date (YYYY-MM-DD)"},{"name":"tz_offset","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Client timezone offset in minutes (JS getTimezoneOffset)","title":"Tz Offset"},"description":"Client timezone offset in minutes (JS getTimezoneOffset)"},{"name":"user_timezone","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"IANA timezone (e.g. Australia/Sydney). Overrides tz_offset","title":"User Timezone"},"description":"IANA timezone (e.g. Australia/Sydney). Overrides tz_offset"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimelineResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/care-team/new-updates":{"get":{"tags":["read","care-team"],"summary":"Get Care Team New Updates","description":"Observations across this care-team member's children since their last visit per child.\n\nSame single SECURITY INVOKER pass as the clinic feed - `get_new_updates` has\nno role-specific SQL, so `child_profiles` RLS scopes the caller (village_free\ncare-team member) to exactly their claimed children. No new read-state\nplumbing: mark-read reuses /read/home/timeline-visited[-all].","operationId":"get_care_team_new_updates_read_care_team_new_updates_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Max entries per child","default":5,"title":"Limit"},"description":"Max entries per child"},{"name":"include_digest","in":"query","required":false,"schema":{"type":"boolean","description":"Attach today's Haiku catch-up digest","default":false,"title":"Include Digest"},"description":"Attach today's Haiku catch-up digest"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewUpdatesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/care-team/catchup-digest":{"get":{"tags":["read","care-team"],"summary":"Get Care Team Catchup Digest","description":"Today's catch-up digest for one child, fetched on its own so the feed's\nlist view renders without waiting on Haiku. Cache hit is instant; a cold\nmiss generates inline (~7s). `child_id` comes from the client, so access is\ngated here (the feed path relies on its own RLS instead).","operationId":"get_care_team_catchup_digest_read_care_team_catchup_digest_get","parameters":[{"name":"child_id","in":"query","required":true,"schema":{"type":"string","description":"Child to summarise","title":"Child Id"},"description":"Child to summarise"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatchupDigestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/catch-up-history":{"get":{"tags":["read"],"summary":"Get Catch Up History","operationId":"get_catch_up_history_read_catch_up_history_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatchupHistoryResponse"}}}}}}},"/read/home/setup-progress":{"get":{"tags":["read","home"],"summary":"Get Home Setup Progress","description":"Fetch journey-aware setup card state for the parent home screen.\n\nReturns initial cards (role='active') in slot order followed by the\nreplacement bench (role='bench') for any dismissed non-persistent slot.\nEach card carries everything the client needs to render - title,\ndescription, icon token, colour and action payload - pre-interpolated\nwith the current child + user names.","operationId":"get_home_setup_progress_read_home_setup_progress_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HomeSetupProgressResponse"}}}}}}},"/read/home/timeline-unreads":{"get":{"tags":["read","home"],"summary":"Get Timeline Unreads","description":"Fetch timeline entries created or materially updated since the user's last visit.\n\nReturns entries across all children the user has access to, grouped by child.","operationId":"get_timeline_unreads_read_home_timeline_unreads_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Max entries to return","default":10,"title":"Limit"},"description":"Max entries to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimelineUnreadsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/home/timeline-visited":{"post":{"tags":["read","home"],"summary":"Record Timeline Visit","description":"Record that the user visited a child's timeline.\n\nUpserts the last_visited_at timestamp so future unread queries\nreturn only entries created/updated after this point.","operationId":"record_timeline_visit_read_home_timeline_visited_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVisitRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVisitResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/read/home/timeline-visited-all":{"post":{"tags":["read","home"],"summary":"Record All Timeline Visits","description":"Mark all children's timelines as read for the current user.\n\nFetches every child the user can see (RLS-enforced) and upserts\nlast_visited_at = now for each one in a single batch.","operationId":"record_all_timeline_visits_read_home_timeline_visited_all_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordVisitResponse"}}}}}}},"/clinic/team/invite":{"post":{"tags":["clinic","clinic-team"],"summary":"Invite Team Member","description":"Invite a team member to the organisation.\n\nCreates a clinician profile with DRAFT or INVITED status.\nIf send_now=True, generates invite token and queues email.","operationId":"invite_team_member_clinic_team_invite_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__clinic__team__invite__InviteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__clinic__team__invite__InviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/agreements/current":{"get":{"tags":["clinic","clinic","agreements"],"summary":"Get Current Agreement","description":"Current published agreement + this org's acceptance state and prefill.","operationId":"get_current_agreement_clinic_agreements_current_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentAgreementResponse"}}}}}}},"/clinic/agreements/accept":{"post":{"tags":["clinic","clinic","agreements"],"summary":"Accept Agreement","description":"Execute the agreement for the caller's org. Owner/org-admin only, idempotent.","operationId":"accept_agreement_clinic_agreements_accept_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/agreements/acceptances":{"get":{"tags":["clinic","clinic","agreements"],"summary":"List Acceptances","description":"Acceptance history for the caller's org (RLS: org admins only see rows).","operationId":"list_acceptances_clinic_agreements_acceptances_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptancesResponse"}}}}}}},"/clinic/agreements/acceptances/{acceptance_id}/pdf":{"get":{"tags":["clinic","clinic","agreements"],"summary":"Get Acceptance Pdf","description":"Short-lived signed URL for the executed agreement PDF.","operationId":"get_acceptance_pdf_clinic_agreements_acceptances__acceptance_id__pdf_get","parameters":[{"name":"acceptance_id","in":"path","required":true,"schema":{"type":"string","title":"Acceptance Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptancePdfResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/billing":{"get":{"tags":["clinic","clinic","billing"],"summary":"Get Clinic Billing","description":"The clinic's plan state (§3.2).\n\n200 with `plan: null` is *confirmed unpaid* - the answer the paywall renders\non. 404 is \"you have no clinic\", which is a different thing and which the\nclient reads as couldn't-confirm. Nothing here is wrapped in a try/except: a\nread that fails has to reach the client AS a failure.","operationId":"get_clinic_billing_clinic_billing_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClinicBillingResponse"}}}}}}},"/clinic/billing/prices":{"get":{"tags":["clinic","clinic","billing"],"summary":"Get Clinic Prices","description":"Every figure on the paywall (§2.1).\n\nAuthenticated, not owner-gated. The owner-only rule is about what *renders* -\nSophie is the only person the plan step is shown to - and these three figures\nare already published on `projectindi.com/allied-health/pricing`, so a 403 here\nwould guard nothing while adding an org lookup to a catalogue read.\n\nA row Stripe has no active price for comes back as `null` and the paywall\nmust not render it: a purchasable row without a price is how a light seat\ngets billed at the full rate (§5.2).","operationId":"get_clinic_prices_clinic_billing_prices_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClinicPricesResponse"}}}}}}},"/clinic/billing/checkout":{"post":{"tags":["clinic","clinic","billing"],"summary":"Create Clinic Checkout","description":"Stripe hosted checkout for a clinic plan (§2.3).\n\nRefusals, and what each one means to the owner: 403 she is not the owner; 409\n`talk_to_us` her clinic is not in Australia, where self-serve does not run and\nthe screen offers a conversation instead; 409 `plan_already_set` her clinic\nalready has a plan, which is what stops a second subscription being opened on\na clinic that is already paying - unless Stripe has ended the subscription,\nwhen a new checkout is the one way back (`_repurchase_allowed`); 409\n`plan_downgrade` a Pro clinic coming back as Lite, which\n`activate_clinic_plan` would refuse from inside the webhook, after Stripe\nhad taken the money (#9185).","operationId":"create_clinic_checkout_clinic_billing_checkout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClinicCheckoutRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClinicCheckoutResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/billing/portal":{"post":{"tags":["clinic","clinic","billing"],"summary":"Create Clinic Portal","description":"Stripe's customer portal for the clinic (§2.3).\n\n400 when the clinic has no Stripe customer - ops-set and migrated clinics have\nnone, and the account page hides the button for exactly that case (§3.3), the\nsame contract the parent portal has at `subscription/routes.py:883`.\n\nNo fallback to Stripe's dashboard-default configuration. The default may allow\nthe owner to edit her subscription's quantity, and seat quantity has exactly\none writer (§5.2); a portal that can write it is a second one.","operationId":"create_clinic_portal_clinic_billing_portal_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClinicPortalResponse"}}}}}}},"/clinic/billing/summary":{"get":{"tags":["clinic","clinic","billing"],"summary":"Get Clinic Billing Summary","description":"The owner's commercial picture, for the account page's billing card.\n\nOwner-only, the same 403 as the checkout and portal. Null when the clinic has\nno Stripe subscription (ops-set, or never bought), and a null `next_amount`\nwhen Stripe has no next invoice to preview (a subscription that is ending).","operationId":"get_clinic_billing_summary_clinic_billing_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ClinicBillingSummary"},{"type":"null"}],"title":"Response Get Clinic Billing Summary Clinic Billing Summary Get"}}}}}}},"/clinic/organisation":{"get":{"tags":["clinic","clinic","organisation"],"summary":"Get Organisation","description":"Get current user's organisation settings.","operationId":"get_organisation_clinic_organisation_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganisationResponse"}}}}}},"patch":{"tags":["clinic","clinic","organisation"],"summary":"Update Organisation","description":"Update organisation name and/or service types.","operationId":"update_organisation_clinic_organisation_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOrganisationRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/organisation/logo":{"post":{"tags":["clinic","clinic","organisation"],"summary":"Upload Organisation Logo","description":"Upload/replace organisation logo.","operationId":"upload_organisation_logo_clinic_organisation_logo_post","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_organisation_logo_clinic_organisation_logo_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["clinic","clinic","organisation"],"summary":"Get Organisation Logo","description":"Get a signed, sized URL for the organisation logo.","operationId":"get_organisation_logo_clinic_organisation_logo_get","parameters":[{"name":"width","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":4096,"minimum":1},{"type":"null"}],"title":"Width"}},{"name":"height","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":4096,"minimum":1},{"type":"null"}],"title":"Height"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"webp","title":"Format"}},{"name":"quality","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":85,"title":"Quality"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/integrations/refused":{"get":{"tags":["clinic","clinic","integrations"],"summary":"Get Refused Credentials","description":"For every clinician in the org, not just admins: the team's banner names the\nowner to ask. The integrations read is the caller's own - any org clinician\nmay read them under RLS. Only the owner join needs the service client.","operationId":"get_refused_credentials_clinic_integrations_refused_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefusedCredentialsResponse"}}}}}}},"/clinic/check-ins":{"post":{"tags":["clinic","clinic","check-ins"],"summary":"Send Check In","description":"Send one check-in.\n\nRuns on the USER client: `send_check_in` authorises off `auth.uid()`, and a\nservice client would erase the caller's identity - which is exactly the\nproperty that makes a SECURITY DEFINER RPC safe to expose here.","operationId":"send_check_in_clinic_check_ins_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendCheckInBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendCheckInResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/check-ins/recipients":{"get":{"tags":["clinic","clinic","check-ins"],"summary":"Get Check In Recipients","description":"The family members the modal offers as recipients.\n\nRuns on the USER client so `check_in_recipient_options` can authorise off\n`auth.uid()` - it returns nothing unless the caller is a clinician with\naccess to this child, so no new visibility is created (spec §9.4).\n\nThe roster comes from the same `check_in_family_recipients` set that\n`send_check_in` validates against, so the modal can never offer someone the\nsend will then reject.\n\nSlice 1 returns no per-person channel readout - that is slice 2.","operationId":"get_check_in_recipients_clinic_check_ins_recipients_get","parameters":[{"name":"child_id","in":"query","required":true,"schema":{"type":"string","title":"Child Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckInRecipientsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/voice-notes/access":{"get":{"tags":["clinic","clinic","voice-notes"],"summary":"Get Voice Note Access","description":"Whether this clinician may file a note about this client.\n\nThe client list is built from individual **and** org-level grants, and only\nan individual grant (or being the child's family) permits authoring. Without\nthis the org-only case is discovered at the end: the clinician dictates,\nuploads the whole file, and is told to try again about something that will\nnever succeed. Asked when the screen opens, answered by the gate itself.","operationId":"get_voice_note_access_clinic_voice_notes_access_get","parameters":[{"name":"child_id","in":"query","required":true,"schema":{"type":"string","title":"Child Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceNoteAccessResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/voice-notes":{"post":{"tags":["clinic","clinic","voice-notes"],"summary":"Create Voice Note","description":"Stage a recording and, unless ``transcribe`` is false, return its transcript.\n\nThe access gate is ``resolve_source_type_and_gate`` - the same one\n``/observations/quick-note`` applies on send. Running it *before* Deepgram\nmeans the transcribe call rejects in exactly the cases the send would, so a\nclinician can never dictate for five minutes into a note they are not\nallowed to file (and we never pay Deepgram for one).\n\nIt runs before ``read_bounded`` too, but that ordering saves a copy and not\na transfer: FastAPI resolves ``audio_file`` by awaiting ``request.form()``,\nwhich drains the whole multipart body before this function's first line, so\nan ungranted clinician has already pushed their recording by the time the\n403 is decided. Refusing the upload before the bytes leave the phone would\ntake a separate pre-flight, which nothing here has.","operationId":"create_voice_note_clinic_voice_notes_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_create_voice_note_clinic_voice_notes_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceNoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/resources/{resource_id}":{"get":{"tags":["clinic","clinic","resources"],"summary":"Get Clinic Resource","description":"The row's listing fields, plus signed URLs for its live version's objects.","operationId":"get_clinic_resource_clinic_resources__resource_id__get","parameters":[{"name":"resource_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Resource Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceUrls"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/document-templates":{"get":{"tags":["clinic","clinic","document-templates"],"summary":"List Templates","operationId":"list_templates_clinic_document_templates_get","parameters":[{"name":"kind","in":"query","required":false,"schema":{"anyOf":[{"enum":["session_note","referral"],"type":"string"},{"type":"null"}],"title":"Kind"}},{"name":"include_archived","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Archived"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateList"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["clinic","clinic","document-templates"],"summary":"Create Template","description":"A new template, or a copy of any template the clinic can see, indi's included.","operationId":"create_template_clinic_document_templates_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTemplate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/document-templates/samples":{"get":{"tags":["clinic","clinic","document-templates"],"summary":"List Samples","operationId":"list_samples_clinic_document_templates_samples_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SampleList"}}}}}}},"/clinic/document-templates/{template_id}":{"get":{"tags":["clinic","clinic","document-templates"],"summary":"Get Template","operationId":"get_template_clinic_document_templates__template_id__get","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Template Id"}},{"name":"version","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["clinic","clinic","document-templates"],"summary":"Save Version","description":"Version n+1; versions are immutable, so documents keep the one they were made with.","operationId":"save_version_clinic_document_templates__template_id__put","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Template Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveVersion"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/document-templates/{template_id}/default":{"post":{"tags":["clinic","clinic","document-templates"],"summary":"Set Default","description":"Any template the clinic can see, indi's included, becomes its default for the kind.","operationId":"set_default_clinic_document_templates__template_id__default_post","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Template Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateList"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/document-templates/{template_id}/archive":{"post":{"tags":["clinic","clinic","document-templates"],"summary":"Archive","description":"Archived, and no longer the clinic's default: the kind falls back to indi's.\nDocuments keep the version they were written with.","operationId":"archive_clinic_document_templates__template_id__archive_post","parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Template Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateList"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/document-templates/preview":{"post":{"tags":["clinic","clinic","document-templates"],"summary":"Preview","description":"The real pipeline on a built-in synthetic note, never a client's. Nothing is saved.","operationId":"preview_clinic_document_templates_preview_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Preview"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/document-templates/import":{"post":{"tags":["clinic","clinic","document-templates"],"summary":"Import Proforma","description":"NDJSON: a ``{\"section\"}`` line for each section as the model drafts it, then\nthe ``{\"result\"}`` (``ImportResult``). A refusal is the usual error response;\na failure after the first line can only be a line, ``{\"error\"}``, carrying the\nstatus and body it would have had.","operationId":"import_proforma_clinic_document_templates_import_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_import_proforma_clinic_document_templates_import_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/document-templates/import/{import_id}/images/{image_id}":{"post":{"tags":["clinic","clinic","document-templates"],"summary":"Replace Import Image","description":"*Upload PNG* for a picture the import couldn't read (an EMF logo, say).\nPNG only, checked by its bytes, and re-encoded on the way in like every other\nimport image.","operationId":"replace_import_image_clinic_document_templates_import__import_id__images__image_id__post","parameters":[{"name":"import_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Import Id"}},{"name":"image_id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{0,62}$","title":"Image Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_replace_import_image_clinic_document_templates_import__import_id__images__image_id__post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportImage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/document-templates/import/confirm":{"post":{"tags":["clinic","clinic","document-templates"],"summary":"Confirm Import","operationId":"confirm_import_clinic_document_templates_import_confirm_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmImport"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/documents":{"post":{"tags":["clinic","clinic","clinic-documents"],"summary":"Create Document","description":"*Format as…* on a posted session note, mobile-posted ones included.","operationId":"create_document_clinic_documents_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDocument"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentView"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["clinic","clinic","clinic-documents"],"summary":"List Documents","description":"*Notes to finish*: oldest first. The cursor is the last item's `created_at|id`:\ntwo documents formatted in one batch can share a timestamp, and paging on it alone\nwould skip one.","operationId":"list_documents_clinic_documents_get","parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"enum":["generating","draft","failed","final"],"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"author","in":"query","required":false,"schema":{"anyOf":[{"const":"me","type":"string"},{"type":"null"}],"title":"Author"}},{"name":"child_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Child Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentList"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/documents/{document_id}":{"get":{"tags":["clinic","clinic","clinic-documents"],"summary":"Get Document","operationId":"get_document_clinic_documents__document_id__get","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Document Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/DocumentView"},{"$ref":"#/components/schemas/FamilyDocumentView"}],"discriminator":{"propertyName":"view","mapping":{"clinician":"#/components/schemas/DocumentView","family":"#/components/schemas/FamilyDocumentView"}},"title":"Response Get Document Clinic Documents  Document Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["clinic","clinic","clinic-documents"],"summary":"Patch Document","operationId":"patch_document_clinic_documents__document_id__patch","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Document Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchDocument"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentView"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/documents/{document_id}/finalise":{"post":{"tags":["clinic","clinic","clinic-documents"],"summary":"Finalise","operationId":"finalise_clinic_documents__document_id__finalise_post","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Document Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentView"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/documents/{document_id}/addendum":{"post":{"tags":["clinic","clinic","clinic-documents"],"summary":"Add Addendum","description":"An addendum is final when it's added (D4): one clinician section, signed now.","operationId":"add_addendum_clinic_documents__document_id__addendum_post","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Document Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAddendum"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentView"}}}},"200":{"description":"The addendum already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentView"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/documents/{document_id}/regenerate":{"post":{"tags":["clinic","clinic","clinic-documents"],"summary":"Regenerate","description":"A new `generating` row with a new id; the old draft or failed row goes (D5).","operationId":"regenerate_clinic_documents__document_id__regenerate_post","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Document Id"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentView"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/documents/{document_id}/download":{"get":{"tags":["clinic","clinic","clinic-documents"],"summary":"Download","operationId":"download_clinic_documents__document_id__download_get","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Document Id"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"pdf","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/setup":{"post":{"tags":["clinic"],"summary":"Setup Clinic","description":"Create organisation and clinician profile during onboarding.\n\nIdempotent: If setup was partially completed (e.g. clinician exists but roles\nfailed), calling again will complete the remaining steps.","operationId":"setup_clinic_clinic_setup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/setup/complete":{"post":{"tags":["clinic"],"summary":"Complete Setup","description":"Finalise clinic owner onboarding (the work the deleted appweb\n``/api/clinic/setup/complete`` proxy did server-side).\n\nIdempotently ensures the org + clinician exist (the wizard's step 1 already\ncreated them), persists the PMS selection, flips onboarding + sends the\nclinician welcome email, invites the team and fires the ad-blocker-resistant\ncompletion event. Consent (region-derived privacy settings) stays client-side\n- the browser writes ``user_privacy_settings`` under RLS before calling this,\nthrough the same helper as the clinician invite-accept flow.","operationId":"complete_setup_clinic_setup_complete_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupCompleteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupCompleteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/invite/validate":{"post":{"tags":["clinic"],"summary":"Validate Invite","description":"Validate invite token (public endpoint, no auth required).","operationId":"validate_invite_clinic_invite_validate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__clinic__routes__ValidateInviteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__clinic__routes__ValidateInviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/invite/eligibility":{"get":{"tags":["clinic"],"summary":"Invite Eligibility","description":"Can the signed-in account claim this invite?\n\nRuns the same two gates ``accept_invite`` does, in the same order, off the\nsame helpers - so the pre-flight can't drift from the write it predicts.\nUnlike accept, a \"no\" is a 200 with a reason rather than an error: the\ncaller is asking a question, and the answer is the point.","operationId":"invite_eligibility_clinic_invite_eligibility_get","parameters":[{"name":"token","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteEligibilityResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinic/invite/accept":{"post":{"tags":["clinic"],"summary":"Accept Invite","description":"Accept team invite and link to authenticated user.","operationId":"accept_invite_clinic_invite_accept_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__clinic__routes__AcceptInviteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__clinic__routes__AcceptInviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/client-import/run":{"post":{"tags":["internal"],"summary":"Run Client Import","description":"Start a pass over every due integration; answers before it runs (#11696).","operationId":"run_client_import_internal_client_import_run_post","responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Run Client Import Internal Client Import Run Post"}}}}}}},"/internal/clinic-documents/{document_id}/generate":{"post":{"tags":["internal"],"summary":"Generate","operationId":"generate_internal_clinic_documents__document_id__generate_post","parameters":[{"name":"document_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Document Id"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Generate Internal Clinic Documents  Document Id  Generate Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/client-auto-archive/run":{"post":{"tags":["internal"],"summary":"Run Client Auto Archive","description":"Start a pass over every flagged clinic, or with ``dry_run`` answer for one clinic (#11794).","operationId":"run_client_auto_archive_internal_client_auto_archive_run_post","parameters":[{"name":"dry_run","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Dry Run"}},{"name":"org_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Run Client Auto Archive Internal Client Auto Archive Run Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/clinic-resources/{resource_id}/versions/{version}/pdf":{"post":{"tags":["internal"],"summary":"Render Clinic Resource Pdf","description":"Render a written version's PDF into its prefix. Idempotent; never rewrites a key.\n\n`key` is null for a kind that doesn't print, which is still a success: publish goes on.","operationId":"render_clinic_resource_pdf_internal_clinic_resources__resource_id__versions__version__pdf_post","parameters":[{"name":"resource_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Resource Id"}},{"name":"version","in":"path","required":true,"schema":{"type":"integer","minimum":1,"title":"Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":"Response Render Clinic Resource Pdf Internal Clinic Resources  Resource Id  Versions  Version  Pdf Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinics/search":{"get":{"tags":["clinics"],"summary":"Search Clinics","description":"Clinics whose name contains ``q``. Name only - no address in V1.","operationId":"search_clinics_clinics_search_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","description":"Clinic name fragment","default":"","title":"Q"},"description":"Clinic name fragment"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClinicSearchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/parent-invite/child":{"post":{"tags":["parent-invite"],"summary":"Create Child","description":"Create a child profile (clinician-initiated).\n\nCreates child_profile linked to clinician's org. Does NOT generate invite.\nUse POST /parent-invite/generate to create invite code separately.\n\nAuthentication: JWT required via Authorization header","operationId":"create_child_parent_invite_child_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__parent_invite__routes__CreateChildRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateChildResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/parent-invite/status":{"post":{"tags":["parent-invite"],"summary":"Get Invite Status","description":"Get current invite status for a child.\n\nReturns the most recent active invite code if one exists and is not expired.\nUsed by the modal to show existing invites instead of auto-generating.\n\nAuthentication: JWT required via Authorization header","operationId":"get_invite_status_parent_invite_status_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteStatusRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/parent-invite/generate":{"post":{"tags":["parent-invite"],"summary":"Generate Invite","description":"Generate a new invite code for an existing child.\n\nCreates a new invite code without revoking existing ones. Multiple active\ncodes can coexist - they expire naturally after 30 days.\n\nAuthentication: JWT required via Authorization header","operationId":"generate_invite_parent_invite_generate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateInviteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateInviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/parent-invite/save-email":{"post":{"tags":["parent-invite"],"summary":"Save Parent Email","description":"Save parent email to child profile without generating invite code.\n\nThis is the first step in the email-first parent connection flow.\nSets parent_email for auto-matching when parent signs up or logs in.\n\nAuthentication: JWT required via Authorization header","operationId":"save_parent_email_parent_invite_save_email_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveEmailRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveEmailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/parent-invite/send":{"post":{"tags":["parent-invite"],"summary":"Send Invite","description":"Send invite email to parent.\n\nStores parent email/name against the invite code and sends email via Mailgun.\nThe invite code must already exist and be active.\n\nAuthentication: JWT required via Authorization header","operationId":"send_invite_parent_invite_send_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendInviteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendInviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/parent-invite/validate":{"post":{"tags":["parent-invite"],"summary":"Validate Invite","description":"Validate an invite code and return child info for messaging.\n\nCalled BEFORE auth to check if code is valid and get child name.\nDoes NOT require authentication - allows checking before signup.\nReturns generic error for both invalid and already-claimed codes (security).\n\nSide-effect: sets first_opened_at on first validation call per code and\nfires a parent_invite_opened PostHog event.","operationId":"validate_invite_parent_invite_validate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__parent_invite__routes__ValidateInviteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__parent_invite__routes__ValidateInviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/parent-invite/claim":{"post":{"tags":["parent-invite"],"summary":"Claim Invite","description":"Claim an invite code after authentication.\n\nCalled AFTER auth - links child to parent's user_id.\nAtomically claims the invite and updates child profile.","operationId":"claim_invite_parent_invite_claim_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimInviteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimInviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/care-team-invite/lookup":{"post":{"tags":["care-team-invite"],"summary":"Lookup Care Team Invite","description":"Pre-claim sanitised preview for the worker landing page.\n\nUNAUTHENTICATED - runs with service-role so the RLS SELECT-only-for-\ninviter-or-claimer policy doesn't block the pre-claim path. Returns\nONLY the five allowed keys; raw fields (code, claimed_by,\nchild_care_team_id, raw IDs / emails) never reach the client.\n\nNo authentication required.","operationId":"lookup_care_team_invite_care_team_invite_lookup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LookupInviteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CareTeamInviteLookupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/profile-match/check":{"get":{"tags":["profile-match"],"summary":"Check Profile Matches","description":"Return unclaimed children whose parent_email matches the authenticated user's email.\n\nUses JWT email - no request body needed.","operationId":"check_profile_matches_profile_match_check_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckResponse"}}}}}}},"/profile-match/claim":{"post":{"tags":["profile-match"],"summary":"Claim Profile Match","description":"Claim a matched child profile, linking the authenticated user as the parent.\n\nVerifies email match, locks row, verifies unclaimed, updates child_profiles.user_id,\nsets journey_type = 'clinic_invite', adds clinicians to care team.","operationId":"claim_profile_match_profile_match_claim_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__profile_match__routes__ClaimRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__profile_match__routes__ClaimResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/profile-match/dismiss":{"post":{"tags":["profile-match"],"summary":"Dismiss Profile Matches","description":"Dismiss pending profile matches so the user is not prompted again.\n\nClears parent_email on unclaimed children matching this user's email,\nremoving them from the pending match count.","operationId":"dismiss_profile_matches_profile_match_dismiss_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/clinician-share/generate":{"post":{"tags":["clinician-share"],"summary":"Generate","description":"Generate a share code for a child profile.\n\nOnly the billing contact (family owner) can generate share codes. Returns the\nnewest active code made for nobody in particular, or mints one (Q35).","operationId":"generate_clinician_share_generate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinician-share/validate":{"post":{"tags":["clinician-share"],"summary":"Validate","description":"Validate a share code without exposing child PII.\n\nPublic endpoint - does not require authentication.\nReturns only valid/invalid status. Child details are shown\nafter clinic login via the claim flow.","operationId":"validate_clinician_share_validate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__clinician_share__routes__ValidateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinician-share/check-profile":{"get":{"tags":["clinician-share"],"summary":"Check Profile","description":"Check if the authenticated user has a clinician profile.\n\nUsed by join flow to pre-verify before showing \"Ready to Claim\".","operationId":"check_profile_clinician_share_check_profile_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckProfileResponse"}}}}}}},"/clinician-share/claim":{"post":{"tags":["clinician-share"],"summary":"Claim","description":"Claim a share code as a clinician.\n\nCreates clinician_child_access, care_team_members and child_care_team entries.\nRequires authenticated clinician with clinician_profile.","operationId":"claim_clinician_share_claim_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__clinician_share__routes__ClaimRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__clinician_share__routes__ClaimResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinician-share/revoke":{"post":{"tags":["clinician-share"],"summary":"Revoke","description":"Revoke an active share code.\n\nOnly the billing contact (family owner) can revoke codes.","operationId":"revoke_clinician_share_revoke_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinician-share/connected":{"get":{"tags":["clinician-share"],"summary":"List Connected Clinicians","description":"List all clinicians connected to the user's family.\n\nReturns clinicians who have claimed share codes and now have access.\nAny family member can view connected clinicians.","operationId":"list_connected_clinicians_clinician_share_connected_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectedCliniciansResponse"}}}}}}},"/clinician-share/list-all":{"get":{"tags":["clinician-share"],"summary":"List All Shares","description":"List all share codes for the user's family.\n\nAny family member can view share codes.\nReturns active and recently claimed codes for all children in the family.","operationId":"list_all_shares_clinician_share_list_all_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListResponse"}}}}}}},"/clinician-share/list/{child_id}":{"get":{"tags":["clinician-share"],"summary":"List Shares","description":"List pending share codes for a child.\n\nOnly the billing contact (family owner) can view share codes.\nReturns active and recently claimed codes.","operationId":"list_shares_clinician_share_list__child_id__get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","title":"Child Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinician-share/disconnect":{"post":{"tags":["clinician-share"],"summary":"Disconnect Clinician","description":"Disconnect a connected clinician from a child.\n\nSets archived_at on clinician_child_access. The clinician remains on the\ncare team as a regular member but loses live profile access.","operationId":"disconnect_clinician_clinician_share_disconnect_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisconnectRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DisconnectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/family-unit":{"get":{"tags":["family-unit"],"summary":"Family","description":"Get current user's family unit with members and invites.\n\nReturns members for all users, invites only for billing contact (owner).\n\nAuthentication: JWT required via Authorization header","operationId":"family_family_unit_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FamilyUnitResponse"}}}}}},"patch":{"tags":["family-unit"],"summary":"Update","description":"Update family unit details.\n\nOnly the billing contact can update the family unit.\n\nAuthentication: JWT required via Authorization header","operationId":"update_family_unit_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFamilyUnitRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFamilyUnitResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/family-unit/invite":{"post":{"tags":["family-unit"],"summary":"Invite","description":"Send an invite to join the family unit.\n\nOnly the billing contact (family owner) can send invites.\n\nAuthentication: JWT required via Authorization header","operationId":"invite_family_unit_invite_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__family_unit__routes__InviteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__family_unit__routes__InviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/family-unit/invite/validate/{token}":{"get":{"tags":["family-unit"],"summary":"Validate","description":"Validate an invite token (public endpoint, no auth required).\n\nReturns invite details if valid, or error information if invalid/expired.","operationId":"validate_family_unit_invite_validate__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__family_unit__routes__ValidateInviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/family-unit/invite/accept":{"post":{"tags":["family-unit"],"summary":"Accept","description":"Accept a family unit invite.\n\nLinks the authenticated user to the family unit.\n\nAuthentication: JWT required via Authorization header","operationId":"accept_family_unit_invite_accept_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__family_unit__routes__AcceptInviteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__family_unit__routes__AcceptInviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/family-unit/invite/{invite_id}":{"delete":{"tags":["family-unit"],"summary":"Revoke","description":"Revoke a pending invite.\n\nOnly the billing contact can revoke invites.\n\nAuthentication: JWT required via Authorization header","operationId":"revoke_family_unit_invite__invite_id__delete","parameters":[{"name":"invite_id","in":"path","required":true,"schema":{"type":"string","title":"Invite Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/family-unit/member/{member_id}":{"delete":{"tags":["family-unit"],"summary":"Remove","description":"Remove a member from the family unit, and settle their access to its children.\n\n``mode=keep_on_care_team`` keeps them on the children's care teams as\n``role_kind`` (support_worker by default); ``remove_all``, the default,\ntakes every link they hold on those children. Billing contact only, never\nthemselves. See ``graph/parent/family_unit/removal.py``.\n\nAuthentication: JWT required via Authorization header","operationId":"remove_family_unit_member__member_id__delete","parameters":[{"name":"member_id","in":"path","required":true,"schema":{"type":"string","title":"Member Id"}},{"name":"mode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mode"}},{"name":"role_kind","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Kind"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/forms/validate":{"post":{"tags":["forms"],"summary":"Validate Form","description":"Validate a form share code and return the form schema.\n\nPublic endpoint - does not require authentication.\nReturns the form schema for rendering, plus the child's first name only.","operationId":"validate_form_forms_validate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__forms__routes__ValidateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/forms/submit":{"post":{"tags":["forms"],"summary":"Submit Form","description":"Submit a form response.\n\nPublic endpoint - does not require authentication.\nCreates a form_submissions L1 record and extracts into child_notes L2.","operationId":"submit_form_forms_submit_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/forms/child/{child_id}":{"get":{"tags":["forms"],"summary":"List Forms","description":"List forms for a child. Requires clinician access.","operationId":"list_forms_forms_child__child_id__get","parameters":[{"name":"child_id","in":"path","required":true,"schema":{"type":"string","title":"Child Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListFormsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/forms/create":{"post":{"tags":["forms"],"summary":"Create Form","description":"Create a new capture form. Requires clinician access.","operationId":"create_form_forms_create_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFormRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFormResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/forms/{form_id}":{"put":{"tags":["forms"],"summary":"Update Form","description":"Update a form's title, description or schema. Requires ownership.","operationId":"update_form_forms__form_id__put","parameters":[{"name":"form_id","in":"path","required":true,"schema":{"type":"string","title":"Form Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFormRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/forms/{form_id}/archive":{"post":{"tags":["forms"],"summary":"Archive Form","description":"Archive a form. Requires clinician access and form ownership.","operationId":"archive_form_forms__form_id__archive_post","parameters":[{"name":"form_id","in":"path","required":true,"schema":{"type":"string","title":"Form Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/forms/{form_id}/unarchive":{"post":{"tags":["forms"],"summary":"Unarchive Form","description":"Restore an archived form to active. Requires clinician ownership.","operationId":"unarchive_form_forms__form_id__unarchive_post","parameters":[{"name":"form_id","in":"path","required":true,"schema":{"type":"string","title":"Form Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/clinicians/profile-picture":{"post":{"tags":["clinicians"],"summary":"Upload Profile Picture","description":"Upload/replace clinician profile picture.\n\nAuthentication: JWT required via Authorization header\n\nArgs:\n    file: Image file (JPEG, PNG, WebP, HEIC)\n\nReturns:\n    Profile picture URL and signed imgproxy URL\n\nRaises:\n    400: Invalid file type or size\n    404: Clinician profile not found\n    500: Upload failed","operationId":"upload_profile_picture_clinicians_profile_picture_post","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_profile_picture_clinicians_profile_picture_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["clinicians"],"summary":"Get Profile Picture","description":"Get signed imgproxy URL for clinician profile picture.\n\nAuthentication: JWT required via Authorization header\n\nArgs:\n    width: Target width (optional)\n    height: Target height (optional)\n    format: Output format (jpeg/webp/avif/png, default: webp)\n    quality: Image quality 1-100 (default: 85)\n\nReturns:\n    Signed imgproxy URL with expiry\n\nRaises:\n    404: Clinician profile not found or no profile picture\n    400: Invalid transformation parameters\n    500: URL generation failed","operationId":"get_profile_picture_clinicians_profile_picture_get","parameters":[{"name":"width","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":4096,"minimum":1},{"type":"null"}],"title":"Width"}},{"name":"height","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":4096,"minimum":1},{"type":"null"}],"title":"Height"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"webp","title":"Format"}},{"name":"quality","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":85,"title":"Quality"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/privacy-settings":{"patch":{"tags":["users"],"summary":"Patch Privacy Settings","description":"Patch consent fields with append-only audit trail.\n\nAccepts any combination of allow_ai_improvement, marketing_consent and\nanalytics_consent.\nFor each changed field, appends { field, from, to, timestamp } to\nconsent_withdrawal_history. No-ops fields whose value is unchanged.\n\nIf no privacy settings row exists (e.g. clinician who skipped the parent\nlocation step), creates one with jurisdiction_code=PENDING.","operationId":"patch_privacy_settings_users_privacy_settings_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrivacySettingsPatch"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/setup-preferences":{"patch":{"tags":["users"],"summary":"Update Setup Preferences","description":"Update setup card dismissal state.\n\nMerges {card_id}_dismissed into the onboarding_setup_prefs JSONB column\nusing PostgreSQL's || operator for atomic, race-safe updates.","operationId":"update_setup_preferences_users_setup_preferences_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSetupPreferencesRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSetupPreferencesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/village-onboarding":{"patch":{"tags":["users"],"summary":"Update Village Onboarding","description":"Persist how far a village_free worker got through the guided walkthrough.\n\nServer-side rather than local storage because the villager is expected to\nstart on the website and finish in the app; a walkthrough that re-runs on\nthe second device is exactly the friction this audience won't forgive.\n\nStored as one namespaced key on the ``onboarding_setup_prefs`` JSONB column.\n**Monotonicity lives in SQL, not here**: ``merge_village_onboarding_step``\ntakes ``GREATEST(stored, p_step)`` in the same statement as the write, so\nthe row lock serialises it. A Python read-then-compare would be a TOCTOU -\ntwo devices (the expected web→app path) both read the old value, and the\nlower write lands last, dropping the villager back into a walkthrough they\nalready skipped. The RPC refuses any ``p_user_id`` other than\n``auth.uid()``, so a caller can only ever move their own progress.\n\nReturns the whole merged column, so a client hydrating its prefs snapshot\nfrom the response can't silently lose the other keys.","operationId":"update_village_onboarding_users_village_onboarding_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVillageOnboardingRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVillageOnboardingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/profile":{"get":{"tags":["users"],"summary":"Get Profile","description":"Get current user's profile.\n\nReturns name, email and onboarded status from user_profiles table.\n\nAuthentication: JWT required via Authorization header","operationId":"get_profile_users_profile_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResponse"}}}}}},"put":{"tags":["users"],"summary":"Update Profile","description":"Update current user's profile.\n\nUpdates the client-writable columns of user_profiles - see\nProfileUpdateRequest for which, and why `email` is not one.\n\nAuthentication: JWT required via Authorization header","operationId":"update_profile_users_profile_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/profile-picture":{"post":{"tags":["users"],"summary":"Upload Profile Picture","description":"Upload/replace user profile picture.\n\nAuthentication: JWT required via Authorization header\n\nArgs:\n    file: Image file (JPEG, PNG, WebP, HEIC)\n\nReturns:\n    Profile picture URL and signed imgproxy URL","operationId":"upload_profile_picture_users_profile_picture_post","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_profile_picture_users_profile_picture_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["users"],"summary":"Get Profile Picture","description":"Get signed imgproxy URL for user profile picture.\n\nAuthentication: JWT required via Authorization header","operationId":"get_profile_picture_users_profile_picture_get","parameters":[{"name":"width","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":4096,"minimum":1},{"type":"null"}],"title":"Width"}},{"name":"height","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":4096,"minimum":1},{"type":"null"}],"title":"Height"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"webp","title":"Format"}},{"name":"quality","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":85,"title":"Quality"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["users"],"summary":"Delete Profile Picture","description":"Delete user profile picture.\n\nAuthentication: JWT required via Authorization header","operationId":"delete_profile_picture_users_profile_picture_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/users/signup-notification":{"post":{"tags":["users"],"summary":"Signup Notification","description":"Send the signup Slack card for the authenticated user.\n\nTakes the user's identity from the JWT and everything else from the database:\nthe caller supplies a `signup_type` hint, which `classify_signup` drops\nwherever the row says otherwise. A row that says nothing cannot outrank anything,\nand every account's row is blank for the window between signup and onboarding -\nwhich is the window this endpoint is called in, and the whole reason the hint\nexists. So the hint is bounded rather than powerless: `SignupType` is the only\nvocabulary it can speak, and any account with a role or a journey recorded gets\nthe card its row describes.","operationId":"signup_notification_users_signup_notification_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupNotificationRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupNotificationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/classify-journey":{"post":{"tags":["users"],"summary":"Classify Journey","description":"Classify the authenticated account's acquisition journey, write-once.\n\nCalled by every signup conversion point right after attribution is persisted.","operationId":"classify_journey_users_classify_journey_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClassifyJourneyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClassifyJourneyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/journey-signal":{"post":{"tags":["users"],"summary":"Journey Signal","description":"Read-only journey resolution - the same `_resolve` as classify, never recorded.\n\nThe mobile `af_complete_registration` gate needs the non-direct verdict\nsynchronously at SIGNED_IN, before the write-once `/classify-journey` has\nnecessarily run. It reads the authoritative answer here (all three signals -\nclinic code, family invite by email, profile match by email) instead of\nre-deriving a partial one client-side. The caller fails open, so a 500 just\nlets the event fire.","operationId":"journey_signal_users_journey_signal_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JourneySignalRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JourneySignalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/onboarding/complete":{"post":{"tags":["users"],"summary":"Onboarding Complete","description":"Complete parent onboarding at the end of the tour. appMobile\n``onboardingService.markComplete`` calls this - its direct write sent no\nwelcome email (#10039). appweb ``onboardingClient.completeOnboarding``\nstill makes the twin direct Supabase write and requests the email itself;\npointing it here is a separate change.\n\nParent-only, like the web twin: a ``clinician_profiles`` holder 409s -\nclinicians complete through the clinic setup / claim flows, and the role is\ndeliberately not a parameter (their own JWT could never write it anyway;\nsee the module invariants). Flips ``onboarded``, derives the role\n(``_derived_role`` - never over a set one), clears the flow marker, then\nsends the idempotent welcome email best-effort. A send missed here (or by a\nstale bundle that never calls this) is picked up by the worker's welcome\nsweep; see ``src/mailer/welcome.py``.\n\nTwo things stay client-side by contract: the JWT claim refresh (appweb\n``commitRoutingWrite`` / mobile ``refreshAuthClaims`` - the middleware\ntrusts the stale claims until then) and the ``onboarding_completed``\ncapture (consent-gated with the rest of the paywall funnel).","operationId":"onboarding_complete_users_onboarding_complete_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingCompleteResponse"}}}}}}},"/users/onboarding/invited":{"post":{"tags":["users"],"summary":"Onboarding Invited","description":"Mark a clinician-invited parent at claim time - server twin of appweb\n``markInvitedParent``'s direct Supabase write. Endpoint only for now: no\nclient calls it yet.\n\nFamily invites never need this: their accept route runs the same\ntransition inline with ``FAMILY_PARENT``. Best-effort like every\npost-claim transition - by the time the client calls this the claim is\ncommitted, so a refused flip is reported (``profile_updated=false``),\nnever raised. Claim refresh stays client-side, as above.","operationId":"onboarding_invited_users_onboarding_invited_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingInvitedResponse"}}}}}}},"/users/welcome-email":{"post":{"tags":["users"],"summary":"Post Welcome Email","description":"Send the parent welcome email to the authenticated user.\n\nIdempotent - safe to call multiple times. There is one template:\naccount_type/onboarding_flow decide whether anything is sent at all, and a\nclinician gets nothing (their drips carry day zero).","operationId":"post_welcome_email_users_welcome_email_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WelcomeEmailResponse"}}}}}}},"/care-team/{member_id}/profile-picture":{"get":{"tags":["care-team"],"summary":"Get Profile Picture","description":"Get signed imgproxy URL for care team member profile picture.\n\nAuthentication: JWT required via Authorization header\nAuthorization: RLS enforces access via family membership","operationId":"get_profile_picture_care_team__member_id__profile_picture_get","parameters":[{"name":"member_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Member Id"}},{"name":"width","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":4096,"minimum":1},{"type":"null"}],"title":"Width"}},{"name":"height","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":4096,"minimum":1},{"type":"null"}],"title":"Height"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"webp","title":"Format"}},{"name":"quality","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":85,"title":"Quality"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/book/{token}":{"get":{"tags":["booking"],"summary":"Get Booking Config","description":"Lookup user info from tracking token for Cal embed pre-fill.\n\nThis is a public endpoint (no auth required) - accessed via email link.","operationId":"get_booking_config_book__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingConfig"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/webhooks/cal":{"post":{"tags":["booking"],"summary":"Cal Webhook","description":"Handle Cal.com booking events.\n\nEvents: BOOKING_CREATED, BOOKING_RESCHEDULED, BOOKING_CANCELLED","operationId":"cal_webhook_webhooks_cal_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/jobs/email":{"post":{"tags":["jobs"],"summary":"Queue Email","description":"Queue email(s) for async delivery via worker.","operationId":"queue_email_api_jobs_email_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailJobRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailJobResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/subscription/prices":{"get":{"tags":["subscription"],"summary":"Get Prices","description":"Get localized subscription prices from Stripe.\n\nReturns pricing in the user's currency based on their jurisdiction setting.\nUsed by web paywall to display accurate, localized pricing.","operationId":"get_prices_subscription_prices_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricesResponse"}}}}}}},"/subscription/status":{"get":{"tags":["subscription"],"summary":"Get Subscription Status","description":"Get current user's subscription status. Pure read - no side effects.\n\nUses check_user_subscription RPC which looks up user's family unit.\nSubscriptions are at the family unit level, not per-child.\n\nThe post-checkout grace snooze that used to ride on a ``?checkout_success``\nquery param here was moved to ``POST /checkout-complete`` so this read is\nidempotent - two reads in one navigation can no longer disagree (#4619 Step 3).","operationId":"get_subscription_status_subscription_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResponse"}}}}}}},"/subscription/checkout-complete":{"post":{"tags":["subscription"],"summary":"Checkout Complete","description":"Settle state after a successful Stripe checkout, then return the status.\n\nStamps a short grace snooze (so a status read in the redirect→webhook\nwindow doesn't bounce a fresh payer to /paywall) and optimistically sets\nthe store to STRIPE, then returns the freshly-settled status from the same\nprojection ``GET /status`` uses - so the post-checkout caller keeps its\nsingle round-trip.\n\nThe grace is gated on RevenueCat - the entitlement broker that ingests\nStripe and feeds our ``/webhooks/revenuecat`` handler - confirming the\ncaller's *own* entitlement (keyed on the JWT user id, so nothing here is\nforgeable). Without that gate any authenticated free account could POST\nhere on a loop to self-grant a permanent paywall snooze, bypassing even the\nhard lockout (#4623):\n\n- RevenueCat confirms an active entitlement → stamp the grace (verified).\n- RevenueCat unreachable → stamp it anyway, logged loudly, so an RC outage\n  never re-paywalls a real payer. Bounded to ``CHECKOUT_GRACE_MINUTES``;\n  the webhook reconciles authoritatively.\n- RevenueCat reachable but no active entitlement → the self-grant case.\n  Behaviour here depends on ``CHECKOUT_GRACE_ENFORCE_REVENUECAT``:\n\n**Two-phase rollout.** The gate ships in *observe* mode by default: the\nRevenueCat lookup runs and every would-be denial is logged, but the grace\nis still stamped - so the deploy changes nothing a returning payer sees and\ncannot regress the redirect→webhook bridge. The logs measure the real\nfalse-negative rate (genuine payers still inside RC's Stripe-ingestion lag)\nin prod. Flip ``CHECKOUT_GRACE_ENFORCE_REVENUECAT=true`` to *enforce* -\nthen a no-entitlement caller gets no grace, closing the self-grant. The\nflip is a config change, not a deploy, and instantly reversible. Even under\nenforcement the blast radius is one ``CHECKOUT_GRACE_MINUTES`` window for a\nfresh payer, cleared by the webhook within minutes.\n\nRe-POSTing just re-stamps the same window (idempotent).","operationId":"checkout_complete_subscription_checkout_complete_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResponse"}}}}}}},"/subscription/checkout":{"post":{"tags":["subscription"],"summary":"Create Checkout","description":"Create Stripe Checkout Session for family unit subscription.\n\nGets or creates family unit, associates Stripe customer with it, returns checkout URL.\nAccepts optional billing_period ('monthly' or 'annual') to select price.","operationId":"create_checkout_subscription_checkout_post","requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/CheckoutRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/subscription/portal":{"post":{"tags":["subscription"],"summary":"Create Portal","description":"Create Stripe Customer Portal session for family unit subscription management.\n\nOnly the billing contact can manage the family subscription. The mobile\nsurface gets a portal that can cancel but not change plans.","operationId":"create_portal_subscription_portal_post","requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/PortalRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/subscription/dev-grant":{"post":{"tags":["subscription"],"summary":"Dev Grant Subscription","description":"Grant 1-day active subscription for local development only.\n\nThis endpoint only works when ENVIRONMENT is 'local' or 'development'.\nUpdates the family_units table directly to simulate an active subscription.","operationId":"dev_grant_subscription_subscription_dev_grant_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DevGrantResponse"}}}}}}},"/subscription/ndis-invoice":{"post":{"tags":["subscription"],"summary":"Create Ndis Invoice","description":"Create NDIS invoice and grant trial access while invoice is processed.\n\nProcess:\n1. Validate NDIS number format (9 digits)\n2. Create Stripe Invoice for annual subscription + GST as a *draft* only -\n   not finalized, not sent. An admin reviews it, then marks it sent from\n   the admin portal, and we email the plan manager from our own address\n   (so we can personalise and attach files, which Stripe can't).\n3. Insert into ndis_invoice_requests table as ``pending`` (snapshot existing\n   expiry into ``activate_from`` for active subscribers - see #4364)\n4. For non-subscribers: grant 21-day promotional entitlement via RevenueCat\n   and flip family_units to ``trialing``. Existing active subscribers keep\n   their paid runway untouched; the webhook adds the 365-day NDIS year on\n   top of ``activate_from`` when the plan manager pays.","operationId":"create_ndis_invoice_subscription_ndis_invoice_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NdisInvoiceRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NdisInvoiceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/subscription/dev-revoke":{"post":{"tags":["subscription"],"summary":"Dev Revoke Subscription","description":"Revoke subscription for local development only.\n\nThis endpoint only works when ENVIRONMENT is 'local' or 'development'.\nResets subscription_status to 'free' and clears expiration.","operationId":"dev_revoke_subscription_subscription_dev_revoke_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DevRevokeResponse"}}}}}}},"/subscription/snooze-paywall":{"post":{"tags":["subscription"],"summary":"Snooze Paywall","description":"Snooze the paywall for the user.\n\nSets paywall_snoozed_until timestamp based on PAYWALL_SNOOZE_HOURS env var.\nRejects with 423 if account is locked out (must subscribe, no snooze allowed).","operationId":"snooze_paywall_subscription_snooze_paywall_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SnoozeResponse"}}}}}}},"/webhooks/revenuecat":{"post":{"tags":["webhooks"],"summary":"Revenuecat Webhook","description":"Handle RevenueCat webhook events.\n\nUpdates family_units table for subscription status changes.\n\nEvents handled:\n- INITIAL_PURCHASE: Set status to active\n- RENEWAL: Set status to active\n- CANCELLATION: Set status to canceled\n- EXPIRATION: Set status to expired\n- BILLING_ISSUE: Set status to grace_period\n- TRANSFER: Clear the entitlement from the families the subscription left","operationId":"revenuecat_webhook_webhooks_revenuecat_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/webhooks/mailgun":{"post":{"tags":["webhooks"],"summary":"Mailgun Webhook","description":"Handle Mailgun inbound email webhook.\n\nReceives emails sent to *@mail.projectindi.com, validates signature,\nstores in emails table, and enqueues worker job for processing.","operationId":"mailgun_webhook_webhooks_mailgun_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/webhooks/mailgun/events":{"post":{"tags":["webhooks"],"summary":"Mailgun Events Webhook","description":"Handle Mailgun delivery-event webhook (delivered/failed/complained).\n\nStamps campaign_recipients in the marketing DB and auto-suppresses\ncomplaints and permanent bounces (spec WS5).","operationId":"mailgun_events_webhook_webhooks_mailgun_events_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/webhooks/mailgun/transactional":{"post":{"tags":["webhooks"],"summary":"Mailgun Transactional Webhook","description":"Handle Mailgun transactional (mail. domain) delivery-event webhook.\n\nStamps email_audit_logs_comprehensive.delivery_status by\nprovider_message_id. Rehomed from appweb's /api/email/webhook/mailgun.","operationId":"mailgun_transactional_webhook_webhooks_mailgun_transactional_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/webhooks/stripe":{"post":{"tags":["webhooks"],"summary":"Stripe Webhook","description":"Handle Stripe webhook events.\n\nAccepts all events from Stripe but only processes:\n- invoice.paid → NDIS invoice grants (RevenueCat 12-month) + recurring Pay It\n  Forward contributions (pool credit per renewal).\n- invoice.finalized → flips a pending NDIS row to 'invoiced' (our \"Sent\"), so\n  finalizing in the Stripe dashboard updates our status the same as the admin\n  Send button. Mirrors adminPortal's mark_invoice_sent; no grants. Also the\n  entry point for a Stripe revision: on a row-miss we re-point the original's\n  row onto the replacement (see _repoint_revised_ndis_invoice).\n- invoice.sent → parallel internal notification to the receivables watcher\n  (Stripe does not support CC/BCC on invoice emails).\n- invoice.voided → marks the ndis_invoice_requests row as 'cancelled', unless\n  the invoice was voided into a revision (latest_revision set).\n- invoice.marked_uncollectible → marks the row as 'uncollectible'.\n- checkout.session.completed → one-off Pay It Forward gifts (sponsor-a-family)\n  when mode='payment'; when mode='subscription', claims family_units.billing_contact_id\n  for the parent who paid (#8920).\n- customer.subscription.created / .updated → mirrors the live subscription onto\n  family_units: stripe_product_id so the account UI can render the plan,\n  subscription_cancel_at when a cancellation is booked for the end of the term,\n  and stripe_subscription_id so a later .deleted can tell this subscription from\n  one that replaced it. Skipped for a subscription that is not the live one.\n  Writes no entitlement - a scheduled cancellation is not a status change.\n- customer.subscription.deleted → the term has ended, so this writes the\n  entitlement: subscription_status='canceled' and subscription_expires_at, plus\n  nulling entitled_from_app_user_id, and clears all three mirror columns.\n  Nothing else writes a status for a Stripe-direct family; RevenueCat never\n  sees one. Skipped entirely when the event names a subscription the family\n  has already replaced.\n\nAnything carrying `metadata.organisation_id` is a CLINIC's event and is routed\nto `clinic/billing.py` before any of the above runs (tech plan §2.4): the\nclinic path writes `organisation_billing` and `clinic_invoices` and nothing a\nfamily reads, and the two must not braid. Handled there: checkout.session.completed,\nthe subscription created / updated / deleted mirror, and the four invoice events,\nwhich record billed periods on the `clinic_invoices` ledger.\n\ninvoice.payment_failed is intentionally a no-op: Stripe leaves the invoice\nin 'open' status on a failed attempt and only attempt_count increments, so\nthe canonical state hasn't changed. Keeping the row at 'invoiced' preserves\nthe duplicate-submission gate in api/src/api/subscription/routes.py\n(status IN ('pending','invoiced')) so a parent cannot create a second\nStripe invoice while the first is still open. Admins see attempt_count in\nthe reconcile dialog. Future agents: do not \"fix\" this absence.\n\nAll other event types are acknowledged (200) but not processed.","operationId":"stripe_webhook_webhooks_stripe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/marketing/unsubscribe":{"get":{"tags":["marketing"],"summary":"Unsubscribe Confirm","description":"Render a confirm button - never act on GET (link scanners follow them).","operationId":"unsubscribe_confirm_marketing_unsubscribe_get","parameters":[{"name":"token","in":"query","required":false,"schema":{"type":"string","default":"","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["marketing"],"summary":"Unsubscribe","description":"Apply the unsubscribe (RFC 8058 one-click POST and the confirm button).","operationId":"unsubscribe_marketing_unsubscribe_post","parameters":[{"name":"token","in":"query","required":false,"schema":{"type":"string","default":"","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/preferences":{"get":{"tags":["marketing"],"summary":"Preferences","description":"Show what marketing mail this address is getting, and act on it.\n\nGET renders; the buttons POST back here. Subscribed or paused, the controls\nonly narrow - pause or unsubscribe. Unsubscribed, an app user gets a\nResubscribe button: the one widening this page allows, deliberately, on a\nPOST they clicked (not a scanner's GET) and only for a contact we can tie to\nan account. A lead's widening still lives in 07-03 step 4's double opt-in, so\na lead stays narrowing-only; a complaint/bounce block offers nothing.","operationId":"preferences_marketing_preferences_get","parameters":[{"name":"token","in":"query","required":false,"schema":{"type":"string","default":"","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["marketing"],"summary":"Preferences Apply","description":"Apply the chosen action, then redirect back to GET (post/redirect/get, so\na refresh can't resubmit and the page re-renders the new state). Link scanners\nfollow GETs, never POSTs, so mutation lives here. Pause and unsubscribe narrow;\nresubscribe widens, so it's gated on the contact being an app user - matching\nwhat the GET offers, and keeping a lead's re-subscribe on 07-03's double opt-in\neven against a hand-crafted POST.","operationId":"preferences_apply_marketing_preferences_post","parameters":[{"name":"token","in":"query","required":false,"schema":{"type":"string","default":"","title":"Token"}}],"requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_preferences_apply_marketing_preferences_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/click":{"get":{"tags":["marketing"],"summary":"Click","description":"First-party click tracking: stamp the send's row, then redirect.\n\nThe row is a campaign's recipient (web DB) or a drip's step (app DB), and the\nfirst click wins on both. The token signs the (row, destination) pair, so this\nis not an open redirect. Tracking is best-effort - the reader always gets\ntheir link.","operationId":"click_marketing_click_get","parameters":[{"name":"token","in":"query","required":false,"schema":{"type":"string","default":"","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/marketing/contact":{"post":{"tags":["marketing"],"summary":"Submit Contact Form","description":"The marketing site's contact form: file it, then tell support.\n\nThe person who wrote it never sees this reply. A failed insert still reaches support\nby Slack and email before the 500, because the message exists nowhere else.\n\nThe sender gets nothing from us: mailing an address typed into a public form\nwould let anyone have us deliver their text to anyone. Support's reply reaches\nthem through Reply-To.\n\nNo analytics event: web sent one only for a visitor who had granted analytics\nconsent, which a cross-origin post can't show us. The marketing site's own\nconsent-aware analytics is the place for it.","operationId":"submit_contact_form_marketing_contact_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/marketing/pif-application":{"post":{"tags":["marketing"],"summary":"Submit Pif Application","description":"/pay-it-forward's form: queue it for review on adminPortal's /pif.\n\nThe service client, because `pif_applications` has no public insert policy, and the\nproduction database, where /pif reads. Slack gets who applied and not why: a reason is\na family's circumstances, and /pif is where those are read. Only a failed insert puts\nthe reason in Slack and the support email, because it then exists nowhere else, and\nthe form treats a 5xx as sent, as every form on the site does.","operationId":"submit_pif_application_marketing_pif_application_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/support":{"post":{"tags":["support"],"summary":"Submit Support","description":"Submit a support request.\n\nStores in contact_us table, sends Slack notification and emails support team.\n\nAuthentication: JWT required via Authorization header","operationId":"submit_support_support_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/qr-tracking/scan":{"post":{"tags":["qr-tracking"],"summary":"Track Scan","description":"Record a QR code scan - upserts qr_code_analytics.\n\nNo authentication required. Called from /start and /joinclinic landing pages.\nAuto-creates the analytics row on first scan.\n\nTwo-step: ensure row exists (idempotent upsert), then increment scans_count.\nThe read-then-write increment can lose a count under heavy concurrency on the\nsame QR code, but that's acceptable for analytics - no business logic depends\non exact counts.","operationId":"track_scan_qr_tracking_scan_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrackScanRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrackScanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/qr-tracking/pending-signup":{"post":{"tags":["qr-tracking"],"summary":"Track Pending Signup","description":"Record a pending signup from a QR code scan.\n\nNo authentication required. Called when a user submits their email\non a QR landing page before OTP verification.","operationId":"track_pending_signup_qr_tracking_pending_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrackPendingSignupRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrackPendingSignupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/paywall-events":{"post":{"tags":["paywall-events"],"summary":"Ingest Paywall Events","description":"Fold a batch of paywall funnel events onto the caller's journey row.\n\nA non-consented caller gets the same 200 and the same body as a consented\none: the client did nothing wrong, must not retry, and must not be able to\nread its consent verdict off the response.\n\nAuth is enforced by the global JWT middleware before we get here (this\nprefix is absent from ``AuthMiddleware.public_paths``), so\n``request.state.user_id`` is already populated - identity never comes from\nthe request body.","operationId":"ingest_paywall_events_paywall_events_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaywallEventBatch"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__paywall_events__routes__IngestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/csp-violations":{"post":{"tags":["csp-violations"],"summary":"Report Csp Violation","description":"Accept a CSP violation report and persist it. Always cheap to reject bots.","operationId":"report_csp_violation_csp_violations_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/account-deletions/eligibility":{"get":{"tags":["account-deletions"],"summary":"Account Deletion Eligibility","description":"The renewing subscription the parent has to be told about, if any.","operationId":"account_deletion_eligibility_account_deletions_eligibility_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Account Deletion Eligibility Account Deletions Eligibility Get"}}}}}}},"/account-deletions/initiate":{"post":{"tags":["account-deletions"],"summary":"Initiate Account Deletion","operationId":"initiate_account_deletion_account_deletions_initiate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitiateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Initiate Account Deletion Account Deletions Initiate Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/account-deletions/verify":{"post":{"tags":["account-deletions"],"summary":"Verify Account Deletion","operationId":"verify_account_deletion_account_deletions_verify_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Verify Account Deletion Account Deletions Verify Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/letters/submit":{"post":{"tags":["letters"],"summary":"Submit Letter","description":"Create a submitted letter, derive its frozen attribution, store it with its moderation job.\n\nThe letter is always created and moderated. A synchronous crisis pre-check\nonly decides whether to surface the Find Help signpost in the response.","operationId":"submit_letter_letters_submit_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitLetterRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitLetterResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/letters":{"get":{"tags":["letters"],"summary":"List Letters","description":"Compatibility only: the current letter and every saved one in one list,\nfor builds from before Home and Keepsakes read apart (#13404). Delete once\nthe API logs show no more calls.","operationId":"list_letters_letters_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LettersResponse"}}}}}}},"/letters/home":{"get":{"tags":["letters"],"summary":"Get Home Letter","description":"Home's letter, without the saved ones' bodies; none when the pool had\nnothing for the caller.","operationId":"get_home_letter_letters_home_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HomeLetterResponse"}}}}}}},"/letters/saved":{"get":{"tags":["letters"],"summary":"List Saved Letters","description":"The letters the caller saved, newest first.","operationId":"list_saved_letters_letters_saved_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LettersResponse"}}}}}}},"/letters/current":{"get":{"tags":["letters"],"summary":"Get Current Letter","description":"Compatibility only: mobile builds from before weekly delivery warm this at\nevery launch, whether or not Letters is on for them. Same draw as ``GET\n/letters``, in the old ``{state, letter}`` shape. Delete once the version\nfloor is past those builds and the API logs show no more calls.","operationId":"get_current_letter_letters_current_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentLetterResponse"}}}}}}},"/letters/written":{"get":{"tags":["letters"],"summary":"List Written Letters","description":"The caller's own letters, newest first: where each is in review, and how\nmany parents it reached and how many thanked it. Counts, never who.","operationId":"list_written_letters_letters_written_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LettersResponse"}}}}}}},"/letters/attribution-preview":{"get":{"tags":["letters"],"summary":"Attribution Preview","description":"Both sign-offs, derived exactly as submit will freeze them.","operationId":"attribution_preview_letters_attribution_preview_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttributionPreviewResponse"}}}}}}},"/letters/{letter_id}/read":{"post":{"tags":["letters"],"summary":"Mark Letter Read","description":"Mark the caller's delivery of this letter as read; a re-open keeps the\nfirst read (see ``reading.mark_read``).","operationId":"mark_letter_read_letters__letter_id__read_post","parameters":[{"name":"letter_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Letter Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/letters/{letter_id}/thanks":{"post":{"tags":["letters"],"summary":"Thank Letter","description":"Record the reader's thanks. Idempotent on (reader, letter): a second call\nreturns the first reaction. The author hears in the worker's daily push, as a\ncount - never who said it.","operationId":"thank_letter_letters__letter_id__thanks_post","parameters":[{"name":"letter_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Letter Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThanksRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThanksResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/letters/{letter_id}/keepsake":{"post":{"tags":["letters"],"summary":"Save Keepsake","description":"Save the letter as a keepsake. Idempotent on (user, letter).","operationId":"save_keepsake_letters__letter_id__keepsake_post","parameters":[{"name":"letter_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Letter Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeepsakeSavedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["letters"],"summary":"Remove Keepsake","description":"Unsave the keepsake. RLS scopes the delete to the caller.","operationId":"remove_keepsake_letters__letter_id__keepsake_delete","parameters":[{"name":"letter_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Letter Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeepsakeSavedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/letters/{letter_id}/flag":{"post":{"tags":["letters"],"summary":"Flag Letter","description":"Flag a delivered letter for review.\n\nThe flagger stops seeing the letter immediately; it is withheld from everyone\nonly once it reaches the flag threshold (see flag_support_letter). The RPC\nraises 'letter_not_delivered' when the caller was never delivered this letter\n(→ 404) and 'flag_rate_limited' when they've flagged too many recently (→ 429).","operationId":"flag_letter_letters__letter_id__flag_post","parameters":[{"name":"letter_id","in":"path","required":true,"schema":{"type":"string","minLength":36,"maxLength":36,"title":"Letter Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlagLetterRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/method-lookup":{"post":{"tags":["auth"],"summary":"Method Lookup","description":"Discriminate the step-2 affordance for the email entered on /login.\n\nUnauthenticated. Registered in ``AuthMiddleware.public_paths`` so the\nJWT middleware skips it.","operationId":"method_lookup_auth_method_lookup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MethodLookupRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MethodLookupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/graph":{"get":{"summary":"Handle Http Get","operationId":"handle_http_get_graph_get","responses":{"200":{"description":"The GraphiQL integrated development environment.","content":{"application/json":{"schema":{}}}},"404":{"description":"Not found if GraphiQL or query via GET are not enabled."}}},"post":{"summary":"Handle Http Post","operationId":"handle_http_post_graph_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health":{"get":{"summary":"Health Check","description":"Basic health check for Fly.io service routing - must be fast","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health/status":{"get":{"summary":"Health Status","description":"Real-traffic service health - derived from sliding 60-second request window.","operationId":"health_status_health_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health/ready":{"get":{"summary":"Readiness Check","description":"Deeper readiness check for Fly.io deployment validation\n\nValidates configuration accuracy without exposing secrets.\nUsed by machine_checks during deployments to gate rollout.","operationId":"readiness_check_health_ready_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/":{"get":{"summary":"Root","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/documents/upload":{"post":{"summary":"Upload Documents","description":"Unified async upload - delegates to upload_pipeline().\n\nFour usage scenarios:\n1. **Conversation upload**: Provide conversation_id only (child_id inferred)\n2. **Standalone upload**: Provide child_id only (no conversation link)\n3. **Explicit override**: Provide both (rare edge case)\n4. **Infer conversation**: Set infer_conversation=true with child_id (mobile chat)\n\nREQUIREMENT: Must return 202 Accepted within 2 seconds\nDocument processing happens asynchronously via worker queue\n\nAuthentication: JWT required via Authorization header\nRLS: Automatically enforced through user_client isolation\n\nArgs:\n    files: List of files to upload (single or multiple)\n    child_id: Optional UUID of child (inferred from conversation_id if not provided)\n    conversation_id: Optional UUID linking to a conversation\n    infer_conversation: Set to \"true\" to infer conversation_id from user's JWT\n    idempotency_key: Optional key to prevent duplicate uploads on retry\n    owned_by_note: Set to \"true\" when the files are being attached to a note,\n        whose card draws them (see upload_pipeline)\n    request: FastAPI request object for JWT authentication\n\nReturns:\n    202 Accepted response with document_ids array and tracking information","operationId":"upload_documents_documents_upload_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_documents_documents_upload_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/attachments/stage":{"post":{"summary":"Stage Attachment","description":"Stage an attachment for later association with a chat message.\n\nUploads file to temporary staged storage. Returns staged_id for use with\nchat endpoint's staged_attachment_ids parameter. Staged files are promoted\nto documents when the chat message is sent.\n\nREQUIREMENT: Must return 200 within 2 seconds\n\nAuthentication: JWT required via Authorization header\n\nArgs:\n    file: Single file to stage\n    child_id: UUID of child this attachment belongs to\n\nReturns:\n    JSON with staged_id, filename and file_size for tracking","operationId":"stage_attachment_attachments_stage_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_stage_attachment_attachments_stage_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/attachments/staged":{"delete":{"summary":"Delete Staged Attachment","description":"Best-effort cleanup of a staged file. 401 when unauthenticated,\n400 on malformed inputs, 204 otherwise (including when the storage\ndelete itself fails - that's the genuine best-effort case).\n\nStorage RLS gates the actual delete, and for a STAGED key exactly one\nactor gets through: the care-team WORKER who uploaded it. ``Workers can\ndelete own documents`` (``20260523002437``) is the bucket's only DELETE\npolicy with no ``documents``-row predicate - it keys on\n``owner = auth.uid()``, and ``upload_to_staged_storage`` puts through the\ncaller's client (``src/upload.py``), so the stager owns the object.\n\nEveryone else is denied, because a staged object has no ``documents`` row\nby construction - the same premise ``list_orphaned_staged_objects`` relies\non to sweep it. The clinician and family DELETE policies both require\n``EXISTS (SELECT 1 FROM documents d WHERE d.file_url = 'documents/' ||\nname)``. That includes the PARENT: the path-scoped policy that once let\nthem through was dropped in ``20260114100000`` and replaced by the\nrow-scoped ``Family members can delete own documents``.\n\nSo a clinician or parent unstaging their own upload gets a 204 that\ndeleted nothing, on the Supabase backend; R2 has no RLS and does delete.\nClosing it means mirroring the worker policy for the other two stagers -\nthe same shape with its access predicate swapped, not unexplored ground -\nwhich still widens DELETE on a PHI bucket and wants its own review. Filed\nas #7943 with the policy in it; until it lands the 24h worker sweep\n(#5092) is the backstop.\n\nInputs are validated to stop `staged_id=../source`-style traversal at the\nroute layer - RLS would still bound the blast radius, but explicit\nformat checks keep the intent legible.","operationId":"delete_staged_attachment_attachments_staged_delete","parameters":[{"name":"staged_id","in":"query","required":true,"schema":{"type":"string","title":"Staged Id"}},{"name":"filename","in":"query","required":true,"schema":{"type":"string","title":"Filename"}},{"name":"child_id","in":"query","required":true,"schema":{"type":"string","title":"Child Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AcceptMatchRequest":{"properties":{"child_care_team_id":{"type":"string","title":"Child Care Team Id"}},"type":"object","required":["child_care_team_id"],"title":"AcceptMatchRequest"},"AcceptMatchResponse":{"properties":{"child_id":{"type":"string","title":"Child Id"},"child_care_team_id":{"type":"string","title":"Child Care Team Id"},"care_team_member_id":{"type":"string","title":"Care Team Member Id"}},"type":"object","required":["child_id","child_care_team_id","care_team_member_id"],"title":"AcceptMatchResponse"},"AcceptRequest":{"properties":{"agreement_version_id":{"type":"string","title":"Agreement Version Id"},"legal":{"$ref":"#/components/schemas/LegalPayload"},"acceptor":{"$ref":"#/components/schemas/AcceptorPayload"},"primary_contact_email":{"type":"string","format":"email","title":"Primary Contact Email"},"authorised_confirmed":{"type":"boolean","title":"Authorised Confirmed"},"offer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Offer Id"}},"type":"object","required":["agreement_version_id","legal","acceptor","primary_contact_email","authorised_confirmed"],"title":"AcceptRequest"},"AcceptResponse":{"properties":{"acceptance":{"$ref":"#/components/schemas/AcceptanceInfo"},"already_accepted":{"type":"boolean","title":"Already Accepted","default":false}},"type":"object","required":["acceptance"],"title":"AcceptResponse"},"AcceptanceInfo":{"properties":{"id":{"type":"string","title":"Id"},"agreement_version_id":{"type":"string","title":"Agreement Version Id"},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Version"},"acceptor_name":{"type":"string","title":"Acceptor Name"},"acceptor_role":{"type":"string","title":"Acceptor Role"},"acceptor_email":{"type":"string","title":"Acceptor Email"},"accepted_at":{"type":"string","title":"Accepted At"},"acceptance_channel":{"type":"string","title":"Acceptance Channel"},"executed_pdf_available":{"type":"boolean","title":"Executed Pdf Available","default":false}},"type":"object","required":["id","agreement_version_id","acceptor_name","acceptor_role","acceptor_email","accepted_at","acceptance_channel"],"title":"AcceptanceInfo"},"AcceptancePdfResponse":{"properties":{"url":{"type":"string","title":"Url"}},"type":"object","required":["url"],"title":"AcceptancePdfResponse"},"AcceptancesResponse":{"properties":{"acceptances":{"items":{"$ref":"#/components/schemas/AcceptanceInfo"},"type":"array","title":"Acceptances"}},"type":"object","required":["acceptances"],"title":"AcceptancesResponse"},"AcceptorPayload":{"properties":{"name":{"type":"string","title":"Name"},"role":{"type":"string","title":"Role"}},"type":"object","required":["name","role"],"title":"AcceptorPayload"},"ActivationState":{"properties":{"steps":{"items":{"$ref":"#/components/schemas/ActivationStep"},"type":"array","title":"Steps"},"complete_count":{"type":"integer","title":"Complete Count"},"required_count":{"type":"integer","title":"Required Count"},"complete":{"type":"boolean","title":"Complete"},"dismissed":{"type":"boolean","title":"Dismissed","default":false},"next_step_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Step Id"},"inbox_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Inbox Email"}},"type":"object","required":["steps","complete_count","required_count","complete"],"title":"ActivationState","description":"The activation deck as its own field. Mobile-only by construction.\n\nThis is the isolation mechanism, and it is also the kill switch. Web\nreads the same endpoint and forks its greeting on `all_initial_complete`;\na field appweb never destructures is inert there, so the activation\nscreen can ship, cohort and roll back server-side with no client release\nand no feature flag (flag delivery is broken product-wide, #7737 - a\nflag-gated activation home would ship dead).\n\nAbsent means today's screen, exactly."},"ActivationStep":{"properties":{"step_id":{"type":"string","title":"Step Id"},"title":{"type":"string","title":"Title"},"caption":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Caption"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"cta_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cta Label"},"status_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status Note"},"icon_key":{"type":"string","enum":["envelope","map_trifold","user_plus","users_three","chat_circle_text","calendar_check","clipboard","file_text","file_arrow_up","chart_line_up"],"title":"Icon Key"},"icon_tone":{"type":"string","enum":["blue","green","pink","purple","orange","teal"],"title":"Icon Tone","default":"teal"},"action":{"$ref":"#/components/schemas/CardAction"},"complete":{"type":"boolean","title":"Complete"}},"type":"object","required":["step_id","title","icon_key","action","complete"],"title":"ActivationStep","description":"One of the activation steps, complete on evidence.\n\nA near-twin of `CardState` on purpose. It carries `complete` where the\ndeck carries `dismissed`, because they are different claims: `dismissed`\nhas always meant \"the parent tapped this\", and `complete` means a row\nexists. Rendering both off one field is what let the deck show done for\nsomething that never happened."},"ActiveIntegration":{"properties":{"provider":{"type":"string","title":"Provider"},"display_name":{"type":"string","title":"Display Name"},"hides_archived":{"items":{"type":"string"},"type":"array","title":"Hides Archived","default":[]}},"type":"object","required":["provider","display_name"],"title":"ActiveIntegration","description":"Active integration provider info."},"AddBatchRequest":{"properties":{"child_id":{"type":"string","title":"Child Id"},"members":{"items":{"$ref":"#/components/schemas/BatchMemberEntry"},"type":"array","title":"Members"},"send_inbox_emails":{"type":"boolean","title":"Send Inbox Emails","default":false},"inbox_email_recipients":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Inbox Email Recipients"},"source":{"type":"string","enum":["wizard","onboarding","agent"],"title":"Source","default":"wizard"}},"type":"object","required":["child_id","members"],"title":"AddBatchRequest","description":"Request body for POST /care-team/add-batch."},"AddBatchResponse":{"properties":{"results":{"items":{"$ref":"#/components/schemas/BatchMemberResult"},"type":"array","title":"Results"},"parent_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Name"},"inbox_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Inbox Email"}},"type":"object","required":["results"],"title":"AddBatchResponse"},"AddCareTeamMemberRequest":{"properties":{"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"organisation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organisation"},"role_kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Kind"},"role_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Type"},"access_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Access Level"},"role_value":{"type":"string","title":"Role Value"},"is_emergency_contact":{"type":"boolean","title":"Is Emergency Contact","default":false},"is_next_of_kin":{"type":"boolean","title":"Is Next Of Kin","default":false}},"type":"object","required":["first_name","last_name","role_value"],"title":"AddCareTeamMemberRequest"},"AddReactionRequest":{"properties":{"child_id":{"type":"string","title":"Child Id"},"item_type":{"type":"string","title":"Item Type"},"item_id":{"type":"string","title":"Item Id"},"reaction":{"type":"string","title":"Reaction"}},"type":"object","required":["child_id","item_type","item_id","reaction"],"title":"AddReactionRequest"},"AddTracksRequest":{"properties":{"tracks":{"items":{"$ref":"#/components/schemas/ChildTrackSeed"},"type":"array","maxItems":8,"minItems":1,"title":"Tracks"}},"type":"object","required":["tracks"],"title":"AddTracksRequest","description":"The session step's picks, for a child the parent claimed from a clinic."},"Addendum":{"properties":{"id":{"type":"string","title":"Id"},"text":{"type":"string","title":"Text"},"author":{"$ref":"#/components/schemas/Person"},"finalised_at":{"type":"string","title":"Finalised At"}},"type":"object","required":["id","text","author","finalised_at"],"title":"Addendum"},"Address":{"properties":{"line1":{"type":"string","title":"Line1"},"line2":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Line2"},"suburb":{"type":"string","title":"Suburb"},"state":{"type":"string","title":"State"},"postcode":{"type":"string","title":"Postcode"}},"type":"object","required":["line1","suburb","state","postcode"],"title":"Address"},"AgreementVersionInfo":{"properties":{"id":{"type":"string","title":"Id"},"version":{"type":"string","title":"Version"},"title":{"type":"string","title":"Title"},"effective_from":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Effective From"}},"type":"object","required":["id","version","title"],"title":"AgreementVersionInfo"},"Allergy":{"properties":{"name":{"type":"string","title":"Name"},"severity":{"type":"string","title":"Severity"},"reaction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reaction"}},"type":"object","required":["name","severity"],"title":"Allergy"},"ArtefactListResponse":{"properties":{"artefacts":{"items":{"$ref":"#/components/schemas/ArtefactResponse"},"type":"array","title":"Artefacts"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["artefacts","total"],"title":"ArtefactListResponse"},"ArtefactResponse":{"properties":{"id":{"type":"string","title":"Id"},"child_id":{"type":"string","title":"Child Id"},"user_id":{"type":"string","title":"User Id"},"artefact_type":{"type":"string","title":"Artefact Type"},"content":{"type":"string","title":"Content"},"is_hidden":{"type":"boolean","title":"Is Hidden"},"created_at":{"type":"string","title":"Created At"},"file_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Url"},"file_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Name"},"file_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Type"},"file_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"File Size"},"ai_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Title"},"ai_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Summary"}},"type":"object","required":["id","child_id","user_id","artefact_type","content","is_hidden","created_at"],"title":"ArtefactResponse"},"AttEventRequest":{"properties":{"event":{"type":"string","enum":["att_ask_shown","att_ask_answered"],"title":"Event"},"status":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Status"},"ms_to_answer":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ms To Answer"}},"type":"object","required":["event"],"title":"AttEventRequest"},"AttEventResponse":{"properties":{"success":{"type":"boolean","title":"Success"}},"type":"object","required":["success"],"title":"AttEventResponse"},"Attachment":{"properties":{"name":{"type":"string","title":"Name"},"url":{"type":"string","title":"Url"}},"type":"object","required":["name","url"],"title":"Attachment"},"AttributionPreviewResponse":{"properties":{"private":{"type":"string","title":"Private"},"public":{"type":"string","title":"Public"}},"type":"object","required":["private","public"],"title":"AttributionPreviewResponse"},"BackToReview":{"properties":{"op":{"type":"string","const":"back_to_review","title":"Op"}},"additionalProperties":false,"type":"object","required":["op"],"title":"BackToReview"},"BasicInfo":{"properties":{"age":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Age"},"date_of_birth":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date Of Birth"},"gender":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gender"},"pronouns":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pronouns"}},"type":"object","title":"BasicInfo","description":"Identity fields only - deliberately no government identifiers.\n\nThis payload serves the parent bio panel and the village-free worker one,\nand since the Key Information panel stopped painting the flat columns\nnothing on either surface reads an identifier from here: the register\n(``child_profile_sections.content``) is what the panel, the emergency PDF\nand the completion check all read, and the clinic reads the flat columns\nthrough its own endpoint (``read/clinic/clients.py``). Sending four\ngovernment identifiers that no consumer renders is exactly the collection\nthe UK columns' own comments cite Art. 5(1)(c) against, so they are not\nselected and not returned.\n\nAdding one back means adding a reader in the same PR, and saying which in\nthe store register in ``supabase/CLAUDE.md``."},"BatchCareTeamResponse":{"properties":{"children":{"items":{"$ref":"#/components/schemas/ChildCareTeamResponse"},"type":"array","title":"Children"}},"type":"object","required":["children"],"title":"BatchCareTeamResponse"},"BatchMemberEntry":{"properties":{"name":{"type":"string","title":"Name"},"email":{"type":"string","title":"Email"},"organisation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organisation"},"role_value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Value"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"role_kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Kind"},"access_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Access Level"},"auto_match_opt_in":{"type":"boolean","title":"Auto Match Opt In","default":false}},"type":"object","required":["name","email"],"title":"BatchMemberEntry","description":"Single member in a batch add request."},"BatchMemberResult":{"properties":{"name":{"type":"string","title":"Name"},"email":{"type":"string","title":"Email"},"success":{"type":"boolean","title":"Success"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Branch"},"clinician_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clinician Name"},"clinic_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clinic Name"},"child_care_team_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Care Team Id"},"role_kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Kind"},"role_value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Value"},"access_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Access Level"},"clinic_sequence_triggered":{"type":"boolean","title":"Clinic Sequence Triggered","default":false},"email_sent":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Email Sent"},"inbox_shared":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Inbox Shared"}},"type":"object","required":["name","email","success"],"title":"BatchMemberResult","description":"Per-member result returned from add-batch."},"BioLocation":{"properties":{"kind":{"type":"string","const":"bio","title":"Kind","default":"bio"},"child_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Id"},"tab":{"type":"string","enum":["about","journey","timeline","records","care-team","calendar"],"title":"Tab"},"sub_filter":{"anyOf":[{"type":"string","enum":["all","documents","media","emails","artefacts"]},{"type":"null"}],"title":"Sub Filter"},"record_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Record Id"},"entry_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entry Id"}},"type":"object","required":["tab"],"title":"BioLocation","description":"Open the child bio panel on a specific tab (+ optional sub-filter)."},"BioPanelResponse":{"properties":{"selected_child_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Selected Child Id"},"children":{"items":{"$ref":"#/components/schemas/ChildBioData"},"type":"array","title":"Children"}},"type":"object","required":["children"],"title":"BioPanelResponse"},"Body_create_voice_note_clinic_voice_notes_post":{"properties":{"audio_file":{"type":"string","contentMediaType":"application/octet-stream","title":"Audio File"},"child_id":{"type":"string","title":"Child Id"},"transcribe":{"type":"boolean","title":"Transcribe","default":true}},"type":"object","required":["audio_file","child_id"],"title":"Body_create_voice_note_clinic_voice_notes_post"},"Body_import_proforma_clinic_document_templates_import_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_import_proforma_clinic_document_templates_import_post"},"Body_preferences_apply_marketing_preferences_post":{"properties":{"action":{"type":"string","title":"Action","default":""}},"type":"object","title":"Body_preferences_apply_marketing_preferences_post"},"Body_replace_import_image_clinic_document_templates_import__import_id__images__image_id__post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_replace_import_image_clinic_document_templates_import__import_id__images__image_id__post"},"Body_stage_attachment_attachments_stage_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"},"child_id":{"type":"string","title":"Child Id"}},"type":"object","required":["file","child_id"],"title":"Body_stage_attachment_attachments_stage_post"},"Body_transcribe_transcription__post":{"properties":{"audio_file":{"type":"string","contentMediaType":"application/octet-stream","title":"Audio File"}},"type":"object","required":["audio_file"],"title":"Body_transcribe_transcription__post"},"Body_upload_documents_documents_upload_post":{"properties":{"files":{"items":{"type":"string","contentMediaType":"application/octet-stream"},"type":"array","title":"Files"},"child_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Id"},"conversation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conversation Id"},"infer_conversation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Infer Conversation"},"idempotency_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency Key"},"owned_by_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owned By Note"}},"type":"object","required":["files"],"title":"Body_upload_documents_documents_upload_post"},"Body_upload_organisation_logo_clinic_organisation_logo_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_organisation_logo_clinic_organisation_logo_post"},"Body_upload_profile_picture_children__child_id__profile_picture_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_profile_picture_children__child_id__profile_picture_post"},"Body_upload_profile_picture_clinicians_profile_picture_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_profile_picture_clinicians_profile_picture_post"},"Body_upload_profile_picture_users_profile_picture_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_profile_picture_users_profile_picture_post"},"BookingConfig":{"properties":{"name":{"type":"string","title":"Name"},"email":{"type":"string","title":"Email"}},"type":"object","required":["name","email"],"title":"BookingConfig","description":"Pre-fill config for Cal.com embed"},"BulkUploadCreateRequest":{"properties":{"fileMetadata":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Filemetadata"}},"type":"object","required":["fileMetadata"],"title":"BulkUploadCreateRequest","description":"Body for creating a bulk upload job. Files are already in storage; this\nrecords lightweight per-file metadata the worker processes asynchronously.\n``file_metadata`` items are stored as-is (camelCase keys the worker reads)."},"BulkUploadSlot":{"properties":{"source":{"$ref":"#/components/schemas/BulkUploadSlotUrl"},"poster":{"anyOf":[{"$ref":"#/components/schemas/BulkUploadSlotUrl"},{"type":"null"}]}},"type":"object","required":["source"],"title":"BulkUploadSlot"},"BulkUploadSlotRequest":{"properties":{"file_name":{"type":"string","title":"File Name"},"needs_poster":{"type":"boolean","title":"Needs Poster","default":false}},"type":"object","required":["file_name"],"title":"BulkUploadSlotRequest"},"BulkUploadSlotUrl":{"properties":{"signed_url":{"type":"string","title":"Signed Url"},"storage_path":{"type":"string","title":"Storage Path"}},"type":"object","required":["signed_url","storage_path"],"title":"BulkUploadSlotUrl"},"BulkUploadUrlsRequest":{"properties":{"files":{"items":{"$ref":"#/components/schemas/BulkUploadSlotRequest"},"type":"array","title":"Files"}},"type":"object","required":["files"],"title":"BulkUploadUrlsRequest"},"BulkUploadUrlsResponse":{"properties":{"slots":{"items":{"$ref":"#/components/schemas/BulkUploadSlot"},"type":"array","title":"Slots"}},"type":"object","required":["slots"],"title":"BulkUploadUrlsResponse"},"CalendarEventHistoryEventResponse":{"properties":{"id":{"type":"string","title":"Id"},"event_type":{"type":"string","title":"Event Type"},"actor_id":{"type":"string","title":"Actor Id"},"actor_type":{"type":"string","title":"Actor Type"},"actor_name":{"type":"string","title":"Actor Name"},"changes":{"additionalProperties":true,"type":"object","title":"Changes"},"snapshot":{"additionalProperties":true,"type":"object","title":"Snapshot"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","event_type","actor_id","actor_type","actor_name","changes","snapshot","metadata","created_at"],"title":"CalendarEventHistoryEventResponse"},"CalendarEventHistoryResponse":{"properties":{"calendar_event_id":{"type":"string","title":"Calendar Event Id"},"events":{"items":{"$ref":"#/components/schemas/CalendarEventHistoryEventResponse"},"type":"array","title":"Events"}},"type":"object","required":["calendar_event_id","events"],"title":"CalendarEventHistoryResponse"},"CalendarEventResponse":{"properties":{"id":{"type":"string","title":"Id"},"child_id":{"type":"string","title":"Child Id"},"title":{"type":"string","title":"Title"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"},"starts_at":{"type":"string","title":"Starts At"},"ends_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ends At"},"all_day":{"type":"boolean","title":"All Day"},"event_timezone":{"type":"string","title":"Event Timezone"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"care_team_member_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Care Team Member Id"},"provider_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Name"},"provider_role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Role"},"provider_phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Phone"},"provider_organisation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Organisation"},"assignees":{"items":{"type":"string"},"type":"array","title":"Assignees"},"created_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created By"},"created_by_type":{"type":"string","title":"Created By Type"},"created_by_name":{"type":"string","title":"Created By Name","default":""},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"},"last_modified_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Modified By"},"last_modified_by_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Modified By Type"},"last_modified_by_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Modified By Name"},"is_deleted":{"type":"boolean","title":"Is Deleted","default":false},"deleted_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deleted At"},"deleted_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deleted By"},"source_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Type"},"source_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Id"},"external_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Id"},"synced_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Synced At"},"recurrence_rule":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recurrence Rule"},"recurrence_master_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recurrence Master Id"}},"type":"object","required":["id","child_id","title","detail","location","starts_at","ends_at","all_day","event_timezone","tags","care_team_member_id","provider_name","provider_role","assignees","created_by","created_by_type","created_at","updated_at"],"title":"CalendarEventResponse"},"CalendarEventWithChildResponse":{"properties":{"id":{"type":"string","title":"Id"},"child_id":{"type":"string","title":"Child Id"},"title":{"type":"string","title":"Title"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"},"starts_at":{"type":"string","title":"Starts At"},"ends_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ends At"},"all_day":{"type":"boolean","title":"All Day"},"event_timezone":{"type":"string","title":"Event Timezone"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"care_team_member_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Care Team Member Id"},"provider_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Name"},"provider_role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Role"},"provider_phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Phone"},"provider_organisation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Organisation"},"assignees":{"items":{"type":"string"},"type":"array","title":"Assignees"},"created_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created By"},"created_by_type":{"type":"string","title":"Created By Type"},"created_by_name":{"type":"string","title":"Created By Name","default":""},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"},"last_modified_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Modified By"},"last_modified_by_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Modified By Type"},"last_modified_by_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Modified By Name"},"is_deleted":{"type":"boolean","title":"Is Deleted","default":false},"deleted_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deleted At"},"deleted_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deleted By"},"source_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Type"},"source_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Id"},"external_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Id"},"synced_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Synced At"},"recurrence_rule":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recurrence Rule"},"recurrence_master_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recurrence Master Id"},"child_name":{"type":"string","title":"Child Name"},"child_avatar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Avatar"}},"type":"object","required":["id","child_id","title","detail","location","starts_at","ends_at","all_day","event_timezone","tags","care_team_member_id","provider_name","provider_role","assignees","created_by","created_by_type","created_at","updated_at","child_name"],"title":"CalendarEventWithChildResponse","description":"Calendar event response with child name and avatar for aggregated view"},"CardAction":{"properties":{"kind":{"type":"string","enum":["chat_canned","chat_prompt","chat_simple","navigate_bio","navigate_invite_family","navigate_care_team","open_quick_note","open_prepare_doc","open_mail_app"],"title":"Kind"},"user_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Message"},"assistant_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assistant Message"},"target":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/BioLocation"},{"$ref":"#/components/schemas/ChatLocation"},{"$ref":"#/components/schemas/TodosLocation"},{"$ref":"#/components/schemas/TrackLocation"},{"$ref":"#/components/schemas/SettingsLocation"}],"discriminator":{"propertyName":"kind","mapping":{"bio":"#/components/schemas/BioLocation","chat":"#/components/schemas/ChatLocation","settings":"#/components/schemas/SettingsLocation","todos":"#/components/schemas/TodosLocation","track":"#/components/schemas/TrackLocation"}}},{"type":"null"}],"title":"Target"},"event_name":{"type":"string","enum":["dynamic_pill_clicked","setup_card_tapped"],"title":"Event Name"}},"type":"object","required":["kind","event_name"],"title":"CardAction"},"CardState":{"properties":{"card_id":{"type":"string","title":"Card Id"},"role":{"type":"string","enum":["active","bench"],"title":"Role"},"title":{"type":"string","title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"cta_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cta Label"},"icon_key":{"type":"string","enum":["envelope","map_trifold","user_plus","users_three","chat_circle_text","calendar_check","clipboard","file_text","file_arrow_up","chart_line_up"],"title":"Icon Key"},"color":{"type":"string","title":"Color"},"action":{"$ref":"#/components/schemas/CardAction"},"dismissed":{"type":"boolean","title":"Dismissed","default":false},"pending":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Pending"},"pending_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pending Email"},"pending_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pending Name"},"accepted_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accepted Name"}},"type":"object","required":["card_id","role","title","icon_key","color","action"],"title":"CardState"},"CareTeamInviteLookupResponse":{"properties":{"status":{"type":"string","title":"Status"},"child_first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child First Name"},"parent_first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent First Name"},"member_first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Member First Name"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"},"member_email_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Member Email Hint"}},"type":"object","required":["status"],"title":"CareTeamInviteLookupResponse","description":"Sanitised preview for the unauthenticated /accept-invite landing page.\n\nSECURITY: this model IS the security boundary. Raw fields (code,\nclaimed_by, child_care_team_id, raw IDs / emails) MUST NEVER appear here.\n``member_email_hint`` is the one email-shaped field and it is **masked**,\nnever raw - see :func:`mask_email`."},"CareTeamMember":{"properties":{"id":{"type":"string","title":"Id"},"member_id":{"type":"string","title":"Member Id"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"organisation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organisation"},"role_type":{"type":"string","title":"Role Type"},"role_value":{"type":"string","title":"Role Value"},"role_kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Kind"},"access_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Access Level"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"},"clinician_profile_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clinician Profile Id"},"is_emergency_contact":{"type":"boolean","title":"Is Emergency Contact","default":false},"is_next_of_kin":{"type":"boolean","title":"Is Next Of Kin","default":false},"is_connected_clinician":{"type":"boolean","title":"Is Connected Clinician","default":false},"is_connected_family":{"type":"boolean","title":"Is Connected Family","default":false},"is_taggable":{"type":"boolean","title":"Is Taggable","default":false},"suggested_clinician":{"type":"boolean","title":"Suggested Clinician","default":false},"is_retired":{"type":"boolean","title":"Is Retired","default":false},"invite_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Status"},"invited_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invited At"},"invite_expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Expires At"},"invite_delivery_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Delivery Status"},"share_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Share Url"}},"type":"object","required":["id","member_id","first_name","last_name","role_type","role_value"],"title":"CareTeamMember"},"CareTeamMemberResponse":{"properties":{"id":{"type":"string","title":"Id"},"member_id":{"type":"string","title":"Member Id"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"organisation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organisation"},"role_type":{"type":"string","title":"Role Type"},"role_value":{"type":"string","title":"Role Value"},"role_kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Kind"},"access_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Access Level"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"},"clinician_profile_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clinician Profile Id"},"clinician_avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clinician Avatar Url"},"is_emergency_contact":{"type":"boolean","title":"Is Emergency Contact","default":false},"is_next_of_kin":{"type":"boolean","title":"Is Next Of Kin","default":false},"is_connected_clinician":{"type":"boolean","title":"Is Connected Clinician","default":false},"is_connected_family":{"type":"boolean","title":"Is Connected Family","default":false},"has_active_invite":{"type":"boolean","title":"Has Active Invite","default":false},"suggested_clinician":{"type":"boolean","title":"Suggested Clinician","default":false},"is_retired":{"type":"boolean","title":"Is Retired","default":false},"is_taggable":{"type":"boolean","title":"Is Taggable","default":false}},"type":"object","required":["id","member_id","first_name","last_name","role_type","role_value"],"title":"CareTeamMemberResponse"},"CatchupDigestResponse":{"properties":{"digest":{"anyOf":[{"items":{"$ref":"#/components/schemas/DigestSection"},"type":"array"},{"type":"null"}],"title":"Digest"}},"type":"object","title":"CatchupDigestResponse","description":"One child's catch-up digest, fetched on its own (the Summarised view\ndecoupled from the feed so the list renders without waiting on Haiku).\n`digest` is None when there's nothing to summarise or generation failed -\nthe client falls back to the list view."},"CatchupHistoryEntry":{"properties":{"date":{"type":"string","title":"Date"},"child_id":{"type":"string","title":"Child Id"},"child_name":{"type":"string","title":"Child Name"},"sections":{"items":{"$ref":"#/components/schemas/DigestSection"},"type":"array","title":"Sections"}},"type":"object","required":["date","child_id","child_name","sections"],"title":"CatchupHistoryEntry"},"CatchupHistoryResponse":{"properties":{"entries":{"items":{"$ref":"#/components/schemas/CatchupHistoryEntry"},"type":"array","title":"Entries"}},"type":"object","required":["entries"],"title":"CatchupHistoryResponse"},"CategoryBreakdown":{"properties":{"category":{"type":"string","title":"Category"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["category","count"],"title":"CategoryBreakdown"},"ChatLocation":{"properties":{"kind":{"type":"string","const":"chat","title":"Kind","default":"chat"}},"type":"object","title":"ChatLocation","description":"Open the main chat surface (no prefill, no child context)."},"CheckInCard":{"properties":{"check_in_id":{"type":"string","title":"Check In Id"},"child_id":{"type":"string","title":"Child Id"},"occurred_at":{"type":"string","title":"Occurred At"},"clinician_id":{"type":"string","title":"Clinician Id"},"clinician_name":{"type":"string","title":"Clinician Name"},"clinic_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clinic Name"},"headline":{"type":"string","title":"Headline"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"reply_line":{"type":"string","title":"Reply Line"},"one_way_line":{"type":"string","title":"One Way Line"},"primary_label":{"type":"string","title":"Primary Label"},"dismiss_label":{"type":"string","title":"Dismiss Label"}},"type":"object","required":["check_in_id","child_id","occurred_at","clinician_id","clinician_name","headline","reply_line","one_way_line","primary_label","dismiss_label"],"title":"CheckInCard","description":"A clinician checked in. Its own typed field, not a `CardState`.\n\nThe deck is a static catalogue of setup cards - one title, one description,\none tap target, dismissal keyed into `onboarding_setup_prefs`. This card has\na quote block, a reply line, TWO actions and per-check-in dismissal\nthat must land on `check_in_recipients`. Forcing it into `CardState` means\neither three check-in-only fields every other card carries as dead weight,\nor branching the renderer on `card_id` - at which point the shared shape has\nbought nothing.\n\nWhat actually matters is kept: one request, and copy composed server-side."},"CheckInRecipient":{"properties":{"user_id":{"type":"string","title":"User Id"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"relationship":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Relationship"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"}},"type":"object","required":["user_id"],"title":"CheckInRecipient"},"CheckInRecipientsResponse":{"properties":{"recipients":{"items":{"$ref":"#/components/schemas/CheckInRecipient"},"type":"array","title":"Recipients"}},"type":"object","required":["recipients"],"title":"CheckInRecipientsResponse"},"CheckProfileResponse":{"properties":{"has_profile":{"type":"boolean","title":"Has Profile"}},"type":"object","required":["has_profile"],"title":"CheckProfileResponse"},"CheckResponse":{"properties":{"matches":{"items":{"$ref":"#/components/schemas/ProfileMatchItem"},"type":"array","title":"Matches"}},"type":"object","required":["matches"],"title":"CheckResponse"},"CheckoutRequest":{"properties":{"billing_period":{"type":"string","enum":["monthly","monthly_pif","annual"],"title":"Billing Period","default":"monthly"}},"type":"object","title":"CheckoutRequest"},"CheckoutResponse":{"properties":{"url":{"type":"string","title":"Url"}},"type":"object","required":["url"],"title":"CheckoutResponse"},"ChildBioData":{"properties":{"child_id":{"type":"string","title":"Child Id"},"name":{"type":"string","title":"Name"},"avatar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"},"latest_conversation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Latest Conversation Id"},"inbox_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Inbox Email"},"inbox_display":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Inbox Display"},"basic_info":{"$ref":"#/components/schemas/BasicInfo"},"diagnosis_info":{"$ref":"#/components/schemas/DiagnosisInfo"},"medical_info":{"$ref":"#/components/schemas/MedicalInfo"},"milestones":{"items":{"$ref":"#/components/schemas/Milestone"},"type":"array","title":"Milestones","default":[]},"care_team":{"items":{"$ref":"#/components/schemas/CareTeamMember"},"type":"array","title":"Care Team","default":[]},"profile_completeness":{"type":"integer","title":"Profile Completeness","default":0},"last_updated":{"type":"string","title":"Last Updated"}},"type":"object","required":["child_id","name","basic_info","diagnosis_info","medical_info","last_updated"],"title":"ChildBioData"},"ChildCareTeamResponse":{"properties":{"child_id":{"type":"string","title":"Child Id"},"name":{"type":"string","title":"Name"},"care_team":{"items":{"$ref":"#/components/schemas/CareTeamMemberResponse"},"type":"array","title":"Care Team"}},"type":"object","required":["child_id","name","care_team"],"title":"ChildCareTeamResponse"},"ChildConversation":{"properties":{"child_id":{"type":"string","title":"Child Id"},"child_name":{"type":"string","title":"Child Name"},"child_date_of_birth":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Date Of Birth"},"child_avatar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Avatar"},"child_avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Avatar Url"},"conversation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conversation Id"},"inbox_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Inbox Email"}},"type":"object","required":["child_id","child_name","child_date_of_birth","child_avatar","child_avatar_url","conversation_id","inbox_email"],"title":"ChildConversation"},"ChildListItem":{"properties":{"child_id":{"type":"string","title":"Child Id"},"name":{"type":"string","title":"Name"},"avatar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"}},"type":"object","required":["child_id","name"],"title":"ChildListItem"},"ChildResponse":{"properties":{"child_id":{"type":"string","title":"Child Id"},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"},"name":{"type":"string","title":"Name"},"date_of_birth":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date Of Birth"},"age":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Age"},"gender":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gender"},"pronouns":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pronouns"},"diagnosis":{"items":{"type":"string"},"type":"array","title":"Diagnosis","default":[]},"conditions":{"items":{"type":"string"},"type":"array","title":"Conditions","default":[]},"diagnosed":{"type":"boolean","title":"Diagnosed","default":false},"stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage"},"initial_concerns":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Initial Concerns"},"avatar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"},"inbox_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Inbox Email"},"ndis_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ndis Number"},"medicare_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Medicare Number"},"nhs_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nhs Number"},"emergency_profile_completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Emergency Profile Completed At"}},"type":"object","required":["child_id","name"],"title":"ChildResponse","description":"Child profile response"},"ChildTrackSeed":{"properties":{"name":{"type":"string","maxLength":80,"minLength":1,"title":"Name"},"item_name":{"type":"string","maxLength":80,"minLength":1,"title":"Item Name"},"item_name_plural":{"type":"string","maxLength":80,"minLength":1,"title":"Item Name Plural"},"icon":{"anyOf":[{"type":"string","pattern":"^[a-z0-9-]{1,40}$"},{"type":"null"}],"title":"Icon"}},"type":"object","required":["name","item_name","item_name_plural"],"title":"ChildTrackSeed","description":"One track to create alongside the child."},"ChildUnreadSummary":{"properties":{"child_id":{"type":"string","title":"Child Id"},"child_name":{"type":"string","title":"Child Name"},"unread_count":{"type":"integer","title":"Unread Count"}},"type":"object","required":["child_id","child_name","unread_count"],"title":"ChildUnreadSummary"},"ChildUpdateGroup":{"properties":{"child_id":{"type":"string","title":"Child Id"},"child_name":{"type":"string","title":"Child Name"},"dob":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dob"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"},"unread_count":{"type":"integer","title":"Unread Count"},"entries":{"items":{"$ref":"#/components/schemas/UnreadEntry"},"type":"array","title":"Entries"},"digest":{"anyOf":[{"items":{"$ref":"#/components/schemas/DigestSection"},"type":"array"},{"type":"null"}],"title":"Digest"},"check_in_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Check In State"},"check_in_last_sent_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Check In Last Sent At"},"check_in_available_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Check In Available At"},"mention_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Mention Count"}},"type":"object","required":["child_id","child_name","unread_count","entries"],"title":"ChildUpdateGroup"},"ChildUpdatesPage":{"properties":{"entries":{"items":{"$ref":"#/components/schemas/UnreadEntry"},"type":"array","title":"Entries"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["entries","has_more"],"title":"ChildUpdatesPage"},"ChildrenListResponse":{"properties":{"children":{"items":{"$ref":"#/components/schemas/ChildListItem"},"type":"array","title":"Children"},"pending_profile_matches":{"type":"integer","title":"Pending Profile Matches","default":0}},"type":"object","required":["children"],"title":"ChildrenListResponse"},"ClaimInviteRequest":{"properties":{"code":{"type":"string","title":"Code"}},"type":"object","required":["code"],"title":"ClaimInviteRequest"},"ClaimInviteResponse":{"properties":{"child_id":{"type":"string","title":"Child Id"},"child_name":{"type":"string","title":"Child Name"},"clinician_user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clinician User Id"},"organisation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organisation Id"}},"type":"object","required":["child_id","child_name"],"title":"ClaimInviteResponse"},"ClassifyJourneyRequest":{"properties":{"platform":{"type":"string","title":"Platform","default":"unknown"},"invite_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Code"}},"type":"object","title":"ClassifyJourneyRequest"},"ClassifyJourneyResponse":{"properties":{"journey_type":{"type":"string","title":"Journey Type"},"classified":{"type":"boolean","title":"Classified"}},"type":"object","required":["journey_type","classified"],"title":"ClassifyJourneyResponse"},"ClientBasicInfo":{"properties":{"age":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Age"},"date_of_birth":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date Of Birth"},"gender":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gender"}},"type":"object","title":"ClientBasicInfo"},"ClientIdentity":{"properties":{"name":{"type":"string","title":"Name"},"date_of_birth":{"type":"string","title":"Date Of Birth"}},"type":"object","required":["name","date_of_birth"],"title":"ClientIdentity","description":"One candidate client, exactly as the CSV spelled it.\n\nRaw, deliberately. Normalising here would put a second spelling of\n``client_identity_key`` on this side of the wire, which is the thing this\nendpoint exists to remove."},"ClientProfile":{"properties":{"child_id":{"type":"string","title":"Child Id"},"name":{"type":"string","title":"Name"},"avatar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar"},"basic_info":{"$ref":"#/components/schemas/ClientBasicInfo"},"diagnosis":{"items":{"type":"string"},"type":"array","title":"Diagnosis","default":[]},"granted_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Granted At"},"has_parent_linked":{"type":"boolean","title":"Has Parent Linked","default":false},"primary_therapist":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Therapist"},"primary_therapist_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Therapist Id"},"primary_therapist_avatar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Therapist Avatar"},"last_parent_activity_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Parent Activity At"},"funnel_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Funnel Status"},"invite_stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Stage"},"invite_stage_since":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Stage Since"},"access_count":{"type":"integer","title":"Access Count","default":0},"can_delete":{"type":"boolean","title":"Can Delete","default":false},"archived_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Archived At"},"auto_archived_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Auto Archived At"},"integration_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Integration Source"},"provider_archived":{"type":"boolean","title":"Provider Archived","default":false},"provider_roster_synced_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Roster Synced At"},"ndis_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ndis Number"},"medicare_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Medicare Number"},"suggested_parent_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suggested Parent Email"},"suggested_parent_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suggested Parent Name"},"suggested_parent_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Suggested Parent Source"},"inbox_push_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Inbox Push Status"},"inbox_push_contact_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Inbox Push Contact Id"},"splose_patient_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Splose Patient Url"},"parent_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Email"},"check_in_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Check In State"},"check_in_last_sent_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Check In Last Sent At"},"check_in_available_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Check In Available At"}},"type":"object","required":["child_id","name","basic_info"],"title":"ClientProfile"},"ClientsPageResponse":{"properties":{"clients":{"items":{"$ref":"#/components/schemas/ClientProfile"},"type":"array","title":"Clients"},"total_count":{"type":"integer","title":"Total Count","default":0},"has_more":{"type":"boolean","title":"Has More","default":false},"therapists":{"items":{"$ref":"#/components/schemas/Therapist"},"type":"array","title":"Therapists"},"active_integration":{"anyOf":[{"$ref":"#/components/schemas/ActiveIntegration"},{"type":"null"}]},"can_edit_therapist":{"type":"boolean","title":"Can Edit Therapist","default":false}},"type":"object","required":["clients","therapists"],"title":"ClientsPageResponse","description":"Consolidated response for clients page."},"ClinicAccessBlock":{"properties":{"state":{"type":"string","enum":["ok","retrying","grace","expired"],"title":"State","default":"ok"},"expires_on":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires On"},"last_full_day":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Full Day"},"owner":{"anyOf":[{"$ref":"#/components/schemas/ClinicAccessOwner"},{"type":"null"}]},"owner_action":{"anyOf":[{"type":"string","enum":["update_card","choose_plan"]},{"type":"null"}],"title":"Owner Action"}},"type":"object","title":"ClinicAccessBlock","description":"Does this clinic's payment still stand - the lapse plan's §2.1 shape.\n\n`subscription_status` is never on the wire, in any spelling: the raw Stripe\nvocabulary is an unbounded vendor enum, and the moment it is client-side\nsomebody writes `status !== 'active'` - the check that walls every\ngrandfathered clinic. The client receives only the conclusion. No\n`days_left` (goes stale in a cached tab; the client derives it from\n`expires_on` at render time) and no raw instants (a shipped instant invites\na client re-derivation that disagrees by a timezone)."},"ClinicAccessOwner":{"properties":{"name":{"type":"string","title":"Name"},"email":{"type":"string","title":"Email"}},"type":"object","required":["name","email"],"title":"ClinicAccessOwner","description":"Who the lapse copy tells the team to email. Name and email are already\nvisible to colleagues on the team page; the mailto IS the feature."},"ClinicBillingResponse":{"properties":{"plan":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan"},"can_manage":{"type":"boolean","title":"Can Manage","default":false},"unit":{"anyOf":[{"type":"string","enum":["clinic","seat"]},{"type":"null"}],"title":"Unit"},"seats":{"$ref":"#/components/schemas/ClinicSeats"},"has_stripe_customer":{"type":"boolean","title":"Has Stripe Customer","default":false},"current_period_end":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Period End"},"access":{"$ref":"#/components/schemas/ClinicAccessBlock"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"}},"type":"object","title":"ClinicBillingResponse"},"ClinicBillingSummary":{"properties":{"next_amount":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Amount"},"currency":{"type":"string","title":"Currency"},"interval":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Interval"},"next_charge_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Charge At"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At"},"deal_ends_on":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deal Ends On"},"ends_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ends At"},"discounts":{"items":{"type":"string"},"type":"array","title":"Discounts"}},"type":"object","required":["currency"],"title":"ClinicBillingSummary","description":"What the owner pays, read live off her subscription so she needn't open\nStripe to find it. `next_amount` is Stripe's own preview of the next invoice\n(cents, after every coupon and any tax), so no amount is re-derived here.\n`next_charge_at` is the subscription's period boundary, when that invoice is\nraised. `deal_ends_on` is the date-only `deal_ends_on` metadata `clinic-deal.sh`\nstamps on a negotiated subscription."},"ClinicCheckoutRequest":{"properties":{"plan":{"type":"string","title":"Plan"},"full_seats":{"type":"integer","maximum":500.0,"minimum":0.0,"title":"Full Seats","default":0},"light_seats":{"type":"integer","maximum":500.0,"minimum":0.0,"title":"Light Seats","default":0},"accept_terms":{"type":"boolean","title":"Accept Terms","default":false}},"type":"object","required":["plan"],"title":"ClinicCheckoutRequest"},"ClinicCheckoutResponse":{"properties":{"url":{"type":"string","title":"Url"}},"type":"object","required":["url"],"title":"ClinicCheckoutResponse"},"ClinicPortalResponse":{"properties":{"url":{"type":"string","title":"Url"}},"type":"object","required":["url"],"title":"ClinicPortalResponse"},"ClinicPriceInfo":{"properties":{"unit_amount":{"type":"integer","title":"Unit Amount"},"currency":{"type":"string","title":"Currency"},"formatted":{"type":"string","title":"Formatted"},"interval":{"type":"string","title":"Interval"}},"type":"object","required":["unit_amount","currency","formatted","interval"],"title":"ClinicPriceInfo","description":"One figure on the paywall, as Stripe holds it. `unit_amount` is cents -\nthe client formats or uses `formatted`, and nothing recomputes GST: the price\nis `tax_behavior=\"inclusive\"`, so this IS what the clinic pays (§2.1)."},"ClinicPricesResponse":{"properties":{"clinic_lite":{"anyOf":[{"$ref":"#/components/schemas/ClinicPriceInfo"},{"type":"null"}]},"full_seat":{"anyOf":[{"$ref":"#/components/schemas/ClinicPriceInfo"},{"type":"null"}]},"light_seat":{"anyOf":[{"$ref":"#/components/schemas/ClinicPriceInfo"},{"type":"null"}]}},"type":"object","title":"ClinicPricesResponse"},"ClinicSearchResponse":{"properties":{"results":{"items":{"$ref":"#/components/schemas/ClinicSearchResult"},"type":"array","title":"Results"}},"type":"object","required":["results"],"title":"ClinicSearchResponse"},"ClinicSearchResult":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"ClinicSearchResult","description":"A name and nothing else - the row ``ClinicFinderStep`` draws. No logo either: it\nwould be a per-row signing on a type-ahead for an image the finder never renders."},"ClinicSeats":{"properties":{"full":{"type":"integer","title":"Full","default":0},"light":{"type":"integer","title":"Light","default":0}},"type":"object","title":"ClinicSeats","description":"Seats the clinic has *paid for* - the Stripe mirror. The live headcount is\na different number; §5.2 is what reconciles the two."},"ClinicianSection":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"title":{"type":"string","maxLength":120,"minLength":1,"title":"Title"},"kind":{"type":"string","const":"clinician","title":"Kind"},"hint":{"anyOf":[{"type":"string","maxLength":2000,"minLength":1},{"type":"null"}],"title":"Hint"}},"additionalProperties":false,"type":"object","required":["id","title","kind"],"title":"ClinicianSection","description":"Left blank for a person. Finalise is blocked until it is filled."},"ClinicianSectionFlag":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"type":{"type":"string","const":"clinician_section_empty","title":"Type"},"section_id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Section Id"},"status":{"type":"string","enum":["open","dismissed","resolved"],"title":"Status","default":"open"}},"additionalProperties":false,"type":"object","required":["id","type","section_id"],"title":"ClinicianSectionFlag","description":"A `clinician` section still empty. Recomputed on every write."},"CommentCreateBody":{"properties":{"child_id":{"type":"string","title":"Child Id"},"item_type":{"type":"string","title":"Item Type"},"item_id":{"type":"string","title":"Item Id"},"body":{"type":"string","maxLength":4000,"minLength":1,"title":"Body"}},"type":"object","required":["child_id","item_type","item_id","body"],"title":"CommentCreateBody"},"ConfirmImport":{"properties":{"import_id":{"type":"string","maxLength":36,"minLength":36,"title":"Import Id"},"name":{"type":"string","maxLength":120,"minLength":1,"title":"Name"},"definition":{"$ref":"#/components/schemas/TemplateDefinition"},"image_roles":{"additionalProperties":{"type":"string","enum":["letterhead","static","sample"]},"type":"object","title":"Image Roles"},"acknowledged_phi":{"items":{"type":"string"},"type":"array","title":"Acknowledged Phi"},"set_default":{"type":"boolean","title":"Set Default","default":false}},"additionalProperties":false,"type":"object","required":["import_id","name","definition","image_roles"],"title":"ConfirmImport"},"ConnectedClinician":{"properties":{"id":{"type":"string","title":"Id"},"clinician_profile_id":{"type":"string","title":"Clinician Profile Id"},"child_id":{"type":"string","title":"Child Id"},"child_name":{"type":"string","title":"Child Name"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"organisation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organisation"},"granted_at":{"type":"string","title":"Granted At"}},"type":"object","required":["id","clinician_profile_id","child_id","child_name","first_name","last_name","granted_at"],"title":"ConnectedClinician"},"ConnectedCliniciansResponse":{"properties":{"clinicians":{"items":{"$ref":"#/components/schemas/ConnectedClinician"},"type":"array","title":"Clinicians"}},"type":"object","required":["clinicians"],"title":"ConnectedCliniciansResponse"},"CreateAddendum":{"properties":{"text":{"type":"string","maxLength":10000,"minLength":1,"title":"Text"}},"additionalProperties":false,"type":"object","required":["text"],"title":"CreateAddendum"},"CreateCalendarEventRequest":{"properties":{"title":{"type":"string","title":"Title"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"},"starts_at":{"type":"string","title":"Starts At"},"ends_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ends At"},"all_day":{"type":"boolean","title":"All Day","default":false},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","default":[]},"care_team_member_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Care Team Member Id"},"assignees":{"items":{"type":"string"},"type":"array","title":"Assignees","default":[]},"event_timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Timezone"},"recurrence_rule":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recurrence Rule"}},"type":"object","required":["title","starts_at"],"title":"CreateCalendarEventRequest"},"CreateChildResponse":{"properties":{"child_id":{"type":"string","title":"Child Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["child_id","name"],"title":"CreateChildResponse"},"CreateDocument":{"properties":{"child_note_id":{"type":"string","maxLength":36,"minLength":36,"title":"Child Note Id"},"template_id":{"type":"string","maxLength":36,"minLength":36,"title":"Template Id"}},"additionalProperties":false,"type":"object","required":["child_note_id","template_id"],"title":"CreateDocument"},"CreateFormRequest":{"properties":{"child_id":{"type":"string","title":"Child Id"},"title":{"type":"string","title":"Title"},"form_schema":{"additionalProperties":true,"type":"object","title":"Form Schema"},"form_type":{"type":"string","title":"Form Type","default":"incident_report"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["child_id","title","form_schema"],"title":"CreateFormRequest"},"CreateFormResponse":{"properties":{"form_id":{"type":"string","title":"Form Id"},"share_code":{"type":"string","title":"Share Code"},"share_url":{"type":"string","title":"Share Url"},"title":{"type":"string","title":"Title"}},"type":"object","required":["form_id","share_code","share_url","title"],"title":"CreateFormResponse"},"CreateTemplate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":120,"minLength":1},{"type":"null"}],"title":"Name"},"definition":{"anyOf":[{"$ref":"#/components/schemas/TemplateDefinition"},{"type":"null"}]},"source_template_id":{"anyOf":[{"type":"string","maxLength":36,"minLength":36},{"type":"null"}],"title":"Source Template Id"}},"additionalProperties":false,"type":"object","title":"CreateTemplate","description":"A new template from `definition`, or a copy of `source_template_id`'s\ncurrent version. Exactly one of the two."},"CreateTodoRequest":{"properties":{"title":{"type":"string","title":"Title"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"assigned_to":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned To"},"due_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Due Date"},"due_option":{"anyOf":[{"type":"string","enum":["asap","this_month","next_3_months"]},{"type":"null"}],"title":"Due Option"}},"type":"object","required":["title"],"title":"CreateTodoRequest"},"CurrentAgreementResponse":{"properties":{"version":{"anyOf":[{"$ref":"#/components/schemas/AgreementVersionInfo"},{"type":"null"}]},"html":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Html"},"acceptance_required":{"type":"boolean","title":"Acceptance Required","default":false},"is_org_admin":{"type":"boolean","title":"Is Org Admin","default":false},"current_acceptance":{"anyOf":[{"$ref":"#/components/schemas/AcceptanceInfo"},{"type":"null"}]},"legal_details":{"anyOf":[{"$ref":"#/components/schemas/LegalDetailsInfo"},{"type":"null"}]}},"type":"object","title":"CurrentAgreementResponse"},"CurrentLetterResponse":{"properties":{"state":{"type":"string","enum":["has-letter","write-first"],"title":"State"},"letter":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Letter"}},"type":"object","required":["state"],"title":"CurrentLetterResponse"},"DailyReminder":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"local_time":{"type":"string","title":"Local Time"},"timezone":{"type":"string","title":"Timezone"}},"type":"object","required":["enabled","local_time","timezone"],"title":"DailyReminder"},"DeclineMatchRequest":{"properties":{"child_care_team_id":{"type":"string","title":"Child Care Team Id"}},"type":"object","required":["child_care_team_id"],"title":"DeclineMatchRequest"},"DeleteDocumentRequest":{"properties":{"documentId":{"type":"string","title":"Documentid"}},"type":"object","required":["documentId"],"title":"DeleteDocumentRequest","description":"Request body for deleting a document. Accepts both camelCase and snake_case."},"DeregisterTokenRequest":{"properties":{"token":{"type":"string","title":"Token"}},"type":"object","required":["token"],"title":"DeregisterTokenRequest"},"DeregisterTokenResponse":{"properties":{"success":{"type":"boolean","title":"Success"}},"type":"object","required":["success"],"title":"DeregisterTokenResponse"},"DevGrantResponse":{"properties":{"granted_until":{"type":"string","title":"Granted Until"},"message":{"type":"string","title":"Message"}},"type":"object","required":["granted_until","message"],"title":"DevGrantResponse"},"DevRevokeResponse":{"properties":{"message":{"type":"string","title":"Message"}},"type":"object","required":["message"],"title":"DevRevokeResponse"},"DiagnosisInfo":{"properties":{"is_diagnosed":{"type":"boolean","title":"Is Diagnosed","default":false},"diagnosis":{"items":{"type":"string"},"type":"array","title":"Diagnosis","default":[]},"conditions":{"items":{"type":"string"},"type":"array","title":"Conditions","default":[]},"stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage"}},"type":"object","title":"DiagnosisInfo"},"DigestSection":{"properties":{"heading":{"type":"string","title":"Heading"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"},"body":{"type":"string","title":"Body"}},"type":"object","required":["heading","body"],"title":"DigestSection","description":"One section of a child's \"past 7 days\" Indi summary. `icon` is the track's\nicon slug when the section maps to a track, else None (model-structured)."},"DisconnectRequest":{"properties":{"access_id":{"type":"string","title":"Access Id"}},"type":"object","required":["access_id"],"title":"DisconnectRequest"},"DisconnectResponse":{"properties":{"success":{"type":"boolean","title":"Success"}},"type":"object","required":["success"],"title":"DisconnectResponse"},"DismissFlag":{"properties":{"op":{"type":"string","const":"dismiss_flag","title":"Op"},"flag_id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Flag Id"}},"additionalProperties":false,"type":"object","required":["op","flag_id"],"title":"DismissFlag"},"DocBlock":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"title":{"type":"string","maxLength":120,"minLength":1,"title":"Title"},"title_quotes":{"items":{"type":"string","maxLength":1000,"minLength":1},"type":"array","title":"Title Quotes"},"statements":{"items":{"$ref":"#/components/schemas/DocStatement"},"type":"array","title":"Statements"}},"additionalProperties":false,"type":"object","required":["id","title","statements"],"title":"DocBlock"},"DocClinicianSection":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"title":{"type":"string","maxLength":120,"minLength":1,"title":"Title"},"kind":{"type":"string","const":"clinician","title":"Kind"},"hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hint"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text"}},"additionalProperties":false,"type":"object","required":["id","title","kind"],"title":"DocClinicianSection"},"DocHeader":{"properties":{"image":{"anyOf":[{"type":"string","pattern":"^(asset:[a-z0-9][a-z0-9-]{0,62}|org:logo)$"},{"type":"null"}],"title":"Image"},"values":{"items":{"$ref":"#/components/schemas/MergeValue"},"type":"array","title":"Values"}},"additionalProperties":false,"type":"object","title":"DocHeader"},"DocImageSection":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"title":{"type":"string","maxLength":120,"minLength":1,"title":"Title"},"kind":{"type":"string","const":"image","title":"Kind"},"image":{"type":"string","pattern":"^(asset:[a-z0-9][a-z0-9-]{0,62}|org:logo)$","title":"Image"}},"additionalProperties":false,"type":"object","required":["id","title","kind","image"],"title":"DocImageSection"},"DocListSection":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"title":{"type":"string","maxLength":120,"minLength":1,"title":"Title"},"kind":{"type":"string","const":"list","title":"Kind"},"state":{"type":"string","enum":["filled","not_discussed","hidden"],"title":"State"},"statements":{"items":{"$ref":"#/components/schemas/DocStatement"},"type":"array","title":"Statements"}},"additionalProperties":false,"type":"object","required":["id","title","kind","state"],"title":"DocListSection"},"DocMediaSection":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"title":{"type":"string","maxLength":120,"minLength":1,"title":"Title"},"kind":{"type":"string","const":"media","title":"Kind"},"document_ids":{"items":{"type":"string"},"type":"array","maxItems":12,"title":"Document Ids"}},"additionalProperties":false,"type":"object","required":["id","title","kind"],"title":"DocMediaSection","description":"`document_ids` are `documents` rows attached to the source note."},"DocMergeSection":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"title":{"type":"string","maxLength":120,"minLength":1,"title":"Title"},"kind":{"type":"string","const":"merge","title":"Kind"},"values":{"items":{"$ref":"#/components/schemas/MergeValue"},"type":"array","title":"Values"}},"additionalProperties":false,"type":"object","required":["id","title","kind","values"],"title":"DocMergeSection"},"DocNarrativeSection":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"title":{"type":"string","maxLength":120,"minLength":1,"title":"Title"},"kind":{"type":"string","const":"narrative","title":"Kind"},"repeat":{"type":"boolean","title":"Repeat","default":false},"state":{"type":"string","enum":["filled","not_discussed","hidden"],"title":"State"},"statements":{"items":{"$ref":"#/components/schemas/DocStatement"},"type":"array","title":"Statements"},"blocks":{"items":{"$ref":"#/components/schemas/DocBlock"},"type":"array","title":"Blocks"}},"additionalProperties":false,"type":"object","required":["id","title","kind","state"],"title":"DocNarrativeSection","description":"`statements` when `repeat` is false, `blocks` when it is true; the other is empty."},"DocStatement":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"text":{"type":"string","maxLength":2000,"minLength":1,"title":"Text"},"source_quotes":{"items":{"type":"string","maxLength":1000,"minLength":1},"type":"array","title":"Source Quotes"},"review":{"anyOf":[{"$ref":"#/components/schemas/Review"},{"type":"null"}]},"origin":{"type":"string","enum":["writer","rewrite","restored","net","clinician"],"title":"Origin"}},"additionalProperties":false,"type":"object","required":["id","text","origin"],"title":"DocStatement"},"DocumentContent":{"properties":{"header":{"$ref":"#/components/schemas/DocHeader"},"sections":{"items":{"oneOf":[{"$ref":"#/components/schemas/DocMergeSection"},{"$ref":"#/components/schemas/DocNarrativeSection"},{"$ref":"#/components/schemas/DocListSection"},{"$ref":"#/components/schemas/DocClinicianSection"},{"$ref":"#/components/schemas/DocImageSection"},{"$ref":"#/components/schemas/DocMediaSection"}],"discriminator":{"propertyName":"kind","mapping":{"clinician":"#/components/schemas/DocClinicianSection","image":"#/components/schemas/DocImageSection","list":"#/components/schemas/DocListSection","media":"#/components/schemas/DocMediaSection","merge":"#/components/schemas/DocMergeSection","narrative":"#/components/schemas/DocNarrativeSection"}}},"type":"array","title":"Sections"},"body":{"anyOf":[{"type":"string","maxLength":50000},{"type":"null"}],"title":"Body"},"body_seed_sha":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body Seed Sha"}},"additionalProperties":false,"type":"object","required":["sections"],"title":"DocumentContent","description":"Sections in the template's order, every one present (hidden ones too).\n\n`body` is the clinician's markdown once they leave review for the editor; null while\nthe draft is in review. From then on `sections` are the reviewed AI version, kept as\nthe audit snapshot, and `body_seed_sha` is the sha256 of the markdown `start_edit`\nbuilt, so *Back to review* is offered only while nothing has been typed."},"DocumentDetailResponse":{"properties":{"id":{"type":"string","title":"Id"},"file_name":{"type":"string","title":"File Name"},"file_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Url"},"ai_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Title"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"summary_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Summary Metadata"},"summary_actions":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Summary Actions"},"summary_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary Type"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"errors":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Errors"},"failure_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Reason"},"scan_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scan Status"},"duration_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration Seconds"},"content_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Text"},"source_role":{"anyOf":[{"type":"string","enum":["clinician","parent"]},{"type":"null"}],"title":"Source Role"}},"type":"object","required":["id","file_name"],"title":"DocumentDetailResponse"},"DocumentFeedEntry":{"properties":{"kind":{"type":"string","const":"document","title":"Kind","default":"document"},"id":{"type":"string","title":"Id"},"timestamp":{"type":"string","title":"Timestamp"},"document":{"$ref":"#/components/schemas/DocumentResponse"}},"type":"object","required":["id","timestamp","document"],"title":"DocumentFeedEntry"},"DocumentList":{"properties":{"documents":{"items":{"$ref":"#/components/schemas/DocumentListItem"},"type":"array","title":"Documents"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"}},"type":"object","required":["documents"],"title":"DocumentList"},"DocumentListItem":{"properties":{"id":{"type":"string","title":"Id"},"child_id":{"type":"string","title":"Child Id"},"child_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Name"},"template_name":{"type":"string","title":"Template Name"},"kind":{"type":"string","enum":["session_note","referral"],"title":"Kind"},"status":{"type":"string","enum":["generating","draft","failed","final"],"title":"Status"},"to_check_count":{"type":"integer","title":"To Check Count"},"stale":{"type":"boolean","title":"Stale"},"session_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Date"},"author":{"$ref":"#/components/schemas/Person"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","child_id","template_name","kind","status","to_check_count","stale","author","created_at"],"title":"DocumentListItem"},"DocumentResponse":{"properties":{"id":{"type":"string","title":"Id"},"user_id":{"type":"string","title":"User Id"},"child_id":{"type":"string","title":"Child Id"},"conversation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conversation Id"},"file_name":{"type":"string","title":"File Name"},"file_type":{"type":"string","title":"File Type"},"file_url":{"type":"string","title":"File Url"},"file_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"File Size"},"ai_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Title"},"ai_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Description"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"failure_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Reason"},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"email_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email Id"},"match_snippet":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Match Snippet"},"message_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message Id"},"attachment_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Attachment Index"},"duration_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration Seconds"},"is_duplicate":{"type":"boolean","title":"Is Duplicate","default":false}},"type":"object","required":["id","user_id","child_id","file_name","file_type","file_url","created_at","updated_at"],"title":"DocumentResponse"},"DocumentView":{"properties":{"view":{"type":"string","const":"clinician","title":"View","default":"clinician"},"id":{"type":"string","title":"Id"},"child_id":{"type":"string","title":"Child Id"},"organisation_id":{"type":"string","title":"Organisation Id"},"template":{"$ref":"#/components/schemas/TemplateRef"},"status":{"type":"string","enum":["generating","draft","failed","final"],"title":"Status"},"content":{"anyOf":[{"$ref":"#/components/schemas/DocumentContent"},{"type":"null"}]},"flags":{"items":{"oneOf":[{"$ref":"#/components/schemas/RemovedFlag"},{"$ref":"#/components/schemas/UnverifiedFlag"},{"$ref":"#/components/schemas/UnplacedFlag"},{"$ref":"#/components/schemas/ClinicianSectionFlag"},{"$ref":"#/components/schemas/MergeMissingFlag"}],"discriminator":{"propertyName":"type","mapping":{"clinician_section_empty":"#/components/schemas/ClinicianSectionFlag","merge_missing":"#/components/schemas/MergeMissingFlag","removed":"#/components/schemas/RemovedFlag","unplaced":"#/components/schemas/UnplacedFlag","unverified":"#/components/schemas/UnverifiedFlag"}}},"type":"array","title":"Flags"},"to_check_count":{"type":"integer","title":"To Check Count","default":0},"stale":{"type":"boolean","title":"Stale","default":false},"session_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Date"},"author":{"$ref":"#/components/schemas/Person"},"finalised_by":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}]},"finalised_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Finalised At"},"amends_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Amends Id"},"addenda":{"items":{"$ref":"#/components/schemas/Addendum"},"type":"array","title":"Addenda"},"source_notes":{"items":{"$ref":"#/components/schemas/SourceNote"},"type":"array","title":"Source Notes"},"asset_urls":{"additionalProperties":{"type":"string"},"type":"object","title":"Asset Urls"},"can_edit":{"type":"boolean","title":"Can Edit","default":false},"can_amend":{"type":"boolean","title":"Can Amend","default":false},"created_at":{"type":"string","title":"Created At"},"signature":{"anyOf":[{"$ref":"#/components/schemas/Signature"},{"type":"null"}]}},"type":"object","required":["id","child_id","organisation_id","template","status","author","created_at"],"title":"DocumentView","description":"The clinician's view: everything, working material included."},"DraftFeedEntry":{"properties":{"kind":{"type":"string","const":"draft","title":"Kind","default":"draft"},"id":{"type":"string","title":"Id"},"timestamp":{"type":"string","title":"Timestamp"},"draft":{"$ref":"#/components/schemas/ArtefactResponse"}},"type":"object","required":["id","timestamp","draft"],"title":"DraftFeedEntry"},"DuplicateCheckRequest":{"properties":{"identities":{"items":{"$ref":"#/components/schemas/ClientIdentity"},"type":"array","maxItems":1000,"title":"Identities"}},"type":"object","title":"DuplicateCheckRequest"},"DuplicateCheckResponse":{"properties":{"keys":{"items":{"type":"string"},"type":"array","title":"Keys"},"existing":{"items":{"type":"string"},"type":"array","title":"Existing"}},"type":"object","required":["keys","existing"],"title":"DuplicateCheckResponse","description":"The canonical key of each submitted identity, and which of them exist.\n\n``keys`` is positional - one entry per submitted identity, in the order they\nwere sent. The client uses it for both duplicate questions: an entry in\n``existing`` is already in the clinic, and two equal entries in ``keys`` are\nthe same person twice in one file. That is what lets the rule live in exactly\none place: the browser holds no copy of it and derives nothing."},"EmailAttachment-Input":{"properties":{"document_id":{"type":"string","title":"Document Id"},"child_id":{"type":"string","title":"Child Id"}},"type":"object","required":["document_id","child_id"],"title":"EmailAttachment","description":"Document to attach - worker will download from storage."},"EmailAttachment-Output":{"properties":{"attachment_id":{"type":"string","title":"Attachment Id"},"filename":{"type":"string","title":"Filename"},"mime_type":{"type":"string","title":"Mime Type"},"size_bytes":{"type":"integer","title":"Size Bytes"},"status":{"type":"string","title":"Status"},"promoted_to_document_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Promoted To Document Id"},"is_inline":{"type":"boolean","title":"Is Inline","default":false},"can_promote":{"type":"boolean","title":"Can Promote","default":false},"failure_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Reason"}},"type":"object","required":["attachment_id","filename","mime_type","size_bytes","status"],"title":"EmailAttachment"},"EmailDeleteResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"notes_deleted":{"type":"integer","title":"Notes Deleted","default":0},"documents_hidden":{"type":"integer","title":"Documents Hidden","default":0},"medical_notes":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Medical Notes","default":[]}},"type":"object","required":["success"],"title":"EmailDeleteResponse"},"EmailDetailResponse":{"properties":{"email_id":{"type":"string","title":"Email Id"},"from_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Name"},"from_email":{"type":"string","title":"From Email"},"subject":{"type":"string","title":"Subject"},"preview":{"type":"string","title":"Preview"},"body_html":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body Html"},"body_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body Text"},"received_at":{"type":"string","title":"Received At"},"is_read":{"type":"boolean","title":"Is Read"},"attachment_count":{"type":"integer","title":"Attachment Count"},"verification":{"$ref":"#/components/schemas/EmailVerification"},"attachments":{"items":{"$ref":"#/components/schemas/EmailAttachment-Output"},"type":"array","title":"Attachments"},"thread_replies":{"items":{"$ref":"#/components/schemas/ThreadReplyItem"},"type":"array","title":"Thread Replies","default":[]}},"type":"object","required":["email_id","from_email","subject","preview","received_at","is_read","attachment_count","verification","attachments"],"title":"EmailDetailResponse"},"EmailFeedEntry":{"properties":{"kind":{"type":"string","const":"email","title":"Kind","default":"email"},"id":{"type":"string","title":"Id"},"timestamp":{"type":"string","title":"Timestamp"},"email":{"$ref":"#/components/schemas/EmailListItem"}},"type":"object","required":["id","timestamp","email"],"title":"EmailFeedEntry"},"EmailJobRequest":{"properties":{"to":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"title":"To"},"subject":{"type":"string","title":"Subject"},"html":{"type":"string","title":"Html"},"text":{"type":"string","title":"Text","default":""},"reply_to":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reply To"},"attachments":{"anyOf":[{"items":{"$ref":"#/components/schemas/EmailAttachment-Input"},"type":"array"},{"type":"null"}],"title":"Attachments"}},"type":"object","required":["to","subject","html"],"title":"EmailJobRequest"},"EmailJobResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"job_ids":{"items":{"type":"string"},"type":"array","title":"Job Ids"}},"type":"object","required":["success","job_ids"],"title":"EmailJobResponse"},"EmailListItem":{"properties":{"email_id":{"type":"string","title":"Email Id"},"from_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Name"},"from_email":{"type":"string","title":"From Email"},"subject":{"type":"string","title":"Subject"},"preview":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preview"},"received_at":{"type":"string","title":"Received At"},"is_read":{"type":"boolean","title":"Is Read"},"attachment_count":{"type":"integer","title":"Attachment Count"},"verification":{"$ref":"#/components/schemas/EmailVerification"},"reply_count":{"type":"integer","title":"Reply Count","default":0}},"type":"object","required":["email_id","from_email","subject","received_at","is_read","attachment_count","verification"],"title":"EmailListItem"},"EmailListResponse":{"properties":{"emails":{"items":{"$ref":"#/components/schemas/EmailListItem"},"type":"array","title":"Emails"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["emails","has_more"],"title":"EmailListResponse"},"EmailStatus":{"type":"string","enum":["not_applicable","sent","failed"],"title":"EmailStatus","description":"Tri-state outcome for the B3 email dispatch.\n\nReplaces an earlier ``email_sent: bool`` that collapsed three real\nstates into two: ``not_applicable`` (B1/B2/already_on_team, where no\nemail is ever attempted), ``sent`` (B3 dispatch succeeded), and\n``failed`` (B3 dispatch errored - the invite row still exists, so\nthe caller can offer a re-send affordance without re-running the\nwhole RPC). Keeps the contract explicit while the API is pre-consumer."},"EmailVerification":{"properties":{"spf":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Spf"},"dkim":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dkim"},"dmarc":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dmarc"}},"type":"object","title":"EmailVerification"},"EventData":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"}},"type":"object","required":["id","title"],"title":"EventData"},"FamilyAddendum":{"properties":{"id":{"type":"string","title":"Id"},"text":{"type":"string","title":"Text"},"finalised_at":{"type":"string","title":"Finalised At"}},"type":"object","required":["id","text","finalised_at"],"title":"FamilyAddendum"},"FamilyBlock":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"statements":{"items":{"$ref":"#/components/schemas/FamilyStatement"},"type":"array","title":"Statements"}},"type":"object","required":["id","title","statements"],"title":"FamilyBlock"},"FamilyClinicianSection":{"properties":{"id":{"type":"string","title":"Id"},"kind":{"type":"string","const":"clinician","title":"Kind"},"title":{"type":"string","title":"Title"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text"}},"type":"object","required":["id","kind","title"],"title":"FamilyClinicianSection"},"FamilyContent":{"properties":{"header":{"$ref":"#/components/schemas/FamilyHeader"},"sections":{"items":{"oneOf":[{"$ref":"#/components/schemas/FamilyMergeSection"},{"$ref":"#/components/schemas/FamilyNarrativeSection"},{"$ref":"#/components/schemas/FamilyListSection"},{"$ref":"#/components/schemas/FamilyClinicianSection"},{"$ref":"#/components/schemas/FamilyImageSection"},{"$ref":"#/components/schemas/FamilyMediaSection"}],"discriminator":{"propertyName":"kind","mapping":{"clinician":"#/components/schemas/FamilyClinicianSection","image":"#/components/schemas/FamilyImageSection","list":"#/components/schemas/FamilyListSection","media":"#/components/schemas/FamilyMediaSection","merge":"#/components/schemas/FamilyMergeSection","narrative":"#/components/schemas/FamilyNarrativeSection"}}},"type":"array","title":"Sections"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body"}},"type":"object","required":["header","sections"],"title":"FamilyContent","description":"`body` (the clinician's markdown) when the document was edited as a whole, with\n`sections` holding only its merge facts and pictures; otherwise `sections`, as every\nfinal made before the editor reads."},"FamilyDocumentView":{"properties":{"view":{"type":"string","const":"family","title":"View","default":"family"},"id":{"type":"string","title":"Id"},"child_id":{"type":"string","title":"Child Id"},"status":{"type":"string","const":"final","title":"Status"},"template_name":{"type":"string","title":"Template Name"},"kind":{"type":"string","enum":["session_note","referral"],"title":"Kind"},"organisation":{"$ref":"#/components/schemas/Organisation"},"author_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author Name"},"session_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Date"},"finalised_at":{"type":"string","title":"Finalised At"},"content":{"$ref":"#/components/schemas/FamilyContent"},"addenda":{"items":{"$ref":"#/components/schemas/FamilyAddendum"},"type":"array","title":"Addenda"},"asset_urls":{"additionalProperties":{"type":"string"},"type":"object","title":"Asset Urls"},"signature":{"anyOf":[{"$ref":"#/components/schemas/FamilySignature"},{"type":"null"}]}},"type":"object","required":["id","child_id","status","template_name","kind","organisation","finalised_at","content","addenda","asset_urls"],"title":"FamilyDocumentView","description":"What a parent reads: only a final document, no working material."},"FamilyHeader":{"properties":{"image":{"anyOf":[{"type":"string","pattern":"^(asset:[a-z0-9][a-z0-9-]{0,62}|org:logo)$"},{"type":"null"}],"title":"Image"},"values":{"items":{"$ref":"#/components/schemas/MergeValue"},"type":"array","title":"Values"}},"type":"object","required":["values"],"title":"FamilyHeader"},"FamilyImageSection":{"properties":{"id":{"type":"string","title":"Id"},"kind":{"type":"string","const":"image","title":"Kind"},"title":{"type":"string","title":"Title"},"image":{"type":"string","pattern":"^(asset:[a-z0-9][a-z0-9-]{0,62}|org:logo)$","title":"Image"}},"type":"object","required":["id","kind","title","image"],"title":"FamilyImageSection"},"FamilyListSection":{"properties":{"id":{"type":"string","title":"Id"},"kind":{"type":"string","const":"list","title":"Kind"},"title":{"type":"string","title":"Title"},"state":{"type":"string","enum":["filled","not_discussed","hidden"],"title":"State"},"statements":{"items":{"$ref":"#/components/schemas/FamilyStatement"},"type":"array","title":"Statements"}},"type":"object","required":["id","kind","title","state","statements"],"title":"FamilyListSection"},"FamilyMediaSection":{"properties":{"id":{"type":"string","title":"Id"},"kind":{"type":"string","const":"media","title":"Kind"},"title":{"type":"string","title":"Title"},"document_ids":{"items":{"type":"string"},"type":"array","title":"Document Ids"}},"type":"object","required":["id","kind","title","document_ids"],"title":"FamilyMediaSection"},"FamilyMember":{"properties":{"id":{"type":"string","title":"Id"},"user_id":{"type":"string","title":"User Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"relationship":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Relationship"},"role":{"type":"string","title":"Role"},"is_owner":{"type":"boolean","title":"Is Owner"},"joined_at":{"type":"string","title":"Joined At"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"}},"type":"object","required":["id","user_id","name","email","relationship","role","is_owner","joined_at"],"title":"FamilyMember"},"FamilyMergeSection":{"properties":{"id":{"type":"string","title":"Id"},"kind":{"type":"string","const":"merge","title":"Kind"},"title":{"type":"string","title":"Title"},"values":{"items":{"$ref":"#/components/schemas/MergeValue"},"type":"array","title":"Values"}},"type":"object","required":["id","kind","title","values"],"title":"FamilyMergeSection"},"FamilyNarrativeSection":{"properties":{"id":{"type":"string","title":"Id"},"kind":{"type":"string","const":"narrative","title":"Kind"},"title":{"type":"string","title":"Title"},"repeat":{"type":"boolean","title":"Repeat"},"state":{"type":"string","enum":["filled","not_discussed","hidden"],"title":"State"},"statements":{"items":{"$ref":"#/components/schemas/FamilyStatement"},"type":"array","title":"Statements"},"blocks":{"items":{"$ref":"#/components/schemas/FamilyBlock"},"type":"array","title":"Blocks"}},"type":"object","required":["id","kind","title","repeat","state","statements","blocks"],"title":"FamilyNarrativeSection"},"FamilySignature":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"clinic":{"type":"string","title":"Clinic"},"signed_on":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signed On"}},"type":"object","required":["clinic"],"title":"FamilySignature"},"FamilyStatement":{"properties":{"id":{"type":"string","title":"Id"},"text":{"type":"string","title":"Text"}},"type":"object","required":["id","text"],"title":"FamilyStatement"},"FamilyUnitResponse":{"properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"is_owner":{"type":"boolean","title":"Is Owner","default":false},"members":{"items":{"$ref":"#/components/schemas/FamilyMember"},"type":"array","title":"Members","default":[]},"invites":{"items":{"$ref":"#/components/schemas/PendingInvite"},"type":"array","title":"Invites","default":[]}},"type":"object","title":"FamilyUnitResponse","description":"Consolidated family unit response with members and invites."},"FavouriteThingRequest":{"properties":{"favourite_thing":{"type":"string","maxLength":500,"title":"Favourite Thing"}},"type":"object","required":["favourite_thing"],"title":"FavouriteThingRequest","description":"Body for PUT /children/{child_id}/favourite-thing."},"FcaDraftDocxRequest":{"properties":{"markdown":{"type":"string","title":"Markdown"},"title":{"type":"string","title":"Title","default":"FCA draft"}},"type":"object","required":["markdown"],"title":"FcaDraftDocxRequest"},"FcaDraftRequest":{"properties":{"child_id":{"type":"string","title":"Child Id"}},"type":"object","required":["child_id"],"title":"FcaDraftRequest"},"FcaDraftResponse":{"properties":{"child_id":{"type":"string","title":"Child Id"},"child_name":{"type":"string","title":"Child Name"},"markdown":{"type":"string","title":"Markdown"},"domains_covered":{"type":"integer","title":"Domains Covered"},"total_observations":{"type":"integer","title":"Total Observations"}},"type":"object","required":["child_id","child_name","markdown","domains_covered","total_observations"],"title":"FcaDraftResponse"},"FeedTokenListResponse":{"properties":{"tokens":{"items":{"$ref":"#/components/schemas/FeedTokenResponse"},"type":"array","title":"Tokens"}},"type":"object","required":["tokens"],"title":"FeedTokenListResponse"},"FeedTokenResponse":{"properties":{"id":{"type":"string","title":"Id"},"token":{"type":"string","title":"Token"},"feed_url":{"type":"string","title":"Feed Url"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","title":"Created At"},"revoked_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revoked At"}},"type":"object","required":["id","token","feed_url","is_active","created_at"],"title":"FeedTokenResponse"},"FileMetadata":{"properties":{"name":{"type":"string","title":"Name"},"url":{"type":"string","title":"Url"},"type":{"type":"string","title":"Type"},"documentId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Documentid"},"thumbnailUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnailurl"},"videoMessageId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Videomessageid"},"videoAttachmentIndex":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Videoattachmentindex"},"durationSeconds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Durationseconds"}},"type":"object","required":["name","url","type"],"title":"FileMetadata","description":"File metadata for messages with attachments"},"FlagLetterRequest":{"properties":{"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","title":"FlagLetterRequest"},"FormSummary":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"form_type":{"type":"string","title":"Form Type"},"status":{"type":"string","title":"Status"},"share_code":{"type":"string","title":"Share Code"},"schema":{"additionalProperties":true,"type":"object","title":"Schema"},"submission_count":{"type":"integer","title":"Submission Count"},"submissions":{"items":{"$ref":"#/components/schemas/SubmissionSummary"},"type":"array","title":"Submissions"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","title","form_type","status","share_code","schema","submission_count","submissions","created_at"],"title":"FormSummary"},"GenerateInviteRequest":{"properties":{"child_id":{"type":"string","title":"Child Id"},"parent_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Parent Email"}},"type":"object","required":["child_id"],"title":"GenerateInviteRequest"},"GenerateInviteResponse":{"properties":{"invite_code":{"type":"string","title":"Invite Code"},"invite_url":{"type":"string","title":"Invite Url"},"expires_at":{"type":"string","title":"Expires At"}},"type":"object","required":["invite_code","invite_url","expires_at"],"title":"GenerateInviteResponse"},"GenerateRequest":{"properties":{"child_id":{"type":"string","title":"Child Id"}},"type":"object","required":["child_id"],"title":"GenerateRequest"},"GenerateResponse":{"properties":{"code":{"type":"string","title":"Code"},"share_url":{"type":"string","title":"Share Url"},"expires_at":{"type":"string","title":"Expires At"},"child_name":{"type":"string","title":"Child Name"}},"type":"object","required":["code","share_url","expires_at","child_name"],"title":"GenerateResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HomeLetterResponse":{"properties":{"letter":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Letter"}},"type":"object","required":["letter"],"title":"HomeLetterResponse"},"HomeSetupProgressResponse":{"properties":{"journey_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Journey Type"},"cards":{"items":{"$ref":"#/components/schemas/CardState"},"type":"array","title":"Cards"},"check_in":{"anyOf":[{"$ref":"#/components/schemas/CheckInCard"},{"type":"null"}]},"reminder_activation":{"anyOf":[{"$ref":"#/components/schemas/ReminderActivationCard"},{"type":"null"}]},"all_initial_complete":{"type":"boolean","title":"All Initial Complete"},"activation":{"anyOf":[{"$ref":"#/components/schemas/ActivationState"},{"type":"null"}]},"clinician_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clinician Name"},"clinician_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clinician Email"},"clinic_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clinic Name"},"records_update_dismissed":{"type":"boolean","title":"Records Update Dismissed","default":false}},"type":"object","required":["journey_type","cards","all_initial_complete"],"title":"HomeSetupProgressResponse"},"ImageSection":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"title":{"type":"string","maxLength":120,"minLength":1,"title":"Title"},"kind":{"type":"string","const":"image","title":"Kind"},"image":{"type":"string","pattern":"^(asset:[a-z0-9][a-z0-9-]{0,62}|org:logo)$","title":"Image"}},"additionalProperties":false,"type":"object","required":["id","title","kind","image"],"title":"ImageSection","description":"A fixed picture from the template: a body chart, a rating scale."},"ImportImage":{"properties":{"id":{"type":"string","title":"Id"},"proposed_role":{"type":"string","enum":["letterhead","static","sample","signature"],"title":"Proposed Role"},"confidence":{"type":"number","title":"Confidence"},"position":{"type":"string","enum":["header","footer","body"],"title":"Position"},"page":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Page"},"index":{"type":"integer","title":"Index"},"width":{"type":"integer","title":"Width"},"height":{"type":"integer","title":"Height"},"importable":{"type":"boolean","title":"Importable"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"replaceable":{"type":"boolean","title":"Replaceable"},"thumbnail_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Url"}},"type":"object","required":["id","proposed_role","confidence","position","index","width","height","importable","replaceable"],"title":"ImportImage"},"InitiateRequest":{"properties":{"platform":{"type":"string","title":"Platform","default":"webapp"},"acknowledge_subscription":{"type":"boolean","title":"Acknowledge Subscription","default":false}},"type":"object","title":"InitiateRequest"},"InviteEligibilityResponse":{"properties":{"can_claim":{"type":"boolean","title":"Can Claim"},"reason":{"type":"string","enum":["eligible","already_in_this_organisation","already_in_organisation","invite_for_another_address","no_pending_invite","invite_expired"],"title":"Reason"},"email":{"type":"string","title":"Email"},"current_organisation_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Organisation Name"}},"type":"object","required":["can_claim","reason","email"],"title":"InviteEligibilityResponse"},"InviteOutcome":{"type":"string","enum":["connected_clinician","connected_worker","invite_sent","already_on_team"],"title":"InviteOutcome","description":"Mirrors the RPC's jsonb ``outcome`` field verbatim.\n\nStable strings - UI copy keys off them. Adding a new branch is a\nmigration + enum extension in lockstep."},"InviteStatusRequest":{"properties":{"child_id":{"type":"string","title":"Child Id"}},"type":"object","required":["child_id"],"title":"InviteStatusRequest"},"InviteStatusResponse":{"properties":{"has_valid_invite":{"type":"boolean","title":"Has Valid Invite"},"has_expired_invite":{"type":"boolean","title":"Has Expired Invite"},"invite_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Code"},"invite_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Url"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["has_valid_invite","has_expired_invite"],"title":"InviteStatusResponse"},"JourneySignalRequest":{"properties":{"invite_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Code"}},"type":"object","title":"JourneySignalRequest"},"JourneySignalResponse":{"properties":{"resolved_journey":{"type":"string","title":"Resolved Journey"}},"type":"object","required":["resolved_journey"],"title":"JourneySignalResponse"},"KeepsakeSavedResponse":{"properties":{"saved":{"type":"boolean","title":"Saved"}},"type":"object","required":["saved"],"title":"KeepsakeSavedResponse"},"LatestConversation":{"properties":{"child_id":{"type":"string","title":"Child Id"},"child_name":{"type":"string","title":"Child Name"},"child_date_of_birth":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Date Of Birth"},"child_age":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Age"},"child_avatar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Avatar"},"child_avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Avatar Url"},"emergency_profile_completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Emergency Profile Completed At"},"emergency_profile_checked":{"items":{"type":"string"},"type":"array","title":"Emergency Profile Checked","default":[]},"latest_conversation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Latest Conversation Id"},"latest_conversation_updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Latest Conversation Updated At"},"total_conversations":{"type":"integer","title":"Total Conversations"},"has_conversations":{"type":"boolean","title":"Has Conversations"},"track_names":{"items":{"type":"string"},"type":"array","title":"Track Names","default":[]}},"type":"object","required":["child_id","child_name","child_date_of_birth","child_age","child_avatar","child_avatar_url","emergency_profile_completed_at","latest_conversation_id","latest_conversation_updated_at","total_conversations","has_conversations"],"title":"LatestConversation"},"LatestConversationResponse":{"properties":{"conversation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conversation Id"},"child_id":{"type":"string","title":"Child Id"},"has_conversations":{"type":"boolean","title":"Has Conversations"}},"type":"object","required":["conversation_id","child_id","has_conversations"],"title":"LatestConversationResponse"},"LegalDetailsInfo":{"properties":{"legal_name":{"type":"string","title":"Legal Name"},"abn":{"type":"string","title":"Abn"},"legal_address":{"$ref":"#/components/schemas/Address"},"shipping_address":{"anyOf":[{"$ref":"#/components/schemas/Address"},{"type":"null"}]},"shipping_same_as_legal":{"type":"boolean","title":"Shipping Same As Legal"},"primary_contact_email":{"type":"string","title":"Primary Contact Email"}},"type":"object","required":["legal_name","abn","legal_address","shipping_same_as_legal","primary_contact_email"],"title":"LegalDetailsInfo"},"LegalPayload":{"properties":{"legal_name":{"type":"string","title":"Legal Name"},"abn":{"type":"string","title":"Abn"},"legal_address":{"$ref":"#/components/schemas/Address"},"shipping_address":{"anyOf":[{"$ref":"#/components/schemas/Address"},{"type":"null"}]},"shipping_same_as_legal":{"type":"boolean","title":"Shipping Same As Legal","default":true}},"type":"object","required":["legal_name","abn","legal_address"],"title":"LegalPayload"},"LettersResponse":{"properties":{"letters":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Letters"}},"type":"object","required":["letters"],"title":"LettersResponse"},"ListFormsResponse":{"properties":{"forms":{"items":{"$ref":"#/components/schemas/FormSummary"},"type":"array","title":"Forms"}},"type":"object","required":["forms"],"title":"ListFormsResponse"},"ListResponse":{"properties":{"shares":{"items":{"$ref":"#/components/schemas/ShareCode"},"type":"array","title":"Shares"}},"type":"object","required":["shares"],"title":"ListResponse"},"ListSection":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"title":{"type":"string","maxLength":120,"minLength":1,"title":"Title"},"kind":{"type":"string","const":"list","title":"Kind"},"instruction":{"type":"string","maxLength":2000,"minLength":1,"title":"Instruction"},"when_missing":{"type":"string","enum":["not_discussed","hide"],"title":"When Missing","default":"not_discussed"},"example":{"anyOf":[{"type":"string","maxLength":2000,"minLength":1},{"type":"null"}],"title":"Example"}},"additionalProperties":false,"type":"object","required":["id","title","kind","instruction"],"title":"ListSection","description":"Bullets written by the writer. No `repeat`: a list already has n items."},"LookupEmailRequest":{"properties":{"email":{"type":"string","title":"Email"}},"type":"object","required":["email"],"title":"LookupEmailRequest"},"LookupEmailResponse":{"properties":{"found":{"type":"boolean","title":"Found"},"clinician_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clinician Name"},"clinic_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clinic Name"}},"type":"object","required":["found"],"title":"LookupEmailResponse"},"LookupInviteRequest":{"properties":{"code":{"type":"string","title":"Code"}},"type":"object","required":["code"],"title":"LookupInviteRequest"},"MarkAllItem":{"properties":{"child_id":{"type":"string","format":"uuid","title":"Child Id"},"ok":{"type":"boolean","title":"Ok"},"changed":{"type":"boolean","title":"Changed","default":false},"previous_visited_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Previous Visited At"},"last_visited_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Visited At"}},"type":"object","required":["child_id","ok"],"title":"MarkAllItem"},"MarkAllRead":{"properties":{"child_ids":{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":500,"minItems":1,"title":"Child Ids"},"as_of":{"type":"string","format":"date-time","title":"As Of"}},"type":"object","required":["child_ids","as_of"],"title":"MarkAllRead"},"MarkAllReadResponse":{"properties":{"updated":{"type":"integer","title":"Updated"}},"type":"object","required":["updated"],"title":"MarkAllReadResponse"},"MarkAllResult":{"properties":{"items":{"items":{"$ref":"#/components/schemas/MarkAllItem"},"type":"array","title":"Items"}},"type":"object","required":["items"],"title":"MarkAllResult"},"MarkRead":{"properties":{"child_id":{"type":"string","format":"uuid","title":"Child Id"},"as_of":{"type":"string","format":"date-time","title":"As Of"}},"type":"object","required":["child_id","as_of"],"title":"MarkRead"},"MarkReadResult":{"properties":{"previous_visited_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Previous Visited At"},"last_visited_at":{"type":"string","format":"date-time","title":"Last Visited At"},"changed":{"type":"boolean","title":"Changed"}},"type":"object","required":["previous_visited_at","last_visited_at","changed"],"title":"MarkReadResult"},"MarkedResponse":{"properties":{"marked":{"type":"integer","title":"Marked"}},"type":"object","required":["marked"],"title":"MarkedResponse"},"MediaFeedEntry":{"properties":{"kind":{"type":"string","const":"media","title":"Kind","default":"media"},"id":{"type":"string","title":"Id"},"timestamp":{"type":"string","title":"Timestamp"},"document":{"$ref":"#/components/schemas/DocumentResponse"}},"type":"object","required":["id","timestamp","document"],"title":"MediaFeedEntry"},"MediaSection":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"title":{"type":"string","maxLength":120,"minLength":1,"title":"Title"},"kind":{"type":"string","const":"media","title":"Kind"}},"additionalProperties":false,"type":"object","required":["id","title","kind"],"title":"MediaSection","description":"Photos the clinician picks from the session's attachments; never the model."},"MedicalInfo":{"properties":{"medical_history":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Medical History"},"current_medications":{"items":{"$ref":"#/components/schemas/Medication"},"type":"array","title":"Current Medications","default":[]},"allergies":{"items":{"$ref":"#/components/schemas/Allergy"},"type":"array","title":"Allergies","default":[]},"healthcare_providers":{"items":{"type":"string"},"type":"array","title":"Healthcare Providers","default":[]}},"type":"object","title":"MedicalInfo"},"Medication":{"properties":{"name":{"type":"string","title":"Name"},"dosage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dosage"},"frequency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Frequency"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["name"],"title":"Medication"},"MergeMissingFlag":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"type":{"type":"string","const":"merge_missing","title":"Type"},"section_id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Section Id"},"field":{"type":"string","enum":["child.full_name","child.first_name","child.dob","child.age_at_session","child.ndis_number","child.medicare_number","session.date","clinician.full_name","clinician.discipline","clinician.provider_number","clinic.name","clinic.address","clinic.phone"],"title":"Field"},"label":{"type":"string","title":"Label"},"status":{"type":"string","enum":["open","dismissed","resolved"],"title":"Status","default":"open"}},"additionalProperties":false,"type":"object","required":["id","type","section_id","field","label"],"title":"MergeMissingFlag","description":"A merge field with no value. A To check item that never blocks Finalise:\nfinalising renders it as nothing. `section_id` is the merge section, or\n`header` for the letterhead."},"MergeSection":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"title":{"type":"string","maxLength":120,"minLength":1,"title":"Title"},"kind":{"type":"string","const":"merge","title":"Kind"},"fields":{"items":{"type":"string","enum":["child.full_name","child.first_name","child.dob","child.age_at_session","child.ndis_number","child.medicare_number","session.date","clinician.full_name","clinician.discipline","clinician.provider_number","clinic.name","clinic.address","clinic.phone"]},"type":"array","maxItems":20,"minItems":1,"title":"Fields"}},"additionalProperties":false,"type":"object","required":["id","title","kind","fields"],"title":"MergeSection","description":"Filled from the database, deterministically. Never shown to the writer."},"MergeValue":{"properties":{"field":{"type":"string","enum":["child.full_name","child.first_name","child.dob","child.age_at_session","child.ndis_number","child.medicare_number","session.date","clinician.full_name","clinician.discipline","clinician.provider_number","clinic.name","clinic.address","clinic.phone"],"title":"Field"},"label":{"type":"string","title":"Label"},"value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Value"}},"additionalProperties":false,"type":"object","required":["field","label","value"],"title":"MergeValue","description":"`value` null is a field indi holds no value for. It renders as nothing, label\nincluded, in a draft and a final alike (D25); a draft carries a `merge_missing`\nflag saying it's left off."},"MessageResponse":{"properties":{"id":{"type":"string","title":"Id"},"role":{"type":"string","title":"Role"},"content":{"type":"string","title":"Content"},"type":{"type":"string","title":"Type"},"hidden":{"type":"boolean","title":"Hidden","default":false},"timestamp":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timestamp"},"user_vote":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Vote"},"user_feedback":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Feedback"},"voted_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Voted At"},"fileMetadata":{"anyOf":[{"$ref":"#/components/schemas/FileMetadata"},{"type":"null"}]},"fileMetadataList":{"anyOf":[{"items":{"$ref":"#/components/schemas/FileMetadata"},"type":"array"},{"type":"null"}],"title":"Filemetadatalist"},"summary_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary Type"},"summary_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary Content"},"summary_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Summary Metadata"},"summary_actions":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Summary Actions"},"summary_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary Status"},"summary_errors":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Summary Errors"},"artefacts":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Artefacts"},"child_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Id"},"child_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Name"},"toolResults":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Toolresults"},"contentParts":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Contentparts"}},"type":"object","required":["id","role","content","type"],"title":"MessageResponse","description":"Response model for individual message"},"MethodLookupRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"MethodLookupRequest"},"MethodLookupResponse":{"properties":{"method":{"type":"string","title":"Method"}},"type":"object","required":["method"],"title":"MethodLookupResponse"},"Milestone":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"category":{"type":"string","title":"Category"},"status":{"type":"string","title":"Status"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"},"target_age":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Age"}},"type":"object","required":["id","title","category","status"],"title":"Milestone"},"MobileLogBatch":{"properties":{"entries":{"items":{"$ref":"#/components/schemas/MobileLogEntry"},"type":"array","maxItems":50,"minItems":1,"title":"Entries"}},"type":"object","required":["entries"],"title":"MobileLogBatch"},"MobileLogEntry":{"properties":{"level":{"type":"string","enum":["trace","debug","info","warn","error","fatal"],"title":"Level"},"message":{"type":"string","maxLength":4000,"title":"Message"},"context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Context"},"timestamp_ms":{"type":"integer","title":"Timestamp Ms"}},"type":"object","required":["level","message","timestamp_ms"],"title":"MobileLogEntry"},"NarrativeSection":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"title":{"type":"string","maxLength":120,"minLength":1,"title":"Title"},"kind":{"type":"string","const":"narrative","title":"Kind"},"instruction":{"type":"string","maxLength":2000,"minLength":1,"title":"Instruction"},"when_missing":{"type":"string","enum":["not_discussed","hide"],"title":"When Missing","default":"not_discussed"},"repeat":{"type":"boolean","title":"Repeat","default":false},"example":{"anyOf":[{"type":"string","maxLength":2000,"minLength":1},{"type":"null"}],"title":"Example"}},"additionalProperties":false,"type":"object","required":["id","title","kind","instruction"],"title":"NarrativeSection","description":"Prose written by the writer. `repeat` makes it one titled block per topic."},"NdisInvoiceRequest":{"properties":{"ndis_number":{"type":"string","title":"Ndis Number"},"participant_name":{"type":"string","maxLength":30,"minLength":1,"title":"Participant Name"},"clinician_name":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Clinician Name"},"pm_email":{"type":"string","title":"Pm Email"},"pm_company":{"type":"string","title":"Pm Company"},"pm_abn":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pm Abn"},"pm_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pm Address"},"parent_first_name":{"type":"string","maxLength":50,"minLength":1,"title":"Parent First Name"},"parent_last_name":{"type":"string","maxLength":50,"minLength":1,"title":"Parent Last Name"}},"type":"object","required":["ndis_number","participant_name","pm_email","pm_company","parent_first_name","parent_last_name"],"title":"NdisInvoiceRequest","description":"Request body for NDIS invoice creation."},"NdisInvoiceResponse":{"properties":{"trial_granted":{"type":"boolean","title":"Trial Granted"},"trial_expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trial Expires At"}},"type":"object","required":["trial_granted","trial_expires_at"],"title":"NdisInvoiceResponse","description":"Response after creating NDIS invoice.\n\nNo invoice URL: the invoice is created as a Stripe *draft* and is not\nfinalized until an admin reviews and marks it sent, so there's no hosted\nURL yet. The client only needs to know the trial was granted."},"NewUpdatesResponse":{"properties":{"groups":{"items":{"$ref":"#/components/schemas/ChildUpdateGroup"},"type":"array","title":"Groups"},"total_unread":{"type":"integer","title":"Total Unread"},"has_assigned_clients":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Has Assigned Clients"},"as_of":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"As Of"}},"type":"object","required":["groups","total_unread"],"title":"NewUpdatesResponse"},"NotificationListResponse":{"properties":{"notifications":{"items":{"$ref":"#/components/schemas/NotificationResponse"},"type":"array","title":"Notifications"},"total":{"type":"integer","title":"Total"},"unread_count":{"type":"integer","title":"Unread Count"}},"type":"object","required":["notifications","total","unread_count"],"title":"NotificationListResponse"},"NotificationResponse":{"properties":{"id":{"type":"string","title":"Id"},"type":{"type":"string","title":"Type"},"title":{"type":"string","title":"Title"},"body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body"},"body_rich":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body Rich"},"tags":{"items":{"$ref":"#/components/schemas/NotificationTag"},"type":"array","title":"Tags","default":[]},"reaction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reaction"},"actor_name":{"type":"string","title":"Actor Name"},"actor_type":{"type":"string","title":"Actor Type"},"resource_type":{"type":"string","title":"Resource Type"},"resource_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resource Id"},"child_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Id"},"child_name":{"type":"string","title":"Child Name","default":""},"is_read":{"type":"boolean","title":"Is Read"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","type","title","body","actor_name","actor_type","resource_type","resource_id","child_id","is_read","created_at"],"title":"NotificationResponse"},"NotificationTag":{"properties":{"junction_id":{"type":"string","title":"Junction Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["junction_id","name"],"title":"NotificationTag","description":"One resolved `{cc:…}` mention from `body_rich`."},"OnboardingCompleteResponse":{"properties":{"success":{"type":"boolean","title":"Success"}},"type":"object","required":["success"],"title":"OnboardingCompleteResponse"},"OnboardingInvitedResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"profile_updated":{"type":"boolean","title":"Profile Updated"}},"type":"object","required":["success","profile_updated"],"title":"OnboardingInvitedResponse"},"Organisation":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"Organisation"},"OrganisationResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"service_types":{"items":{"type":"string"},"type":"array","title":"Service Types","default":[]},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"signed_logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signed Logo Url"},"can_edit":{"type":"boolean","title":"Can Edit","default":false}},"type":"object","required":["id","name"],"title":"OrganisationResponse"},"OutboxEntryPayload":{"properties":{"id":{"type":"string","title":"Id"},"type":{"type":"string","title":"Type"},"recipients":{"items":{"$ref":"#/components/schemas/OutboxRecipientPayload"},"type":"array","title":"Recipients"},"subject":{"type":"string","title":"Subject"},"sent_at":{"type":"string","title":"Sent At"},"status":{"type":"string","title":"Status"},"snapshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Snapshot Url"},"child_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Id"},"invite_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Status"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"},"child_care_team_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Care Team Id"}},"type":"object","required":["id","type","recipients","subject","sent_at","status"],"title":"OutboxEntryPayload","description":"Pydantic mirror of the Strawberry `OutboundEntry`\n(`api/src/api/graph/parent/outbound/types.py`). Kept field-for-field in sync\nby hand; `tests/api/records/test_types.py` fails if the two drift."},"OutboxFeedEntry":{"properties":{"kind":{"type":"string","const":"outbox","title":"Kind","default":"outbox"},"id":{"type":"string","title":"Id"},"timestamp":{"type":"string","title":"Timestamp"},"outbox":{"$ref":"#/components/schemas/OutboxEntryPayload"}},"type":"object","required":["id","timestamp","outbox"],"title":"OutboxFeedEntry"},"OutboxRecipientPayload":{"properties":{"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"resolved_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resolved Name"}},"type":"object","title":"OutboxRecipientPayload"},"PaginatedDocumentResponse":{"properties":{"documents":{"items":{"$ref":"#/components/schemas/DocumentResponse"},"type":"array","title":"Documents"},"total":{"type":"integer","title":"Total"},"has_more":{"type":"boolean","title":"Has More"},"next_offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Offset"}},"type":"object","required":["documents","total","has_more"],"title":"PaginatedDocumentResponse"},"PaginatedMessagesResponse":{"properties":{"messages":{"items":{"$ref":"#/components/schemas/MessageResponse"},"type":"array","title":"Messages"},"pagination":{"$ref":"#/components/schemas/src__api__chat__get_messages__Pagination"}},"type":"object","required":["messages","pagination"],"title":"PaginatedMessagesResponse","description":"Response model for paginated messages endpoint"},"PatchCareTeamMemberRequest":{"properties":{"auto_match_opt_in":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Match Opt In"},"access_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Access Level"}},"type":"object","title":"PatchCareTeamMemberRequest","description":"Partial update payload for a care-team-member junction row.\n\nFuture fields (e.g. ``disconnected_at``) plug in here without a new\nroute. Every field is optional so a caller can toggle one knob at a\ntime. ``model_dump(exclude_unset=True)`` is what gates \"did the caller\nactually pass this value\" - a None default would conflate \"explicitly\ncleared\" with \"not sent\"."},"PatchCareTeamMemberResponse":{"properties":{"junction_id":{"type":"string","title":"Junction Id"},"care_team_member_id":{"type":"string","title":"Care Team Member Id"},"auto_match_opt_in":{"type":"boolean","title":"Auto Match Opt In"},"access_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Access Level"}},"type":"object","required":["junction_id","care_team_member_id","auto_match_opt_in"],"title":"PatchCareTeamMemberResponse"},"PatchDocument":{"properties":{"ops":{"items":{"oneOf":[{"$ref":"#/components/schemas/RestoreClaim"},{"$ref":"#/components/schemas/PlaceUnplaced"},{"$ref":"#/components/schemas/DismissFlag"},{"$ref":"#/components/schemas/ReopenFlag"},{"$ref":"#/components/schemas/StartEdit"},{"$ref":"#/components/schemas/SetBody"},{"$ref":"#/components/schemas/BackToReview"},{"$ref":"#/components/schemas/SetMedia"}],"discriminator":{"propertyName":"op","mapping":{"back_to_review":"#/components/schemas/BackToReview","dismiss_flag":"#/components/schemas/DismissFlag","place_unplaced":"#/components/schemas/PlaceUnplaced","reopen_flag":"#/components/schemas/ReopenFlag","restore_claim":"#/components/schemas/RestoreClaim","set_body":"#/components/schemas/SetBody","set_media":"#/components/schemas/SetMedia","start_edit":"#/components/schemas/StartEdit"}}},"type":"array","maxItems":50,"minItems":1,"title":"Ops"}},"additionalProperties":false,"type":"object","required":["ops"],"title":"PatchDocument","description":"Applied in order, all or nothing."},"PaywallEvent":{"properties":{"event":{"type":"string","enum":["viewed","checkout_started","checkout_dismissed","converted","web_fallback_tapped"],"title":"Event"},"platform":{"type":"string","enum":["ios","android","web"],"title":"Platform"},"surface":{"anyOf":[{"type":"string","enum":["onboarding","dashboard"]},{"type":"null"}],"title":"Surface"},"billing_period":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Billing Period"}},"type":"object","required":["event","platform"],"title":"PaywallEvent","description":"One funnel step, as the client observed it.\n\nNote what is absent: no ``user_id``, no ``family_unit_id``, and no event id.\nIdentity is stamped server-side - a client that sends it is ignored, not\ntrusted - and dedup is a property of the monotonic upsert, not of an id the\nclient mints.\n\n**Every field here is tighter than what consumes it, and they all fail the\nsame way.** Three bound the column they feed; ``event`` bounds the registry\nkey it looks up. Either way, a value this model lets through but the next\nlayer rejects sinks the WHOLE batch: it is one upsert per batch, and the\nwrite is swallowed (see ``ingest_paywall_events``), so every milestone in it\nis lost silently behind a 200 with only a log line. That makes the types\nload-bearing rather than decorative - reject here what the next layer can't\ntake, and keep each field's own note to what is specific to it.\n\n**There is deliberately no ``occurred_at``.** Milestone time is stamped\nSERVER-SIDE (see ``_project``). A client-supplied instant bought nothing -\nneither emitter queues, both post the moment the event happens, so device\ntime only ever differed from server time by flight time - while costing\nforgeability: ``occurred_at`` was request-body input, so any authenticated\nconsented caller could choose it, and ``LEAST``/``GREATEST`` then made the\nchoice PERMANENT. A backdated ``first_viewed_at`` can never be raised by a\nlater honest write and a forward-dated ``last_checkout_dismissed_at`` can\nnever be lowered; repair is a manual UPDATE as postgres. Observed live\nbefore this was closed: one request pinned ``first_viewed_at`` to 2001 and\n``last_checkout_dismissed_at`` to 2035.\n\n**If a client-side queue ever ships**, offline batches will genuinely carry\nan older-than-now instant and server time stops being right. Reintroduce\n``occurred_at`` THEN - but WITH a bounded skew clamp (ceiling ``now()``, and\na floor the server already knows, e.g. the caller's\n``user_privacy_settings.created_at`` - a paywall view cannot predate\nsignup). Do not simply re-add the field: unbounded is how it got here."},"PaywallEventBatch":{"properties":{"events":{"items":{"$ref":"#/components/schemas/PaywallEvent"},"type":"array","maxItems":20,"minItems":1,"title":"Events"}},"type":"object","required":["events"],"title":"PaywallEventBatch"},"PendingClinicCard":{"properties":{"child_id":{"type":"string","title":"Child Id"},"organisation_name":{"type":"string","title":"Organisation Name"},"clinician_first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clinician First Name"}},"type":"object","required":["child_id","organisation_name","clinician_first_name"],"title":"PendingClinicCard","description":"One child still waiting on a contact from the clinic their parent named - exactly\nwhat home's care-team row prefills the wizard with, and nothing it does not read."},"PendingClinicResponse":{"properties":{"is_clinic_referred":{"type":"boolean","title":"Is Clinic Referred"}},"type":"object","required":["is_clinic_referred"],"title":"PendingClinicResponse"},"PendingClinicsResponse":{"properties":{"pending":{"items":{"$ref":"#/components/schemas/PendingClinicCard"},"type":"array","title":"Pending"}},"type":"object","required":["pending"],"title":"PendingClinicsResponse"},"PendingInvite":{"properties":{"id":{"type":"string","title":"Id"},"email":{"type":"string","title":"Email"},"relationship":{"type":"string","title":"Relationship"},"status":{"type":"string","title":"Status"},"expires_at":{"type":"string","title":"Expires At"},"created_at":{"type":"string","title":"Created At"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},"type":"object","required":["id","email","relationship","status","expires_at","created_at"],"title":"PendingInvite"},"PendingMatch":{"properties":{"child_care_team_id":{"type":"string","title":"Child Care Team Id"},"child_id":{"type":"string","title":"Child Id"},"child_first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child First Name"},"child_avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Avatar Url"},"parent_first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent First Name"},"role_kind":{"type":"string","title":"Role Kind"},"role_value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Value"}},"type":"object","required":["child_care_team_id","child_id","role_kind"],"title":"PendingMatch"},"PendingMatchesResponse":{"properties":{"matches":{"items":{"$ref":"#/components/schemas/PendingMatch"},"type":"array","title":"Matches"}},"type":"object","required":["matches"],"title":"PendingMatchesResponse"},"Person":{"properties":{"user_id":{"type":"string","title":"User Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},"type":"object","required":["user_id"],"title":"Person"},"PlaceUnplaced":{"properties":{"op":{"type":"string","const":"place_unplaced","title":"Op"},"flag_id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Flag Id"},"section_id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Section Id"},"block_id":{"anyOf":[{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$"},{"type":"null"}],"title":"Block Id"}},"additionalProperties":false,"type":"object","required":["op","flag_id","section_id"],"title":"PlaceUnplaced"},"PortalRequest":{"properties":{"surface":{"type":"string","enum":["web","mobile"],"title":"Surface","default":"web"}},"type":"object","title":"PortalRequest"},"PortalResponse":{"properties":{"url":{"type":"string","title":"Url"}},"type":"object","required":["url"],"title":"PortalResponse"},"PrepRequest":{"properties":{"child_id":{"type":"string","title":"Child Id"},"period_days":{"type":"integer","enum":[7,14,30],"title":"Period Days"}},"type":"object","required":["child_id","period_days"],"title":"PrepRequest"},"PrepResponse":{"properties":{"child_id":{"type":"string","title":"Child Id"},"child_name":{"type":"string","title":"Child Name"},"period_days":{"type":"integer","title":"Period Days"},"period_label":{"type":"string","title":"Period Label"},"summary":{"type":"string","title":"Summary"},"data_snapshot":{"additionalProperties":true,"type":"object","title":"Data Snapshot"}},"type":"object","required":["child_id","child_name","period_days","period_label","summary","data_snapshot"],"title":"PrepResponse"},"Preview":{"properties":{"sample":{"$ref":"#/components/schemas/SampleNote"},"content":{"$ref":"#/components/schemas/DocumentContent"},"flags":{"items":{"oneOf":[{"$ref":"#/components/schemas/RemovedFlag"},{"$ref":"#/components/schemas/UnverifiedFlag"},{"$ref":"#/components/schemas/UnplacedFlag"},{"$ref":"#/components/schemas/ClinicianSectionFlag"},{"$ref":"#/components/schemas/MergeMissingFlag"}],"discriminator":{"propertyName":"type","mapping":{"clinician_section_empty":"#/components/schemas/ClinicianSectionFlag","merge_missing":"#/components/schemas/MergeMissingFlag","removed":"#/components/schemas/RemovedFlag","unplaced":"#/components/schemas/UnplacedFlag","unverified":"#/components/schemas/UnverifiedFlag"}}},"type":"array","title":"Flags"},"asset_urls":{"additionalProperties":{"type":"string"},"type":"object","title":"Asset Urls"}},"type":"object","required":["sample","content","flags"],"title":"Preview"},"PreviewRequest":{"properties":{"definition":{"$ref":"#/components/schemas/TemplateDefinition"},"sample_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sample Id"}},"additionalProperties":false,"type":"object","required":["definition"],"title":"PreviewRequest"},"PreviewUrlResponse":{"properties":{"signed_url":{"type":"string","title":"Signed Url"}},"type":"object","required":["signed_url"],"title":"PreviewUrlResponse"},"PriceInfo":{"properties":{"price":{"type":"number","title":"Price"},"currency":{"type":"string","title":"Currency"},"formatted":{"type":"string","title":"Formatted"},"interval":{"type":"string","title":"Interval"}},"type":"object","required":["price","currency","formatted","interval"],"title":"PriceInfo","description":"Price information for a subscription product."},"PricesResponse":{"properties":{"monthly":{"anyOf":[{"$ref":"#/components/schemas/PriceInfo"},{"type":"null"}]},"annual":{"anyOf":[{"$ref":"#/components/schemas/PriceInfo"},{"type":"null"}]},"pif_monthly":{"anyOf":[{"$ref":"#/components/schemas/PriceInfo"},{"type":"null"}]}},"type":"object","required":["monthly","annual"],"title":"PricesResponse","description":"Response containing available subscription prices."},"PrivacySettingsPatch":{"properties":{"allow_ai_improvement":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Allow Ai Improvement"},"marketing_consent":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Marketing Consent"},"analytics_consent":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Analytics Consent"}},"type":"object","title":"PrivacySettingsPatch"},"ProfileMatchItem":{"properties":{"child_id":{"type":"string","title":"Child Id"},"child_name":{"type":"string","title":"Child Name"},"child_avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Avatar Url"},"therapist_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Therapist Name"},"therapist_avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Therapist Avatar Url"},"organisation_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organisation Name"},"organisation_logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organisation Logo Url"}},"type":"object","required":["child_id","child_name"],"title":"ProfileMatchItem"},"ProfileResponse":{"properties":{"profile":{"$ref":"#/components/schemas/UserProfile"}},"type":"object","required":["profile"],"title":"ProfileResponse"},"ProfileUpdateRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"default_child_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Default Child Id"},"chat_onboarded":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Chat Onboarded"},"parent_needs":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Parent Needs"}},"type":"object","title":"ProfileUpdateRequest","description":"Fields that users can update directly. Note: onboarded and account_type are server-controlled.\n\n`email` is deliberately absent: `guard_user_profiles_server_columns` holds\nthe column to the caller's own `auth.users` address, and this route writes on\nthe caller's own JWT, so declaring the field made it the one writer that\nforwarded a client-supplied one. See `20260827125137` for the argument.\n\nExtra keys are ignored (pydantic's default), so a stale client still sending\n`email` is dropped rather than 500ing on the guard's raise."},"PromoDeal":{"properties":{"code":{"type":"string","title":"Code"},"percent_off":{"type":"integer","title":"Percent Off"},"months":{"type":"integer","title":"Months"},"play_offer_id":{"type":"string","title":"Play Offer Id"},"apple_redeem_url":{"type":"string","title":"Apple Redeem Url"}},"type":"object","required":["code","percent_off","months","play_offer_id","apple_redeem_url"],"title":"PromoDeal"},"QuickNoteBody":{"properties":{"child_id":{"type":"string","title":"Child Id"},"value":{"type":"string","maxLength":50000,"minLength":1,"title":"Value"},"staged_attachment_ids":{"items":{"type":"string"},"type":"array","title":"Staged Attachment Ids"},"video_document_ids":{"items":{"type":"string"},"type":"array","title":"Video Document Ids"},"used_voice":{"type":"boolean","title":"Used Voice","default":false},"surface":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Surface"},"used_starter":{"type":"boolean","title":"Used Starter","default":false},"audio_duration_seconds":{"anyOf":[{"type":"number","maximum":86400.0,"exclusiveMinimum":0.0},{"type":"null"}],"title":"Audio Duration Seconds"},"occurred_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Occurred At"},"parent_questions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Parent Questions"},"template_id":{"anyOf":[{"type":"string","maxLength":36,"minLength":36},{"type":"null"}],"title":"Template Id"}},"type":"object","required":["child_id","value"],"title":"QuickNoteBody"},"QuietClient":{"properties":{"child_id":{"type":"string","title":"Child Id"},"child_name":{"type":"string","title":"Child Name"},"dob":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dob"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"},"days_quiet":{"type":"integer","title":"Days Quiet"},"check_in_state":{"type":"string","title":"Check In State"},"check_in_last_sent_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Check In Last Sent At"}},"type":"object","required":["child_id","child_name","days_quiet","check_in_state"],"title":"QuietClient"},"QuietClientsResponse":{"properties":{"clients":{"items":{"$ref":"#/components/schemas/QuietClient"},"type":"array","title":"Clients"}},"type":"object","required":["clients"],"title":"QuietClientsResponse"},"ReactionResponse":{"properties":{"id":{"type":"string","title":"Id"},"child_id":{"type":"string","title":"Child Id"},"item_type":{"type":"string","title":"Item Type"},"item_id":{"type":"string","title":"Item Id"},"user_id":{"type":"string","title":"User Id"},"reaction":{"type":"string","title":"Reaction"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","child_id","item_type","item_id","user_id","reaction","created_at"],"title":"ReactionResponse"},"ReadMatching":{"properties":{"item_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Item Id"},"child_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Child Id"},"before":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Before"}},"type":"object","title":"ReadMatching","description":"An item the caller opened, or a child up to the moment its card loaded."},"RecipientActionBody":{"properties":{"action":{"type":"string","enum":["dismiss","acted"],"title":"Action"},"child_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Id"}},"type":"object","required":["action"],"title":"RecipientActionBody"},"RecipientActionResponse":{"properties":{"updated":{"type":"boolean","title":"Updated"}},"type":"object","required":["updated"],"title":"RecipientActionResponse"},"RecommendClinicRequest":{"properties":{"clinic_email":{"type":"string","title":"Clinic Email"},"clinic_name":{"type":"string","title":"Clinic Name"},"parent_name":{"type":"string","title":"Parent Name"}},"type":"object","required":["clinic_email","clinic_name","parent_name"],"title":"RecommendClinicRequest"},"RecommendClinicResponse":{"properties":{"success":{"type":"boolean","title":"Success"}},"type":"object","required":["success"],"title":"RecommendClinicResponse"},"RecordReport":{"properties":{"document_id":{"type":"string","title":"Document Id"},"template_name":{"type":"string","title":"Template Name"},"kind":{"type":"string","enum":["session_note","referral"],"title":"Kind"},"organisation_name":{"type":"string","title":"Organisation Name"},"author_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Author Name"},"session_date":{"type":"string","title":"Session Date"},"finalised_at":{"type":"string","title":"Finalised At"},"amended":{"type":"boolean","title":"Amended"}},"type":"object","required":["document_id","template_name","kind","organisation_name","session_date","finalised_at","amended"],"title":"RecordReport"},"RecordVisitRequest":{"properties":{"child_id":{"type":"string","title":"Child Id"}},"type":"object","required":["child_id"],"title":"RecordVisitRequest"},"RecordVisitResponse":{"properties":{"last_visited_at":{"type":"string","title":"Last Visited At"}},"type":"object","required":["last_visited_at"],"title":"RecordVisitResponse"},"RecordsFeedResponse":{"properties":{"entries":{"items":{"oneOf":[{"$ref":"#/components/schemas/DocumentFeedEntry"},{"$ref":"#/components/schemas/MediaFeedEntry"},{"$ref":"#/components/schemas/DraftFeedEntry"},{"$ref":"#/components/schemas/EmailFeedEntry"},{"$ref":"#/components/schemas/OutboxFeedEntry"},{"$ref":"#/components/schemas/ReportFeedEntry"}],"discriminator":{"propertyName":"kind","mapping":{"document":"#/components/schemas/DocumentFeedEntry","draft":"#/components/schemas/DraftFeedEntry","email":"#/components/schemas/EmailFeedEntry","media":"#/components/schemas/MediaFeedEntry","outbox":"#/components/schemas/OutboxFeedEntry","report":"#/components/schemas/ReportFeedEntry"}}},"type":"array","title":"Entries"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["entries","has_more"],"title":"RecordsFeedResponse"},"RefusedCredential":{"properties":{"provider":{"type":"string","title":"Provider"},"provider_name":{"type":"string","title":"Provider Name"}},"type":"object","required":["provider","provider_name"],"title":"RefusedCredential"},"RefusedCredentialsResponse":{"properties":{"refused":{"items":{"$ref":"#/components/schemas/RefusedCredential"},"type":"array","title":"Refused"},"owner":{"anyOf":[{"$ref":"#/components/schemas/ClinicAccessOwner"},{"type":"null"}]}},"type":"object","required":["refused"],"title":"RefusedCredentialsResponse","description":"The portal banner's read (#11926): which PMS keys are being refused, and who to ask."},"RegisterTokenRequest":{"properties":{"token":{"type":"string","title":"Token"},"platform":{"type":"string","title":"Platform"},"placement":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Placement"},"variant":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variant"}},"type":"object","required":["token","platform"],"title":"RegisterTokenRequest"},"RegisterTokenResponse":{"properties":{"id":{"type":"string","title":"Id"},"token":{"type":"string","title":"Token"},"platform":{"type":"string","title":"Platform"},"active":{"type":"boolean","title":"Active"}},"type":"object","required":["id","token","platform","active"],"title":"RegisterTokenResponse"},"ReminderActivationCard":{"properties":{"title":{"type":"string","title":"Title"},"body":{"type":"string","title":"Body"},"cta_label":{"type":"string","title":"Cta Label"}},"type":"object","required":["title","body","cta_label"],"title":"ReminderActivationCard","description":"The daily-reminder activation card. Deliberately NOT a `CardState`.\n\nSame call, and the same reasoning, as `CheckInCard` above. The deck's\n`CardState` is a 48%-wide grid tile padded to exactly four slots: icon row,\na `lora-h4` title, a CTA text label. This card is full-width with a\ndescription paragraph and a primary Button, and it is condition-dismissed\noff `daily_reminders`, a table no other card touches. Forcing it into the\ndeck gives a half-width tile in an awkward fifth slot on a third row.\n\nA typed field also keeps it mobile-only for free: a new deck `card_id`\nauto-renders on web, whereas a field appweb never destructures is inert.\nPush is a mobile capability we own end-to-end; web parity is V2."},"RemovedFlag":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"type":{"type":"string","const":"removed","title":"Type"},"section_id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Section Id"},"block_id":{"anyOf":[{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$"},{"type":"null"}],"title":"Block Id"},"text":{"type":"string","maxLength":2000,"minLength":1,"title":"Text"},"source_quotes":{"items":{"type":"string","maxLength":1000,"minLength":1},"type":"array","title":"Source Quotes"},"reason":{"type":"string","title":"Reason"},"caught_by":{"type":"string","enum":["checks","reviewer"],"title":"Caught By"},"check":{"anyOf":[{"type":"string","enum":["quote_present","quote_substantive","numbers","proper_nouns","repeat_title","negation"]},{"type":"null"}],"title":"Check"},"label":{"anyOf":[{"type":"string","enum":["supported","over_inferred","contradicted","unsupported"]},{"type":"null"}],"title":"Label"},"status":{"type":"string","enum":["open","dismissed","resolved"],"title":"Status","default":"open"}},"additionalProperties":false,"type":"object","required":["id","type","section_id","text","reason","caught_by"],"title":"RemovedFlag","description":"A statement that failed checks or review after its one rewrite."},"ReopenFlag":{"properties":{"op":{"type":"string","const":"reopen_flag","title":"Op"},"flag_id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Flag Id"}},"additionalProperties":false,"type":"object","required":["op","flag_id"],"title":"ReopenFlag","description":"Undo a dismiss, in review: the flag is open again."},"ReportFeedEntry":{"properties":{"kind":{"type":"string","const":"report","title":"Kind","default":"report"},"id":{"type":"string","title":"Id"},"timestamp":{"type":"string","title":"Timestamp"},"report":{"$ref":"#/components/schemas/RecordReport"}},"type":"object","required":["id","timestamp","report"],"title":"ReportFeedEntry","description":"A finalised clinic document. Opt-in (`include=report`): installed mobile\nbuilds don't know the kind, so they must never be sent one."},"ResourceUrls":{"properties":{"id":{"type":"string","title":"Id"},"version":{"type":"integer","title":"Version"},"title":{"type":"string","title":"Title"},"subtitle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subtitle"},"kind":{"type":"string","title":"Kind"},"section":{"type":"string","title":"Section"},"index_url":{"type":"string","title":"Index Url"},"pdf_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pdf Url"},"attachments":{"items":{"$ref":"#/components/schemas/Attachment"},"type":"array","title":"Attachments"}},"type":"object","required":["id","version","title","subtitle","kind","section","index_url","pdf_url","attachments"],"title":"ResourceUrls"},"Restore":{"properties":{"child_id":{"type":"string","format":"uuid","title":"Child Id"},"restore_to":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Restore To"},"expected":{"type":"string","format":"date-time","title":"Expected"}},"type":"object","required":["child_id","restore_to","expected"],"title":"Restore"},"RestoreAll":{"properties":{"items":{"items":{"$ref":"#/components/schemas/Restore"},"type":"array","maxItems":500,"minItems":1,"title":"Items"}},"type":"object","required":["items"],"title":"RestoreAll"},"RestoreAllItem":{"properties":{"restored":{"type":"boolean","title":"Restored"},"child_id":{"type":"string","format":"uuid","title":"Child Id"},"ok":{"type":"boolean","title":"Ok"}},"type":"object","required":["restored","child_id","ok"],"title":"RestoreAllItem"},"RestoreAllResult":{"properties":{"items":{"items":{"$ref":"#/components/schemas/RestoreAllItem"},"type":"array","title":"Items"}},"type":"object","required":["items"],"title":"RestoreAllResult"},"RestoreClaim":{"properties":{"op":{"type":"string","const":"restore_claim","title":"Op"},"flag_id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Flag Id"}},"additionalProperties":false,"type":"object","required":["op","flag_id"],"title":"RestoreClaim"},"RestoreResult":{"properties":{"restored":{"type":"boolean","title":"Restored"}},"type":"object","required":["restored"],"title":"RestoreResult"},"Review":{"properties":{"label":{"type":"string","enum":["supported","over_inferred","contradicted","unsupported"],"title":"Label"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"additionalProperties":false,"type":"object","required":["label"],"title":"Review"},"RevokeRequest":{"properties":{"code":{"type":"string","title":"Code"}},"type":"object","required":["code"],"title":"RevokeRequest"},"RevokeResponse":{"properties":{"success":{"type":"boolean","title":"Success"}},"type":"object","required":["success"],"title":"RevokeResponse"},"SampleList":{"properties":{"samples":{"items":{"$ref":"#/components/schemas/SampleNote"},"type":"array","title":"Samples"}},"type":"object","required":["samples"],"title":"SampleList"},"SampleNote":{"properties":{"id":{"type":"string","title":"Id"},"title":{"type":"string","title":"Title"},"kind":{"type":"string","enum":["session_note","referral"],"title":"Kind"},"text":{"type":"string","title":"Text"}},"type":"object","required":["id","title","kind","text"],"title":"SampleNote"},"SaveEmailRequest":{"properties":{"child_id":{"type":"string","title":"Child Id"},"parent_email":{"type":"string","format":"email","title":"Parent Email"}},"type":"object","required":["child_id","parent_email"],"title":"SaveEmailRequest"},"SaveEmailResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","message"],"title":"SaveEmailResponse"},"SaveVersion":{"properties":{"definition":{"$ref":"#/components/schemas/TemplateDefinition"},"base_version":{"type":"integer","minimum":1.0,"title":"Base Version"},"name":{"anyOf":[{"type":"string","maxLength":120,"minLength":1},{"type":"null"}],"title":"Name"}},"additionalProperties":false,"type":"object","required":["definition","base_version"],"title":"SaveVersion"},"SendCheckInBody":{"properties":{"child_id":{"type":"string","title":"Child Id"},"recipient_user_ids":{"items":{"type":"string"},"type":"array","minItems":1,"title":"Recipient User Ids"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"sent_from":{"type":"string","enum":["clients_page","child_profile","dashboard","clinic_app"],"title":"Sent From"}},"type":"object","required":["child_id","recipient_user_ids","sent_from"],"title":"SendCheckInBody"},"SendCheckInResponse":{"properties":{"check_in_id":{"type":"string","title":"Check In Id"},"state":{"type":"string","title":"State"},"available_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Available At"}},"type":"object","required":["check_in_id","state"],"title":"SendCheckInResponse"},"SendInviteRequest":{"properties":{"invite_code":{"type":"string","title":"Invite Code"},"email":{"type":"string","title":"Email"},"first_name":{"type":"string","title":"First Name"},"message":{"type":"string","title":"Message"},"child_name":{"type":"string","title":"Child Name"}},"type":"object","required":["invite_code","email","first_name","message","child_name"],"title":"SendInviteRequest"},"SendInviteResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","message"],"title":"SendInviteResponse"},"SendWelcomeEmailEntry":{"properties":{"email":{"type":"string","title":"Email"},"name":{"type":"string","title":"Name"},"branch":{"type":"string","title":"Branch"}},"type":"object","required":["email","name","branch"],"title":"SendWelcomeEmailEntry"},"SendWelcomeEmailsRequest":{"properties":{"child_id":{"type":"string","title":"Child Id"},"members":{"items":{"$ref":"#/components/schemas/SendWelcomeEmailEntry"},"type":"array","title":"Members"}},"type":"object","required":["child_id","members"],"title":"SendWelcomeEmailsRequest","description":"Request body for POST /care-team/send-welcome-emails."},"SendWelcomeEmailsResponse":{"properties":{"emails_sent":{"type":"integer","title":"Emails Sent"}},"type":"object","required":["emails_sent"],"title":"SendWelcomeEmailsResponse"},"SetBody":{"properties":{"op":{"type":"string","const":"set_body","title":"Op"},"markdown":{"type":"string","maxLength":50000,"title":"Markdown"}},"additionalProperties":false,"type":"object","required":["op","markdown"],"title":"SetBody"},"SetMedia":{"properties":{"op":{"type":"string","const":"set_media","title":"Op"},"section_id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Section Id"},"document_ids":{"items":{"type":"string","maxLength":36,"minLength":36},"type":"array","maxItems":12,"title":"Document Ids"}},"additionalProperties":false,"type":"object","required":["op","section_id","document_ids"],"title":"SetMedia"},"SettingsLocation":{"properties":{"kind":{"type":"string","const":"settings","title":"Kind","default":"settings"},"page":{"type":"string","enum":["family","connections","notifications","indi","account"],"title":"Page"}},"type":"object","required":["page"],"title":"SettingsLocation","description":"Open one of the parent's settings pages: `family` (children, family members,\ninvites), `connections` (clinicians with access), `notifications`, `indi` (chat\npreferences), `account`."},"SetupCompleteRequest":{"properties":{"organisation_name":{"type":"string","title":"Organisation Name"},"service_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Service Types"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"team_emails":{"items":{"type":"string"},"type":"array","maxItems":50,"title":"Team Emails","default":[]},"team_seat_types":{"additionalProperties":{"type":"string"},"type":"object","title":"Team Seat Types"},"pms":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Pms"},"pms_other":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pms Other"},"attribution":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Attribution"}},"type":"object","required":["organisation_name","first_name","last_name"],"title":"SetupCompleteRequest"},"SetupCompleteResponse":{"properties":{"organisation_id":{"type":"string","title":"Organisation Id"},"clinician_id":{"type":"string","title":"Clinician Id"},"organisation_name":{"type":"string","title":"Organisation Name"},"onboarding_complete":{"type":"boolean","title":"Onboarding Complete"},"invites":{"items":{"$ref":"#/components/schemas/TeamInviteResult"},"type":"array","title":"Invites","default":[]}},"type":"object","required":["organisation_id","clinician_id","organisation_name","onboarding_complete"],"title":"SetupCompleteResponse"},"SetupRequest":{"properties":{"organisation_name":{"type":"string","title":"Organisation Name"},"service_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Service Types"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"attribution":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Attribution"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"}},"type":"object","required":["organisation_name","first_name","last_name"],"title":"SetupRequest"},"SetupResponse":{"properties":{"organisation_id":{"type":"string","title":"Organisation Id"},"clinician_id":{"type":"string","title":"Clinician Id"},"organisation_name":{"type":"string","title":"Organisation Name"}},"type":"object","required":["organisation_id","clinician_id","organisation_name"],"title":"SetupResponse"},"ShareArtefactsRequest":{"properties":{"emails":{"items":{"type":"string","format":"email"},"type":"array","maxItems":10,"title":"Emails"},"artefact_ids":{"items":{"type":"string"},"type":"array","maxItems":20,"title":"Artefact Ids"},"child_id":{"type":"string","maxLength":36,"minLength":36,"title":"Child Id"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","required":["emails","artefact_ids","child_id"],"title":"ShareArtefactsRequest"},"ShareArtefactsResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"queued":{"type":"boolean","title":"Queued"},"job_count":{"type":"integer","title":"Job Count"}},"type":"object","required":["success","queued","job_count"],"title":"ShareArtefactsResponse"},"ShareCode":{"properties":{"id":{"type":"string","title":"Id"},"code":{"type":"string","title":"Code"},"child_id":{"type":"string","title":"Child Id"},"child_name":{"type":"string","title":"Child Name"},"status":{"type":"string","title":"Status"},"expires_at":{"type":"string","title":"Expires At"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","code","child_id","child_name","status","expires_at","created_at"],"title":"ShareCode"},"ShareDocumentsRequest":{"properties":{"emails":{"items":{"type":"string"},"type":"array","title":"Emails"},"document_ids":{"items":{"type":"string"},"type":"array","title":"Document Ids"},"child_id":{"type":"string","title":"Child Id"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","required":["emails","document_ids","child_id"],"title":"ShareDocumentsRequest"},"ShareDocumentsResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"queued":{"type":"boolean","title":"Queued"},"job_count":{"type":"integer","title":"Job Count"}},"type":"object","required":["success","queued","job_count"],"title":"ShareDocumentsResponse"},"Signature":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"clinic":{"type":"string","title":"Clinic"},"signed_on":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signed On"}},"type":"object","required":["clinic"],"title":"Signature","description":"The sign-off every rendering ends with: the signer (the finaliser, or a draft's\nauthor), their discipline on the client's care team, and the clinic. `signed_on` is\nthe signer's local day; null until finalised."},"SignedUploadBody":{"properties":{"child_id":{"type":"string","format":"uuid4","title":"Child Id"},"mime_type":{"type":"string","title":"Mime Type"},"file_size":{"type":"integer","minimum":1.0,"title":"File Size"},"duration_seconds":{"type":"number","title":"Duration Seconds"},"file_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Name"},"poster_mime_type":{"type":"string","title":"Poster Mime Type"},"poster_file_size":{"type":"integer","minimum":1.0,"title":"Poster File Size"}},"type":"object","required":["child_id","mime_type","file_size","duration_seconds","poster_mime_type","poster_file_size"],"title":"SignedUploadBody"},"SignedUploadResponse":{"properties":{"document_id":{"type":"string","title":"Document Id"},"video":{"$ref":"#/components/schemas/SignedUploadSlot"},"poster":{"$ref":"#/components/schemas/SignedUploadSlot"}},"type":"object","required":["document_id","video","poster"],"title":"SignedUploadResponse"},"SignedUploadSlot":{"properties":{"signed_url":{"type":"string","title":"Signed Url"},"storage_path":{"type":"string","title":"Storage Path"},"token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token"}},"type":"object","required":["signed_url","storage_path"],"title":"SignedUploadSlot"},"SignupNotificationRequest":{"properties":{"signup_type":{"type":"string","enum":["parent","family_invite","clinician","village_free"],"title":"Signup Type"}},"type":"object","required":["signup_type"],"title":"SignupNotificationRequest"},"SignupNotificationResponse":{"properties":{"success":{"type":"boolean","title":"Success"}},"type":"object","required":["success"],"title":"SignupNotificationResponse"},"SnoozeResponse":{"properties":{"snoozed_until":{"type":"string","title":"Snoozed Until"},"snooze_hours":{"type":"integer","title":"Snooze Hours"}},"type":"object","required":["snoozed_until","snooze_hours"],"title":"SnoozeResponse"},"SourceNote":{"properties":{"child_note_id":{"type":"string","title":"Child Note Id"},"text":{"type":"string","title":"Text"},"session_date":{"type":"string","title":"Session Date"},"attachment_document_ids":{"items":{"type":"string"},"type":"array","title":"Attachment Document Ids"}},"type":"object","required":["child_note_id","text","session_date"],"title":"SourceNote"},"StartEdit":{"properties":{"op":{"type":"string","const":"start_edit","title":"Op"}},"additionalProperties":false,"type":"object","required":["op"],"title":"StartEdit"},"SubmissionSummary":{"properties":{"id":{"type":"string","title":"Id"},"submitter_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Submitter Name"},"submitter_role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Submitter Role"},"response_data":{"additionalProperties":true,"type":"object","title":"Response Data"},"incident_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Incident At"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","response_data","created_at"],"title":"SubmissionSummary"},"SubmitLetterRequest":{"properties":{"body":{"type":"string","maxLength":1500,"minLength":1,"title":"Body"},"attribution_kind":{"type":"string","enum":["private","public"],"title":"Attribution Kind"}},"type":"object","required":["body","attribution_kind"],"title":"SubmitLetterRequest"},"SubmitLetterResponse":{"properties":{"id":{"type":"string","title":"Id"},"status":{"type":"string","title":"Status"},"find_help":{"type":"boolean","title":"Find Help"}},"type":"object","required":["id","status","find_help"],"title":"SubmitLetterResponse"},"SubmitRequest":{"properties":{"code":{"type":"string","title":"Code"},"response_data":{"additionalProperties":true,"type":"object","title":"Response Data"},"submitter_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Submitter Name"},"submitter_role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Submitter Role"},"incident_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Incident At"}},"type":"object","required":["code","response_data"],"title":"SubmitRequest"},"SubmitResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"submission_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Submission Id"}},"type":"object","required":["success"],"title":"SubmitResponse"},"SubscriptionResponse":{"properties":{"subscription_status":{"type":"string","title":"Subscription Status"},"subscription_store":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subscription Store"},"has_active_subscription":{"type":"boolean","title":"Has Active Subscription"},"subscription_expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subscription Expires At"},"is_billing_contact":{"type":"boolean","title":"Is Billing Contact"},"is_locked_out":{"type":"boolean","title":"Is Locked Out"},"trial_expired":{"type":"boolean","title":"Trial Expired"},"message_count":{"type":"integer","title":"Message Count"},"requires_payment":{"type":"boolean","title":"Requires Payment"},"is_snoozed":{"type":"boolean","title":"Is Snoozed","default":false},"snoozed_until":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Snoozed Until"},"is_clinic_referred":{"type":"boolean","title":"Is Clinic Referred","default":false},"clinic_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clinic Name"},"is_sponsored":{"type":"boolean","title":"Is Sponsored","default":false},"sponsoring_clinic_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sponsoring Clinic Name"},"sponsorship_ends_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sponsorship Ends At"},"has_own_subscription":{"type":"boolean","title":"Has Own Subscription","default":false},"trial_eligible":{"type":"boolean","title":"Trial Eligible"},"jurisdiction_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Jurisdiction Code"},"has_pending_ndis_request":{"type":"boolean","title":"Has Pending Ndis Request","default":false},"plan_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Type"},"prefill_clinician":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prefill Clinician"},"pending_user_action_store":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pending User Action Store"},"pending_user_action_deep_link":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pending User Action Deep Link"},"promo":{"anyOf":[{"$ref":"#/components/schemas/PromoDeal"},{"type":"null"}]}},"type":"object","required":["subscription_status","subscription_store","has_active_subscription","subscription_expires_at","is_billing_contact","is_locked_out","trial_expired","message_count","requires_payment","trial_eligible"],"title":"SubscriptionResponse","description":"Unified subscription status response."},"SupportRequest":{"properties":{"name":{"type":"string","title":"Name"},"email":{"type":"string","title":"Email"},"subject":{"type":"string","title":"Subject"},"message":{"type":"string","title":"Message"},"related_child_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Related Child Id"},"platform":{"type":"string","title":"Platform"},"browser":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Browser"},"device_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Device Type"},"app_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"App Version"},"timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timezone"}},"type":"object","required":["name","email","subject","message","platform"],"title":"SupportRequest","description":"Support form request payload."},"SupportResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","message"],"title":"SupportResponse","description":"Support form response."},"TeamInviteResult":{"properties":{"email":{"type":"string","title":"Email"},"success":{"type":"boolean","title":"Success"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["email","success"],"title":"TeamInviteResult"},"TemplateDefinition":{"properties":{"kind":{"type":"string","enum":["session_note","referral"],"title":"Kind"},"header":{"$ref":"#/components/schemas/TemplateHeader"},"sections":{"items":{"oneOf":[{"$ref":"#/components/schemas/MergeSection"},{"$ref":"#/components/schemas/NarrativeSection"},{"$ref":"#/components/schemas/ListSection"},{"$ref":"#/components/schemas/ClinicianSection"},{"$ref":"#/components/schemas/ImageSection"},{"$ref":"#/components/schemas/MediaSection"}],"discriminator":{"propertyName":"kind","mapping":{"clinician":"#/components/schemas/ClinicianSection","image":"#/components/schemas/ImageSection","list":"#/components/schemas/ListSection","media":"#/components/schemas/MediaSection","merge":"#/components/schemas/MergeSection","narrative":"#/components/schemas/NarrativeSection"}}},"type":"array","maxItems":60,"minItems":1,"title":"Sections"}},"additionalProperties":false,"type":"object","required":["kind","sections"],"title":"TemplateDefinition"},"TemplateDetail":{"properties":{"id":{"type":"string","title":"Id"},"organisation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organisation Id"},"kind":{"type":"string","enum":["session_note","referral"],"title":"Kind"},"name":{"type":"string","title":"Name"},"current_version":{"type":"integer","title":"Current Version"},"is_indi":{"type":"boolean","title":"Is Indi"},"is_org_default":{"type":"boolean","title":"Is Org Default"},"archived_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Archived At"},"updated_at":{"type":"string","title":"Updated At"},"version":{"type":"integer","title":"Version"},"definition":{"$ref":"#/components/schemas/TemplateDefinition"},"versions":{"items":{"$ref":"#/components/schemas/TemplateVersionInfo"},"type":"array","title":"Versions"},"asset_urls":{"additionalProperties":{"type":"string"},"type":"object","title":"Asset Urls"}},"type":"object","required":["id","organisation_id","kind","name","current_version","is_indi","is_org_default","updated_at","version","definition","versions"],"title":"TemplateDetail"},"TemplateHeader":{"properties":{"image":{"anyOf":[{"type":"string","pattern":"^(asset:[a-z0-9][a-z0-9-]{0,62}|org:logo)$"},{"type":"null"}],"title":"Image"},"merge":{"items":{"type":"string","enum":["child.full_name","child.first_name","child.dob","child.age_at_session","child.ndis_number","child.medicare_number","session.date","clinician.full_name","clinician.discipline","clinician.provider_number","clinic.name","clinic.address","clinic.phone"]},"type":"array","maxItems":10,"title":"Merge"}},"additionalProperties":false,"type":"object","title":"TemplateHeader"},"TemplateList":{"properties":{"templates":{"items":{"$ref":"#/components/schemas/TemplateSummary"},"type":"array","title":"Templates"},"can_manage":{"type":"boolean","title":"Can Manage"}},"type":"object","required":["templates","can_manage"],"title":"TemplateList"},"TemplateRef":{"properties":{"id":{"type":"string","title":"Id"},"version":{"type":"integer","title":"Version"},"name":{"type":"string","title":"Name"},"kind":{"type":"string","enum":["session_note","referral"],"title":"Kind"}},"type":"object","required":["id","version","name","kind"],"title":"TemplateRef"},"TemplateSummary":{"properties":{"id":{"type":"string","title":"Id"},"organisation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organisation Id"},"kind":{"type":"string","enum":["session_note","referral"],"title":"Kind"},"name":{"type":"string","title":"Name"},"current_version":{"type":"integer","title":"Current Version"},"is_indi":{"type":"boolean","title":"Is Indi"},"is_org_default":{"type":"boolean","title":"Is Org Default"},"archived_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Archived At"},"updated_at":{"type":"string","title":"Updated At"}},"type":"object","required":["id","organisation_id","kind","name","current_version","is_indi","is_org_default","updated_at"],"title":"TemplateSummary"},"TemplateVersionInfo":{"properties":{"version":{"type":"integer","title":"Version"},"created_at":{"type":"string","title":"Created At"},"created_by_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created By Name"},"imported":{"type":"boolean","title":"Imported","default":false}},"type":"object","required":["version","created_at"],"title":"TemplateVersionInfo"},"ThanksRequest":{"properties":{"reaction":{"type":"string","enum":["thank_you","helped","me_too"],"title":"Reaction"}},"type":"object","required":["reaction"],"title":"ThanksRequest"},"ThanksResponse":{"properties":{"thanked_with":{"type":"string","title":"Thanked With"}},"type":"object","required":["thanked_with"],"title":"ThanksResponse"},"Therapist":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"}},"type":"object","required":["id","name"],"title":"Therapist","description":"Therapist for filter dropdown."},"ThreadReplyItem":{"properties":{"email_id":{"type":"string","title":"Email Id"},"from_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Name"},"from_email":{"type":"string","title":"From Email"},"body_html":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body Html"},"body_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body Text"},"received_at":{"type":"string","title":"Received At"},"attachments":{"items":{"$ref":"#/components/schemas/EmailAttachment-Output"},"type":"array","title":"Attachments","default":[]}},"type":"object","required":["email_id","from_email","received_at"],"title":"ThreadReplyItem"},"TimelineItem":{"properties":{"item_type":{"type":"string","title":"Item Type"},"id":{"type":"string","title":"Id"},"date":{"type":"string","title":"Date"},"is_new":{"type":"boolean","title":"Is New","default":false},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"period":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Period"},"total_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Count"},"notable_event":{"anyOf":[{"$ref":"#/components/schemas/EventData"},{"type":"null"}]},"remaining_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Remaining Count"},"breakdown":{"anyOf":[{"items":{"$ref":"#/components/schemas/CategoryBreakdown"},"type":"array"},{"type":"null"}],"title":"Breakdown"},"collapsed_events":{"anyOf":[{"items":{"$ref":"#/components/schemas/EventData"},"type":"array"},{"type":"null"}],"title":"Collapsed Events"}},"type":"object","required":["item_type","id","date"],"title":"TimelineItem"},"TimelineResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/TimelineItem"},"type":"array","title":"Items"},"pagination":{"$ref":"#/components/schemas/src__api__read__shared_timeline__Pagination"},"available_years":{"items":{"type":"integer"},"type":"array","title":"Available Years"},"month_counts":{"additionalProperties":{"type":"integer"},"type":"object","title":"Month Counts","default":{}}},"type":"object","required":["items","pagination","available_years"],"title":"TimelineResponse"},"TimelineUnreadsResponse":{"properties":{"entries":{"items":{"$ref":"#/components/schemas/UnreadTimelineEntry"},"type":"array","title":"Entries"},"total_unread":{"type":"integer","title":"Total Unread"},"children":{"items":{"$ref":"#/components/schemas/ChildUnreadSummary"},"type":"array","title":"Children"}},"type":"object","required":["entries","total_unread","children"],"title":"TimelineUnreadsResponse"},"TodoEventResponse":{"properties":{"id":{"type":"string","title":"Id"},"event_type":{"type":"string","title":"Event Type"},"actor_id":{"type":"string","title":"Actor Id"},"actor_type":{"type":"string","title":"Actor Type"},"actor_name":{"type":"string","title":"Actor Name"},"changes":{"additionalProperties":true,"type":"object","title":"Changes"},"snapshot":{"additionalProperties":true,"type":"object","title":"Snapshot"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","event_type","actor_id","actor_type","actor_name","changes","snapshot","metadata","created_at"],"title":"TodoEventResponse"},"TodoHistoryResponse":{"properties":{"todo_id":{"type":"string","title":"Todo Id"},"events":{"items":{"$ref":"#/components/schemas/TodoEventResponse"},"type":"array","title":"Events"}},"type":"object","required":["todo_id","events"],"title":"TodoHistoryResponse"},"TodoResponse":{"properties":{"id":{"type":"string","title":"Id"},"child_id":{"type":"string","title":"Child Id"},"title":{"type":"string","title":"Title"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"completed":{"type":"boolean","title":"Completed"},"created_by":{"type":"string","title":"Created By"},"created_by_type":{"type":"string","title":"Created By Type","default":"parent"},"created_by_name":{"type":"string","title":"Created By Name","default":""},"assigned_to":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned To"},"assigned_to_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned To Name"},"due_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Due Date"},"due_option":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Due Option"},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"},"last_modified_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Modified By"},"last_modified_by_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Modified By Type"},"last_modified_by_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Modified By Name"},"is_deleted":{"type":"boolean","title":"Is Deleted","default":false},"deleted_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deleted At"},"deleted_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deleted By"}},"type":"object","required":["id","child_id","title","detail","completed","created_by","assigned_to","due_date","created_at","updated_at","completed_at"],"title":"TodoResponse"},"TodoWithChildResponse":{"properties":{"id":{"type":"string","title":"Id"},"child_id":{"type":"string","title":"Child Id"},"title":{"type":"string","title":"Title"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"completed":{"type":"boolean","title":"Completed"},"created_by":{"type":"string","title":"Created By"},"created_by_type":{"type":"string","title":"Created By Type","default":"parent"},"created_by_name":{"type":"string","title":"Created By Name","default":""},"assigned_to":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned To"},"assigned_to_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned To Name"},"due_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Due Date"},"due_option":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Due Option"},"created_at":{"type":"string","title":"Created At"},"updated_at":{"type":"string","title":"Updated At"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"},"last_modified_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Modified By"},"last_modified_by_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Modified By Type"},"last_modified_by_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Modified By Name"},"is_deleted":{"type":"boolean","title":"Is Deleted","default":false},"deleted_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deleted At"},"deleted_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deleted By"},"child_name":{"type":"string","title":"Child Name"},"child_avatar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Avatar"}},"type":"object","required":["id","child_id","title","detail","completed","created_by","assigned_to","due_date","created_at","updated_at","completed_at","child_name"],"title":"TodoWithChildResponse","description":"Todo response with child name and avatar for aggregated view"},"TodosLocation":{"properties":{"kind":{"type":"string","const":"todos","title":"Kind","default":"todos"},"todo_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Todo Id"},"child_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Id"}},"type":"object","title":"TodosLocation","description":"Open the parent's tasks/todos surface, optionally a specific todo."},"TrackLocation":{"properties":{"kind":{"type":"string","const":"track","title":"Kind","default":"track"},"child_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Id"},"track_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Track Id"}},"type":"object","title":"TrackLocation","description":"Open the child's tracks (a track is a parent-defined log, e.g. a food\ndiary). One track opens on its own screen, so a track is its own kind rather\nthan a `bio` tab; without one it lands on the About tab's tracks grid.\n\nTier 1 (cold-start safe): both platforms expose a route that reaches a\ntrack without prior in-app state - web `?showBio&childId&tab=about&track_id`,\nmobile the standalone `/tracks/track/[trackId]` deep link - so notification\nand email builders may embed it. See docs/specs/2026-05-22-internal-link-schema.md."},"TrackPendingSignupRequest":{"properties":{"qr_code":{"type":"string","maxLength":200,"minLength":1,"title":"Qr Code"},"email":{"type":"string","minLength":1,"title":"Email"},"referral_code":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Referral Code"},"utm_source":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Utm Source"},"utm_medium":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Utm Medium"},"utm_campaign":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Utm Campaign"},"tracking_params":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Tracking Params"}},"type":"object","required":["qr_code","email"],"title":"TrackPendingSignupRequest"},"TrackPendingSignupResponse":{"properties":{"success":{"type":"boolean","title":"Success"}},"type":"object","required":["success"],"title":"TrackPendingSignupResponse"},"TrackScanRequest":{"properties":{"qr_code":{"type":"string","maxLength":200,"minLength":1,"title":"Qr Code"}},"type":"object","required":["qr_code"],"title":"TrackScanRequest"},"TrackScanResponse":{"properties":{"qr_code":{"type":"string","title":"Qr Code"},"scans_count":{"type":"integer","title":"Scans Count"}},"type":"object","required":["qr_code","scans_count"],"title":"TrackScanResponse"},"TranscriptionResponse":{"properties":{"transcript":{"type":"string","title":"Transcript"},"confidence":{"type":"number","title":"Confidence"},"duration":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration"},"model":{"type":"string","title":"Model"}},"type":"object","required":["transcript","confidence","model"],"title":"TranscriptionResponse","description":"Response model for transcription endpoint"},"UnlockDocumentRequest":{"properties":{"password":{"type":"string","maxLength":1024,"minLength":1,"title":"Password"}},"type":"object","required":["password"],"title":"UnlockDocumentRequest"},"UnplacedFlag":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"type":{"type":"string","const":"unplaced","title":"Type"},"text":{"type":"string","maxLength":2000,"minLength":1,"title":"Text"},"status":{"type":"string","enum":["open","dismissed","resolved"],"title":"Status","default":"open"}},"additionalProperties":false,"type":"object","required":["id","type","text"],"title":"UnplacedFlag","description":"Note content that fits no section. Shown as \"Not used from your note\"."},"UnreadCountResponse":{"properties":{"count":{"type":"integer","title":"Count"}},"type":"object","required":["count"],"title":"UnreadCountResponse"},"UnreadEntry":{"properties":{"id":{"type":"string","title":"Id"},"type":{"type":"string","title":"Type"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"date":{"type":"string","title":"Date"},"created_at":{"type":"string","title":"Created At"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"}},"type":"object","required":["id","type","date","created_at"],"title":"UnreadEntry"},"UnreadTimelineEntry":{"properties":{"id":{"type":"string","title":"Id"},"child_id":{"type":"string","title":"Child Id"},"child_name":{"type":"string","title":"Child Name"},"type":{"type":"string","title":"Type"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"date":{"type":"string","title":"Date"},"created_at":{"type":"string","title":"Created At"},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"}},"type":"object","required":["id","child_id","child_name","type","date","created_at"],"title":"UnreadTimelineEntry"},"UnverifiedFlag":{"properties":{"id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Id"},"type":{"type":"string","const":"unverified","title":"Type"},"section_id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Section Id"},"block_id":{"anyOf":[{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$"},{"type":"null"}],"title":"Block Id"},"statement_id":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,39}$","title":"Statement Id"},"reason":{"type":"string","title":"Reason"},"caught_by":{"type":"string","enum":["checks","reviewer"],"title":"Caught By"},"check":{"anyOf":[{"type":"string","enum":["quote_present","quote_substantive","numbers","proper_nouns","repeat_title","negation"]},{"type":"null"}],"title":"Check"},"label":{"anyOf":[{"type":"string","enum":["supported","over_inferred","contradicted","unsupported"]},{"type":"null"}],"title":"Label"},"status":{"type":"string","enum":["open","dismissed","resolved"],"title":"Status","default":"open"}},"additionalProperties":false,"type":"object","required":["id","type","section_id","statement_id","reason","caught_by"],"title":"UnverifiedFlag","description":"A safeguarding or risk statement that still failed checks or review after\nits one rewrite. Unlike `removed`, it stays IN the document, carrying its\nfailing review label: dropping a disclosure is the worse error (D34). A To\ncheck item (\"Check this: <reason>\") that doesn't block Finalise. Dismissing\nkeeps the statement as written; editing or deleting it resolves the flag."},"UpdateCalendarEventRequest":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"},"starts_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Starts At"},"ends_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ends At"},"all_day":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"All Day"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"care_team_member_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Care Team Member Id"},"assignees":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Assignees"},"event_timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Timezone"},"recurrence_rule":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recurrence Rule"}},"type":"object","title":"UpdateCalendarEventRequest"},"UpdateCareTeamMemberRequest":{"properties":{"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"organisation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organisation"},"role_kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Kind"},"role_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Type"},"role_value":{"type":"string","title":"Role Value"},"is_emergency_contact":{"type":"boolean","title":"Is Emergency Contact","default":false},"is_next_of_kin":{"type":"boolean","title":"Is Next Of Kin","default":false}},"type":"object","required":["first_name","last_name","role_value"],"title":"UpdateCareTeamMemberRequest"},"UpdateChatPreferencesRequest":{"properties":{"auto_approve_mutations":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Auto Approve Mutations"}},"type":"object","required":["auto_approve_mutations"],"title":"UpdateChatPreferencesRequest"},"UpdateChatPreferencesResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"chat_preferences":{"additionalProperties":true,"type":"object","title":"Chat Preferences"}},"type":"object","required":["success","chat_preferences"],"title":"UpdateChatPreferencesResponse"},"UpdateChildRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"Name"},"date_of_birth":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date Of Birth"},"age":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Age"},"gender":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gender"},"pronouns":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pronouns"},"diagnosis":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Diagnosis"},"conditions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Conditions"},"diagnosed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Diagnosed"},"stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage"},"initial_concerns":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Initial Concerns"},"ndis_number":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Ndis Number"},"medicare_number":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Medicare Number"},"nhs_number":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Nhs Number"}},"type":"object","title":"UpdateChildRequest","description":"Partial update - all fields optional. At least one required."},"UpdateDailyReminderRequest":{"properties":{"local_time":{"type":"string","title":"Local Time"},"timezone":{"type":"string","title":"Timezone"},"enabled":{"type":"boolean","title":"Enabled","default":true}},"type":"object","required":["local_time","timezone"],"title":"UpdateDailyReminderRequest"},"UpdateDocumentRequest":{"properties":{"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"summary_data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Summary Data"}},"type":"object","title":"UpdateDocumentRequest"},"UpdateFamilyUnitRequest":{"properties":{"name":{"type":"string","title":"Name"}},"type":"object","required":["name"],"title":"UpdateFamilyUnitRequest"},"UpdateFamilyUnitResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["success"],"title":"UpdateFamilyUnitResponse"},"UpdateFormRequest":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"form_schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Form Schema"}},"type":"object","title":"UpdateFormRequest"},"UpdateNotificationPreferencesRequest":{"properties":{"preferences":{"additionalProperties":{"additionalProperties":{"type":"boolean"},"type":"object"},"type":"object","title":"Preferences"}},"type":"object","title":"UpdateNotificationPreferencesRequest","description":"Partial update - `{ category: { channel: bool } }`.\n\nOnly the (category, channel) pairs the caller sends are touched; missing\npairs stay as-is (or fall back to coded defaults if no row exists yet)."},"UpdateNotificationPreferencesResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"preferences":{"additionalProperties":{"additionalProperties":{"type":"boolean"},"type":"object"},"type":"object","title":"Preferences"}},"type":"object","required":["success","preferences"],"title":"UpdateNotificationPreferencesResponse"},"UpdateOrganisationRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"service_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Service Types"}},"type":"object","title":"UpdateOrganisationRequest"},"UpdateSetupPreferencesRequest":{"properties":{"card_id":{"type":"string","title":"Card Id"},"dismissed":{"type":"boolean","title":"Dismissed","default":true}},"type":"object","required":["card_id"],"title":"UpdateSetupPreferencesRequest"},"UpdateSetupPreferencesResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"onboarding_setup_prefs":{"additionalProperties":true,"type":"object","title":"Onboarding Setup Prefs"}},"type":"object","required":["success","onboarding_setup_prefs"],"title":"UpdateSetupPreferencesResponse"},"UpdateTodoRequest":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"assigned_to":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned To"},"due_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Due Date"},"due_option":{"anyOf":[{"type":"string","enum":["asap","this_month","next_3_months"]},{"type":"null"}],"title":"Due Option"},"completed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Completed"}},"type":"object","title":"UpdateTodoRequest"},"UpdateVillageOnboardingRequest":{"properties":{"step":{"type":"integer","maximum":3.0,"minimum":0.0,"title":"Step"}},"type":"object","required":["step"],"title":"UpdateVillageOnboardingRequest"},"UpdateVillageOnboardingResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"onboarding_setup_prefs":{"additionalProperties":true,"type":"object","title":"Onboarding Setup Prefs"}},"type":"object","required":["success","onboarding_setup_prefs"],"title":"UpdateVillageOnboardingResponse"},"UserProfile":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"onboarded":{"type":"boolean","title":"Onboarded"},"chat_onboarded":{"type":"boolean","title":"Chat Onboarded"},"default_child_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Default Child Id"},"account_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Type"},"parent_needs":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Parent Needs"},"onboarding_setup_prefs":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Onboarding Setup Prefs"}},"type":"object","required":["name","first_name","last_name","email","onboarded","chat_onboarded","default_child_id","account_type"],"title":"UserProfile"},"ValidateRequest":{"properties":{"code":{"type":"string","title":"Code"}},"type":"object","required":["code"],"title":"ValidateRequest"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VerifyRequest":{"properties":{"otp":{"type":"string","pattern":"^\\d{6}$","title":"Otp"},"platform":{"type":"string","title":"Platform","default":"webapp"},"acknowledge_subscription":{"type":"boolean","title":"Acknowledge Subscription","default":false}},"type":"object","required":["otp"],"title":"VerifyRequest"},"VoiceNoteAccessResponse":{"properties":{"can_add_notes":{"type":"boolean","title":"Can Add Notes"}},"type":"object","required":["can_add_notes"],"title":"VoiceNoteAccessResponse"},"VoiceNoteResponse":{"properties":{"staged_attachment_id":{"type":"string","title":"Staged Attachment Id"},"staged_filename":{"type":"string","title":"Staged Filename"},"transcription_failed":{"type":"boolean","title":"Transcription Failed","default":false},"transcript":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transcript"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Confidence"},"duration_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duration Seconds"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"}},"type":"object","required":["staged_attachment_id","staged_filename"],"title":"VoiceNoteResponse","description":"What the client needs to reach the review screen, transcript or not.\n\n``staged_attachment_id`` is always present: it is the only handle on the\naudio, and without it a failed transcription orphans the object in the\nbucket and quietly drops the recording from the note that follows."},"WelcomeEmailResponse":{"properties":{"sent":{"type":"boolean","title":"Sent"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["sent"],"title":"WelcomeEmailResponse"},"WorkerChild":{"properties":{"child_id":{"type":"string","title":"Child Id"},"name":{"type":"string","title":"Name"},"avatar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar"},"dob":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dob"},"role_kind":{"type":"string","enum":["support_worker","educator","clinician","family","other"],"title":"Role Kind"},"role_value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Value"}},"type":"object","required":["child_id","name","role_kind"],"title":"WorkerChild"},"WorkerChildrenResponse":{"properties":{"children":{"items":{"$ref":"#/components/schemas/WorkerChild"},"type":"array","title":"Children"}},"type":"object","required":["children"],"title":"WorkerChildrenResponse"},"src__api__artefacts__routes__DownloadUrlResponse":{"properties":{"signed_url":{"type":"string","title":"Signed Url"},"expires_at":{"type":"string","title":"Expires At"},"file_name":{"type":"string","title":"File Name"},"file_type":{"type":"string","title":"File Type"}},"type":"object","required":["signed_url","expires_at","file_name","file_type"],"title":"DownloadUrlResponse"},"src__api__care_team_invite_canonical__routes__InviteRequest":{"properties":{"child_id":{"type":"string","title":"Child Id"},"email":{"type":"string","title":"Email"},"first_name":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Last Name"},"role_value":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Role Value"},"care_team_member_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Care Team Member Id"},"surface":{"anyOf":[{"type":"string","enum":["wizard_panel","connect_sheet","resend"]},{"type":"null"}],"title":"Surface"}},"type":"object","required":["child_id","email"],"title":"InviteRequest","description":"Request body for POST /care-team/invite.\n\nEmail validation is intentionally minimal - a syntactic ``@`` check\nvia a custom ``field_validator``. We deliberately avoid pydantic's\n``EmailStr`` because it rejects test / staging domains (``@test.local``,\n``@example.invalid``) that are valid identity keys in the rest of\nthis codebase. Stricter validation (DNS / disposable-domain checks)\nis not how identity is gated here. The RPC's ``invalid_email``\nP0001 path is reserved for blanks-after-trim."},"src__api__care_team_invite_canonical__routes__InviteResponse":{"properties":{"outcome":{"$ref":"#/components/schemas/InviteOutcome"},"child_care_team_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Care Team Id"},"care_team_member_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Care Team Member Id"},"clinician_access_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Clinician Access Id"},"invite_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Code"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"},"recipient_user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recipient User Id"},"email_status":{"$ref":"#/components/schemas/EmailStatus","default":"not_applicable"},"recipient_display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recipient Display Name"},"recipient_organisation_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recipient Organisation Name"},"converted":{"type":"boolean","title":"Converted","default":false}},"type":"object","required":["outcome"],"title":"InviteResponse","description":"Echoes the RPC payload + a typed outcome enum.\n\n``recipient_display_name`` and ``recipient_organisation_name`` are\npopulated by the route AFTER the RPC succeeds - they are not part of\nthe RPC contract. The route does a best-effort canonical-name lookup\nso the appweb hook can render the toast without re-querying. Field\nsemantics by branch:\n\n- ``connected_clinician`` / clinician ``already_on_team`` - name comes\n  from ``clinician_profiles.first_name + last_name``; org name comes\n  from the invitee's ``clinician_profiles.organisation_id`` (i.e. the\n  invitee's home org, not the caller's).\n- ``connected_worker`` / worker ``already_on_team`` - name comes from\n  ``care_team_members.first_name + last_name``; org name is ``None``\n  (workers aren't tied to an organisation in our model).\n- ``invite_sent`` - name echoes the request body's first+last (joined),\n  falling back to the request email if both halves are blank. Org name\n  is ``None`` (no profile exists yet beyond the pending invite row).\n\nIf the lookup itself errors (DB exception), both fields default to\n``None`` - the invite already succeeded, display names are nice-to-have."},"src__api__chat__get_messages__Pagination":{"properties":{"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"total_items":{"type":"integer","title":"Total Items"},"total_pages":{"type":"integer","title":"Total Pages"},"has_next":{"type":"boolean","title":"Has Next"},"has_prev":{"type":"boolean","title":"Has Prev"}},"type":"object","required":["page","page_size","total_items","total_pages","has_next","has_prev"],"title":"Pagination","description":"Pagination metadata"},"src__api__children__emergency_profile_share__DownloadUrlResponse":{"properties":{"signed_url":{"type":"string","title":"Signed Url"},"expires_at":{"type":"string","title":"Expires At"},"file_name":{"type":"string","title":"File Name"},"file_type":{"type":"string","title":"File Type"}},"type":"object","required":["signed_url","expires_at","file_name","file_type"],"title":"DownloadUrlResponse"},"src__api__children__profile__CreateChildRequest":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"},"date_of_birth":{"type":"string","format":"date","title":"Date Of Birth"},"age":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Age"},"gender":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gender"},"pronouns":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pronouns"},"diagnosis":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Diagnosis"},"conditions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Conditions"},"diagnosed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Diagnosed"},"stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage"},"initial_concerns":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Initial Concerns"},"ndis_number":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Ndis Number"},"medicare_number":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Medicare Number"},"nhs_number":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Nhs Number"},"tracks":{"anyOf":[{"items":{"$ref":"#/components/schemas/ChildTrackSeed"},"type":"array","maxItems":8},{"type":"null"}],"title":"Tracks"}},"type":"object","required":["name","date_of_birth"],"title":"CreateChildRequest","description":"Required: name + date_of_birth. All other fields optional."},"src__api__clinic__routes__AcceptInviteRequest":{"properties":{"token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token"},"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"}},"type":"object","required":["first_name","last_name"],"title":"AcceptInviteRequest"},"src__api__clinic__routes__AcceptInviteResponse":{"properties":{"clinician_id":{"type":"string","title":"Clinician Id"},"organisation_id":{"type":"string","title":"Organisation Id"},"organisation_name":{"type":"string","title":"Organisation Name"}},"type":"object","required":["clinician_id","organisation_id","organisation_name"],"title":"AcceptInviteResponse"},"src__api__clinic__routes__ValidateInviteRequest":{"properties":{"token":{"type":"string","title":"Token"}},"type":"object","required":["token"],"title":"ValidateInviteRequest"},"src__api__clinic__routes__ValidateInviteResponse":{"properties":{"valid":{"type":"boolean","title":"Valid"},"organisation_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organisation Name"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"}},"type":"object","required":["valid"],"title":"ValidateInviteResponse"},"src__api__clinic__team__invite__InviteRequest":{"properties":{"email":{"type":"string","title":"Email"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"role_ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Role Ids"},"send_now":{"type":"boolean","title":"Send Now","default":true},"seat_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Seat Type"}},"type":"object","required":["email"],"title":"InviteRequest"},"src__api__clinic__team__invite__InviteResponse":{"properties":{"clinician_id":{"type":"string","title":"Clinician Id"},"invite_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invite Token"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"},"status":{"type":"string","title":"Status"}},"type":"object","required":["clinician_id","invite_token","expires_at","status"],"title":"InviteResponse"},"src__api__clinician_share__routes__ClaimRequest":{"properties":{"code":{"type":"string","title":"Code"}},"type":"object","required":["code"],"title":"ClaimRequest"},"src__api__clinician_share__routes__ClaimResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"child_id":{"type":"string","title":"Child Id"},"child_name":{"type":"string","title":"Child Name"}},"type":"object","required":["success","child_id","child_name"],"title":"ClaimResponse"},"src__api__clinician_share__routes__ValidateResponse":{"properties":{"valid":{"type":"boolean","title":"Valid"},"child_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Name"},"child_age":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Age"},"parent_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Name"},"family_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Family Name"}},"type":"object","required":["valid"],"title":"ValidateResponse"},"src__api__documents__routes__DownloadUrlResponse":{"properties":{"signed_url":{"type":"string","title":"Signed Url"},"expires_at":{"type":"string","title":"Expires At"},"file_name":{"type":"string","title":"File Name"},"file_type":{"type":"string","title":"File Type"},"processing_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Processing Status"}},"type":"object","required":["signed_url","expires_at","file_name","file_type"],"title":"DownloadUrlResponse"},"src__api__family_unit__routes__AcceptInviteRequest":{"properties":{"token":{"type":"string","minLength":1,"title":"Token"}},"type":"object","required":["token"],"title":"AcceptInviteRequest"},"src__api__family_unit__routes__AcceptInviteResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"profile_updated":{"type":"boolean","title":"Profile Updated"},"family_unit_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Family Unit Id"},"family_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Family Name"},"relationship":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Relationship"},"invited_by_user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invited By User Id"},"invited_by_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invited By Email"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["success","profile_updated"],"title":"AcceptInviteResponse"},"src__api__family_unit__routes__InviteRequest":{"properties":{"email":{"type":"string","title":"Email"},"relationship":{"type":"string","maxLength":500,"minLength":1,"title":"Relationship"},"name":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Name"}},"type":"object","required":["email","relationship"],"title":"InviteRequest"},"src__api__family_unit__routes__InviteResponse":{"properties":{"invite_id":{"type":"string","title":"Invite Id"},"invite_url":{"type":"string","title":"Invite Url"},"expires_at":{"type":"string","title":"Expires At"}},"type":"object","required":["invite_id","invite_url","expires_at"],"title":"InviteResponse"},"src__api__family_unit__routes__ValidateInviteResponse":{"properties":{"valid":{"type":"boolean","title":"Valid"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"relationship":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Relationship"},"family_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Family Name"},"inviter_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Inviter Name"},"expires_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expires At"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["valid"],"title":"ValidateInviteResponse"},"src__api__forms__routes__ValidateResponse":{"properties":{"valid":{"type":"boolean","title":"Valid"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"child_first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child First Name"},"schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Schema"}},"type":"object","required":["valid"],"title":"ValidateResponse"},"src__api__logs__routes__IngestResponse":{"properties":{"accepted":{"type":"integer","title":"Accepted"}},"type":"object","required":["accepted"],"title":"IngestResponse"},"src__api__parent_invite__routes__CreateChildRequest":{"properties":{"first_name":{"type":"string","title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"date_of_birth":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date Of Birth"},"therapist_ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Therapist Ids"},"parent_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Parent Email"}},"type":"object","required":["first_name"],"title":"CreateChildRequest"},"src__api__parent_invite__routes__ValidateInviteRequest":{"properties":{"code":{"type":"string","title":"Code"}},"type":"object","required":["code"],"title":"ValidateInviteRequest"},"src__api__parent_invite__routes__ValidateInviteResponse":{"properties":{"valid":{"type":"boolean","title":"Valid"},"child_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Child Name"},"organisation_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organisation Name"},"organisation_logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Organisation Logo Url"},"therapist_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Therapist Name"}},"type":"object","required":["valid"],"title":"ValidateInviteResponse"},"src__api__paywall_events__routes__IngestResponse":{"properties":{"accepted":{"type":"integer","title":"Accepted"}},"type":"object","required":["accepted"],"title":"IngestResponse","description":"``accepted`` counts events taken off the client's hands, NOT rows written.\n\nIt is deliberately the same for a consented and a non-consented caller: the\nold event table let \"0 rows written\" stand in for both, and losing that would\nturn the response into a consent oracle. Nothing here reports what was\nstored - a journey row has no per-event acceptance to report, and both\nclients are fire-and-forget and never read the body."},"src__api__profile_match__routes__ClaimRequest":{"properties":{"child_id":{"type":"string","title":"Child Id"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"platform":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform"}},"type":"object","required":["child_id"],"title":"ClaimRequest"},"src__api__profile_match__routes__ClaimResponse":{"properties":{"child_id":{"type":"string","title":"Child Id"},"child_name":{"type":"string","title":"Child Name"},"has_more_matches":{"type":"boolean","title":"Has More Matches"}},"type":"object","required":["child_id","child_name","has_more_matches"],"title":"ClaimResponse"},"src__api__read__mobile__latest_conversations__LatestConversationsResponse":{"properties":{"conversations_by_child":{"items":{"$ref":"#/components/schemas/LatestConversation"},"type":"array","title":"Conversations By Child"},"total_conversations":{"type":"integer","title":"Total Conversations"},"pending_profile_matches":{"type":"integer","title":"Pending Profile Matches","default":0}},"type":"object","required":["conversations_by_child","total_conversations"],"title":"LatestConversationsResponse"},"src__api__read__shared_timeline__Pagination":{"properties":{"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"total_items":{"type":"integer","title":"Total Items"},"total_pages":{"type":"integer","title":"Total Pages"},"has_next":{"type":"boolean","title":"Has Next"},"has_prev":{"type":"boolean","title":"Has Prev"}},"type":"object","required":["page","page_size","total_items","total_pages","has_next","has_prev"],"title":"Pagination"},"src__api__read__web__latest_conversations__LatestConversationsResponse":{"properties":{"children":{"items":{"$ref":"#/components/schemas/ChildConversation"},"type":"array","title":"Children"}},"type":"object","required":["children"],"title":"LatestConversationsResponse"}}}}