Candidates

Dinner candidates Bryti suggests for a day.4 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

POST/api/v1/households/{householdId}/candidates/generate

Put a day's new dinner suggestions in the planning queue

Adults only; a Junior member gets 403. Answers 202 with the run's id (ADR-289): the model call is a background job, GET plans/runs/{jobId} says where it stands, and GET candidates for the day has the suggestions once it is done. Costs credits and replaces the day's current candidates, except one a plan entry still points at. A run that ends in candidate_pool_in_plan — somebody planned the week over these very candidates while they were being replaced (#533) — says so on its status; read the day again and ask once more.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—

Request body

application/jsonRequiredGenerateCandidatesRequest

Responses

202Accepted
application/jsonPlanRunAccepted
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/candidates/generate" \
  -H "Content-Type: application/json" \
  -d '{"date":"2026-09-07","category":"Fish"}'

Example response

202application/json
{
  "jobId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "weekStart": "2026-09-07"
}
GET/api/v1/households/{householdId}/candidates

List the candidates generated for one day

date is required. What is missing from the pantry is recomputed on every read — no model call, no write. price is each dish's estimated kroner per portion and class (#3226), from the household's receipts, the store catalogue or the table.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
datequerystring (date)Required—

Responses

200OK
application/jsonMealCandidateResponse[]
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
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/candidates?date=2026-09-07"

Example response

200application/json
[
  {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "householdId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "targetDate": "2026-09-07",
    "category": "Fish",
    "content": {
      "title": "string",
      "rationale": "string",
      "ingredients": [
        {}
      ],
      "steps": [
        "string"
      ],
      "activeMinutes": 0,
      "totalMinutes": 0,
      "portions": 0,
      "tags": [
        "string"
      ],
      "leftoverPotential": "string",
      "confidence": 0,
      "assumptions": [
        "string"
      ],
      "safetyWarnings": [
        "string"
      ]
    },
    "scores": {
      "key": 0
    },
    "createdAt": "2026-09-07T16:30:00Z"
  }
]
GET/api/v1/households/{householdId}/candidates/range

List the candidates for every day in a window of at most 92 days

One round-trip for a whole week (#1017); ordered by date, then by when each candidate was created. from and to are both required and the window may cover at most 92 days — a calendar read, not a page (#2977, ADR-292). A day's hand is a dozen dishes with their ingredients on each, so the window is what bounds the answer: three years of it was 2.4 MB.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
fromquerystring (date)Required—
toquerystring (date)Required—

Responses

200OK
application/jsonMealCandidateResponse[]
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/candidates/range?from=2026-09-07&to=2026-09-07"

Example response

200application/json
[
  {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "householdId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "targetDate": "2026-09-07",
    "category": "Fish",
    "content": {
      "title": "string",
      "rationale": "string",
      "ingredients": [
        {}
      ],
      "steps": [
        "string"
      ],
      "activeMinutes": 0,
      "totalMinutes": 0,
      "portions": 0,
      "tags": [
        "string"
      ],
      "leftoverPotential": "string",
      "confidence": 0,
      "assumptions": [
        "string"
      ],
      "safetyWarnings": [
        "string"
      ]
    },
    "scores": {
      "key": 0
    },
    "createdAt": "2026-09-07T16:30:00Z"
  }
]
GET/api/v1/households/{householdId}/candidates/use-up

Read the use-up section for one day: the swaps that would use what is running out, as the day's Swap panel shows them.

The bundle is the same as the week's (ADR-173): what remains after the planned use this week and next, and the fewest changes that would use it. This is the day's slice of it. Read-only; applying goes through the home use-up endpoints.

Parameters

NameInTypeRequiredDescription
householdIdpathstring (uuid)Required—
datequerystring (date)Required—

Responses

200OK
application/jsonHomeUseUpBundleQuestion
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/candidates/use-up?date=2026-09-07"

Example response

200application/json
{
  "bundleId": "string",
  "changes": [
    {
      "id": "string",
      "day": "2026-09-07",
      "kind": {},
      "recipeId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "title": "string",
      "uses": [
        {}
      ],
      "handsBack": [
        {}
      ],
      "activeMinutes": 0,
      "shoppingDelta": 0
    }
  ],
  "coveredCount": 0,
  "urgentCount": 0,
  "notDinner": [
    {
      "foodKey": "string",
      "displayName": "string",
      "reason": {}
    }
  ]
}

Schemas

CandidateContent

PropertyTypeRequired
titlestringRequired
rationalestringRequired
ingredientsCandidateIngredient[]Required
stepsstring[]Required
activeMinutesinteger (int32)Required
totalMinutesinteger (int32)Required
portionsinteger (int32)Required
tagsstring[]Required
leftoverPotentialstringRequired
confidencenumber (double)Required
assumptionsstring[]Required
safetyWarningsstring[]Required
nutritionCandidateNutrition | null—
timersCandidateStepTimer[] | null—
sectionsCandidateSection[] | null—

CandidateIngredient

PropertyTypeRequired
foodKeystringRequired
displayNamestringRequired
quantitynumber (double)Required
unitstringRequired
isOptionalbooleanRequired
missingbooleanRequired
displayQuantitynumber (double) | null—
displayUnitstring | null—

CandidateNutrition

PropertyTypeRequired
kcalPerPortioninteger (int32)Required
proteinGramsnumber (double)Required
fibreGramsnumber (double)Required
addedSugarGramsnumber (double)Required
saltGramsnumber (double)Required
fruitVegPortionsnumber (double)Required
coveragenumber (double)Required

CandidatePrice

PropertyTypeRequired
classPriceClassRequired
perPortionNoknumber (double) | nullRequired
sourcePriceSourceRequired
coveragenumber (double)Required

CandidateSection

PropertyTypeRequired
namestring | nullRequired
kindRecipeSectionKindRequired
ingredientsCandidateIngredient[]Required
stepsstring[]Required
timersCandidateStepTimer[] | nullRequired
sourceRecipeIdstring (uuid) | nullRequired
sourceRecipeTitlestring | nullRequired

CandidateStepTimer

PropertyTypeRequired
stepinteger (int32)Required
minutesinteger (int32)Required
namestringRequired

GenerateCandidatesRequest

PropertyTypeRequired
datestring (date)Required
categoryMealCategory | nullRequired

HomeUseUpBundleQuestion

PropertyTypeRequired
bundleIdstringRequired
changesHomeUseUpChange[]Required
coveredCountinteger (int32)Required
urgentCountinteger (int32)Required
notDinnerHomeUseUpFood[]Required
nextWeekHomeUseUpNextWeek | null—

HomeUseUpChange

PropertyTypeRequired
idstringRequired
daystring (date)Required
kindHomeUseUpChangeKindRequired
recipeIdstring (uuid) | nullRequired
titlestringRequired
usesHomeUseUpUse[]Required
handsBackHomeUseUpUse[]Required
activeMinutesinteger (int32)Required
shoppingDeltainteger (int32)Required

HomeUseUpChangeKind

Type

Values

SwapDishAdaptIngredientFillOpenDay

HomeUseUpFood

PropertyTypeRequired
foodKeystringRequired
displayNamestringRequired
reasonHomeUseUpFoodReason—

HomeUseUpFoodReason

Type

Values

BreadFoodNoRecipeLeftoversNoChangeInTime

Default "BreadFood"

HomeUseUpNextWeek

PropertyTypeRequired
changeCountinteger (int32)Required
foodNamesstring[]Required

HomeUseUpUse

PropertyTypeRequired
foodKeystringRequired
displayNamestringRequired
quantitynumber (double) | nullRequired
unitstring | nullRequired
usesMostOfItboolean—

MealCandidateResponse

PropertyTypeRequired
idstring (uuid)Required
householdIdstring (uuid)Required
targetDatestring (date)Required
categoryMealCategoryRequired
contentCandidateContentRequired
scoresmapRequired
createdAtstring (date-time)Required
recipeIdstring (uuid) | null—
imageUrlstring | null—
priceCandidatePrice | null—

MealCategory

Type

Values

FishMeatPoultryVegetarianVeganSoupPastaTacoLeftoversOther

PlanRunAccepted

PropertyTypeRequired
jobIdstring (uuid)Required
weekStartstring (date)Required

PriceClass

Type

Values

CheapMidExpensive

PriceSource

Type

Values

ObservedCatalogueTableUnknown

ProblemDetails

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

RecipeSectionKind

Type

Values

OwnLinkedUnresolved