live against api.food-lib.gr·greek food catalog·rest api
···· Greek foods.Searched in ····ms.
Energy and macros on every food, photos on most — for the food people in Greece actually buy. It gets bigger every month, and every figure on this page is read from the live API rather than typed into the HTML, gaps included. The box below is searching it as you type, with no key.
photos
—
brands
—
nutrition fields
13
per serving
100 g
try
server
—ms
round trip
—ms
showing
—
mode
—
api networkmedianlast 0 queries
Type a food. Greek, greeklish or English all work.
Every food carries energy, protein, carbohydrate and fat — not as a statistic that happens to be high, but because those four columns cannot be null. A row missing one does not exist.
Everything else is optional, so the only useful thing to publish is how often it is actually there. These are counted live on every request, gaps included. Barcodes are thin — a couple of percent — and printing that is deliberate: you would find out on your first scan anyway, and a number you can watch move is worth more than an adjective. It is also the field the review queue fills fastest, because the apps posting foods back are the ones holding a camera.
guaranteed by the schema
Energy (kcal)every food
Proteinevery food
Carbohydrateevery food
Fatevery food
measured, live
Saturated fat···
part of the per-100 g declaration
Sugars···
added sugars where the label states them
Sodium···
milligrams, not salt equivalent
Product photo···
foods with at least one, most have several
Fibre···
declared far less often than the rest
Brand as a field···
many rows carry it inside the name instead
Serving size···
convenience only — macros are per 100 g
Barcode···
the thinnest column, and the one filling fastest
the catalog over time
The number only goes up.
A food catalog is only worth integrating against if it still covers your users next year. So the useful question is not how big this one is today — it is which direction it moves, and how fast.
It is a Greek catalog first — the everyday products people here actually eat, brands included, rather than a global database with some Greek entries in it. And it grows by contribution: any key holder can post a food the catalog is missing, it lands in a review queue, and once approved it becomes an ordinary row — normalised into the same per-100 g shape as everything else, barcodes and all. So it thickens exactly where the apps using it are looking.
Nothing is quietly dropped, either. Deletions are soft, so a food you built against does not disappear from under you between releases.
last 30 days
—
rolling, not calendar
foods today
—
live count
newest in
—
image_urls[]
Photos of the actual packet, not a stock salad.
Product shots come back as absolute URLs on every hit — nothing to assemble client-side, no second request, no signing. These are loading from the catalog right now.
what you get
Built for a food picker that has to feel instant.
?q=
Type it however it comes out
Accents fold both ways, so σοκολατα finds Σοκολάτα — 433 of them. Typos are tolerated: nutela finds NUTELLA. And greeklish is indexed deliberately, so kritharaki finds MISKO Κριθαράκι, a word it shares no letters with — because Latin spellings of Greek names are how a large share of real searches arrive.
?semantic=1
Ask by meaning — on the second pass
greek yoghurt finds Γιαούρτι στραγγιστό, which shares not one character with the query. Keyword and vector search run together and merge by relevance. It costs an embedding call, so expect roughly a second and a half against the ~20 ms above — this belongs where keyword came up short, not on the keystroke path. Try it in the box and watch the trace jump.
image_urls[]
Photos arrive with the food
Absolute URLs on every hit, so there is no base path to assemble, no signing step and no follow-up request. A picker can render a row — photo, name, macros — straight from the search response.
barcodes[]
One barcode, one food — where there is one
Uniqueness is a database constraint, not a convention, so a scan never resolves to two foods. Coverage is the honest caveat: a couple of percent of the catalog today, printed live further down this page. It is the fastest-filling column, because scanning apps are the ones posting foods back.
If-None-Match
Stop re-downloading the catalog
Every cached read carries an ETag; send it back and an unchanged body returns as a 304 with no payload — most of them, on a catalog that barely moves. There is deliberately no freshness window, so an edit reaches you on your very next read rather than after a TTL.
POST /food-contributions
Add what is missing
A food your users need and the catalog does not have is a submission, not a support ticket. Post it with its macros and barcodes, it lands in a review queue, and once approved it is an ordinary catalog row that every other caller gets too. This is why the catalog thickens fastest exactly where it is being used.
per 100 g
Thirteen nutrition fields, one basis
Energy, protein, carbs, fat, fibre, sugars, added sugars, three more fats, trans fat, sodium, cholesterol — always per 100 grams, whatever the serving says. The first four cannot be null: a food missing one is a row the database refuses. The rest are optional, so a value nobody recorded stays null rather than becoming zero — those are different facts and your UI should be able to tell them apart.
integration
One GET, one header, done.
No SDK to install and none needed — it is JSON over HTTP with a bearer token. The full contract is published as OpenAPI 3.1, and the reference page is generated from that same file, so it cannot describe an endpoint that does not exist.
# A key works on every route a login token does. Server-side only —
# it identifies your account, so treat it like a password.
# -G with --data-urlencode keeps Greek readable instead of %CF%86%CE%AC…
curl -sS -G 'https://api.food-lib.gr/api/foods/search' \
--data-urlencode 'q=kritharaki' \
-H 'Authorization: Bearer flk_live_…' \
-H 'Accept: application/json'
# → 22 matches, top one "MISKO Κριθαράκι Χονδρό 500g".
# A Latin-spelled query against a Greek name it shares no letters with.
# Or exchange email + password for a 60-minute token instead.
TOKEN=$(curl -sS -X POST https://api.food-lib.gr/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"you@example.com","password":"…"}' | jq -r .access_token)
plans
Two limits, both enforced, both printed here.
A burst limit per minute and a volume cap per month. Every response carries your meter in its headers, and GET /api/usage reads it without spending a request.
Free
€0no card
Enough to build the whole integration and see if the catalog fits.
requests / month
10,000
requests / minute
120
Every field and every photo — nothing is held back by tier
Keys are issued by a person, one account at a time — which means we read what you are building before you integrate, and you get a straight answer about whether the catalog covers it. Tell us the shape of it and expect a reply the same week.
What you are building. A food logger, a recipe app, a retail tool — it changes which endpoints matter.
Rough monthly volume. It sets the plan, and there is no penalty for guessing low.
Server or app. A consumer app should be rate-limited per end user rather than sharing one ceiling, and that is set up on our side.
Anything missing. The catalog is Greek-first and grows every month, so gaps close on their own. If there is a category you need sooner, say so and we will backfill it for you — that is a job to schedule, not a no.