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.

GETapi.food-lib.gr/api/demo/search?q=%CF%83%CE%BF%CE%BA%CE%BF%CE%BB%CE%B1%CF%84%CE%B1

what is in a row

Four fields guaranteed. The rest, measured.

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···
  • Sugars···
  • Sodium···
  • Product photo···
  • Fibre···
  • Brand as a field···
  • Serving size···
  • Barcode···

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.

Read the reference
# 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
  • Meaning-based search included
  • Barcode lookup and category browsing

Pro

Talk to usmonthly

For something in production, with room for search-as-you-type.

requests / month
1,000,000
requests / minute
600
  • The same catalog and the same fields — the difference is volume
  • Meaning-based search included
  • A person to email when something looks wrong

App scale

Talk to usper app

For a consumer app whose users all search at once.

rate limiting
per user
service account
1
  • Your users get their own buckets via a forwarded id, not one shared ceiling
  • A moderation queue, so your users can submit foods the catalog is missing
  • Contributions arrive tagged with which client and whether a human wrote them

getting a key

There is no signup form.

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.

worth mentioning

  • 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.