A food and nutrition REST API covering 4.7M+ foods — fuzzy search, EAN/UPC barcode lookup, and normalized nutrition fields behind a single JSON endpoint.
Docs · Pricing · OpenAPI spec · Uptime
curl "https://api.getdietly.com/search?q=greek%20yogurt&limit=1"No signup required to try it — the read endpoints below answer anonymous requests.
1. All nutrition values are per 100 g — never per serving.
This is the most common integration mistake. serving_size_g tells you how big one serving is, but every nutrient field is normalized to 100 g regardless:
To get per-serving values, multiply by serving_size_g / 100.
2. Invalid API keys do not error on public endpoints.
A bad or expired Authorization header returns 200, not 401 — the request is simply served at anonymous rate limits. If you rely on a 401 to detect a bad key, you will silently fall back to the free tier under load. Check X-RateLimit-Limit instead.
Base URL: https://api.getdietly.com
| Method | Path | Description |
|---|---|---|
GET |
/search?q= |
Fuzzy food search. q min 2 chars, limit 1–50 (default 5), optional source filter |
GET |
/food/{food_id} |
Fetch one food by its stable ID |
GET |
/barcode/{code} |
EAN/UPC lookup. Returns 404 if the barcode is unknown |
GET |
/foods/popular |
Paginated listing. limit 1–500, offset, category, has_image |
GET |
/foods/categories |
All available category names |
GET |
/health |
Service status and live food count |
All endpoints return 429 when rate limited, with Retry-After set.
{
"id": 1068319,
"name": "Greek yogurt",
"brand": null,
"barcode": "0855088005245",
"category": "Dairies",
"serving_size_g": 170.0, // grams per declared serving, when the source declares one
"serving_desc": "3/4 cup (170 g)",
"calories_kcal": 105.88, // ↓ all nutrients are PER 100 G
"protein_g": 7.65,
"fat_g": 3.53,
"carbs_g": 12.35,
"fiber_g": 0.0,
"sugar_g": 10.0,
"sodium_mg": 44.12,
"saturated_fat_g": 2.35,
"cholesterol_mg": 18.0,
"potassium_mg": 112.0,
"image_url": "https://api.getdietly.com/img?u=...",
"image_thumb_url": "https://api.getdietly.com/img?u=...",
"source": "off", // off | usda | claude | community
"confidence": 0.9, // 0–1
"static_url": "food/19/greek-yogurt-2.html"
}Nutrient fields are null when the underlying source does not publish that value. Check for null on every nutrient — coverage varies significantly across a catalog this size, particularly for micronutrients on branded products.
Public read endpoints work without a key. Send a bearer token to get account-level rate limits and skip the fairness delay applied to shared traffic:
curl -H "Authorization: Bearer $DIETLY_API_KEY" \
"https://api.getdietly.com/search?q=oats&limit=5"Get a key at getdietly.com/api — instant, no card required.
| Plan | Limit | Scope |
|---|---|---|
| Starter (free) | 30 req/min | per IP, shared, with a fairness delay |
| Pro — €27/mo | 500 req/min | per account, no delay |
| Scale — €92/mo | 3,000 req/min | per account, no delay |
| Enterprise — from €199/mo | custom | per account, SLA |
X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset and Retry-After are exposed via CORS, so you can read them from browser JavaScript.
Commercial use requires a paid plan. Full terms on the pricing page.
Access-Control-Allow-Origin: * is set, so you can call the API directly from a browser with no proxy. Responses carry Cache-Control: max-age=14400 (4 hours).
Note that calling from the browser exposes your key to end users. For anything beyond a prototype, proxy through your own backend.
Runnable, dependency-light, in examples/:
examples/curl— every endpoint as a shell one-linerexamples/python— search, barcode lookup, per-serving conversionexamples/node— same, using built-infetch(Node 18+)examples/typescript— typed client interface
openapi.json mirrors the spec served at https://www.getdietly.com/openapi.json. Generate a client with your tool of choice:
npx @hey-api/openapi-ts -i openapi.json -o src/clientDietly aggregates several catalogs and normalizes them onto one schema. The source field on every record tells you where that row came from:
source |
Origin | License |
|---|---|---|
off |
Open Food Facts | ODbL 1.0 |
usda |
USDA FoodData Central | US public domain (CC0) |
claude |
AI-generated estimate, labeled as such | — |
community |
User submissions | — |
If you display data derived from Open Food Facts, ODbL requires you to attribute it. ODbL is a share-alike licence — read it before building a commercial product on top. Filter with ?source=usda if you need public-domain records only.
Dietly's contribution is normalization, indexing, plausibility checks and scheduled daily updates. Values are passed through from upstream sources; use confidence and the source field to decide how much to trust a given record, and validate anything safety-critical yourself.
- Docs: getdietly.com/api-guide
- Issues with this repo's examples: open a GitHub issue
- API support: getdietly.com/support?topic=api
Example code in this repository is MIT licensed — see LICENSE. The licence applies to the sample code only, not to data returned by the API, which is governed by the upstream licences above.
{ "serving_desc": "3/4 cup (170 g)", "serving_size_g": 170.0, "calories_kcal": 105.88235294118 // per 100 g → a serving is 105.88 × 1.7 = 180 kcal }