Inventory & shopping

The pantry, leftovers and the shopping list.35 operations

Headers on every response

Every response on this page carries these headers.
X-Trace-Id
— The W3C trace id of this request — the same id in the log and in the traceId of a problem. Quote it when reporting.
Server-Timing
— Where the time went: total, db;dur=…;desc="N queries", and every step the handler named (ADR-163).
X-Diagnostics
— Only when the request asked with X-Diagnostics: 1 or ?diagnostics=1: the same breakdown as one JSON object, with the trace id (ADR-163).

Operations

GET/api/v1/households/{householdId}/inventory

Read the pantry a page at a time: one row per food, as the household's evidence stands

Each row is a fold over the household's observations — quantity, confidence, «last seen», use-by window and the keys merged into it (#466). Names come back in the household's language. ?q= matches the row's display name and its food key, case-insensitively; ?place= is one StorageLocation; ?group= is one of the pantry's four sections — UseSoon, LikelyAvailable, Uncertain or Aged — and leaving it out gives the three the list shows, the archive excluded (#390). ?limit= is 1–100, 50 by default. The order is the pantry's own: the section first, so the reader's headings stay whole across pages, then the use priority, the name and the food key. total counts every row the filter matches, and nextCursor — opaque — is handed back as ?cursor= for the next page; null on the last. A cursor nobody handed out is a 400. The numbers over the list — the place tabs, the section headings, the triage deck — come from GET …/inventory/summary (#3000, ADR-292).

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
qquerystring——
placequeryStorageLocation——
groupqueryInventoryGroup——
cursorquerystring——
limitqueryinteger (int32)——

Responses

200OK
application/jsonPagedInventoryItemResponse
400Bad Request
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/inventory"

Example response

200application/json
{
  "items": [
    {
      "foodKey": "string",
      "displayName": "string",
      "estimatedQuantity": 0,
      "unit": "string",
      "confidence": 0,
      "storageLocation": {},
      "usePriority": {},
      "lastEvidenceAt": "2026-09-07T16:30:00Z",
      "aisle": {},
      "asksForDate": false,
      "lastEvidenceKind": {}
    }
  ],
  "nextCursor": "string",
  "total": 0
}
GET/api/v1/households/{householdId}/inventory/summary

Count the pantry without reading it: rows per place, per section, and the triage deck

Any member. byGroup and total are counted under the same ?q= and ?place= the rows were asked for, because a heading's number has to match the list under it; byPlace and triage are about the whole pantry on purpose — the tab strip has to show every place the pantry has, and the triage deck is the whole kitchen or the freezer's «vet ikke» rows are never asked about (#455). byPlace leaves the archived rows out, the way the tabs have always counted (#390); total counts them, so it is the sum of the four in byGroup.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
qquerystring——
placequeryStorageLocation——

Responses

200OK
application/jsonInventorySummaryResponse
400The request could not be read as the route needs it: a body that is not the documented shape (a required field left out, a null where none is allowed, a value too long for its field), a parameter that does not parse, or a NUL character anywhere (#3540, #3541, #3543). Code validation_failed or value_too_long.
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/inventory/summary"

Example response

200application/json
{
  "byPlace": {
    "fridge": 0,
    "pantry": 0,
    "freezer": 0,
    "unknown": 0
  },
  "byGroup": {
    "useSoon": 0,
    "likelyAvailable": 0,
    "uncertain": 0,
    "aged": 0
  },
  "triage": 0,
  "total": 0,
  "matchesByPlace": {
    "fridge": 0,
    "pantry": 0,
    "freezer": 0,
    "unknown": 0
  }
}
POST/api/v1/households/{householdId}/inventory/observations

Record a pantry observation for one food (bought, seen, used up, gone…)

Any member. Answers the observation's own id — the handle for undoing the tick (#457) — and the food's row as it now stands; a «gone» tick answers an empty row. Free-form food keys are normalized server-side.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—

Request body

application/jsonRequiredAddInventoryObservationRequest

Responses

200OK
application/jsonAddObservationResponse
400Bad Request
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X POST \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/inventory/observations" \
  -H "Content-Type: application/json" \
  -d '{"foodKey":"string","displayName":"string","observationType":"Purchased","quantity":0,"unit":"string","storageLocation":"Fridge","confidence":0}'

Example response

200application/json
{
  "observationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "item": {
    "foodKey": "string",
    "displayName": "string",
    "estimatedQuantity": 0,
    "unit": "string",
    "confidence": 0,
    "storageLocation": {},
    "usePriority": {},
    "lastEvidenceAt": "2026-09-07T16:30:00Z",
    "aisle": {},
    "asksForDate": false,
    "lastEvidenceKind": {}
  }
}
DELETE/api/v1/households/{householdId}/inventory/observations

Empty the pantry evidence — all of it, or one storage location's

Adults only; a Junior member gets 403 (#981, ADR-083). Pass ?location=Fridge|Freezer|Pantry|Unknown to wipe one shelf; without it every observation goes. Answers how many observations were removed.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
locationqueryStorageLocation——

Responses

400The request could not be read as the route needs it: a body that is not the documented shape (a required field left out, a null where none is allowed, a value too long for its field), a parameter that does not parse, or a NUL character anywhere (#3540, #3541, #3543). Code validation_failed or value_too_long.
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X DELETE \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/inventory/observations"

Example response

200application/json
{
  "removedObservations": 0
}
DELETE/api/v1/households/{householdId}/inventory/observations/{observationId}

Undo one pantry observation

Any member. The observation leaves the history, so the row is exactly what it was before it — «last seen» included (#457). 404 on a stale id is not an error: another device may have retracted it already.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
observationIdpathstring (uuid)Required—

Responses

204No Content
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X DELETE \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/inventory/observations/3fa85f64-5717-4562-b3fc-2c963f66afa6"
GET/api/v1/households/{householdId}/inventory/merge-suggestions

Suggest pairs of pantry rows that look like the same food

Any member. Computed on every read, never stored: at most three pairs, leaving out the pairs the household has already said no to (#466). The pair of keys is the suggestion's identity — there is no id.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—

Responses

200OK
application/jsonPantryMergeSuggestionResponse[]
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/inventory/merge-suggestions"

Example response

200application/json
[
  {
    "from": {
      "foodKey": "string",
      "displayName": "string",
      "estimatedQuantity": 0,
      "unit": "string",
      "confidence": 0,
      "storageLocation": {},
      "usePriority": {},
      "lastEvidenceAt": "2026-09-07T16:30:00Z",
      "aisle": {},
      "asksForDate": false,
      "lastEvidenceKind": {}
    },
    "to": {
      "foodKey": "string",
      "displayName": "string",
      "estimatedQuantity": 0,
      "unit": "string",
      "confidence": 0,
      "storageLocation": {},
      "usePriority": {},
      "lastEvidenceAt": "2026-09-07T16:30:00Z",
      "aisle": {},
      "asksForDate": false,
      "lastEvidenceKind": {}
    },
    "signal": "ContainedTokens"
  }
]
GET/api/v1/households/{householdId}/inventory/merges

List a page of the household's pantry merges

Any member. Cursor-paged (ADR-292): ordered by the surviving row's key, then newest answer within it, so the page's cards stay whole across a page boundary. The «nei, ulike» answers are their own read — GetPantryMergeRejections. 400 on a limit out of range or a foreign cursor.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
cursorquerystring——
limitqueryinteger (int32)——

Responses

400Bad Request
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/inventory/merges"

Example response

200application/json
{
  "items": [
    {
      "fromKey": "string",
      "fromDisplayName": "string",
      "toKey": "string",
      "toDisplayName": "string",
      "mergedAt": "2026-09-07T16:30:00Z"
    }
  ],
  "nextCursor": "string",
  "total": 0
}
POST/api/v1/households/{householdId}/inventory/merges

Merge one pantry food key into another («yes, same food»)

Adults only; a Junior member gets 403 (#981, ADR-083). Safe to retry: the same pair twice is the same answer, and two devices racing land on one alias row. A yes overrides an earlier «different foods» answer. 400 when both keys are the same food; 409 when the merge would point the two rows at each other (A→B already stands and B→A is asked).

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—

Request body

application/jsonRequiredMergePantryKeysRequest

Responses

200OK
application/jsonPantryMergeResponse
400Bad Request
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
409Conflict
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X POST \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/inventory/merges" \
  -H "Content-Type: application/json" \
  -d '{"fromKey":"string","toKey":"string","source":"Suggestion"}'

Example response

200application/json
{
  "fromKey": "string",
  "toKey": "string",
  "item": {
    "foodKey": "string",
    "displayName": "string",
    "estimatedQuantity": 0,
    "unit": "string",
    "confidence": 0,
    "storageLocation": {},
    "usePriority": {},
    "lastEvidenceAt": "2026-09-07T16:30:00Z",
    "aisle": {},
    "asksForDate": false,
    "lastEvidenceKind": {}
  }
}
GET/api/v1/households/{householdId}/inventory/merge-rejections

List a page of the household's «different foods» answers

Any member. Cursor-paged (ADR-292), newest answer first. A no keeps a pair out of the suggestions until «Spør igjen» lifts it (#550). 400 on a limit out of range or a foreign cursor.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
cursorquerystring——
limitqueryinteger (int32)——

Responses

400Bad Request
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/inventory/merge-rejections"

Example response

200application/json
{
  "items": [
    {
      "keyA": "string",
      "keyADisplayName": "string",
      "keyB": "string",
      "keyBDisplayName": "string",
      "decidedAt": "2026-09-07T16:30:00Z"
    }
  ],
  "nextCursor": "string",
  "total": 0
}
POST/api/v1/households/{householdId}/inventory/merge-rejections

Say two pantry rows are different foods, so the pair is not suggested again

Adults only; a Junior member gets 403. The pair is unordered, and the answer is idempotent — a second no is the same no.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—

Request body

application/jsonRequiredRejectPantryMergeRequest

Responses

204No Content
400The request could not be read as the route needs it: a body that is not the documented shape (a required field left out, a null where none is allowed, a value too long for its field), a parameter that does not parse, or a NUL character anywhere (#3540, #3541, #3543). Code validation_failed or value_too_long.
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X POST \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/inventory/merge-rejections" \
  -H "Content-Type: application/json" \
  -d '{"keyA":"string","keyB":"string"}'
DELETE/api/v1/households/{householdId}/inventory/merges/{fromKey}

Split a merged pantry food key back out into its own row

Adults only; a Junior member gets 403. Also remembers a no for the pair, so it is not the very next suggestion (lift it with DELETE merge-rejections/{keyA}/{keyB}, #550). 404 when there is no merge on that key — another device may already have split it.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
fromKeypathstringRequired—

Responses

204No Content
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X DELETE \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/inventory/merges/string"
DELETE/api/v1/households/{householdId}/inventory/merge-rejections/{keyA}/{keyB}

Lift a «different foods» answer so the pair can be suggested again

Adults only; a Junior member gets 403. The pair is unordered — the server sorts the two keys (#550). 404 when no answer is stored for the pair, which is not an error: the pair is already in the asked-for state.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
keyApathstringRequired—
keyBpathstringRequired—

Responses

204No Content
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X DELETE \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/inventory/merge-rejections/string/string"
GET/api/v1/households/{householdId}/inventory/unit-weights

List what one unit of a food weighs in this household's kitchen

Any member. «One cheese is 400 g here» (#551): the household's own answers per food and unit, in grams, which the pantry projection and the shopping list convert with. Bounded by the foods the household has corrected, so it does not page (ADR-292) — but foodKey narrows it to one food, which is how the item sheet reads it (#3003).

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
foodKeyquerystring——

Responses

200OK
application/jsonUnitWeightResponse[]
400The request could not be read as the route needs it: a body that is not the documented shape (a required field left out, a null where none is allowed, a value too long for its field), a parameter that does not parse, or a NUL character anywhere (#3540, #3541, #3543). Code validation_failed or value_too_long.
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/inventory/unit-weights"

Example response

200application/json
[
  {
    "foodKey": "string",
    "unit": "string",
    "displayName": "string",
    "grams": 0,
    "updatedAt": "2026-09-07T16:30:00Z"
  }
]
PUT/api/v1/households/{householdId}/inventory/unit-weights/{foodKey}/{unit}

Set what one unit of a food weighs in this kitchen, in grams

Adults only; a Junior member gets 403 (#981, ADR-083). One answer per food and unit: a second call restates the first, so it is safe to retry. Deliberately rebuilds no shopping list — ask for a regeneration when ready (#551). 400 when the grams are out of bounds.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
foodKeypathstringRequired—
unitpathstringRequired—

Request body

application/jsonRequiredSetUnitWeightRequest

Responses

200OK
application/jsonUnitWeightResponse
400Bad Request
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X PUT \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/inventory/unit-weights/string/string" \
  -H "Content-Type: application/json" \
  -d '{"grams":0}'

Example response

200application/json
{
  "foodKey": "string",
  "unit": "string",
  "displayName": "string",
  "grams": 0,
  "updatedAt": "2026-09-07T16:30:00Z"
}
DELETE/api/v1/households/{householdId}/inventory/unit-weights/{foodKey}/{unit}

Forget the household's unit weight for a food

Adults only; a Junior member gets 403. The conversion refuses again afterwards — two honest lines rather than one invented one. 404 when there is no answer on that food and unit; another device may already have forgotten it.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
foodKeypathstringRequired—
unitpathstringRequired—

Responses

204No Content
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X DELETE \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/inventory/unit-weights/string/string"
POST/api/v1/households/{householdId}/plans/{planId}/shopping-list/generate

Build, or rebuild, the shopping list for a planned week

Any member. Since ADR-352 the list is derived on every read that finds the week or the pantry changed, so this call is no longer needed to have a list: it derives the list again now, prices included, which is what «Oppdater prisene» uses, and older app builds still call it. Ticks and hand-added lines are kept. Prices are a garnish: when the price provider fails the list ships without suggestions.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
planIdpathstring (uuid)Required—

Responses

200OK
application/jsonShoppingListResponse
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X POST \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/plans/3fa85f64-5717-4562-b3fc-2c963f66afa6/shopping-list/generate"

Example response

200application/json
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "householdId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "weeklyPlanId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "generatedAt": "2026-09-07T16:30:00Z",
  "items": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "foodKey": "string",
      "displayName": "string",
      "requiredQuantity": 0,
      "unit": "string",
      "status": {},
      "purchasedQuantity": 0,
      "reasonCode": {},
      "haveQuantity": 0,
      "relatedPlanEntryIds": [
        "3fa85f64-5717-4562-b3fc-2c963f66afa6"
      ],
      "addedAfterShopping": false,
      "suggestedPriceIsAggregate": false,
      "suggestedPriceSource": {},
      "aisle": {},
      "isManual": false,
      "preferenceFit": {}
    }
  ],
  "sharingOff": false,
  "priceCatalogueOn": false
}
GET/api/v1/households/{householdId}/plans/{planId}/shopping-list

Read the shopping list for a planned week

Any member. The list is derived from the week's dinners and the pantry and follows every change to either (ADR-352), so it exists as soon as the plan does; 404 only when the plan is not this household's. The response carries a weak ETag over the list itself and Cache-Control: private, no-cache; an If-None-Match that still holds is answered 304 with no body, which is what makes the apps' fifteen-second poll free in a shop with bad coverage (#2984).

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
planIdpathstring (uuid)Required—

Responses

200OK
application/jsonShoppingListResponse
304Not Modified
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/plans/3fa85f64-5717-4562-b3fc-2c963f66afa6/shopping-list"

Example response

200application/json
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "householdId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "weeklyPlanId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "generatedAt": "2026-09-07T16:30:00Z",
  "items": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "foodKey": "string",
      "displayName": "string",
      "requiredQuantity": 0,
      "unit": "string",
      "status": {},
      "purchasedQuantity": 0,
      "reasonCode": {},
      "haveQuantity": 0,
      "relatedPlanEntryIds": [
        "3fa85f64-5717-4562-b3fc-2c963f66afa6"
      ],
      "addedAfterShopping": false,
      "suggestedPriceIsAggregate": false,
      "suggestedPriceSource": {},
      "aisle": {},
      "isManual": false,
      "preferenceFit": {}
    }
  ],
  "sharingOff": false,
  "priceCatalogueOn": false
}
GET/api/v1/households/{householdId}/plans/{planId}/shopping-list/better-choices

Suggest less processed products for the heavily processed lines on a week's list

Any member. For each line still to buy whose suggested product is NOVA 4 in Open Food Facts (or, without one, whose food mostly is), at most three NOVA 1-3 products: the household's own earlier buys first, then what its chains' catalogues list, then the same food before another in its Matvaretabellen group, then the lower step and price. Deterministic from data, no model call; lines without a choice are left out (#3248).

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
planIdpathstring (uuid)Required—

Responses

200OK
application/jsonBetterChoicesResponse
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/plans/3fa85f64-5717-4562-b3fc-2c963f66afa6/shopping-list/better-choices"

Example response

200application/json
{
  "weeklyPlanId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "lines": [
    {
      "foodKey": "string",
      "basis": {},
      "productName": "string",
      "choices": [
        {}
      ]
    }
  ]
}
GET/api/v1/households/{householdId}/shopping/purchase-classification

Count what the household's own receipts bought, by how processed the products are

Any member. Distinct receipt lines with a price in the last days (default 30, at most 365), each read as an Open Food Facts product when its words and food match one; counts per NOVA group, raw. The share is of the recognised lines only, and the apps say so in the same sentence (#2525, ADR-213). Own receipts only, never aggregated.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
daysqueryinteger (int32)——

Responses

200OK
application/jsonPurchaseClassificationResponse
400The request could not be read as the route needs it: a body that is not the documented shape (a required field left out, a null where none is allowed, a value too long for its field), a parameter that does not parse, or a NUL character anywhere (#3540, #3541, #3543). Code validation_failed or value_too_long.
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/shopping/purchase-classification"

Example response

200application/json
{
  "days": 0,
  "linesTotal": 0,
  "linesRecognised": 0,
  "heavilyProcessed": 0,
  "processed": 0,
  "lightlyProcessed": 0,
  "processingUnknown": 0,
  "examples": [
    {
      "productName": "string",
      "novaGroup": 0,
      "nutriScore": "string"
    }
  ]
}
POST/api/v1/households/{householdId}/plans/{planId}/shopping-list/complete

Finish the shopping trip and book what was bought into the pantry

Any member. Idempotent: only the first call writes the ticked lines into the pantry as purchases and answers a TripSummary (#448). ?markAllBought=true ticks every remaining line as part of the closing, so a reopen can take exactly those ticks back (#1121). The shopper gets one receipt-reminder push (#37).

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
planIdpathstring (uuid)Required—
markAllBoughtqueryboolean——

Responses

200OK
application/jsonShoppingListResponse
400The request could not be read as the route needs it: a body that is not the documented shape (a required field left out, a null where none is allowed, a value too long for its field), a parameter that does not parse, or a NUL character anywhere (#3540, #3541, #3543). Code validation_failed or value_too_long.
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X POST \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/plans/3fa85f64-5717-4562-b3fc-2c963f66afa6/shopping-list/complete"

Example response

200application/json
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "householdId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "weeklyPlanId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "generatedAt": "2026-09-07T16:30:00Z",
  "items": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "foodKey": "string",
      "displayName": "string",
      "requiredQuantity": 0,
      "unit": "string",
      "status": {},
      "purchasedQuantity": 0,
      "reasonCode": {},
      "haveQuantity": 0,
      "relatedPlanEntryIds": [
        "3fa85f64-5717-4562-b3fc-2c963f66afa6"
      ],
      "addedAfterShopping": false,
      "suggestedPriceIsAggregate": false,
      "suggestedPriceSource": {},
      "aisle": {},
      "isManual": false,
      "preferenceFit": {}
    }
  ],
  "sharingOff": false,
  "priceCatalogueOn": false
}
POST/api/v1/households/{householdId}/plans/{planId}/shopping-list/reopen

Reopen a finished shopping trip

Any member. Idempotent. Takes back the pantry evidence the closing wrote, and the ticks the closing itself made (#1121); the household's own ticks stand.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
planIdpathstring (uuid)Required—

Responses

200OK
application/jsonShoppingListResponse
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X POST \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/plans/3fa85f64-5717-4562-b3fc-2c963f66afa6/shopping-list/reopen"

Example response

200application/json
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "householdId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "weeklyPlanId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "generatedAt": "2026-09-07T16:30:00Z",
  "items": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "foodKey": "string",
      "displayName": "string",
      "requiredQuantity": 0,
      "unit": "string",
      "status": {},
      "purchasedQuantity": 0,
      "reasonCode": {},
      "haveQuantity": 0,
      "relatedPlanEntryIds": [
        "3fa85f64-5717-4562-b3fc-2c963f66afa6"
      ],
      "addedAfterShopping": false,
      "suggestedPriceIsAggregate": false,
      "suggestedPriceSource": {},
      "aisle": {},
      "isManual": false,
      "preferenceFit": {}
    }
  ],
  "sharingOff": false,
  "priceCatalogueOn": false
}
POST/api/v1/households/{householdId}/plans/{planId}/shopping-list/items

Add a hand-typed line to the shopping list («we're out of milk»)

Any member. A name like «1 l melk» is read for amount and unit when the request gives none (#448); a food already on the list becomes one line (#1833). Hand-added lines survive a regenerated list, and are the only ones that can be removed by hand. The household gets one push (#198). 400 on an empty name, and on a quantity that is not greater than 0 and at most 100000.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
planIdpathstring (uuid)Required—

Request body

application/jsonRequiredAddShoppingItemRequest

Responses

200OK
application/jsonShoppingListItemResponse
400Bad Request
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X POST \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/plans/3fa85f64-5717-4562-b3fc-2c963f66afa6/shopping-list/items" \
  -H "Content-Type: application/json" \
  -d '{"displayName":"string"}'

Example response

200application/json
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "foodKey": "string",
  "displayName": "string",
  "requiredQuantity": 0,
  "unit": "string",
  "status": "Buy",
  "purchasedQuantity": 0,
  "reasonCode": "OptionalOnly",
  "haveQuantity": 0,
  "relatedPlanEntryIds": [
    "3fa85f64-5717-4562-b3fc-2c963f66afa6"
  ],
  "addedAfterShopping": false,
  "suggestedPriceIsAggregate": false,
  "suggestedPriceSource": "None",
  "aisle": "Other",
  "isManual": false,
  "preferenceFit": "NotAssessed"
}
POST/api/v1/households/{householdId}/plans/{planId}/shopping-list/recipe

Add a recipe's ingredients to the plan's shopping list

Any member. «I'm making this at some point» — the lines are the household's own, tied to no day (#115). Optional ingredients are left out; a base recipe the dish points at contributes its lines, and a reference nobody has linked is reported in SkippedReferences rather than bought (ADR-154). 404 when the recipe is not the household's, or the plan has no list yet; 400 on portions outside 1–100.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
planIdpathstring (uuid)Required—

Request body

application/jsonRequiredAddRecipeToShoppingListRequest

Responses

200OK
application/jsonShoppingListResponse
400Bad Request
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X POST \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/plans/3fa85f64-5717-4562-b3fc-2c963f66afa6/shopping-list/recipe" \
  -H "Content-Type: application/json" \
  -d '{"recipeId":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}'

Example response

200application/json
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "householdId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "weeklyPlanId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "generatedAt": "2026-09-07T16:30:00Z",
  "items": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "foodKey": "string",
      "displayName": "string",
      "requiredQuantity": 0,
      "unit": "string",
      "status": {},
      "purchasedQuantity": 0,
      "reasonCode": {},
      "haveQuantity": 0,
      "relatedPlanEntryIds": [
        "3fa85f64-5717-4562-b3fc-2c963f66afa6"
      ],
      "addedAfterShopping": false,
      "suggestedPriceIsAggregate": false,
      "suggestedPriceSource": {},
      "aisle": {},
      "isManual": false,
      "preferenceFit": {}
    }
  ],
  "sharingOff": false,
  "priceCatalogueOn": false
}
POST/api/v1/households/{householdId}/shopping-list/recipe

Add a recipe's ingredients to a week's shopping list, opening the week if needed

Any member. Addressed by week rather than plan id: WeekStart is any day in the wanted week, default the household's current one. A week nobody has planned gets an empty plan and a fresh list on the way through (#1681); a list already in progress is never regenerated. Otherwise as the per-plan route. 404 when the recipe is not found; 400 on portions outside 1–100.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—

Request body

application/jsonRequiredAddRecipeToWeekShoppingListRequest

Responses

200OK
application/jsonShoppingListResponse
400Bad Request
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X POST \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/shopping-list/recipe" \
  -H "Content-Type: application/json" \
  -d '{"recipeId":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}'

Example response

200application/json
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "householdId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "weeklyPlanId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "generatedAt": "2026-09-07T16:30:00Z",
  "items": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "foodKey": "string",
      "displayName": "string",
      "requiredQuantity": 0,
      "unit": "string",
      "status": {},
      "purchasedQuantity": 0,
      "reasonCode": {},
      "haveQuantity": 0,
      "relatedPlanEntryIds": [
        "3fa85f64-5717-4562-b3fc-2c963f66afa6"
      ],
      "addedAfterShopping": false,
      "suggestedPriceIsAggregate": false,
      "suggestedPriceSource": {},
      "aisle": {},
      "isManual": false,
      "preferenceFit": {}
    }
  ],
  "sharingOff": false,
  "priceCatalogueOn": false
}
PATCH/api/v1/households/{householdId}/shopping-items/{itemId}

Tick, untick or change the status of one shopping-list line

Any member. Status Purchased with no PurchasedQuantity means everything was bought; a smaller amount keeps the remainder on the list. PurchasedUnit, when the amount is in another unit than the line's, is converted where the household's piece weight knows how and otherwise kept as said, the line left open (#3266). The first tick on a line queues one «ticked N items» push (#198).

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
itemIdpathstring (uuid)Required—

Request body

application/jsonRequiredUpdateShoppingItemRequest

Responses

200OK
application/jsonShoppingListItemResponse
400The request could not be read as the route needs it: a body that is not the documented shape (a required field left out, a null where none is allowed, a value too long for its field), a parameter that does not parse, or a NUL character anywhere (#3540, #3541, #3543). Code validation_failed or value_too_long.
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X PATCH \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/shopping-items/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Content-Type: application/json" \
  -d '{"status":"Buy"}'

Example response

200application/json
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "foodKey": "string",
  "displayName": "string",
  "requiredQuantity": 0,
  "unit": "string",
  "status": "Buy",
  "purchasedQuantity": 0,
  "reasonCode": "OptionalOnly",
  "haveQuantity": 0,
  "relatedPlanEntryIds": [
    "3fa85f64-5717-4562-b3fc-2c963f66afa6"
  ],
  "addedAfterShopping": false,
  "suggestedPriceIsAggregate": false,
  "suggestedPriceSource": "None",
  "aisle": "Other",
  "isManual": false,
  "preferenceFit": "NotAssessed"
}
DELETE/api/v1/households/{householdId}/shopping-items/{itemId}

Remove a hand-added line from the shopping list

Any member. Only lines the household typed in can go: a line the week's dinners need answers 404 rather than pretending — the next regeneration would put it back anyway.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
itemIdpathstring (uuid)Required—

Responses

204No Content
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X DELETE \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/shopping-items/3fa85f64-5717-4562-b3fc-2c963f66afa6"
POST/api/v1/households/{householdId}/plans/{planId}/shopping-list/shopping-items/{itemId}/answer

Answer «Har det» / «Tomt» on a «Sjekk hjemme» line

Adults only; a Junior member gets 403 (#981, ADR-083). Writes a pantry observation (ADR-177/230) — ConfirmedPresent for HaveIt, ConfirmedGone for Out, no amount — and adjusts the list in place (ADR-173 §6), so ids and ticks survive. «Har det» takes the line off the list (it is not a purchase, so never Checked); «Tomt» moves it to «Kjøp» under the same id. Answers the whole list. 400 when the line is not a «Sjekk hjemme» line; 404 when the plan, its list or the line is not this household's.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
planIdpathstring (uuid)Required—
itemIdpathstring (uuid)Required—

Request body

application/jsonRequiredAnswerCheckAtHomeRequest

Responses

200OK
application/jsonShoppingListResponse
400Bad Request
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X POST \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/plans/3fa85f64-5717-4562-b3fc-2c963f66afa6/shopping-list/shopping-items/3fa85f64-5717-4562-b3fc-2c963f66afa6/answer" \
  -H "Content-Type: application/json" \
  -d '{"answer":"HaveIt"}'

Example response

200application/json
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "householdId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "weeklyPlanId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "generatedAt": "2026-09-07T16:30:00Z",
  "items": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "foodKey": "string",
      "displayName": "string",
      "requiredQuantity": 0,
      "unit": "string",
      "status": {},
      "purchasedQuantity": 0,
      "reasonCode": {},
      "haveQuantity": 0,
      "relatedPlanEntryIds": [
        "3fa85f64-5717-4562-b3fc-2c963f66afa6"
      ],
      "addedAfterShopping": false,
      "suggestedPriceIsAggregate": false,
      "suggestedPriceSource": {},
      "aisle": {},
      "isManual": false,
      "preferenceFit": {}
    }
  ],
  "sharingOff": false,
  "priceCatalogueOn": false
}
PUT/api/v1/households/{householdId}/shopping-items/{itemId}/product

Price a shopping-list line from another product («use this one»)

Any member — a swap is shopping, not setup (#1884, ADR-161). The product is one of the row's alternatives, or a product-search hit sent with its price; the previous product becomes an alternative, so the swap is reversible. Nothing is remembered — that is PUT product-preferences/{foodKey}. 400 when the chain is not one of the household's stores, or the product is new to the row and no price was given.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
itemIdpathstring (uuid)Required—

Request body

application/jsonRequiredChooseShoppingProductRequest

Responses

200OK
application/jsonShoppingListItemResponse
400Bad Request
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X PUT \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/shopping-items/3fa85f64-5717-4562-b3fc-2c963f66afa6/product" \
  -H "Content-Type: application/json" \
  -d '{"chainCode":"string","productName":"string"}'

Example response

200application/json
{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "foodKey": "string",
  "displayName": "string",
  "requiredQuantity": 0,
  "unit": "string",
  "status": "Buy",
  "purchasedQuantity": 0,
  "reasonCode": "OptionalOnly",
  "haveQuantity": 0,
  "relatedPlanEntryIds": [
    "3fa85f64-5717-4562-b3fc-2c963f66afa6"
  ],
  "addedAfterShopping": false,
  "suggestedPriceIsAggregate": false,
  "suggestedPriceSource": "None",
  "aisle": "Other",
  "isManual": false,
  "preferenceFit": "NotAssessed"
}
GET/api/v1/households/{householdId}/shopping-items/{itemId}/product-search

Search the household's stores' catalogue for products matching ?q=

Any member. ?q= needs between two and 64 characters (400 otherwise). Hits are grouped per store, cheapest first, at most 12 per store; SearchAvailable is false when no product catalogue is configured. Each call asks the catalogue, so it is rate-limited per household — 30 a minute by default (ADR-127, ADR-161): over the ceiling answers 429 with a Retry-After header.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
itemIdpathstring (uuid)Required—
qquerystring——

Responses

200OK
application/jsonProductSearchResponse
400Bad Request
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too Many Requests
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Problem codes

The `code` in the problem body is what to branch on. `detail` is English, written for a log.

product_search_length
— Type at least two characters to look for a product.

Example

curl -b "bryti_session=…" \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/shopping-items/3fa85f64-5717-4562-b3fc-2c963f66afa6/product-search"

Example response

200application/json
{
  "searchAvailable": false,
  "stores": [
    {
      "chainCode": "string",
      "storeName": "string",
      "products": [
        {}
      ]
    }
  ]
}
GET/api/v1/households/{householdId}/product-preferences

List the products the household has asked for by food

Any member. Newest choice first (#1884, ADR-161).

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—

Responses

200OK
application/jsonProductPreferenceResponse[]
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/product-preferences"

Example response

200application/json
[
  {
    "foodKey": "string",
    "displayName": "string",
    "chainCode": "string",
    "storeName": "string",
    "productName": "string",
    "chosenAt": "2026-09-07T16:30:00Z"
  }
]
PUT/api/v1/households/{householdId}/product-preferences/{foodKey}

Remember a product for a food («remember this choice»)

Adults only; a Junior member gets 403 (ADR-083). One choice per food: a second call restates it, so it is safe to retry. Matching rows on the open lists get the household-choice badge at once; the price follows at the next list build (#1884, ADR-161). 400 on a blank chain or product name, and on a food key that is not a word.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
foodKeypathstringRequired—

Request body

application/jsonRequiredSetProductPreferenceRequest

Responses

200OK
application/jsonProductPreferenceResponse
400Bad Request
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X PUT \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/product-preferences/string" \
  -H "Content-Type: application/json" \
  -d '{"chainCode":"string","productName":"string"}'

Example response

200application/json
{
  "foodKey": "string",
  "displayName": "string",
  "chainCode": "string",
  "storeName": "string",
  "productName": "string",
  "chosenAt": "2026-09-07T16:30:00Z"
}
DELETE/api/v1/households/{householdId}/product-preferences/{foodKey}

Forget the remembered product for a food

Adults only; a Junior member gets 403. Open lists lose the badge now; the line goes back to the cheapest match at its next build. 404 when nothing was remembered — another device may already have forgotten it.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
foodKeypathstringRequired—

Responses

204No Content
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
404Not Found
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X DELETE \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/product-preferences/string"
GET/api/v1/households/{householdId}/off/products/{barcode}

What a scanned barcode is: name, brand, pack size and Bryti's food key

Any member, Junior included — scanning is the pantry's daily upkeep (ADR-055). EAN-8, EAN-13 or UPC-A (answered as EAN-13); anything else is 400. «found: false» is a 200, not a 404: a Norwegian shelf has products Open Food Facts does not know, and that is the scanner's empty state (#2587). foodKey is null when the product is known but nobody has said what food it is.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
barcodepathstringRequired—

Responses

200OK
application/jsonOffProductLookupResponse
400Bad Request
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/off/products/string"

Example response

200application/json
{
  "found": false,
  "barcode": "string",
  "productName": "string",
  "brands": "string",
  "quantity": "string",
  "foodKey": "string",
  "novaGroup": 0,
  "nutriScore": "string",
  "allergensTags": [
    "string"
  ]
}
POST/api/v1/households/{householdId}/off/products/{barcode}/food-key

Name the food a scanned product is, for everyone who scans it next

Any member. The name is normalised to a canonical food key and written as a manual barcode → food-key row — additive (ADR-200): an existing row is never moved, and the same answer twice is a no-op («written: false»). No household id is stored; the row is part of the ODbL derivative Bryti publishes (#2587).

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
barcodepathstringRequired—

Request body

application/jsonRequiredSetOffFoodKeyRequest

Responses

200OK
application/jsonSetOffFoodKeyResponse
400Bad Request
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.

Example

curl -b "bryti_session=…" \
  -X POST \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/off/products/string/food-key" \
  -H "Content-Type: application/json" \
  -d '{"foodKey":"string"}'

Example response

200application/json
{
  "barcode": "string",
  "foodKey": "string",
  "written": false
}
POST/api/v1/households/{householdId}/off/contributions

Send a product Open Food Facts does not know to Open Food Facts

Adults only; a Junior gets 403 junior_forbidden (ADR-055). The barcode, name, brand and pack size leave Bryti and become public on Open Food Facts under Bryti's contributor account — the flow says so before the button (ADR-215). No picture (ADR-214). 202 with the product's page; 503 off_contribution_unavailable where no contributor account is configured (the client shows the product page instead); 502 when Open Food Facts refuses.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—

Request body

application/jsonRequiredOffContributionRequest

Responses

202Accepted
application/jsonOffContributionResponse
400Bad Request
application/problem+jsonProblemDetails
401No session, or the session is no longer valid.
application/problem+jsonProblemDetails
426The build named in X-App-Version is below its platform's version floor (ADR-070). Problem type app-version-unsupported; the only way forward is the store. Callers without the header are never turned away.
application/problem+jsonProblemDetails
429Too many calls in the window; Retry-After says how long.
application/problem+jsonProblemDetails
Headers
Retry-After
— Seconds to wait when a rate limit answered, or an HTTP date when the household's AI is paused. Absent when the household's AI quota for the period is used up — that resets by itself.
502Bad Gateway
application/problem+jsonProblemDetails
503Service Unavailable
application/problem+jsonProblemDetails

Problem codes

The `code` in the problem body is what to branch on. `detail` is English, written for a log.

off_contribution_failed
— Open Food Facts didn't take the product. Try again later.
off_contribution_unavailable
— Sharing with Open Food Facts isn't available here.

Example

curl -b "bryti_session=…" \
  -X POST \
  "https://bryti.app/api/v1/households/3fa85f64-5717-4562-b3fc-2c963f66afa6/off/contributions" \
  -H "Content-Type: application/json" \
  -d '{"barcode":"string","productName":"string","brands":"string","quantity":"string"}'

Example response

202application/json
{
  "barcode": "string",
  "productUrl": "string"
}

Schemas

AddInventoryObservationRequest

PropertyTypeRequired
foodKeystringRequired
displayNamestringRequired
observationTypeObservationTypeRequired
quantitynumber (double) | nullRequired
unitstring | nullRequired
storageLocationStorageLocationRequired
confidencenumber (double) | nullRequired
bestBeforestring (date) | null—
barcodestring | null—

AddObservationResponse

PropertyTypeRequired
observationIdstring (uuid)Required
itemInventoryItemResponseRequired

AddRecipeToShoppingListRequest

PropertyTypeRequired
recipeIdstring (uuid)Required
portionsinteger (int32) | null—

AddRecipeToWeekShoppingListRequest

PropertyTypeRequired
recipeIdstring (uuid)Required
portionsinteger (int32) | null—
weekStartstring (date) | null—

AddShoppingItemRequest

PropertyTypeRequired
displayNamestringRequired
quantitynumber (double) | null—
unitstring | null—

AnswerCheckAtHomeRequest

PropertyTypeRequired
answerCheckAtHomeAnswerRequired

BasketEstimateResponse

PropertyTypeRequired
storesStoreBasketEstimateResponse[]Required
optimizedTotalnumber (double)Required
pricedItemCountinteger (int32)Required
unpricedItemCountinteger (int32)Required
hasEnoughPricesboolean—
hasIndexEstimatesboolean—

BetterChoiceBasis

Type

Values

SuggestedProductUsuallyHeavilyProcessed

or null

BetterChoiceResponse

PropertyTypeRequired
productNamestringRequired
brandsstring | nullRequired
novaGroupinteger (int32)Required
sameFoodbooleanRequired
boughtBeforebooleanRequired
chainCodestring | nullRequired
storeNamestring | nullRequired
pricenumber (double) | nullRequired
singleIngredientboolean—

BetterChoicesLineResponse

PropertyTypeRequired
foodKeystringRequired
basisBetterChoiceBasis | nullRequired
productNamestring | nullRequired
choicesBetterChoiceResponse[]Required
novaGroupinteger (int32) | null—
novaReasonsPurchaseNovaReasonResponse[] | null—
productStepsProductStepResponse[] | null—

BetterChoicesResponse

PropertyTypeRequired
weeklyPlanIdstring (uuid)Required
linesBetterChoicesLineResponse[]Required

CheckAtHomeAnswer

Type

Values

HaveItOut

ChooseShoppingProductRequest

PropertyTypeRequired
chainCodestringRequired
productNamestringRequired
pricenumber (double) | null—

ClearInventoryObservationsResponse

PropertyTypeRequired
removedObservationsinteger (int32)Required

DinnerRole

Type

Values

DinnerBreadFoodUnknownLeftovers

or null

EvidenceKind

Type

Values

SightingPurchase

Default "Sighting"

HouseholdChoiceResponse

PropertyTypeRequired
productNamestringRequired
chainCodestringRequired
storeNamestring | nullRequired
appliedbooleanRequired

InventoryGroup

Type

Values

UseSoonLikelyAvailableUncertainAged

or null

InventoryGroupCounts

PropertyTypeRequired
useSooninteger (int32)Required
likelyAvailableinteger (int32)Required
uncertaininteger (int32)Required
agedinteger (int32)Required

InventoryItemResponse

PropertyTypeRequired
foodKeystringRequired
displayNamestringRequired
estimatedQuantitynumber (double) | nullRequired
unitstring | nullRequired
confidencenumber (double)Required
storageLocationStorageLocationRequired
usePriorityUsePriorityRequired
lastEvidenceAtstring (date-time)Required
aisleShoppingAisle—
useWithinDaysinteger (int32) | null—
mergedFromKeysstring[] | null—
bestBeforestring (date) | null—
asksForDateboolean—
lastEvidenceKindEvidenceKind—
plannedQuantitynumber (double) | null—
remainingQuantitynumber (double) | null—
dinnerRoleDinnerRole | null—
lotCountinteger (int32) | null—
oldestLotQuantitynumber (double) | null—
oldestLotUnitstring | null—
lotsInventoryLotResponse[] | null—
plannedForInventoryPlannedUseResponse[] | null—

InventoryLotResponse

PropertyTypeRequired
quantitynumber (double) | nullRequired
unitstring | nullRequired
acquiredAtstring (date-time)Required
bestBeforestring (date) | nullRequired

InventoryPlaceCounts

PropertyTypeRequired
fridgeinteger (int32)Required
pantryinteger (int32)Required
freezerinteger (int32)Required
unknowninteger (int32)Required

InventoryPlannedUseResponse

PropertyTypeRequired
titlestringRequired
datestring (date)Required

InventorySummaryResponse

PropertyTypeRequired
byPlaceInventoryPlaceCountsRequired
byGroupInventoryGroupCountsRequired
triageinteger (int32)Required
totalinteger (int32)Required
matchesByPlaceInventoryPlaceCountsRequired

MergePantryKeysRequest

PropertyTypeRequired
fromKeystringRequired
toKeystringRequired
sourcePantryMergeSource—

NovaAdditiveClass

Type

Values

ColourEmulsifierFlavourEnhancerGlazingSweetenerModifiedStarch

or null

NovaReasonKind

Type

Values

AdditiveIngredient

ObservationType

Type

Values

PurchasedConfirmedPresentEstimatedConsumedManuallyAdjustedFrozenDiscardedLeftoverCreatedConfirmedGone

OffContributionRequest

PropertyTypeRequired
barcodestringRequired
productNamestringRequired
brandsstring | nullRequired
quantitystring | nullRequired

OffContributionResponse

PropertyTypeRequired
barcodestringRequired
productUrlstringRequired

OffProductLookupResponse

PropertyTypeRequired
foundbooleanRequired
barcodestringRequired
productNamestring | nullRequired
brandsstring | nullRequired
quantitystring | nullRequired
foodKeystring | nullRequired
novaGroupinteger (int32) | nullRequired
nutriScorestring | nullRequired
allergensTagsstring[]Required
sugarsPer100gnumber (double) | null—
saltPer100gnumber (double) | null—

PackageSuggestionResponse

PropertyTypeRequired
countinteger (int32)Required
unitstringRequired
gramsPerPackagenumber (double)Required

PagedInventoryItemResponse

PropertyTypeRequired
itemsInventoryItemResponse[]Required
nextCursorstring | nullRequired
totalinteger (int32) | nullRequired

PagedPantryMergeListItemResponse

PropertyTypeRequired
itemsPantryMergeListItemResponse[]Required
nextCursorstring | nullRequired
totalinteger (int32) | nullRequired

PagedPantryMergeRejectionListItemResponse

PropertyTypeRequired
itemsPantryMergeRejectionListItemResponse[]Required
nextCursorstring | nullRequired
totalinteger (int32) | nullRequired

PantryMergeListItemResponse

PropertyTypeRequired
fromKeystringRequired
fromDisplayNamestringRequired
toKeystringRequired
toDisplayNamestringRequired
mergedAtstring (date-time)Required

PantryMergeRejectionListItemResponse

PropertyTypeRequired
keyAstringRequired
keyADisplayNamestringRequired
keyBstringRequired
keyBDisplayNamestringRequired
decidedAtstring (date-time)Required

PantryMergeResponse

PropertyTypeRequired
fromKeystringRequired
toKeystringRequired
itemInventoryItemResponseRequired

PantryMergeSignal

Type

Values

ContainedTokensSharedStem

PantryMergeSource

Type

Values

SuggestionManualChat

Default "Suggestion"

PantryMergeSuggestionResponse

PropertyTypeRequired
fromInventoryItemResponseRequired
toInventoryItemResponseRequired
signalPantryMergeSignalRequired

PreferenceFit

Type

Values

NotAssessedFollowsNoCandidateFollowsAllergensUnknown

Default "NotAssessed"

PriceCertainty

Type

Values

ConfirmedEstimatedUncertain

or null

ProblemDetails

PropertyTypeRequired
typestring | null—
titlestring | null—
statusinteger (int32) | null—
detailstring | null—
instancestring | null—
codestring | null—

ProductPreferenceResponse

PropertyTypeRequired
foodKeystringRequired
displayNamestringRequired
chainCodestringRequired
storeNamestring | nullRequired
productNamestringRequired
chosenAtstring (date-time)Required

ProductSearchHitResponse

PropertyTypeRequired
productNamestringRequired
pricenumber (double)Required
unitPricenumber (double) | nullRequired
unitPriceUnitstring | nullRequired

ProductSearchResponse

PropertyTypeRequired
searchAvailablebooleanRequired
storesProductSearchStoreResponse[]Required

ProductSearchStoreResponse

PropertyTypeRequired
chainCodestringRequired
storeNamestringRequired
productsProductSearchHitResponse[]Required

ProductStepResponse

PropertyTypeRequired
productNamestringRequired
novaGroupinteger (int32)Required

PurchaseClassificationExampleResponse

PropertyTypeRequired
productNamestringRequired
novaGroupinteger (int32) | nullRequired
nutriScorestring | nullRequired
sugarsPer100gnumber (double) | null—
saltPer100gnumber (double) | null—
offProductNamestring | null—
brandsstring | null—
quantitystring | null—
novaReasonsPurchaseNovaReasonResponse[] | null—

PurchaseClassificationResponse

PropertyTypeRequired
daysinteger (int32)Required
linesTotalinteger (int32)Required
linesRecognisedinteger (int32)Required
heavilyProcessedinteger (int32)Required
processedinteger (int32)Required
lightlyProcessedinteger (int32)Required
processingUnknowninteger (int32)Required
examplesPurchaseClassificationExampleResponse[]Required

PurchaseNovaReasonResponse

PropertyTypeRequired
kindNovaReasonKindRequired
codestring | nullRequired
additiveClassNovaAdditiveClass | nullRequired
textstring | nullRequired

RejectPantryMergeRequest

PropertyTypeRequired
keyAstringRequired
keyBstringRequired

SetOffFoodKeyRequest

PropertyTypeRequired
foodKeystringRequired

SetOffFoodKeyResponse

PropertyTypeRequired
barcodestringRequired
foodKeystringRequired
writtenbooleanRequired

SetProductPreferenceRequest

PropertyTypeRequired
chainCodestringRequired
productNamestringRequired

SetUnitWeightRequest

PropertyTypeRequired
gramsnumber (double)Required

ShoppingAisle

Type

Values

ProduceBakeryMeatAndFishDairyFrozenDryGoodsHouseholdOther

Default "Other"

ShoppingItemReason

Type

Values

OptionalOnlyPartiallyAtHomeStaleEvidenceUnlikelyAtHomeNothingAtHomeRecentlyDepletedUnmeasuredNoLongerPlannedStapleFullyAtHome

ShoppingItemStatus

Type

Values

BuyCheckAtHomeOptionalCheckedPurchasedAtHome

ShoppingListItemResponse

PropertyTypeRequired
idstring (uuid)Required
foodKeystringRequired
displayNamestringRequired
requiredQuantitynumber (double) | nullRequired
unitstring | nullRequired
statusShoppingItemStatusRequired
purchasedQuantitynumber (double) | nullRequired
reasonCodeShoppingItemReasonRequired
haveQuantitynumber (double) | nullRequired
relatedPlanEntryIdsstring (uuid)[]Required
suggestedStoreNamestring | null—
suggestedChainCodestring | null—
suggestedPricenumber (double) | null—
suggestedProductNamestring | null—
suggestedAlternativesSuggestedAlternativeResponse[] | null—
suggestedPriceCertaintyPriceCertainty | null—
addedAfterShoppingboolean—
displayQuantitynumber (double) | null—
displayUnitstring | null—
suggestedPackagePackageSuggestionResponse | null—
suggestedPriceObservedAtstring (date-time) | null—
suggestedPriceIsAggregateboolean—
suggestedPriceSourceSuggestedPriceSource—
suggestedPriceHouseholdCountinteger (int32) | null—
aisleShoppingAisle—
isManualboolean—
lastSeenAtstring (date-time) | null—
householdChoiceHouseholdChoiceResponse | null—
preferenceFitPreferenceFit—
dearerThanCheapestnumber (double) | null—
suggestedSugarsPer100gnumber (double) | null—
suggestedSaltPer100gnumber (double) | null—
tracesDroppedTracesDroppedResponse | null—
haveUnitstring | null—
purchasedAsQuantitynumber (double) | null—
purchasedAsUnitstring | null—

ShoppingListResponse

PropertyTypeRequired
idstring (uuid)Required
householdIdstring (uuid)Required
weeklyPlanIdstring (uuid)Required
generatedAtstring (date-time)Required
itemsShoppingListItemResponse[]Required
basketEstimateBasketEstimateResponse | null—
completedAtstring (date-time) | null—
tripSummaryShoppingTripSummaryResponse | null—
sharingOffboolean—
skippedReferencesSkippedReferenceResponse[] | null—
priceCatalogueOnboolean—

ShoppingTripSummaryResponse

PropertyTypeRequired
stockedItemCountinteger (int32)Required
skippedItemCountinteger (int32)Required

SkippedReferenceResponse

PropertyTypeRequired
referenceIdstring (uuid)Required
labelstringRequired
sourceHintstring | nullRequired

StorageLocation

Type

Values

FridgeFreezerPantryUnknown

StoreBasketEstimateResponse

PropertyTypeRequired
chainCodestringRequired
storeNamestringRequired
totalnumber (double)Required
pricedItemsinteger (int32)Required
estimatedItemsinteger (int32)Required
seenItemsinteger (int32)—
totalItemsinteger (int32)—
coverageStoreCoverage—

StoreCoverage

Type

Values

UnknownFullPartial

Default "Unknown"

SuggestedAlternativeResponse

PropertyTypeRequired
storeNamestringRequired
chainCodestringRequired
pricenumber (double)Required
productNamestringRequired

SuggestedPriceSource

Type

Values

NoneOwnReceiptHouseholdAverageCatalogueIndexEstimate

Default "None"

TracesDroppedResponse

PropertyTypeRequired
allergenstringRequired
memberNamestring | nullRequired

UnitWeightResponse

PropertyTypeRequired
foodKeystringRequired
unitstringRequired
displayNamestringRequired
gramsnumber (double)Required
updatedAtstring (date-time)Required

UpdateShoppingItemRequest

PropertyTypeRequired
statusShoppingItemStatusRequired
purchasedQuantitynumber (double) | null—
purchasedUnitstring | null—

UsePriority

Type

Values

UrgentSoonNormalStableUnknown