App reference

API reference

Every capability of the system, generated from the protobuf sources. Clients call these RPCs through Connect โ€” there is no other surface. Each section is one domain: its service, then the messages and enums it speaks.

API Key

ApiKeyService

ApiKeyService manages machine credentials (ADR-0016). Every RPC is admin-only via the permission matrix (ADR-0002/0008).

RPC Request Response Description
CreateApiKey CreateApiKeyRequest CreateApiKeyResponse Mint a new key. The response carries the signed token exactly once.
ListApiKeys ListApiKeysRequest ListApiKeysResponse List all keys (records only โ€” no tokens)
RevokeApiKey ApiKeyRequest ApiKeyResponse Revoke a key: dead on the next request. Idempotent.

ApiKey

ApiKey is an admin-managed machine credential (ADR-0016). The signed token is a JWT whose jti mirrors this record's uid; the record โ€” not the token โ€” is the authority: revocation, roles and the act_as allowlist are consulted on every request. The token itself is never stored and never appears on this message; it exists exactly once, as CreateApiKeyResponse.token.

Field Type Description
uid string Unique identifier (also the JWT jti claim)
name string Human-readable label, e.g. "lukes-claude", "home-assistant"
user_uid string Personal key: uid of the owning user โ€” the key acts as that user and inherits (and is capped by) the user's live roles. Empty = standalone: the key is its own principal (e.g. a shared device) with the roles below.
roles repeated Role Standalone keys only; ignored when user_uid is set.
act_as repeated string User uids this key may claim via the acting-user mechanism. Empty = no impersonation. Admin-managed; consulted on every honoured claim.
created_by UserRef Admin who minted the key
created_at google.protobuf.Timestamp When the key was minted
last_used_at google.protobuf.Timestamp Best-effort, throttled touch on use โ€” admin visibility, not an audit
revoked_at google.protobuf.Timestamp Set = the key is dead on the next request. Never cleared.
mutations repeated Mutation Audit trail of changes made to this key

ApiKeyRequest

ApiKeyRequest names one key by uid.

Field Type Description
uid string UID of the key

ApiKeyResponse

ApiKeyResponse returns one key record.

Field Type Description
api_key ApiKey The key record

CreateApiKeyRequest

CreateApiKeyRequest mints a new key (ADMIN only).

Field Type Description
name string Human-readable label (required)
user_uid string Owning user for a personal key; empty mints a standalone key
roles repeated Role Standalone keys only: the principal's roles. Rejected with user_uid.
act_as repeated string Acting-user allowlist (uids must exist)

CreateApiKeyResponse

CreateApiKeyResponse carries the record and โ€” exactly once โ€” the signed token. The token is not persisted and cannot be retrieved again.

Field Type Description
api_key ApiKey The stored key record
token string The signed bearer token; shown only in this response

ListApiKeysRequest

ListApiKeysRequest lists every key, revoked ones included.

Field Type Description
limit int32 Maximum number of keys to return (0 = no limit)

ListApiKeysResponse

ListApiKeysResponse returns key records (structurally token-free).

Field Type Description
api_keys repeated ApiKey The key records

Audit

AuditEntry

AuditEntry is one row of the install-wide audit log: who did what to which entity, when. Entries are written append-only alongside the per-record mutations[] trail, so they survive the record's deletion โ€” the whole point of a global log. History starts at the deploy that introduced the table; older in-record mutations are not backfilled.

Field Type Description
uid string Unique identifier (UUIDv7 โ€” time-ordered, so uid order is time order)
date google.protobuf.Timestamp Timestamp when the change occurred
actor UserRef User who performed the change. May be empty for unauthenticated creations (first-time setup), matching the mutations[] contract.
entity_type string Table/kind of the changed entity, e.g. "user", "event", "item"
entity_uid string UID of the changed entity
entity_label string Human-readable label of the entity at the time of the change (its name field when it has one), kept here so deleted entities stay identifiable
action MutationAction What happened: create, update or delete
credential_kind string How the change was made: "session" or "api_key" (ADR-0016). Empty on rows written before credentials were recorded โ€” read those as "session".
credential_uid string ApiKey.uid when credential_kind is "api_key"
credential_name string ApiKey.name snapshot at write time, so entries survive key deletion
subject UserRef The credential's own principal, set only when an acting-user claim was honoured and therefore differs from actor. actor is always the effective actor โ€” who gets chore/reward credit; this answers "via whom".

Error

ErrorDetail

ErrorDetail rides on Connect errors as a detail message: a stable machine-readable code the web client maps to translated copy, plus optional parameters for interpolation. The error's message string stays English โ€” it is the server-log form and the client fallback for codes the catalog does not know.

Field Type Description
code string Stable code, e.g. "NOT_ENOUGH_POINTS"
params map<string, string> Interpolation parameters, e.g. {"entity": "reward"}

Event

EventService

EventService provides CRUD operations and user management for events

RPC Request Response Description
Create CreateEventRequest EventResponse Create a new event
Read EventRequest EventResponse Read an existing event by UID
Update UpdateEventRequest EventResponse Update an existing event
Delete EventRequest SuccessResponse Delete an event by UID
AddUser AddUserToEventRequest EventResponse Add a user to an event
RemoveUser RemoveUserFromEventRequest EventResponse Remove a user from an event
ListEvents ListEventsRequest ListEventsResponse List all events
ListOccurrences ListOccurrencesRequest ListOccurrencesResponse Everything on the calendar in a window: plain events plus projected occurrences of repeating events
SplitOccurrence SplitOccurrenceRequest EventResponse Materialise one occurrence as an editable child row (idempotent)
CancelOccurrence CancelOccurrenceRequest EventResponse Cancel one occurrence (tombstone its slot)

AddUserToEventRequest

AddUserToEventRequest contains the data needed to add a user to an event

Field Type Description
event_uid string UID of the event
user_uid string UID of the user to add

CancelOccurrenceRequest

CancelOccurrenceRequest tombstones one occurrence of a repeating event

Field Type Description
event_uid string UID of the repeating parent event
occurrence_date string The occurrence slot to cancel (the occurrence_date key)
time_zone string IANA time zone the slot key was produced in (must match the ListOccurrences call that showed it)

CreateEventRequest

CreateEventRequest contains the data needed to create a new event

Field Type Description
repeat EventRepeat Optional repeat rule for the new event
name string Name of the new event
type EventType Type/category of the event
start_time google.protobuf.Timestamp Event start time
end_time google.protobuf.Timestamp Event end time
description string Event description
user_uids repeated string UIDs of users to associate with the event
item_uid string Optional UID of related item
all_day bool The event covers whole days (see Event.all_day)
daily_times bool The event repeats its clock times on each day of the span (see Event.daily_times)
time_zone string IANA time zone for span validation arithmetic (e.g. "Europe/Dublin"). Empty falls back to UTC.
location string Physical or virtual location of the event
uid string Optional client-minted uid (UUIDv7) so an offline write queue can replay this create safely: a resend lands on ALREADY_EXISTS instead of minting a duplicate (ADR-0019). Empty lets the server mint one.

Event

Event represents a scheduled event in the family organization system

Field Type Description
uid string Unique identifier for the event
name string Display name of the event
type EventType Category/type of the event
start_time google.protobuf.Timestamp When the event begins
end_time google.protobuf.Timestamp When the event ends
description string Detailed description of the event
mutations repeated Mutation Audit trail of changes
users repeated UserRef Users associated with this event
item ItemRef Optional related item
location string Physical or virtual location of the event
repeat EventRepeat Optional repeat rule: occurrences are derived from this event within a requested window (ListOccurrences) โ€” no rows are minted per cycle.
recurrence_of string On an override/tombstone child row: the repeating parent's UID
occurrence_date string On a child row: the original occurrence slot it replaces (an opaque YYYY-MM-DD key, UTC). Also populated on projected occurrences so the client can name a slot when splitting or cancelling it.
cancelled bool On a child row: true tombstones the slot โ€” the occurrence is cancelled
all_day bool The event covers whole days: start/end are local midnights and the end date is inclusive (start Jul 28, end Jul 30 = three full days)
daily_times bool The event runs at its start/end clock times on each day of the span separately (a block per day), rather than as one continuous block. start_time holds day one + the daily start clock; end_time holds the last day + the daily end clock. Each day projects as its own occurrence. Note the repeat until cuts span starts only โ€” a span anchored on or before it runs to completion.
span_start_date string On projected daily_times occurrences and their child rows: the YYYY-MM-DD start date of the span instance this day belongs to. Never set on stored parent rows.
span_end_date string The span instance's last covered date (YYYY-MM-DD, inclusive) โ€” the other half of span_start_date, same rows only.

EventRepeat

EventRepeat is an event's repeat rule. The anchor is the event's start time: the first occurrence is the event itself, and every shape keeps the anchor's clock and duration.

Field Type Description
kind RepeatKind The shape of the rule (shares the jobs' RepeatKind; adds YEARS)
interval int32 Every N days/weeks/months/years; minimum 1
weekdays repeated int32 Weekdays (0 = Sunday โ€ฆ 6 = Saturday) for the weekly kind โ€” a set, so Mon/Wed/Fri swimming is one event. The nth-weekday kind reads the first entry.
day_of_month int32 Day of month (1-31) for MONTHLY_ON_DAY; clamped to the month's length
nth int32 Which weekday occurrence (1-5, 5 = last) for MONTHLY_ON_NTH_WEEKDAY
until string Optional inclusive end date (YYYY-MM-DD): no occurrences after it

EventRequest

EventRequest is used for operations that only need an event UID

Field Type Description
uid string UID of the event

EventResponse

EventResponse returns an event object

Field Type Description
event Event The requested event

ListEventsRequest

ListEventsRequest contains optional filters for listing events

Field Type Description
limit int32 Optional maximum number of events to return (0 means no limit)

ListEventsResponse

ListEventsResponse returns a list of events

Field Type Description
events repeated Event The list of events

ListOccurrencesRequest

ListOccurrencesRequest asks for everything on the calendar in a window

Field Type Description
from google.protobuf.Timestamp Window start (inclusive)
to google.protobuf.Timestamp Window end (exclusive)
time_zone string IANA time zone for calendar arithmetic (e.g. "Europe/Dublin") โ€” the zone in which weekdays and month days mean what the family means. Empty falls back to UTC.

ListOccurrencesResponse

ListOccurrencesResponse returns concrete calendar entries for the window: plain events intersecting it, plus projected occurrences of repeating events (overrides swapped in, cancelled slots dropped)

Field Type Description
events repeated Event The window's events and occurrences

RemoveUserFromEventRequest

RemoveUserFromEventRequest contains the data needed to remove a user from an event

Field Type Description
event_uid string UID of the event
user_uid string UID of the user to remove

SplitOccurrenceRequest

SplitOccurrenceRequest materialises one occurrence of a repeating event as a real child row, so it can be edited on its own

Field Type Description
event_uid string UID of the repeating parent event
occurrence_date string The occurrence slot to split (the occurrence_date key)
time_zone string IANA time zone the slot key was produced in (must match the ListOccurrences call that showed it)

UpdateEventRequest

UpdateEventRequest contains the data needed to update an existing event

Field Type Description
uid string UID of the event to update
name string Updated name
type EventType Updated type
start_time google.protobuf.Timestamp Updated start time
end_time google.protobuf.Timestamp Updated end time
description string Updated description
user_uids repeated string Updated list of associated user UIDs
item_uid string Updated related item UID
all_day bool Updated all-day flag (see Event.all_day)
daily_times bool Updated daily-times flag (see Event.daily_times)
time_zone string IANA time zone for span validation arithmetic. Empty falls back to UTC.
location string Updated location

EventType

EventType defines the different categories of events in the system

Value Description
EVENT_TYPE_UNSPECIFIED Default/unknown event type
EVENT_TYPE_APPOINTMENT Scheduled appointments or meetings
EVENT_TYPE_BIRTHDAY Birthday celebrations
EVENT_TYPE_DEADLINE Important deadlines
EVENT_TYPE_HOLIDAY Holidays and special occasions

Item

ItemService

ItemService provides operations for managing items

RPC Request Response Description
Create CreateItemRequest ItemResponse Create a new item
Read ItemRequest ItemResponse Read an existing item by UID
Update UpdateItemRequest ItemResponse Update an existing item
Delete ItemRequest SuccessResponse Delete an item by UID
AssignUser AssignUserRequest ItemResponse Assign a user to an item
SetDeadline SetDeadlineRequest ItemResponse Set a deadline for an item
SetRepeat SetRepeatRequest ItemResponse Set or clear an item's repeat rule (standalone jobs only)
CompleteItem CompleteItemRequest ItemResponse Mark an item as complete or incomplete
SetList SetListRequest ItemResponse Move an item into a list, or make it standalone (empty list_uid)
SetParent SetParentRequest ItemResponse Make an item a sub-task of a job, or promote it back to standalone (empty parent_uid). ADR-0025.
ListItems ListItemsRequest ListItemsResponse List all items

ItemListService

ItemListService provides operations for managing item lists

RPC Request Response Description
Create CreateItemListRequest ItemListResponse Create a new item list
Read ItemListRequest ItemListResponse Read an existing item list by UID, including its items
Update UpdateItemListRequest ItemListResponse Update an existing item list
Delete ItemListRequest SuccessResponse Delete an item list by UID; cascade-deletes the list's items
List ListItemListsRequest ListItemListsResponse List all item lists
UncheckAll ItemListRequest ItemListResponse Mark every item in the list incomplete; ADMIN/MEMBER only

AssignUserRequest

AssignUserRequest contains the data needed to assign a user to an item

Field Type Description
item_uid string UID of the item to assign
user_uid string UID of the user to assign to the item

CompleteItemRequest

CompleteItemRequest contains the data needed to mark an item complete or incomplete

Field Type Description
item_uid string UID of the item to complete
complete bool true to mark complete, false to mark incomplete

CreateItemListRequest

CreateItemListRequest contains the data needed to create a new item list

Field Type Description
name string Name of the new item list
uid string Optional client-minted uid (UUIDv7) so an offline write queue can replay this create safely: a resend lands on ALREADY_EXISTS instead of minting a duplicate (ADR-0019). Empty lets the server mint one.

CreateItemRequest

Request messages CreateItemRequest contains the data needed to create a new item

Field Type Description
title string Title of the new item
description string Description of the new item
list_uid string UID of the list to add the item to
owner_uid string Optional owner to assign at creation. A standalone job born with an owner announces "assigned to you"; born without one it announces "up for grabs" โ€” creating then assigning separately would announce both.
uid string Optional client-minted uid (UUIDv7) so an offline write queue can replay this create safely: a resend lands on ALREADY_EXISTS instead of minting a duplicate (ADR-0019). Empty lets the server mint one.
parent_uid string Optional parent job this item is a step of (ADR-0025). Mutually exclusive with list_uid. The new sub-task inherits the parent's owner unless owner_uid is set.

Item

Item represents a task or todo item in the family organization system

Field Type Description
uid string Unique identifier for the item
title string Title or name of the item
description string Detailed description of the item
complete bool Whether the item has been completed
owner UserRef User who owns or is assigned to this item
mutations repeated Mutation Audit trail of changes made to this item
deadline string Optional deadline for completing the item (ISO 8601 format)
list ListRef Optional list this item belongs to; absent = standalone job
repeat ItemRepeat Optional repeat rule: completing this item mints its successor (the chained model โ€” no scheduler, exactly one open instance per chain). Standalone jobs only; list entries never repeat.
spawned_next string UID of the successor this item minted at close-out. Presence blocks un-completion (the chain has moved on) and records the lineage.
parent_uid string UID of the job this item is a step of (ADR-0025). Empty = not a sub-task. One level deep: an item with a parent never has children. Sub-tasks carry no repeat rule, list membership or deadline, and never appear on list surfaces outside their parent.
sub_items repeated Item The item's sub-tasks. Read-time projection populated by ItemService.Read; never stored on the item itself.

ItemList

ItemList represents a collection of items grouped together

Field Type Description
uid string Unique identifier for the item list
name string Display name of the item list
items repeated Item Collection of items within this list. Read-time projection populated by ItemListService.Read; never stored on the list itself.

ItemListRequest

ItemListRequest is used for operations that only need an item list UID

Field Type Description
uid string UID of the item list

ItemListResponse

ItemListResponse returns an item list object

Field Type Description
item_list ItemList The requested item list

ItemRepeat

ItemRepeat is a job's repeat rule. The successor's deadline lands on the next occurrence strictly after max(old deadline, completion time) โ€” early completion keeps the cadence, late completion skips the missed slots.

Field Type Description
kind RepeatKind The shape of the rule; decides which of the fields below apply
interval int32 Every N days/weeks/months; minimum 1
weekday int32 Weekday for the weekly and nth-weekday kinds: 0 = Sunday โ€ฆ 6 = Saturday
day_of_month int32 Day of month (1-31) for MONTHLY_ON_DAY; clamped to the month's length
nth int32 Which weekday occurrence (1-5) for MONTHLY_ON_NTH_WEEKDAY; 5 means the last such weekday of the month
time_zone string IANA time zone the rule lives in (e.g. "Europe/Dublin"), captured when the rule is set. Successor math runs in this zone so the chain keeps a stable wall clock across DST boundaries. Empty falls back to the deadline's own offset.

ItemRequest

Common request/response patterns ItemRequest is used for operations that only need an item UID

Field Type Description
uid string UID of the item

ItemResponse

ItemResponse returns an item object

Field Type Description
item Item The requested item

ListItemListsRequest

ListItemListsRequest contains optional filters for listing item lists

Field Type Description
limit int32 Optional maximum number of item lists to return (0 means no limit)

ListItemListsResponse

ListItemListsResponse returns a list of item lists

Field Type Description
item_lists repeated ItemList The list of item lists

ListItemsRequest

ListItemsRequest contains optional filters for listing items

Field Type Description
limit int32 Optional maximum number of items to return (0 means no limit)
include_sub_tasks bool Include sub-tasks in the result. Off by default so list surfaces never show a step outside its parent (ADR-0025); the web and Android caches opt in because they hold the full collection and filter locally.

ListItemsResponse

ListItemsResponse returns a list of items

Field Type Description
items repeated Item The list of items

SetDeadlineRequest

SetDeadlineRequest contains the data needed to set a deadline for an item

Field Type Description
item_uid string UID of the item to set deadline for
deadline string Deadline to set (ISO 8601 format)

SetListRequest

SetListRequest contains the data needed to move an item into or out of a list

Field Type Description
item_uid string UID of the item to move
list_uid string UID of the list to place the item in; empty = make the item standalone

SetParentRequest

SetParentRequest makes an item a sub-task of a job, or promotes it back to a standalone job (ADR-0025)

Field Type Description
item_uid string UID of the item to convert
parent_uid string UID of the parent job; empty = promote to a standalone job

SetRepeatRequest

SetRepeatRequest sets or clears an item's repeat rule

Field Type Description
item_uid string UID of the item
repeat ItemRepeat The rule to set; absent clears the repeat (the chain ends here)

UpdateItemListRequest

UpdateItemListRequest contains the data needed to update an existing item list

Field Type Description
uid string UID of the item list to update
name string Updated name

UpdateItemRequest

UpdateItemRequest contains the data needed to update an existing item

Field Type Description
uid string UID of the item to update
title string Updated title
description string Updated description
complete bool Updated completion status
deadline string Updated deadline (ISO 8601 format)

RepeatKind

RepeatKind is the shape of a repeat rule.

Value Description
REPEAT_KIND_UNSPECIFIED No rule โ€” the item does not repeat
REPEAT_KIND_EVERY_N_DAYS Every interval days
REPEAT_KIND_EVERY_N_WEEKS_ON_WEEKDAY Every interval weeks on weekday
REPEAT_KIND_MONTHLY_ON_DAY Every interval months on day_of_month (clamped to month length)
REPEAT_KIND_MONTHLY_ON_NTH_WEEKDAY Every interval months on the nth weekday (e.g. 2nd Thursday)
REPEAT_KIND_EVERY_N_YEARS Every interval years on the anchor date (events only; job rules reject it)

Meal

MealService

MealService provides operations for managing the meal library

RPC Request Response Description
Create CreateMealRequest MealResponse Create a new meal
Read MealRequest MealResponse Read an existing meal by UID
Update UpdateMealRequest MealResponse Update an existing meal
Delete MealRequest SuccessResponse Delete a meal by UID. Rota slots and future overrides referencing it are cleared; frozen week snapshots keep their stamped name copy so history stays readable.
List ListMealsRequest ListMealsResponse List all meals
PushIngredients PushIngredientsRequest PushIngredientsResponse Add the meal's ingredient lines to an item list, one item per line, skipping lines already open on the list

CreateMealRequest

CreateMealRequest contains the data needed to create a new meal

Field Type Description
name string Name of the new meal
ingredients repeated string Ingredient lines, one per entry
notes string Free-form notes
uid string Optional client-minted uid (UUIDv7) so an offline write queue can replay this create safely: a resend lands on ALREADY_EXISTS instead of minting a duplicate (ADR-0019). Empty lets the server mint one.

ListMealsRequest

ListMealsRequest contains optional filters for listing meals

Field Type Description
limit int32 Optional maximum number of meals to return (0 means no limit)

ListMealsResponse

ListMealsResponse returns a list of meals

Field Type Description
meals repeated Meal The list of meals

Meal

Meal is a reusable dish in the family's meal library. Putting a meal on a day is a rota slot or a day override carrying a MealRef โ€” the library row holds what the dish is, the rota holds when it happens and who cooks.

Field Type Description
uid string Unique identifier for the meal
name string Display name of the meal ("Chicken curry")
ingredients repeated string Ingredient lines, one per entry, quantity in free text ("500g mince"). Each line becomes one shopping-list item when pushed.
notes string Free-form notes (method pointers, cookbook page, allergy flags)
mutations repeated Mutation Audit trail of changes made to this meal

MealRequest

MealRequest is used for operations that only need a meal UID

Field Type Description
uid string UID of the meal

MealResponse

MealResponse returns a meal object

Field Type Description
meal Meal The requested meal

PushIngredientsRequest

PushIngredientsRequest asks for a meal's ingredient lines to be added to an item list as one item per line

Field Type Description
meal_uid string UID of the meal whose ingredients to push
list_uid string UID of the target item list

PushIngredientsResponse

PushIngredientsResponse reports what the push did. A line is skipped when an incomplete item with the same title (case-insensitive) already sits on the target list; completed items do not block re-adding.

Field Type Description
added int32 Number of items created on the list
skipped int32 Number of lines skipped as already on the list

UpdateMealRequest

UpdateMealRequest contains the data needed to update an existing meal. Renaming a meal does not rewrite the name copies stamped on rota slots, overrides or week snapshots โ€” those are deliberate history (ListRef precedent).

Field Type Description
uid string UID of the meal to update
name string Updated name
ingredients repeated string Updated ingredient lines (full replacement)
notes string Updated notes

Meal Rota

MealRotaService

MealRotaService runs the standing rota: the board itself, per-date overrides, and the merged read the calendar and Today consume. Reading a range that covers completed weeks freezes them on first touch (lazy snapshots), so the read may write.

RPC Request Response Description
Get GetMealRotaRequest MealRotaResponse Get the raw rota for editing
SetSlot SetMealRotaSlotRequest MealRotaResponse Replace one weekday slot; assigning a new cook notifies them
SetTimeZone SetMealRotaTimeZoneRequest MealRotaResponse Change the rota's time zone
SetOverride SetMealOverrideRequest MealOverrideResponse Pin one date (swap, one-off or skip); assigning a new cook notifies them
ClearOverride ClearMealOverrideRequest SuccessResponse Unpin a date, resuming the rota
ListResolvedDays ListResolvedMealDaysRequest ListResolvedMealDaysResponse The merged day-by-day view: override beats rota, completed weeks read from their snapshot (frozen on first touch)

ClearMealOverrideRequest

ClearMealOverrideRequest unpins a date, putting it back on the rota. Past dates are rejected.

Field Type Description
date string The date to unpin, YYYY-MM-DD

GetMealRotaRequest

GetMealRotaRequest asks for the raw rota (the edit view).

ListResolvedMealDaysRequest

ListResolvedMealDaysRequest asks for the merged day-by-day view of an inclusive date range (at most ~100 days).

Field Type Description
from string First date, YYYY-MM-DD
to string Last date, YYYY-MM-DD

ListResolvedMealDaysResponse

ListResolvedMealDaysResponse returns one entry per date in the range. Empty days are included with source EMPTY so callers can render gaps.

Field Type Description
days repeated ResolvedMealDay The resolved days, in date order
time_zone string The rota's time zone, for callers reasoning about "today"

MealDayOverride

MealDayOverride pins one specific date. The row is a full replacement: while it exists the day is exactly what it says, and rota edits no longer reach that date. An override with neither meal nor cook is a skipped day; deleting the row puts the date back on the rota.

Field Type Description
uid string Unique identifier for the override
date string The pinned date, YYYY-MM-DD in the rota's time zone
meal MealRef The dish for this date; name stamped from the library at set time
cook UserRef The single cook on duty; may be absent
mutations repeated Mutation Audit trail of changes made to this override

MealOverrideResponse

MealOverrideResponse returns an override object

Field Type Description
override MealDayOverride The pinned day

MealRota

MealRota is the family's standing weekly menu board โ€” a singleton row (uid "rota", the system-settings precedent). Editing a slot changes every future week at once; a specific date is pinned with a MealDayOverride.

Field Type Description
uid string Always "rota"
slots repeated MealRotaSlot At most seven entries, keyed by weekday
time_zone string IANA time zone the rota's days are reckoned in ("Europe/Dublin"). Empty is treated as UTC; the web board offers the browser's zone.
reminder_last_sent string Local date (YYYY-MM-DD in time_zone) the day-of cooking reminder last fired. Written with a locked compare-and-set and no mutation entry (the api-key last-used precedent) โ€” bookkeeping, not history.
mutations repeated Mutation Audit trail of changes made to the rota

MealRotaResponse

MealRotaResponse returns the rota object

Field Type Description
rota MealRota The standing rota

MealRotaSlot

MealRotaSlot is one weekday of the standing rota. The slots list is sparse: an absent weekday is an empty day.

Field Type Description
weekday int32 ISO weekday, 1 = Monday .. 7 = Sunday
meal MealRef The dish for this weekday; name stamped from the library at set time
cook UserRef The single cook on duty; may be absent (nobody assigned)

MealWeek

MealWeek is the frozen record of a completed week. Its uid is the week's Monday (natural key โ€” materialization is write-if-absent and idempotent). A row is never rewritten once present.

Field Type Description
uid string Always equal to week_start
week_start string The week's Monday, YYYY-MM-DD
days repeated MealWeekDay Exactly seven entries, Monday through Sunday
time_zone string The rota's time zone at freeze time
mutations repeated Mutation Single CREATE entry recording who caused the freeze

MealWeekDay

MealWeekDay is one day inside a frozen week. Meal and cook are stamped copies โ€” the meal name survives later meal deletion; the uid may dangle.

Field Type Description
date string The date, YYYY-MM-DD
meal MealRef The dish that stood on this date when the week froze
cook UserRef The cook that stood on this date when the week froze
source MealDaySource How the day resolved at freeze time (ROTA, OVERRIDE or EMPTY)

ResolvedMealDay

ResolvedMealDay is the merged answer for one date: override beats rota beats empty, and completed weeks come from their snapshot.

Field Type Description
date string The date, YYYY-MM-DD
meal MealRef The dish on this date, if any
cook UserRef The cook on duty, if any
source MealDaySource Where the answer came from

SetMealOverrideRequest

SetMealOverrideRequest pins one date. Upserts by date; dates already in the past (in the rota's zone) are rejected โ€” finished days belong to their snapshot. Both uids empty pins a skip.

Field Type Description
date string The date to pin, YYYY-MM-DD
meal_uid string UID of the meal for this date, or empty for none
cook_uid string UID of the cook for this date, or empty for none

SetMealRotaSlotRequest

SetMealRotaSlotRequest replaces one weekday slot. Empty meal_uid clears the dish; empty cook_uid clears the cook; both empty clears the slot.

Field Type Description
weekday int32 ISO weekday to set, 1 = Monday .. 7 = Sunday
meal_uid string UID of the meal to put on this weekday, or empty to clear
cook_uid string UID of the cook on duty, or empty to clear

SetMealRotaTimeZoneRequest

SetMealRotaTimeZoneRequest changes the zone the rota's days are reckoned in.

Field Type Description
time_zone string IANA time zone name ("Europe/Dublin")

MealDaySource

MealDaySource says where a resolved day's content came from.

Value Description
MEAL_DAY_SOURCE_UNSPECIFIED Unknown source
MEAL_DAY_SOURCE_EMPTY Nothing planned
MEAL_DAY_SOURCE_ROTA The standing rota slot for that weekday
MEAL_DAY_SOURCE_OVERRIDE A pinned one-day override (swap, one-off or skip)
MEAL_DAY_SOURCE_SNAPSHOT Read from a frozen past-week snapshot

Mutation

Mutation

Mutation represents an audit record of a change made to an entity

Field Type Description
date google.protobuf.Timestamp Timestamp when the mutation occurred
user UserRef User who performed the mutation
action MutationAction Type of action that was performed

MutationAction

MutationAction defines the types of actions that can be performed on entities

Value Description
MUTATION_ACTION_UNSPECIFIED Default/unknown action type
MUTATION_ACTION_CREATE Entity was created
MUTATION_ACTION_UPDATE Entity was updated/modified
MUTATION_ACTION_DELETE Entity was deleted
MUTATION_ACTION_EXPORT Data was exported (read-only; records that an archive left the system)
MUTATION_ACTION_IMPORT Data was imported/restored from a backup archive

Notification

NotificationService

NotificationService serves each member their own inbox โ€” every RPC is scoped to the requester; there is no way to read another member's rows.

RPC Request Response Description
List ListNotificationsRequest ListNotificationsResponse List the requester's notifications, newest first
MarkRead NotificationRequest NotificationResponse Mark one of the requester's notifications read
MarkAllRead MarkAllReadRequest SuccessResponse Mark all of the requester's notifications read
Subscribe SubscribeRequest Notification Stream the requester's notifications as they are minted, until the client disconnects. Live delivery only โ€” missed rows are in List.
Watch WatchRequest DataChange Stream data-change announcements: an entity name per committed write, so clients can silently re-fetch what they're showing. No payload โ€” the announcement is a doorbell, the entity's List RPC is the ledger.

DataChange

DataChange announces that rows of an entity changed

Field Type Description
entity string Lowercase proto message name: "item", "reward", "event", "user", "itemlist", "notification"

ListNotificationsRequest

ListNotificationsRequest asks for the requester's inbox

Field Type Description
limit int32 Optional maximum number of rows to return (0 = server default)

ListNotificationsResponse

ListNotificationsResponse returns the requester's rows, newest first

Field Type Description
notifications repeated Notification The notifications

MarkAllReadRequest

MarkAllReadRequest marks the requester's whole inbox read

Notification

Notification is one row of a member's inbox. Rows are minted server-side at the emission points (fan-out on write), pruned to the newest ~100 per recipient, and carry a pre-rendered message plus a link into the app.

Field Type Description
uid string Unique identifier for the notification
recipient UserRef Who this row belongs to โ€” the inbox owner
actor UserRef Who did the thing (their mark leads the row in the feed)
kind NotificationKind What kind of moment this was
message string The rendered sentence, second person where the recipient is the target
link string App path the row opens (e.g. "/jobs?view=everyone")
created_at google.protobuf.Timestamp When the moment happened
read bool Whether the recipient has read this row

NotificationRequest

NotificationRequest names one notification by UID

Field Type Description
uid string UID of the notification

NotificationResponse

NotificationResponse returns one notification

Field Type Description
notification Notification The notification

SubscribeRequest

SubscribeRequest opens the requester's live stream

WatchRequest

WatchRequest opens the live data-change stream

NotificationKind

NotificationKind names the moment a notification was minted for.

Value Description
NOTIFICATION_KIND_UNSPECIFIED Unknown kind
NOTIFICATION_KIND_JOB_COMPLETED Someone completed a job
NOTIFICATION_KIND_JOB_UP_FOR_GRABS A job (or bounty) landed in the up-for-grabs pool
NOTIFICATION_KIND_REWARD_GRANTED A reward was granted to the recipient
NOTIFICATION_KIND_JOB_ASSIGNED A job was assigned to the recipient
NOTIFICATION_KIND_REWARD_CLAIMED Someone claimed a reward (hand-claims only โ€” points banked by finishing a job are part of that completion's announcement)
NOTIFICATION_KIND_MEAL_ASSIGNED The recipient was put on cooking duty for a planned meal
NOTIFICATION_KIND_MEAL_REMINDER Day-of nudge: the recipient cooks tonight

Push

PushService

PushService manages Web Push device registrations. Every RPC is scoped to the requester โ€” there is no way to see or touch another member's devices.

RPC Request Response Description
GetVapidPublicKey GetVapidPublicKeyRequest GetVapidPublicKeyResponse The public VAPID key browsers subscribe with
Subscribe PushSubscribeRequest PushSubscriptionResponse Register this device. Re-subscribing an endpoint that already has a row replaces it โ€” re-owned by the requester (shared-device account switch).
ListSubscriptions ListPushSubscriptionsRequest ListPushSubscriptionsResponse List the requester's subscribed devices
Unsubscribe PushSubscriptionRequest SuccessResponse Remove one of the requester's subscriptions
SendTest SendTestPushRequest SuccessResponse Push a localized test message to the requester's devices

GetVapidPublicKeyRequest

GetVapidPublicKeyRequest asks for the install's public VAPID key.

GetVapidPublicKeyResponse

GetVapidPublicKeyResponse carries the base64url public VAPID key the browser needs for pushManager.subscribe.

Field Type Description
public_key string The public VAPID key (base64url)

ListPushSubscriptionsRequest

ListPushSubscriptionsRequest lists the requester's own subscriptions.

ListPushSubscriptionsResponse

ListPushSubscriptionsResponse returns the requester's device rows.

Field Type Description
subscriptions repeated PushSubscription The subscriptions

PushSubscribeRequest

PushSubscribeRequest registers (or re-registers) the calling device.

Field Type Description
endpoint string Push-service URL from the browser's PushSubscription (required)
p256dh string Client public key, base64url (required)
auth string Auth secret, base64url (required)
label string Friendly device label derived client-side from the user agent

PushSubscription

PushSubscription is one browser's Web Push registration โ€” one row per device the member switched notifications on for. The p256dh/auth crypto material is server-internal (structurally scrubbed from responses); the endpoint survives responses so a device can recognise its own row.

Field Type Description
uid string Unique identifier for the subscription
user_uid string Owning member โ€” pushes for this member fan out to their rows
endpoint string Push-service URL the browser minted (unique per registration)
p256dh string Client public key for payload encryption (server-internal)
auth string Auth secret for payload encryption (server-internal)
label string Human-readable device label, e.g. "Chrome on Android"
created_at google.protobuf.Timestamp When the device subscribed
mutations repeated Mutation Audit trail of changes made to this subscription

PushSubscriptionRequest

PushSubscriptionRequest names one subscription by uid.

Field Type Description
uid string UID of the subscription

PushSubscriptionResponse

PushSubscriptionResponse returns one subscription row.

Field Type Description
subscription PushSubscription The subscription

SendTestPushRequest

SendTestPushRequest pushes a test notification to every one of the requester's subscribed devices, ignoring per-kind preferences.

Refs

ItemRef

ItemRef represents a reference to an item

Field Type Description
uid string Unique identifier of the referenced item

ListRef

ListRef represents a reference to an item list

Field Type Description
uid string Unique identifier of the referenced item list
name string Display name of the referenced item list

MealRef

MealRef represents a reference to a meal. The name is stamped from the meal row when the reference is written and is never rewritten โ€” if the meal is later deleted, the copy keeps history readable.

Field Type Description
uid string Unique identifier of the referenced meal
name string Display name of the referenced meal at the time the reference was made

SuccessResponse

SuccessResponse indicates whether an operation was successful

Field Type Description
success bool True if the operation succeeded

UserRef

UserRef represents a reference to a user with relationship information

Field Type Description
uid string Unique identifier of the referenced user
name string Display name of the referenced user
type RelationType Type of relationship to the referenced user

RelationType

RelationType defines the types of relationships between users.

Stored user relations carry only PARENT, PARTNER and EX_PARTNER (plus OWNER on non-user entities such as events, items and rewards). Everything else is derived server-side and appears only in User.derived_relations (ADR-0004).

Value Description
RELATION_TYPE_UNSPECIFIED Default/unknown relationship type
RELATION_TYPE_PARENT Parent edge, stored on the child: the referenced user is a parent of the holder. Any number of parent edges per person (ADR-0004).
RELATION_TYPE_CHILD Child relationship. No longer stored: writes are auto-inverted into a PARENT edge on the referenced user, and CHILD appears in derived_relations as the inverse of a parent edge (ADR-0004).
RELATION_TYPE_OWNER Owner relationship (user owns or is responsible for something)
RELATION_TYPE_PARTNER Live partnership, symmetric, stored once (on the member the write targeted). At most one live partnership per person.
RELATION_TYPE_EX_PARTNER Ended partnership. Inert: never walked by derivations, but still blocks member deletion like any stored edge.
RELATION_TYPE_SIBLING Derived only: shares at least one parent.
RELATION_TYPE_GRANDPARENT Derived only: parent of a parent.
RELATION_TYPE_GRANDCHILD Derived only: child of a child.
RELATION_TYPE_AUNT_UNCLE Derived only: a parent's sibling.
RELATION_TYPE_COUSIN Derived only: a parent's sibling's child.
RELATION_TYPE_PARENT_IN_LAW Derived only: the partner's parent.
RELATION_TYPE_CHILD_IN_LAW Derived only: a child's partner.

Reward

RewardService

RewardService provides operations for managing rewards

RPC Request Response Description
Create CreateRewardRequest RewardResponse Create a new reward
Read RewardRequest RewardResponse Read an existing reward by UID
Update UpdateRewardRequest RewardResponse Update an existing reward
Delete RewardRequest SuccessResponse Delete a reward by UID
Claim ClaimRewardRequest RewardResponse Claim a reward
LinkItem LinkRewardItemRequest RewardResponse Link a reward to an item, or unlink it (empty item_uid). Only unclaimed points rewards can be linked, and never to an item in a list (ADR-0015).
GetUserRewards GetUserRewardsRequest RewardListResponse Get all rewards for a specific user
ListRewards ListRewardsRequest ListRewardsResponse List all rewards

ClaimRewardRequest

ClaimRewardRequest contains the data needed to claim a reward

Field Type Description
reward_uid string UID of the reward to claim
user_uid string UID of the user claiming the reward

CreateRewardRequest

CreateRewardRequest contains the data needed to create a new reward

Field Type Description
name string Name of the reward
description string Description of the reward
type RewardType Type of reward
value int32 Value of the reward
user_uid string UID of the user to reward
item_uid string UID of the item/task that triggered the reward (optional)
cost int32 Points cost to claim the reward (0 = free). Rejected for REWARD_TYPE_POINTS โ€” points are earnings, not purchases (ADR-0003).
uid string Optional client-minted uid (UUIDv7) so an offline write queue can replay this create safely: a resend lands on ALREADY_EXISTS instead of minting a duplicate (ADR-0019). Empty lets the server mint one.

GetUserRewardsRequest

GetUserRewardsRequest contains the data needed to get all rewards for a user

Field Type Description
user_uid string UID of the user to get rewards for
unclaimed_only bool Whether to include only unclaimed rewards

LinkRewardItemRequest

LinkRewardItemRequest contains the data needed to link a reward to an item, or to unlink it (ADR-0015). Linking a points reward to a job makes the job worth those points: completing the job auto-claims the reward.

Field Type Description
reward_uid string UID of the reward to link or unlink
item_uid string UID of the item to link the reward to; empty = unlink the reward

ListRewardsRequest

ListRewardsRequest contains optional filters for listing rewards

Field Type Description
limit int32 Optional maximum number of rewards to return (0 means no limit)

ListRewardsResponse

ListRewardsResponse returns a list of rewards

Field Type Description
rewards repeated Reward The list of rewards

Reward

Reward represents a reward given to users for completing tasks or achievements

Field Type Description
uid string Unique identifier for the reward
name string Name or title of the reward
description string Detailed description of what the reward is for
type RewardType Type of reward (points, badge, privilege, etc.)
value int32 Numerical value of the reward (points, currency amount, etc.)
user UserRef User who earned this reward
item ItemRef Item or task that triggered this reward (optional)
earned_at google.protobuf.Timestamp When the reward was earned
claimed_at google.protobuf.Timestamp When the reward was claimed/redeemed (optional)
claimed bool Whether the reward has been claimed
mutations repeated Mutation Audit trail of changes made to this reward
cost int32 Points cost to claim this reward (0 = free). A costed reward is paid from the owner's points ledger when claimed (ADR-0003).
spent_on string UID of the claimed reward this SPEND entry paid for. Only set on REWARD_TYPE_SPEND entries, which are written by Claim (ADR-0003).

RewardListResponse

RewardListResponse returns a list of rewards

Field Type Description
rewards repeated Reward List of rewards

RewardRequest

RewardRequest is used for operations that only need a reward UID

Field Type Description
uid string UID of the reward

RewardResponse

RewardResponse returns a reward object

Field Type Description
reward Reward The requested reward

UpdateRewardRequest

UpdateRewardRequest contains the data needed to update an existing reward

Field Type Description
uid string UID of the reward to update
name string Updated name
description string Updated description
type RewardType Updated type
value int32 Updated value

RewardType

RewardType defines the different types of rewards that can be given

Value Description
REWARD_TYPE_UNSPECIFIED Default/unknown reward type
REWARD_TYPE_POINTS Points-based reward
REWARD_TYPE_BADGE Achievement badge
REWARD_TYPE_PRIVILEGE Special privilege or permission
REWARD_TYPE_CURRENCY Monetary reward
REWARD_TYPE_ITEM Physical item or gift
REWARD_TYPE_SPEND Points ledger debit written by Claim when a costed reward is claimed (ADR-0003). Never created directly; balance = sum POINTS - sum SPEND.

Role

Permission

Permission defines which roles can access a specific RPC method.

This message is used for documentation and client-side reference only. Actual authorization enforcement happens server-side in the auth interceptor. Permissions cannot be modified programmatically - any changes require a code update and new version release.

Field Type Description
service string Service name (e.g., "UserService", "EventService")
method string Method name (e.g., "Create", "Read", "Update", "Delete")
allowed_roles repeated Role Roles that are allowed to call this method

PermissionMatrix

PermissionMatrix provides a read-only reference to all service permissions.

This allows clients to understand what each role can do, enabling:

  • Client-side validation before making requests (UX optimization)
  • Permission documentation and discovery
  • CLI help text generation

Note: This is for reference/documentation only. The server is authoritative and always enforces permissions regardless of client-side checks.

Field Type Description
permissions repeated Permission All permission rules for the system

Role

Role defines user roles in the family organization system.

Roles determine what actions a user can perform in the system. The permission model is enforced server-side via the authorization interceptor.

Value Description
ROLE_UNSPECIFIED Unspecified/unknown role (should not be used in practice). This is the zero value required by Protocol Buffers.
ROLE_ADMIN Administrator with full system access. Can manage all users, events, items, and rewards. Typical use: Parents or guardians
ROLE_MEMBER Standard family member with moderate permissions. Can manage their own resources and participate in family activities. Typical use: Adult family members, teenagers
ROLE_CHILD Child user with limited permissions. Can view content and complete assigned tasks. Typical use: Young children
ROLE_GUEST Guest user with read-only access. Can only view content they're explicitly granted access to. Typical use: Extended family, friends, babysitters

Settings

SystemSettings

SystemSettings is the storage shape of the install-wide settings singleton (one row, uid "system"). It is never embedded in an RPC response โ€” the SystemService settings RPCs carry scalar fields instead, precisely so jwt_secret can never cross the wire.

Field Type Description
uid string Fixed row identifier, always "system"
family_name string Household display name
token_expiry_seconds int64 Lifetime of newly issued login tokens, in seconds. Changing it affects new sign-ins only; outstanding tokens keep their embedded expiry.
jwt_secret string HS256 signing secret for login tokens. Server-internal: seeded on first boot (from EAG_JWT_SECRET if set, otherwise generated), replaced by RotateJWTSecret, and structurally scrubbed from responses like password_hash.
mutations repeated Mutation Audit trail of changes made to the settings
default_locale string Family-wide default locale (BCP-47 tag), applied to members whose own settings carry no locale. Empty means English.
vapid_public_key string Public half of the Web Push VAPID keypair, generated on first boot and handed to browsers via PushService.GetVapidPublicKey.
vapid_private_key string Private half of the VAPID keypair. Server-internal: structurally scrubbed from responses like jwt_secret.
mcp_enabled bool Whether the /mcp endpoint answers at all. Absent means false: MCP is off until an admin turns it on.

System

SystemService

SystemService reports install-level state.

It is the home for install-level concerns: setup state, the install-wide settings singleton and the global audit log. It deliberately ships with only what is needed now โ€” no speculative endpoints.

RPC Request Response Description
SetupStatus SetupStatusRequest SetupStatusResponse SetupStatus reports whether first-time setup is needed. This is a public endpoint: the web app calls it unauthenticated to decide whether to show the welcome/first-admin flow instead of sign-in.
GetSystemSettings GetSystemSettingsRequest GetSystemSettingsResponse GetSystemSettings returns the install-wide settings. Readable by every signed-in member: the family name is shared identity and the token lifetime is not sensitive. The JWT secret is never included.
UpdateSystemSettings UpdateSystemSettingsRequest GetSystemSettingsResponse UpdateSystemSettings changes the install-wide settings (ADMIN only). Field presence decides what changes; absent fields are left untouched.
RotateJWTSecret RotateJWTSecretRequest SuccessResponse RotateJWTSecret replaces the token signing secret with a freshly generated one (ADMIN only). Every outstanding token becomes invalid immediately โ€” including the caller's. The secret itself never crosses the wire, in either direction.
AuditLog AuditLogRequest AuditLogResponse AuditLog pages backward through the install-wide audit trail (ADMIN only), newest first, optionally filtered by actor and entity type.
CheckForUpdate CheckForUpdateRequest CheckForUpdateResponse CheckForUpdate asks the release feed for the newest published version and compares it with the running one (ADMIN only). On demand only โ€” the server never phones home unprompted.
ExportData ExportDataRequest ExportDataResponse ExportData builds a downloadable archive of the install's data (ADMIN only, on demand). The archive is a gzipped JSON envelope carried as opaque bytes โ€” deliberately outside the sanitize walk so BACKUP mode can include credential material (ADR-0022).
ImportData ImportDataRequest ImportDataResponse ImportData restores a backup archive produced by ExportData (ADR-0023). On an empty install this is a public setup window like UserService/Create (ADR-0018), honouring X-Initial-Admin-Token when configured. Once any user exists it requires an ADMIN and an explicit wipe flag; the response then carries a backup of the replaced data.
ExportUserData ExportUserDataRequest ExportDataResponse ExportUserData builds a downloadable archive of one member's data โ€” their own record plus what they own or take part in, always scrubbed (ADR-0027). Every signed-in member may export themselves; exporting another member requires ADMIN. The archive reuses ADR-0022's opaque bytes envelope and can never be restored by ImportData.

AuditLogRequest

AuditLogRequest describes one page of the audit log.

Field Type Description
page_size int32 Maximum entries to return. Server clamps: default 50, cap 200.
cursor string UID of the last entry from the previous page; empty for the first page. Entry uids are time-ordered (UUIDv7), so paging is uid < cursor.
actor_uid string Restrict to changes performed by this user
entity_type string Restrict to changes on this entity type, e.g. "user", "event"

AuditLogResponse

AuditLogResponse carries one page of audit entries, newest first.

Field Type Description
entries repeated AuditEntry The entries, newest first
next_cursor string Cursor for the next page; empty when this is the last page

CheckForUpdateRequest

CheckForUpdateRequest is empty; the feed is server configuration.

CheckForUpdateResponse

CheckForUpdateResponse compares the running version with the newest published release.

Field Type Description
current_version string The version this server is running
latest_version string The newest published version the feed reports
update_available bool True when latest_version is newer than current_version
release_url string Human-readable page for the newest release (empty when the feed has none)

ExportDataRequest

ExportDataRequest names the archive to build.

Field Type Description
mode ExportMode Which archive to build; UNSPECIFIED is rejected

ExportDataResponse

ExportDataResponse carries the finished archive.

Field Type Description
archive bytes gzip-compressed JSON envelope (formatVersion, exportedAt, mode, appVersion, tables). Opaque to the response interceptors by design (ADR-0022).
filename string Suggested download name, e.g. eagraiclainne-backup-2026-08-08T12-00-00Z.json.gz

ExportUserDataRequest

ExportUserDataRequest names whose data to export.

Field Type Description
user_uid string UID of the member to export. Empty means the caller themselves; a non-self target requires ADMIN (enforced in the handler, ADR-0027).

GetSystemSettingsRequest

GetSystemSettingsRequest is empty; the settings are global.

GetSystemSettingsResponse

GetSystemSettingsResponse carries the readable settings scalars. The JWT secret is deliberately not part of this message.

Field Type Description
family_name string Household display name
token_expiry_seconds int64 Lifetime of newly issued login tokens, in seconds
default_locale string Family-wide default locale (BCP-47 tag); empty means English
mcp_enabled bool Whether the /mcp endpoint is enabled

ImportDataRequest

ImportDataRequest carries the archive to restore.

Field Type Description
archive bytes gzipped backup envelope produced by ExportData; backup mode only โ€” portable archives carry no credentials and are refused
wipe bool Consent to replace existing data. Required once any user exists; ignored on an empty install.

ImportDataResponse

ImportDataResponse reports the restore and, after a wipe, carries the replaced data.

Field Type Description
pre_wipe_archive bytes Backup of the data that existed before a wipe, read inside the import transaction. Empty on a setup-window restore. Opaque bytes by design โ€” ADR-0022's sanitize bypass, extended by ADR-0023.
pre_wipe_filename string Suggested filename for the pre-wipe backup; empty when no wipe happened
rows_restored int64 Total rows restored across all tables

RotateJWTSecretRequest

RotateJWTSecretRequest is empty: the server generates the new secret; callers never supply or see it.

SetupStatusRequest

SetupStatusRequest is empty; setup state is global.

SetupStatusResponse

SetupStatusResponse describes the install's setup state.

Field Type Description
needs_setup bool True when no users exist yet
setup_token_required bool True when EAG_INITIAL_ADMIN_TOKEN is configured on the server

UpdateSystemSettingsRequest

UpdateSystemSettingsRequest names the settings to change; absent fields are left untouched.

Field Type Description
family_name string New household display name
token_expiry_seconds int64 New lifetime for newly issued login tokens, in seconds. Affects new sign-ins only; outstanding tokens keep their embedded expiry.
default_locale string New family-wide default locale (BCP-47 tag, one of the supported set)
mcp_enabled bool Turn the /mcp endpoint on or off. Takes effect on the next request.

ExportMode

ExportMode selects what an export archive contains.

Value Description
EXPORT_MODE_UNSPECIFIED No mode chosen; the server rejects this โ€” secrets must never ship by default.
EXPORT_MODE_BACKUP Full fidelity: every table verbatim, secrets included. Restore-capable.
EXPORT_MODE_PORTABLE Sanitized: content tables only, credential and session material stripped. Safe to keep or hand over.

User

UserService

UserService provides operations for managing users

RPC Request Response Description
Create CreateUserRequest UserResponse Create a new user
Read UserRequest UserResponse Read an existing user by UID
Update UpdateUserRequest UserResponse Update an existing user
Delete UserRequest SuccessResponse Delete a user by UID
ReferenceUser ReferenceUserRequest UserResponse Add a reference/relationship to another user
Login LoginRequest LoginResponse Authenticate a user with email and password
RenewToken RenewTokenRequest LoginResponse Re-issue the requester's token with a fresh expiry (sliding renewal). Roles come from the stored account, not the presented token, so a renewal also picks up role changes made since sign-in. Requires a currently valid token โ€” an expired session cannot renew itself.
AssignRoles AssignRolesRequest AssignRolesResponse Assign roles to a user (ADMIN only)
Logout LogoutRequest SuccessResponse Clear the web session cookie. Public: it must work even when the presented session is already dead. Clears the cookie only โ€” it does not invalidate the token elsewhere.
RefreshSession RefreshSessionRequest LoginResponse Exchange a valid refresh token for a fresh access token and a new refresh token (rotation: the presented token is dead afterwards). Public: the access token is typically expired when this is called. Presenting a rotated-out token revokes the whole session chain โ€” the reuse means either theft or a client that lost a rotation.
ListSessions ListSessionsRequest ListSessionsResponse List the requester's own device sessions (one entry per chain, newest first). Token hashes never leave the server.
RevokeSession RevokeSessionRequest SuccessResponse Revoke one of the requester's own session chains: every refresh token in the chain is dead on the next exchange. Idempotent.
ChangePassword ChangePasswordRequest SuccessResponse Change the requester's own password (proving the current one)
SetPassword SetPasswordRequest SuccessResponse Set another user's password without proof of the current one (ADMIN only) โ€” the recovery path when a member forgets theirs.
SwitchProfile SwitchProfileRequest LoginResponse Swap the device's active session to another profile whose parked refresh chain this device holds (ADR-0020). Public: the caller's access token may be absent (sign-in screen) โ€” possession of the parked chain is the base proof, plus the target's PIN when one is set.
SetPin SetPinRequest SuccessResponse Set or clear the requester's own quick-switch PIN, proving the current password. Strictly self-service โ€” the request carries no uid by design.
ClearPin ClearPinRequest SuccessResponse Clear another member's quick-switch PIN (ADMIN only) โ€” the recovery path when a member forgets theirs. PINs are cleared, never read.
ListUsers ListUsersRequest ListUsersResponse List all users

AssignRolesRequest

AssignRolesRequest contains the data needed to assign roles to a user

Field Type Description
user_uid string UID of the user to assign roles to
roles repeated Role Roles to assign to the user

AssignRolesResponse

AssignRolesResponse returns the updated user with new roles

Field Type Description
user User The updated user

ChangePasswordRequest

ChangePasswordRequest carries a self-service password change: the caller proves the current password and supplies the new one. The account is always the requester's own โ€” there is no uid field by design.

Field Type Description
current_password string The account's current password
new_password string The new password (minimum length enforced server-side)

ClearPinRequest

ClearPinRequest carries an admin PIN reset: another member's PIN is cleared, never read. The member sets a new one themselves via SetPin.

Field Type Description
user_uid string UID of the account to clear the PIN on

CreateUserRequest

CreateUserRequest contains the data needed to create a new user

Field Type Description
user User User data for the new user
password string Plain text password (will be hashed server-side)
initial_roles repeated Role Initial roles to assign (only ADMIN can set, defaults to [ROLE_MEMBER])

ListSessionsRequest

ListSessionsRequest is empty: sessions listed are the requester's own.

ListSessionsResponse

ListSessionsResponse returns the requester's device sessions, one per chain, newest first. Token hashes are scrubbed.

Field Type Description
sessions repeated Session The session records

ListUsersRequest

ListUsersRequest contains optional filters for listing users

Field Type Description
limit int32 Optional maximum number of users to return (0 means no limit)

ListUsersResponse

ListUsersResponse returns a list of users

Field Type Description
users repeated User The list of users

LoginRequest

LoginRequest contains credentials for authentication

Field Type Description
email string Email address
password string Plain text password
remember_device bool Ask for a refresh token alongside the access token, starting a device session that outlives the access token's expiry.
device_label string Human-readable device label for the session list, e.g. "Luke's phone". Only meaningful with remember_device.

LoginResponse

LoginResponse returns authentication token and user info

Field Type Description
token string JWT token for authentication
expires_at google.protobuf.Timestamp Token expiration time
user User Authenticated user information
refresh_token string Opaque refresh token (remember_device logins and RefreshSession only). Shown exactly once per rotation; the server stores a hash. Blanked in cookie mode โ€” the browser gets it as an httpOnly cookie scoped to the RefreshSession procedure instead.

LogoutRequest

LogoutRequest ends the caller's session. Browsers send it empty โ€” the refresh cookie names the chain to revoke. Bearer clients (the app) have no cookie and pass their refresh token here instead.

Field Type Description
refresh_token string The opaque refresh token whose chain this logout revokes (bearer clients; cookie mode leaves it empty)
forget_user_uid string Forget this user's PARKED chain on this device instead of the active session (ADR-0020): the parked chain is revoked and its cookie cleared, the active session untouched. Possession of the parked cookie is the authority. The server half of "Remove me from this device".

ReferenceUserRequest

ReferenceUserRequest contains the data needed to add a relationship reference

Field Type Description
uid string UID of the user to add the reference to
ref UserRef Reference/relationship to add

RefreshSessionRequest

RefreshSessionRequest presents the opaque refresh token. Empty in cookie mode: the browser's httpOnly refresh cookie carries it instead.

Field Type Description
refresh_token string The opaque refresh token (bearer clients; cookie mode leaves it empty)

RenewTokenRequest

RenewTokenRequest is empty: the account is always the requester's own, identified by the presented token.

RevokeSessionRequest

RevokeSessionRequest names one of the requester's chains to kill.

Field Type Description
chain_uid string chain_uid of the session to revoke

Session

Session is one refresh-token record. Rotation writes a new record into the same chain, so a device session is a chain of records; the newest unrevoked one holds the only exchangeable token. Rows are server-side bookkeeping โ€” ListSessions returns one Session per chain with the hash scrubbed.

Field Type Description
uid string Unique identifier of this record
user_uid string The account the session belongs to
label string Human-readable device label, from the login that started the chain
token_hash string SHA-256 of the opaque token. Never returned in API responses (response-scrubbed); the plaintext token is never stored.
chain_uid string Chain identity: constant across rotations of one device session
created_at google.protobuf.Timestamp When this record was minted
last_used_at google.protobuf.Timestamp When this record's token was last presented
revoked_at google.protobuf.Timestamp Set when rotated out or revoked. A revoked record's token no longer exchanges โ€” presenting it anyway revokes the whole chain.
successor_uid string Set when the revocation was a rotation: the uid of the record this one rotated into. Absent on explicitly revoked records โ€” the distinction gates the reuse grace (a race loser gets grace; a revoked session gets refused on the spot).
pin_misses int32 Consecutive failed quick-switch PIN attempts against this chain (ADR-0020). Copied to the successor on rotation, like label. The fifth miss locks the chain for PIN switching.
pin_locked_at google.protobuf.Timestamp Set when the fifth miss locked this chain for PIN switching. Only a fresh password login clears it โ€” the new chain replaces this one.
pin_attempted_at google.protobuf.Timestamp When a PIN was last attempted against this chain, for attempt-rate throttling.

SetPasswordRequest

SetPasswordRequest carries an admin password reset: a temporary password set on another member's account, no current-password proof. The member is expected to change it themselves via ChangePassword afterwards; nothing forces that (household trust model).

Field Type Description
user_uid string UID of the account to set the password on
new_password string The new password (minimum length enforced server-side)

SetPinRequest

SetPinRequest carries a self-service PIN change: the caller proves the current password and supplies the new PIN. The account is always the requester's own โ€” there is no uid field by design.

Field Type Description
current_password string The account's current password
pin string The new PIN โ€” exactly 4 digits. Empty clears the caller's PIN.

SwitchProfileRequest

SwitchProfileRequest asks to make another resident profile the device's active session (ADR-0020). In cookie mode the parked chains ride httpOnly eagraiclainne_parked_ cookies and both token fields stay empty.

Field Type Description
target_user_uid string UID of the profile to switch to
pin string The target's 4-digit quick-switch PIN. Required when the target has one; ignored otherwise.
target_refresh_token string The target's parked refresh token (bearer clients; cookie mode leaves it empty โ€” the eagraiclainne_parked_ cookie carries it)
park_refresh_token string The caller's own active refresh token, to be parked โ€” or revoked, when it belongs to a PIN-less admin (bearer clients; cookie mode leaves it empty โ€” the eagraiclainne_refresh cookie carries it)

UpdateUserRequest

UpdateUserRequest contains the data needed to update an existing user

Field Type Description
uid string UID of the user to update
user User Updated user data
update_mask google.protobuf.FieldMask Names of the User fields to apply from user. Must name at least one field; unmasked fields are left untouched. Members updating their own profile may mask name, email, birthday and settings; ADMIN may additionally mask deathday and relations. Masking "settings" replaces the whole message (no sub-paths); masking it with settings absent clears the stored settings.

User

User represents a person in the family organization system

Field Type Description
uid string Unique identifier for the user
name string Full name of the user
birthday google.protobuf.Timestamp Date of birth
deathday google.protobuf.Timestamp Date of death (optional, for deceased family members)
mutations repeated Mutation Audit trail of changes made to this user
email string Email address of the user
relations repeated UserRef Family relationships to other users. Stored edges only: PARENT (directed child -> parent, stored on the child), PARTNER (symmetric, stored once) and EX_PARTNER (inert). See ADR-0004.
password_hash string Password hash (bcrypt) - never returned in API responses
roles repeated Role User's assigned roles (determines permissions)
derived_relations repeated UserRef Derived family relations (CHILD, SIBLING, GRANDPARENT, GRANDCHILD, AUNT_UNCLE, COUSIN, PARENT_IN_LAW, CHILD_IN_LAW), computed server-side from the stored PARENT and PARTNER edges on every read (ADR-0004). Response-only: never stored and never writable.
settings UserSettings Synced appearance settings: mark and theme. Visible to every member โ€” the mark is shared identity โ€” and writable via the Update mask path "settings" (self, or ADMIN for members who cannot sign in).
token_generation int64 Credential generation, bumped on every password change so tokens minted before the change stop verifying. Never returned in API responses (response-scrubbed) and never client-writable.
pin_hash string bcrypt hash of the 4-digit quick-switch PIN (ADR-0020). Empty means no PIN is set. Never returned in API responses (response-scrubbed).
has_pin bool Whether a quick-switch PIN is set. Response-only: derived from pin_hash by the sanitize pass before the hash is scrubbed โ€” never stored, never client-writable.

UserMark

UserMark is a member's shared identity mark: a colour id and a symbol id. The web owns the id vocabularies; the server only caps lengths.

Field Type Description
color string Colour id (Okabe-Ito palette id in the web client)
symbol string Symbol id (emoji symbol id in the web client)

UserRequest

Common request/response patterns UserRequest is used for operations that only need a user UID

Field Type Description
uid string UID of the user

UserResponse

UserResponse returns a user object with its UID

Field Type Description
uid string UID of the user
user User The user data

UserSettings

UserSettings carries the synced per-member preferences.

Field Type Description
mark UserMark The member's mark, rendered for everyone
theme UserTheme The member's theme preferences
tour_seen_version int32 Highest first-login tour version this member has seen (0 = never). The web shows the walkthrough when this trails its current version, so a member sees each tour once across every device โ€” and future releases can append "what's new" cards by bumping the version.
locale string BCP-47 language tag for the member's UI and notifications ("en", "ga", "fr", "de", "es", "pl"). Empty means "use the family default".
push_disabled_kinds repeated NotificationKind Notification kinds Web Push delivery is switched OFF for. Absent means every kind pushes. Gates push only โ€” the in-app inbox always gets every row.

UserTheme

UserTheme is a member's synced appearance: theme family, light/dark/auto mode, and the custom theme's token overrides plus the hand-pinned token list. Text scale and reduce-motion are deliberately device-local and not synced here.

Field Type Description
family string Theme family id, or "custom"
mode string "light", "dark" or "auto"
custom_tokens map<string, string> Custom theme token overrides (CSS custom property name -> value)
custom_touched repeated string Token names the user pinned by hand in the custom theme editor

Webhook

WebhookService

WebhookService manages outbound event targets (ADR-0024). Every RPC is admin-only via the permission matrix (ADR-0002/0008).

RPC Request Response Description
CreateWebhook CreateWebhookRequest CreateWebhookResponse Register a webhook. The response carries the signing secret exactly once.
ListWebhooks ListWebhooksRequest ListWebhooksResponse List all webhooks (records only โ€” no secrets)
UpdateWebhook UpdateWebhookRequest WebhookResponse Replace a webhook's name, URL and event patterns
DeleteWebhook WebhookRequest DeleteWebhookResponse Remove a webhook; in-flight deliveries stop at their next retry
TestWebhook WebhookRequest TestWebhookResponse Send a signed webhook.test event synchronously and report the outcome

CreateWebhookRequest

CreateWebhookRequest registers a new outbound target (ADMIN only).

Field Type Description
name string Human-readable label (required)
url string Delivery target (required; http or https)
events repeated string Event patterns to subscribe to

CreateWebhookResponse

CreateWebhookResponse carries the record and โ€” exactly once โ€” the raw signing secret. It cannot be retrieved again; rotation is delete-and-recreate.

Field Type Description
webhook Webhook The stored webhook record (secret scrubbed)
secret string The HMAC signing secret; shown only in this response

DeleteWebhookResponse

DeleteWebhookResponse confirms removal.

ListWebhooksRequest

ListWebhooksRequest lists every webhook.

Field Type Description
limit int32 Maximum number of webhooks to return (0 = no limit)

ListWebhooksResponse

ListWebhooksResponse returns webhook records (secrets scrubbed).

Field Type Description
webhooks repeated Webhook The webhook records

TestWebhookResponse

TestWebhookResponse reports the outcome of a synchronous test delivery.

Field Type Description
status_code int32 HTTP status returned by the target (0 when the request never completed)
latency_ms int64 Round-trip time of the delivery attempt
error string Transport error when the request never completed; empty on success

UpdateWebhookRequest

UpdateWebhookRequest replaces a webhook's name, URL and event patterns in full. The secret is never changed here โ€” rotation is delete-and-recreate.

Field Type Description
uid string UID of the webhook
name string New label (required)
url string New delivery target (required)
events repeated string New event patterns (full replace)

Webhook

Webhook is an admin-configured outbound event target (ADR-0024). Matching events are POSTed to the URL as signed JSON envelopes. The secret keys the HMAC signature and is stored on this record because signing needs the raw value; the sanitize scrub map clears it from every response โ€” it appears in clear exactly once, as CreateWebhookResponse.secret.

Field Type Description
uid string Unique identifier
name string Human-readable label, e.g. "home-assistant"
url string Delivery target; http or https
events repeated string Event patterns this webhook subscribes to. Exact match, or prefix when the pattern ends in "" ("notify.", "mutation.item.", bare ""). Empty = deliver nothing.
secret string Raw HMAC-SHA256 key. Stored for signing; scrubbed from every response.
created_by UserRef Admin who created the webhook
created_at google.protobuf.Timestamp When the webhook was created
last_delivery_status string Outcome of the most recent delivery ("delivered" or "failed: "). Operational stamp โ€” written without a mutation trail or audit entry.
last_delivery_at google.protobuf.Timestamp When the most recent delivery finished
mutations repeated Mutation Audit trail of changes made to this webhook

WebhookRequest

WebhookRequest names one webhook by uid.

Field Type Description
uid string UID of the webhook

WebhookResponse

WebhookResponse returns one webhook record.

Field Type Description
webhook Webhook The webhook record