Open data

Data Bryti shares back, such as the Open Food Facts derivative under ODbL.7 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/data/off-derived.jsonl.gzNo session needed

Download the Open Food Facts derivative Bryti publishes under ODbL

Public, no account (ODbL 4.6): every product row and every barcode → food-key mapping Bryti holds, as gzipped JSON lines whose first line names the licence, the source and the attribution. Rate-limited per IP; ETag is the file's SHA-256; 404 until the first sync has run (ADR-227).

Parameters

No parameters

Responses

200OK
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 \
  "https://bryti.app/api/v1/data/off-derived.jsonl.gz"
GET/api/v1/data/library-derived.jsonl.gzNo session needed

Download the CC BY-SA recipes Bryti's library adapted from open sources

Public, no account (CC BY-SA 4.0 share-alike): every recipe in Bryti's sourced library that carries a CC BY-SA licence — the bokmål adaptation of a Wikibooks or Unitools page — as gzipped JSON lines whose first line names the licence, the sources and the attribution. Rate-limited per IP; ETag is the file's SHA-256; always 200, with only the header line while no such recipe is seeded (#2828).

Parameters

No parameters

Responses

200OK
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 \
  "https://bryti.app/api/v1/data/library-derived.jsonl.gz"
GET/api/v1/data/dinner-prices.jsonNo session needed

Read the published dinner price index as JSON

Public, no account (CC BY 4.0): per household type and published month, the median of the month's weekly measurements, each the median of the fully priced weeks among 1 000 drawn from Bryti's library at the shops' list prices, with p10, p90, kroner per portion, coverage and the number of chains behind the figure. No figure per chain and no price per product (#3619).

Parameters

No parameters

Responses

200OK
application/jsonDinnerPricesPublic
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 \
  "https://bryti.app/api/v1/data/dinner-prices.json"

Example response

200application/json
{
  "generatedAt": "2026-09-07T16:30:00Z",
  "source": "string",
  "license": "string",
  "recipeSetVersion": "string",
  "sampleSize": 0,
  "chainsRead": [
    "string"
  ],
  "missingChains": [
    "string"
  ],
  "firstMonth": "string",
  "latestMonth": "string",
  "nextMonth": "string",
  "baskets": [
    {
      "slug": "string",
      "persona": "string",
      "portions": 0,
      "recipeSetVersion": "string",
      "latest": {},
      "series": [
        {}
      ],
      "exampleWeek": {},
      "cheapestWeek": {}
    }
  ],
  "topTen": [
    {
      "rank": 0,
      "recipeId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "title": "string",
      "perPortion": 0,
      "ssbGroup": "string",
      "mainItem": {}
    }
  ],
  "breaks": [
    {
      "date": "string",
      "kind": "string",
      "note": "string"
    }
  ],
  "nextPublishDate": "string",
  "items": [
    {
      "foodKey": "string",
      "label": "string",
      "labelEn": "string",
      "form": "string",
      "unit": "string",
      "derivedUnit": false,
      "singleChain": false
    }
  ]
}
GET/api/v1/data/dinner-prices.csvNo session needed

Download the published dinner price index as CSV

Public, no account (CC BY 4.0): one row per household type and published month with the median, p10 and p90 week price, kroner per portion, coverage, chains, source and recipe-set version. Totals only (#3619).

Parameters

No parameters

Responses

200OK
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 \
  "https://bryti.app/api/v1/data/dinner-prices.csv"
POST/api/v1/data/dinner-prices/subscribeNo session needed

Ask for the monthly dinner price by e-mail

Public, no account (#3619). Takes an address and a language (nb or en) and nothing else. Always 202 whatever the list already knew about the address: a new one, one already confirmed and a resend inside the day's cooldown look the same. A confirmation mail with a single-use link goes out for a new address, and again for an unconfirmed one at most once a day; an unconfirmed address is deleted after seven days. 400 (code email_invalid) only when the address is not one. Rate-limited per IP (dinner-price-signup-per-ip, 5 an hour by default): 429 with Retry-After.

Parameters

No parameters

Request body

application/jsonRequiredDinnerPriceSubscribeRequest

Responses

202Accepted
400Bad Request
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.

Example

curl \
  -X POST \
  "https://bryti.app/api/v1/data/dinner-prices/subscribe" \
  -H "Content-Type: application/json" \
  -d '{"email":"string","language":"string"}'
GET/api/v1/data/dinner-prices/confirmNo session needed

Confirm a dinner price e-mail address from the link in the mail

Public: the link opens in a browser that may never have seen Bryti (#3619). Safe to retry: a second click is still confirmed. 404 (code dinner_price_token_unknown) when no address carries the token; 410 (code dinner_price_token_expired) when the address outlived its seven days unconfirmed.

Parameters

NameInTypeRequiredDescription
tokenquerystring——

Responses

200OK
application/jsonDinnerPriceConfirmResponse
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
404Not Found
application/problem+jsonProblemDetails
410Gone
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.

Problem codes

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

dinner_price_token_expired
— This link is too old. Enter your address again for a new one.
dinner_price_token_unknown
— This link doesn't work. Enter your address again for a new one.

Example

curl \
  "https://bryti.app/api/v1/data/dinner-prices/confirm"

Example response

200application/json
{
  "confirmed": false
}
GET/api/v1/data/dinner-prices/unsubscribeNo session needed

Leave the dinner price e-mail list from the link in a mail

Public, one click, no account (#3619). Deletes the address, it is not marked. Safe to retry: a second click on the same link is still unsubscribed. 404 (code dinner_price_token_unknown) for a link Bryti did not mint.

Parameters

NameInTypeRequiredDescription
tokenquerystring——

Responses

200OK
application/jsonDinnerPriceUnsubscribeResponse
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
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.

Problem codes

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

dinner_price_token_unknown
— This link doesn't work. Enter your address again for a new one.

Example

curl \
  "https://bryti.app/api/v1/data/dinner-prices/unsubscribe"

Example response

200application/json
{
  "unsubscribed": false
}

Schemas

DinnerPriceBasketPublic

PropertyTypeRequired
slugstringRequired
personastringRequired
portionsinteger (int32)Required
recipeSetVersionstringRequired
latestDinnerPriceLatestPublic | nullRequired
seriesDinnerPriceSeriesPoint[]Required
exampleWeekDinnerPriceWeekPublic | nullRequired
cheapestWeekDinnerPriceWeekPublic | nullRequired

DinnerPriceBreak

PropertyTypeRequired
datestringRequired
kindstringRequired
notestringRequired

DinnerPriceConfirmResponse

PropertyTypeRequired
confirmedbooleanRequired

DinnerPriceExcludedRecipePublic

PropertyTypeRequired
recipeIdstring (uuid)Required
titlestringRequired
reasonstringRequired
itemstringRequired
itemEnstring | nullRequired

DinnerPriceItemPublic

PropertyTypeRequired
foodKeystringRequired
labelstringRequired
labelEnstring | nullRequired
formstring | nullRequired
unitstringRequired
derivedUnitbooleanRequired
singleChainbooleanRequired

DinnerPriceLatestPublic

PropertyTypeRequired
monthstringRequired
measuredAtstring (date-time)Required
medianinteger (int32)Required
p10integer (int32)Required
p90integer (int32)Required
perPortioninteger (int32)Required
itemsPricedinteger (int32)Required
itemsTotalinteger (int32)Required
coveragenumber (double)Required
chainCountinteger (int32)Required
changeFromPreviousinteger (int32) | nullRequired
changeFromYearAgointeger (int32) | nullRequired
weeksPricedinteger (int32)Required
weeksTotalinteger (int32)Required
singleChainItemsinteger (int32)Required
derivedUnitItemsinteger (int32)Required
measurementsinteger (int32)Required

DinnerPriceMainItem

PropertyTypeRequired
labelstringRequired
labelEnstring | nullRequired
formstring | nullRequired

DinnerPriceSeriesPoint

PropertyTypeRequired
monthstringRequired
medianinteger (int32)Required

DinnerPricesPublic

PropertyTypeRequired
generatedAtstring (date-time)Required
sourcestringRequired
licensestringRequired
recipeSetVersionstring | nullRequired
sampleSizeinteger (int32)Required
chainsReadstring[]Required
missingChainsstring[]Required
firstMonthstring | nullRequired
latestMonthstring | nullRequired
nextMonthstringRequired
basketsDinnerPriceBasketPublic[]Required
topTenDinnerPriceTopTenPublic[]Required
breaksDinnerPriceBreak[]Required
nextPublishDatestringRequired
itemsDinnerPriceItemPublic[]Required
weightingDinnerPriceWeightingPublic | null—
excludedRecipesDinnerPriceExcludedRecipePublic[] | null—

DinnerPriceSubscribeRequest

PropertyTypeRequired
emailstringRequired
languagestring | nullRequired

DinnerPriceTopTenPublic

PropertyTypeRequired
rankinteger (int32)Required
recipeIdstring (uuid)Required
titlestringRequired
perPortioninteger (int32)Required
ssbGroupstringRequired
mainItemDinnerPriceMainItem | nullRequired

DinnerPriceUnsubscribeResponse

PropertyTypeRequired
unsubscribedbooleanRequired

DinnerPriceWeekPublic

PropertyTypeRequired
monthstringRequired
weekPriceinteger (int32)Required
recipesDinnerPriceWeekRecipe[]Required

DinnerPriceWeekRecipe

PropertyTypeRequired
dayinteger (int32)Required
recipeIdstring (uuid)Required
titlestringRequired
ssbGroupstringRequired
priceinteger (int32)Required
perPortioninteger (int32)Required
mainItemDinnerPriceMainItem | nullRequired

DinnerPriceWeightingPublic

PropertyTypeRequired
kindstringRequired
versionstring | nullRequired
sourcestring | nullRequired
sourceEnstring | nullRequired
capShareOfWeeksnumber (double) | nullRequired

ProblemDetails

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