{"openapi":"3.1.0","info":{"title":"Mavo API","version":"1","description":"Read and write household data with an API key. Authenticate every request with the `x-api-key` header. Keys are scoped to a single family."},"servers":[{"url":"https://mavolife.com"}],"security":[{"apiKey":[]}],"tags":[{"name":"Collections","description":"Create and manage household collections."},{"name":"Entries","description":"Add and edit entries inside a collection."},{"name":"Calendar","description":"Manage family calendar events, external feeds, and share links."},{"name":"People","description":"Manage household people."},{"name":"Notifications","description":"Send notifications and manage notification routines."},{"name":"Webhooks","description":"Manage outbound webhook destinations."},{"name":"Context","description":"Search household context."},{"name":"External info","description":"Look up weather and public web content."}],"paths":{"/api/v1/families/{familySlug}/trackers":{"get":{"operationId":"listCollections","tags":["Collections"],"summary":"List collections","description":"Returns every collection in the family, built-in and custom.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"trackers":[{"key":"meals","name":"Meals","description":"What’s for dinner.","fields":[]}]},"schema":{"properties":{"trackers":{"items":{"properties":{"key":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"fields":{"items":{},"type":"array"}},"type":"object"},"type":"array"}},"type":"object"}}},"description":"The family’s collections."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"operationId":"createCollection","tags":["Collections"],"summary":"Create a collection","description":"Creates a custom collection with the given fields.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTracker"}}},"required":true},"responses":{"201":{"content":{"application/json":{"example":{"tracker":{"key":"chores","name":"Chores","fields":[]}},"schema":{"properties":{"tracker":{"properties":{"key":{"type":"string"},"name":{"type":"string"},"fields":{"items":{},"type":"array"}},"type":"object"}},"type":"object"}}},"description":"The created collection."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/trackers/{collectionKey}":{"patch":{"operationId":"updateCollection","tags":["Collections"],"summary":"Update a collection","description":"Updates a custom collection. Send only the fields you want to change.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Key of the collection, e.g. \"meals\".","in":"path","name":"collectionKey","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTracker"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"tracker":{"key":"chores","name":"Weekly chores"}},"schema":{"properties":{"tracker":{"properties":{"key":{"type":"string"},"name":{"type":"string"}},"type":"object"}},"type":"object"}}},"description":"The updated collection."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}},"delete":{"operationId":"deleteCollection","tags":["Collections"],"summary":"Delete a collection","description":"Deletes a custom collection and its entries. Built-in collections cannot be deleted.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Key of the collection, e.g. \"meals\".","in":"path","name":"collectionKey","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"tracker":{"key":"chores","name":"Weekly chores"}},"schema":{"properties":{"tracker":{"properties":{"key":{"type":"string"},"name":{"type":"string"}},"type":"object"}},"type":"object"}}},"description":"The deleted collection."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/trackers/{collectionKey}/entries":{"get":{"operationId":"listCollectionEntries","tags":["Entries"],"summary":"List entries","description":"Returns entries in a collection, optionally narrowed by text, status, or result count.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Key of the collection, e.g. \"meals\".","in":"path","name":"collectionKey","required":true,"schema":{"type":"string"}},{"description":"Case-insensitive text to match against entry titles and data.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Only return entries with this status.","in":"query","name":"status","required":false,"schema":{"enum":["active","done","archived"],"type":"string"}},{"description":"Maximum number of matching entries to return.","in":"query","name":"limit","required":false,"schema":{"default":20,"maximum":50,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"example":{"entries":[{"id":"ent_123","title":"Taco night","data":{"day":"2026-06-09","status":"Planned"}}]},"schema":{"properties":{"entries":{"items":{"properties":{"id":{"type":"string"},"title":{"type":"string"},"data":{"properties":{"day":{"type":"string"},"status":{"type":"string"}},"type":"object"}},"type":"object"},"type":"array"}},"type":"object"}}},"description":"The collection’s entries."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"operationId":"createCollectionEntry","tags":["Entries"],"summary":"Create an entry","description":"Adds an entry to a collection. `title` is the entry’s display label; collection-specific fields go in `data`.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Key of the collection, e.g. \"meals\".","in":"path","name":"collectionKey","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTrackerEntry"}}},"required":true},"responses":{"201":{"content":{"application/json":{"example":{"entry":{"id":"ent_123","title":"Taco night","data":{"day":"2026-06-09","status":"Planned"}}},"schema":{"properties":{"entry":{"properties":{"id":{"type":"string"},"title":{"type":"string"},"data":{"properties":{"day":{"type":"string"},"status":{"type":"string"}},"type":"object"}},"type":"object"}},"type":"object"}}},"description":"The created entry."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/trackers/{collectionKey}/entries/{entryId}":{"patch":{"operationId":"updateCollectionEntry","tags":["Entries"],"summary":"Update an entry","description":"Updates an entry. Send only the fields you want to change. `title` renames the entry; collection-specific fields go in `data`.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Key of the collection, e.g. \"meals\".","in":"path","name":"collectionKey","required":true,"schema":{"type":"string"}},{"description":"Identifier of the entry within the collection.","in":"path","name":"entryId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTrackerEntry"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"entry":{"id":"ent_123","title":"Taco night","status":"done"}},"schema":{"properties":{"entry":{"properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"}},"type":"object"}},"type":"object"}}},"description":"The updated entry."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}},"delete":{"operationId":"deleteCollectionEntry","tags":["Entries"],"summary":"Delete an entry","description":"Removes an entry from a collection by id. No request body is needed; the deleted entry is returned for confirmation.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Key of the collection, e.g. \"meals\".","in":"path","name":"collectionKey","required":true,"schema":{"type":"string"}},{"description":"Identifier of the entry within the collection.","in":"path","name":"entryId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"entry":{"id":"ent_123","title":"Taco night"}},"schema":{"properties":{"entry":{"properties":{"id":{"type":"string"},"title":{"type":"string"}},"type":"object"}},"type":"object"}}},"description":"The deleted entry."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/trackers/{collectionKey}/entries/batch":{"post":{"operationId":"createCollectionEntries","tags":["Entries"],"summary":"Create entries","description":"Adds multiple entries to a collection in one request.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Key of the collection, e.g. \"meals\".","in":"path","name":"collectionKey","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCollectionItems"}}},"required":true},"responses":{"201":{"content":{"application/json":{"example":{"count":2,"entries":[{"id":"ent_123","title":"Taco night"}],"ok":true},"schema":{"properties":{"count":{"type":"integer"},"entries":{"items":{"properties":{"id":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"ok":{"type":"boolean"}},"type":"object"}}},"description":"The created entries."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}},"patch":{"operationId":"updateCollectionEntries","tags":["Entries"],"summary":"Update entries","description":"Updates multiple entries in a collection in one request.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Key of the collection, e.g. \"meals\".","in":"path","name":"collectionKey","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCollectionItems"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"count":2,"entries":[{"id":"ent_123","title":"Taco night","status":"done"}],"ok":true},"schema":{"properties":{"count":{"type":"integer"},"entries":{"items":{"properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"}},"type":"object"},"type":"array"},"ok":{"type":"boolean"}},"type":"object"}}},"description":"The updated entries."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}},"delete":{"operationId":"deleteCollectionEntries","tags":["Entries"],"summary":"Delete entries","description":"Deletes multiple entries from a collection in one request. Pass entry ids only; titles are returned in the response for confirmation.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Key of the collection, e.g. \"meals\".","in":"path","name":"collectionKey","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteCollectionItems"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"count":2,"entries":[{"id":"ent_123","title":"Taco night"}],"ok":true},"schema":{"properties":{"count":{"type":"integer"},"entries":{"items":{"properties":{"id":{"type":"string"},"title":{"type":"string"}},"type":"object"},"type":"array"},"ok":{"type":"boolean"}},"type":"object"}}},"description":"The deleted entries."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/calendar/events":{"get":{"operationId":"listCalendarEvents","tags":["Calendar"],"summary":"List calendar events","description":"Returns family calendar events, optionally narrowed by date window, text, status, or result count.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Only include events on or after this date (YYYY-MM-DD).","in":"query","name":"from","required":false,"schema":{"format":"date","type":"string"}},{"description":"Only include events on or before this date (YYYY-MM-DD).","in":"query","name":"to","required":false,"schema":{"format":"date","type":"string"}},{"description":"Case-insensitive text to match against event titles and data.","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Only return events with this status.","in":"query","name":"status","required":false,"schema":{"enum":["active","done","archived"],"type":"string"}},{"description":"Maximum number of matching events to return.","in":"query","name":"limit","required":false,"schema":{"default":20,"maximum":50,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"example":{"events":[{"id":"ent_123","title":"Soccer practice","data":{"date":"2026-07-01","time":"17:00"}}],"ok":true},"schema":{"properties":{"events":{"items":{"properties":{"id":{"type":"string"},"title":{"type":"string"},"data":{"properties":{"date":{"type":"string"},"time":{"type":"string"}},"type":"object"}},"type":"object"},"type":"array"},"ok":{"type":"boolean"}},"type":"object"}}},"description":"The matching calendar events."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"operationId":"createCalendarEvent","tags":["Calendar"],"summary":"Create calendar event","description":"Adds an event to the family calendar.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddCalendarEvent"}}},"required":true},"responses":{"201":{"content":{"application/json":{"example":{"entryId":"ent_123","ok":true,"title":"Soccer practice"},"schema":{"properties":{"entryId":{"type":"string"},"ok":{"type":"boolean"},"title":{"type":"string"}},"type":"object"}}},"description":"The created calendar event."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/calendar/events/{eventId}":{"patch":{"operationId":"updateCalendarEvent","tags":["Calendar"],"summary":"Update calendar event","description":"Updates one family calendar event.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Identifier of the calendar event.","in":"path","name":"eventId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCalendarEvent"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"event":{"id":"ent_123","title":"Soccer practice","data":{"date":"2026-07-01"}},"ok":true},"schema":{"properties":{"event":{"properties":{"id":{"type":"string"},"title":{"type":"string"},"data":{"properties":{"date":{"type":"string"}},"type":"object"}},"type":"object"},"ok":{"type":"boolean"}},"type":"object"}}},"description":"The updated calendar event."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}},"delete":{"operationId":"deleteCalendarEvent","tags":["Calendar"],"summary":"Delete calendar event","description":"Deletes a calendar event series by default, or one occurrence when both occurrence query parameters are provided.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Identifier of the calendar event.","in":"path","name":"eventId","required":true,"schema":{"type":"string"}},{"description":"Use `occurrence` to delete one date in a repeating series. Defaults to the entire series.","in":"query","name":"editScope","required":false,"schema":{"enum":["occurrence","series"],"type":"string"}},{"description":"Original occurrence date (YYYY-MM-DD). Required when `editScope=occurrence`.","in":"query","name":"occurrenceDate","required":false,"schema":{"format":"date","type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"event":{"id":"ent_123","title":"Soccer practice"},"ok":true},"schema":{"properties":{"event":{"properties":{"id":{"type":"string"},"title":{"type":"string"}},"type":"object"},"ok":{"type":"boolean"}},"type":"object"}}},"description":"The deleted calendar event."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/context":{"get":{"operationId":"searchHouseholdContext","tags":["Context"],"summary":"Search household context","description":"Searches household collections, members, and upcoming calendar items. Use the optional `query` query parameter to narrow results.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Text to match across household collections, people, and calendar items.","in":"query","name":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"ok":true,"query":"soccer","results":[]},"schema":{"properties":{"ok":{"type":"boolean"},"query":{"type":"string"},"results":{"items":{},"type":"array"}},"type":"object"}}},"description":"The household context summary."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/families/{familySlug}/notifications":{"get":{"operationId":"listRecentNotifications","tags":["Notifications"],"summary":"List recent notifications","description":"Returns recent household notifications. Supports optional `sinceMinutes` and `triggerId` query parameters.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Only include notifications newer than this many minutes.","in":"query","name":"sinceMinutes","required":false,"schema":{"maximum":43200,"minimum":1,"type":"integer"}},{"description":"Only include notifications associated with this exact trigger id returned by Mavo.","in":"query","name":"triggerId","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"notifications":[{"title":"Practice moved","body":"Field changed."}]},"schema":{"properties":{"notifications":{"items":{"properties":{"title":{"type":"string"},"body":{"type":"string"}},"type":"object"},"type":"array"}},"type":"object"}}},"description":"Recent notifications."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"operationId":"sendNotification","tags":["Notifications"],"summary":"Send notification","description":"Sends a household notification.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendNotification"}}},"required":true},"responses":{"201":{"content":{"application/json":{"example":{"delivered":1,"ok":true,"suppressed":0},"schema":{"properties":{"delivered":{"type":"integer"},"ok":{"type":"boolean"},"suppressed":{"type":"integer"}},"type":"object"}}},"description":"The delivery result."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/checks":{"post":{"operationId":"scheduleEventCheck","tags":["Notifications"],"summary":"Schedule event check","description":"Schedules a background check ahead of a calendar event.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleCheck"}}},"required":true},"responses":{"201":{"content":{"application/json":{"example":{"eventId":"ent_123","ok":true,"triggerId":"trg_123"},"schema":{"properties":{"eventId":{"type":"string"},"ok":{"type":"boolean"},"triggerId":{"type":"string"}},"type":"object"}}},"description":"The scheduled check."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/people":{"get":{"operationId":"listPeople","tags":["People"],"summary":"List people","description":"Returns household people.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"ok":true,"people":[{"id":"person_123","name":"Maya","role":"child"}]},"schema":{"properties":{"ok":{"type":"boolean"},"people":{"items":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string"}},"type":"object"},"type":"array"}},"type":"object"}}},"description":"The household people."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"operationId":"createPerson","tags":["People"],"summary":"Create person","description":"Adds a household person profile.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateHouseholdPerson"}}},"required":true},"responses":{"201":{"content":{"application/json":{"example":{"ok":true,"person":{"id":"person_123","displayName":"Maya"}},"schema":{"properties":{"ok":{"type":"boolean"},"person":{"properties":{"id":{"type":"string"},"displayName":{"type":"string"}},"type":"object"}},"type":"object"}}},"description":"The created person."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/people/{personId}":{"patch":{"operationId":"updatePerson","tags":["People"],"summary":"Update person","description":"Updates a household person profile.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Identifier of the household person.","in":"path","name":"personId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateHouseholdPerson"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"ok":true,"person":{"id":"person_123","displayName":"Maya"}},"schema":{"properties":{"ok":{"type":"boolean"},"person":{"properties":{"id":{"type":"string"},"displayName":{"type":"string"}},"type":"object"}},"type":"object"}}},"description":"The updated person."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}},"delete":{"operationId":"deletePerson","tags":["People"],"summary":"Delete person","description":"Removes a household person profile from active household views.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Identifier of the household person.","in":"path","name":"personId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"ok":true,"personId":"person_123"},"schema":{"properties":{"ok":{"type":"boolean"},"personId":{"type":"string"}},"type":"object"}}},"description":"The deleted person."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/webhook-destinations":{"get":{"operationId":"listWebhookDestinations","tags":["Webhooks"],"summary":"List webhook destinations","description":"Returns outbound webhook destinations, delivery history, available events, and usage.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"destinations":[],"events":["tracker.entry.created"],"ok":true},"schema":{"properties":{"destinations":{"items":{},"type":"array"},"events":{"items":{"type":"string"},"type":"array"},"ok":{"type":"boolean"}},"type":"object"}}},"description":"The webhook destinations."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"operationId":"createWebhookDestination","tags":["Webhooks"],"summary":"Create webhook destination","description":"Creates an outbound webhook destination. The signing secret is returned once.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookDestination"}}},"required":true},"responses":{"201":{"content":{"application/json":{"example":{"destination":{"id":"whd_123","name":"Zapier","url":"https://example.com/webhook"},"ok":true,"signingSecret":"whsec_..."},"schema":{"properties":{"destination":{"properties":{"id":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"ok":{"type":"boolean"},"signingSecret":{"type":"string"}},"type":"object"}}},"description":"The created webhook destination."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/webhook-destinations/{destinationId}":{"patch":{"operationId":"updateWebhookDestination","tags":["Webhooks"],"summary":"Update webhook destination","description":"Updates an outbound webhook destination or rotates its signing secret.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Identifier of the webhook destination.","in":"path","name":"destinationId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookDestination"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"destination":{"id":"whd_123","name":"Zapier"},"ok":true},"schema":{"properties":{"destination":{"properties":{"id":{"type":"string"},"name":{"type":"string"}},"type":"object"},"ok":{"type":"boolean"}},"type":"object"}}},"description":"The updated webhook destination."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}},"delete":{"operationId":"deleteWebhookDestination","tags":["Webhooks"],"summary":"Delete webhook destination","description":"Deletes an outbound webhook destination.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Identifier of the webhook destination.","in":"path","name":"destinationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"ok":true},"schema":{"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"The deletion result."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/webhook-destinations/{destinationId}/test":{"post":{"operationId":"testWebhookDestination","tags":["Webhooks"],"summary":"Test webhook destination","description":"Sends a test delivery to a webhook destination.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Identifier of the webhook destination.","in":"path","name":"destinationId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"ok":true},"schema":{"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"The test delivery result."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/notification-preferences":{"get":{"operationId":"getNotificationPreferences","tags":["Notifications"],"summary":"Get notification preferences","description":"Returns household notification preferences.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"ok":true,"preferences":{}},"schema":{"properties":{"ok":{"type":"boolean"},"preferences":{"properties":{},"type":"object"}},"type":"object"}}},"description":"The notification preferences."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"operationId":"setNotificationPreference","tags":["Notifications"],"summary":"Set notification preference","description":"Updates one household notification preference.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetNotificationPreference"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"ok":true,"preferences":{}},"schema":{"properties":{"ok":{"type":"boolean"},"preferences":{"properties":{},"type":"object"}},"type":"object"}}},"description":"The updated notification preferences."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/notification-routines":{"get":{"operationId":"listNotificationRoutines","tags":["Notifications"],"summary":"List notification routines","description":"Returns household notification routines.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"ok":true,"routines":[]},"schema":{"properties":{"ok":{"type":"boolean"},"routines":{"items":{},"type":"array"}},"type":"object"}}},"description":"The notification routines."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"operationId":"createNotificationRoutine","tags":["Notifications"],"summary":"Create notification routine","description":"Creates a household notification routine.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationRoutine"}}},"required":true},"responses":{"201":{"content":{"application/json":{"example":{"ok":true,"routine":{"id":"trg_123"}},"schema":{"properties":{"ok":{"type":"boolean"},"routine":{"properties":{"id":{"type":"string"}},"type":"object"}},"type":"object"}}},"description":"The notification routine."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/notification-routines/{triggerId}":{"patch":{"operationId":"updateNotificationRoutine","tags":["Notifications"],"summary":"Update notification routine","description":"Updates a household notification routine.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Identifier of the notification routine.","in":"path","name":"triggerId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationRoutine"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"ok":true,"routine":{"id":"trg_123"}},"schema":{"properties":{"ok":{"type":"boolean"},"routine":{"properties":{"id":{"type":"string"}},"type":"object"}},"type":"object"}}},"description":"The notification routine."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}},"delete":{"operationId":"deleteNotificationRoutine","tags":["Notifications"],"summary":"Delete notification routine","description":"Deletes a household notification routine.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Identifier of the notification routine.","in":"path","name":"triggerId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"ok":true},"schema":{"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"The deletion result."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/weather":{"get":{"operationId":"getWeather","tags":["External info"],"summary":"Check weather","description":"Looks up weather for a location. Send `location`, and optionally `date` and `time`, as query parameters.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Place to look up, such as a venue, city, or postal code.","in":"query","name":"location","required":true,"schema":{"minLength":1,"type":"string"}},{"description":"Date to focus on (YYYY-MM-DD). Defaults to the soonest available day.","in":"query","name":"date","required":false,"schema":{"format":"date","type":"string"}},{"description":"Local time to focus on (HH:mm).","in":"query","name":"time","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"ok":true},"schema":{"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"The weather lookup result."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/families/{familySlug}/web/search":{"get":{"operationId":"searchWeb","tags":["External info"],"summary":"Search web","description":"Searches the public web. Send `query`, and optionally `numResults`, as query parameters.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"What to search the public web for.","in":"query","name":"query","required":true,"schema":{"minLength":1,"type":"string"}},{"description":"Number of search results to return.","in":"query","name":"numResults","required":false,"schema":{"default":5,"maximum":10,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"example":{"ok":true,"results":[{"title":"Example","url":"https://example.com"}]},"schema":{"properties":{"ok":{"type":"boolean"},"results":{"items":{"properties":{"title":{"type":"string"},"url":{"type":"string"}},"type":"object"},"type":"array"}},"type":"object"}}},"description":"The web search results."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/families/{familySlug}/web/page":{"get":{"operationId":"readWebPage","tags":["External info"],"summary":"Read web page","description":"Reads the main text of a public web page. Send `url` as a query parameter.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Public HTTP or HTTPS URL to read.","in":"query","name":"url","required":true,"schema":{"format":"uri","type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"ok":true,"text":"Readable page content...","url":"https://example.com"},"schema":{"properties":{"ok":{"type":"boolean"},"text":{"type":"string"},"url":{"type":"string"}},"type":"object"}}},"description":"The readable page content."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/families/{familySlug}/calendar/external":{"get":{"operationId":"listExternalCalendars","tags":["Calendar"],"summary":"List external calendars","description":"Returns linked external calendar feeds.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"feeds":[],"ok":true},"schema":{"properties":{"feeds":{"items":{},"type":"array"},"ok":{"type":"boolean"}},"type":"object"}}},"description":"The external calendars."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"operationId":"createExternalCalendar","tags":["Calendar"],"summary":"Create external calendar","description":"Links an external ICS calendar feed and syncs its events.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarExternalFeed"}}},"required":true},"responses":{"201":{"content":{"application/json":{"example":{"eventCount":12,"ok":true},"schema":{"properties":{"eventCount":{"type":"integer"},"ok":{"type":"boolean"}},"type":"object"}}},"description":"The linked external calendar."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/calendar/external/probe":{"post":{"operationId":"probeExternalCalendar","tags":["Calendar"],"summary":"Probe external calendar","description":"Checks whether an external ICS calendar URL can be read.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadWebPage"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"ok":true},"schema":{"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"The probe result."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/calendar/external/{sourceId}":{"patch":{"operationId":"updateExternalCalendar","tags":["Calendar"],"summary":"Update external calendar","description":"Updates notes about a linked external calendar feed.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Identifier of the external calendar feed.","in":"path","name":"sourceId","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateExternalCalendar"}}},"required":true},"responses":{"200":{"content":{"application/json":{"example":{"ok":true},"schema":{"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"The update result."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}},"delete":{"operationId":"deleteExternalCalendar","tags":["Calendar"],"summary":"Delete external calendar","description":"Removes a linked external calendar feed and its synced calendar.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Identifier of the external calendar feed.","in":"path","name":"sourceId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"ok":true},"schema":{"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"The deletion result."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/calendar/external/{sourceId}/refresh":{"post":{"operationId":"refreshExternalCalendar","tags":["Calendar"],"summary":"Refresh external calendar","description":"Requests a refresh for a linked external calendar feed.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Identifier of the external calendar feed.","in":"path","name":"sourceId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"ok":true},"schema":{"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"The refresh request result."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/calendar/shares":{"get":{"operationId":"listCalendarShares","tags":["Calendar"],"summary":"List calendar shares","description":"Returns household calendar share links.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"ok":true,"shares":[]},"schema":{"properties":{"ok":{"type":"boolean"},"shares":{"items":{},"type":"array"}},"type":"object"}}},"description":"The calendar shares."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"operationId":"createCalendarShare","tags":["Calendar"],"summary":"Create calendar share","description":"Creates a calendar share link. The plaintext share token is returned once.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarShare"}}},"required":true},"responses":{"201":{"content":{"application/json":{"example":{"ok":true,"share":{"id":"share_123","name":"Soccer calendar"},"token":"share-token"},"schema":{"properties":{"ok":{"type":"boolean"},"share":{"properties":{"id":{"type":"string"},"name":{"type":"string"}},"type":"object"},"token":{"type":"string"}},"type":"object"}}},"description":"The calendar share."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/api/v1/families/{familySlug}/calendar/shares/{shareId}":{"delete":{"operationId":"deleteCalendarShare","tags":["Calendar"],"summary":"Revoke calendar share","description":"Revokes a calendar share link.","parameters":[{"description":"Slug of the family (household) to act on.","in":"path","name":"familySlug","required":true,"schema":{"type":"string"}},{"description":"Identifier of the calendar share link.","in":"path","name":"shareId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"example":{"ok":true},"schema":{"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"The revocation result."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}}},"components":{"responses":{"BadRequest":{"content":{"application/json":{"example":{"error":"Invalid request."},"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"The request did not match the API contract."},"Unauthorized":{"content":{"application/json":{"example":{"error":"Authentication required."},"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"The API key is missing or invalid."},"Forbidden":{"content":{"application/json":{"example":{"error":"This API key does not have access."},"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"The API key cannot perform this operation."},"NotFound":{"content":{"application/json":{"example":{"error":"Resource not found."},"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"The requested family resource was not found."},"Conflict":{"content":{"application/json":{"example":{"error":"The requested change conflicts with an existing resource."},"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"The requested change conflicts with the current resource state."}},"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"x-api-key","description":"A family-scoped API key. Generate one in Settings → Developer."}},"schemas":{"ApiError":{"type":"object","properties":{"error":{"type":"string"},"issues":{"type":"array","items":{"type":"object","properties":{},"additionalProperties":{}}}},"required":["error"]},"CreateTracker":{"type":"object","properties":{"category":{"type":"string","const":"calendar"},"color":{"type":"string","enum":["sage","blue","clay","plum","gold"]},"description":{"type":"string"},"fields":{"default":[],"type":"array","items":{"type":"object","properties":{"key":{"type":"string","minLength":1},"label":{"type":"string","minLength":1},"options":{"type":"array","items":{"type":"string"}},"type":{"default":"text","type":"string","enum":["date","number","person","select","text","textarea"]}},"required":["key","label"]}},"name":{"type":"string","minLength":1}},"required":["name"]},"UpdateTracker":{"type":"object","properties":{"color":{"type":"string","enum":["sage","blue","clay","plum","gold"]},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"fields":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","minLength":1},"label":{"type":"string","minLength":1},"options":{"type":"array","items":{"type":"string"}},"type":{"default":"text","type":"string","enum":["date","number","person","select","text","textarea"]}},"required":["key","label"]}},"name":{"type":"string","minLength":1}}},"CreateTrackerEntry":{"type":"object","properties":{"data":{"default":{},"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Collection-specific fields for this entry. Only fields defined by the collection are saved."},"title":{"type":"string","minLength":1,"description":"Human-readable entry label. This is stored separately from collection-specific data fields and is returned in entry responses."}},"required":["title"]},"UpdateTrackerEntry":{"type":"object","properties":{"data":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Collection-specific fields for this entry. Only fields defined by the collection are saved."},"status":{"type":"string","enum":["active","archived","done"]},"title":{"type":"string","minLength":1,"description":"Human-readable entry label. This is stored separately from collection-specific data fields and is returned in entry responses."}}},"CreateCollectionItems":{"type":"object","properties":{"items":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"object","properties":{"data":{"default":{},"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"title":{"type":"string","minLength":1}},"required":["title"]}}},"required":["items"]},"UpdateCollectionItems":{"type":"object","properties":{"items":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"object","properties":{"data":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"entryId":{"type":"string","minLength":1},"status":{"type":"string","enum":["active","done","archived"]},"title":{"type":"string","minLength":1}},"required":["entryId"]}}},"required":["items"]},"DeleteCollectionItems":{"type":"object","properties":{"entryIds":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"string","minLength":1}}},"required":["entryIds"]},"AddCalendarEvent":{"type":"object","properties":{"allDay":{"type":"boolean"},"assignee":{"type":"string"},"attendance":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","enum":["going","maybe","out"]}},"calendarKey":{"type":"string"},"data":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"Required event date in YYYY-MM-DD format."},"durationMinutes":{"type":"integer","minimum":15,"maximum":1440},"endDate":{"type":"string","description":"Inclusive ISO end date for multi-day events."},"endTime":{"type":"string","description":"Local event end time when known."},"note":{"type":"string"},"ownerPersonId":{"type":"string"},"responsiblePersonIds":{"type":"array","items":{"type":"string","minLength":1}},"reminders":{"type":"array","items":{"type":"object","properties":{"audience":{"default":"household","type":"string","enum":["household","responsible","going","people"]},"channels":{"default":["in_app"],"type":"array","items":{"type":"string","enum":["in_app","email","push","sms"]}},"mode":{"default":"plain","type":"string","enum":["plain","mavo"]},"offsetMinutes":{"type":"integer","minimum":0,"maximum":20160},"recipientPersonIds":{"default":[],"type":"array","items":{"type":"string","minLength":1}}},"required":["offsetMinutes"]}},"repeatDays":{"type":"array","items":{"type":"integer","minimum":0,"maximum":6}},"repeatFrequency":{"type":"string","enum":["none","daily","weekdays","weekends","weekly","custom"]},"repeatInterval":{"type":"integer","minimum":1,"maximum":52},"time":{"type":"string"},"title":{"type":"string","minLength":1},"travelPlan":{"anyOf":[{"type":"object","properties":{"arriveEarlyMinutes":{"default":0,"type":"integer","minimum":0,"maximum":720},"baseTravelMinutes":{"type":"integer","minimum":1,"maximum":1440},"origin":{"type":"string","minLength":1,"maxLength":240}},"required":["baseTravelMinutes","origin"]},{"type":"null"}]},"where":{"type":"string"}},"required":["date","title"]},"UpdateCalendarEvent":{"type":"object","properties":{"allDay":{"type":"boolean"},"assignee":{"type":"string"},"attendance":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","enum":["going","maybe","out"]}},"calendarKey":{"type":"string"},"data":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"date":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"Required event date in YYYY-MM-DD format."},"durationMinutes":{"type":"integer","minimum":15,"maximum":1440},"endDate":{"type":"string","description":"Inclusive ISO end date for multi-day events."},"endTime":{"type":"string","description":"Local event end time when known."},"note":{"type":"string"},"ownerPersonId":{"type":"string"},"responsiblePersonIds":{"type":"array","items":{"type":"string","minLength":1}},"reminders":{"type":"array","items":{"type":"object","properties":{"audience":{"default":"household","type":"string","enum":["household","responsible","going","people"]},"channels":{"default":["in_app"],"type":"array","items":{"type":"string","enum":["in_app","email","push","sms"]}},"mode":{"default":"plain","type":"string","enum":["plain","mavo"]},"offsetMinutes":{"type":"integer","minimum":0,"maximum":20160},"recipientPersonIds":{"default":[],"type":"array","items":{"type":"string","minLength":1}}},"required":["offsetMinutes"]}},"repeatDays":{"type":"array","items":{"type":"integer","minimum":0,"maximum":6}},"repeatFrequency":{"type":"string","enum":["none","daily","weekdays","weekends","weekly","custom"]},"repeatInterval":{"type":"integer","minimum":1,"maximum":52},"time":{"type":"string"},"title":{"type":"string","minLength":1},"travelPlan":{"anyOf":[{"type":"object","properties":{"arriveEarlyMinutes":{"default":0,"type":"integer","minimum":0,"maximum":720},"baseTravelMinutes":{"type":"integer","minimum":1,"maximum":1440},"origin":{"type":"string","minLength":1,"maxLength":240}},"required":["baseTravelMinutes","origin"]},{"type":"null"}]},"where":{"type":"string"},"clearTravelPlan":{"type":"boolean"},"editScope":{"type":"string","enum":["occurrence","series"]},"occurrenceDate":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},"status":{"type":"string","enum":["active","done","archived"]}}},"SendNotification":{"type":"object","properties":{"body":{"default":"","type":"string"},"channels":{"type":"array","items":{"type":"string","enum":["in_app","email","push","sms"]}},"title":{"type":"string","minLength":1},"triggerId":{"description":"Exact trigger id returned by Mavo. Omit this instead of inventing a label.","type":"string"}},"required":["title"]},"ScheduleCheck":{"type":"object","properties":{"channels":{"type":"array","items":{"type":"string","enum":["in_app","email","push","sms"]}},"eventId":{"type":"string","minLength":1},"leadHours":{"type":"number","minimum":0.5,"maximum":336},"task":{"type":"string","minLength":1}},"required":["eventId","leadHours","task"]},"CreateHouseholdPerson":{"type":"object","properties":{"email":{"type":"string","pattern":"^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$"},"kind":{"default":"adult","type":"string","enum":["adult","child","helper","caregiver","other"]},"name":{"type":"string","minLength":1}},"required":["name"]},"UpdateHouseholdPerson":{"type":"object","properties":{"email":{"anyOf":[{"type":"string","pattern":"^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$"},{"type":"null"}]},"kind":{"type":"string","enum":["adult","child","helper","caregiver","other"]},"name":{"type":"string","minLength":1}}},"CreateWebhookDestination":{"type":"object","properties":{"enabled":{"type":"boolean"},"eventTypes":{"minItems":1,"type":"array","items":{"type":"string","enum":["collection.created","collection.updated","collection.deleted","tracker.entry.created","tracker.entry.updated","tracker.entry.deleted","calendar.event.created","calendar.event.updated","calendar.event.deleted","calendar.check.created","external_calendar.created","external_calendar.updated","external_calendar.refresh_requested","external_calendar.deleted","calendar_share.created","calendar_share.deleted","person.created","person.updated","person.deleted","notification.sent","notification_preference.updated","notification_routine.created","notification_routine.updated","notification_routine.deleted","webhook_destination.created","webhook_destination.updated","webhook_destination.deleted"]}},"name":{"type":"string","minLength":1,"maxLength":80},"url":{"type":"string","format":"uri"}},"required":["eventTypes","name","url"]},"UpdateWebhookDestination":{"type":"object","properties":{"enabled":{"type":"boolean"},"eventTypes":{"minItems":1,"type":"array","items":{"type":"string","enum":["collection.created","collection.updated","collection.deleted","tracker.entry.created","tracker.entry.updated","tracker.entry.deleted","calendar.event.created","calendar.event.updated","calendar.event.deleted","calendar.check.created","external_calendar.created","external_calendar.updated","external_calendar.refresh_requested","external_calendar.deleted","calendar_share.created","calendar_share.deleted","person.created","person.updated","person.deleted","notification.sent","notification_preference.updated","notification_routine.created","notification_routine.updated","notification_routine.deleted","webhook_destination.created","webhook_destination.updated","webhook_destination.deleted"]}},"name":{"type":"string","minLength":1,"maxLength":80},"url":{"type":"string","format":"uri"},"rotateSecret":{"type":"boolean"}}},"SetNotificationPreference":{"type":"object","properties":{"channel":{"type":"string","enum":["email","push"]},"eventKind":{"type":"string","enum":["reminder","coverage_alert","follow_up_nudge","digest","intake_update"]},"isEnabled":{"type":"boolean"}},"required":["channel","eventKind","isEnabled"]},"NotificationRoutine":{"type":"object","properties":{"channels":{"type":"array","items":{"type":"string","enum":["in_app","email","push","sms"]}},"cron":{"type":"string","minLength":1},"intent":{"type":"string","enum":["briefing","reminder","digest"]},"isEnabled":{"type":"boolean"},"mode":{"type":"string","enum":["plain","mavo"]},"timezone":{"type":"string"}}},"SearchWeb":{"type":"object","properties":{"numResults":{"default":5,"type":"integer","minimum":1,"maximum":10},"query":{"type":"string","minLength":1}},"required":["query"]},"ReadWebPage":{"type":"object","properties":{"url":{"type":"string","format":"uri"}},"required":["url"]},"CalendarExternalFeed":{"type":"object","properties":{"color":{"type":"string"},"hint":{"type":"string","maxLength":280},"name":{"type":"string","minLength":1,"maxLength":120},"url":{"type":"string","minLength":1,"maxLength":2048}},"required":["name","url"]},"UpdateExternalCalendar":{"type":"object","properties":{"hint":{"type":"string","maxLength":280}}},"CalendarShare":{"type":"object","properties":{"categories":{"default":[],"type":"array","items":{"type":"string"}},"eventIds":{"default":[],"type":"array","items":{"type":"string"}},"name":{"type":"string","minLength":1,"maxLength":120},"personIds":{"default":[],"type":"array","items":{"type":"string"}},"sourceIds":{"default":[],"type":"array","items":{"type":"string"}}},"required":["name"]}}}}