Sign up takes 30 seconds — $0.50 free on your account. Claim credit →

Wolt restaurant data API

The most complete Wolt scraper on the market. Full menus, allergens, nutrition, photos, and translations in every language a restaurant offers — as a single ZIP download.

Wolt coverage: 23 countries, every region verified

We've parsed and verified restaurants across 23 countries end-to-end — every one of them tested with real URLs, real menus, real photos. This isn't a list of countries "in theory supported" by scraping wolt.com — these are markets where we've actually confirmed the parser works perfectly, edge cases and all.

🇦🇹 AUT 🇩🇪 DEU 🇪🇪 EST 🇱🇻 LVA 🇸🇰 SVK 🇸🇮 SVN 🇭🇷 HRV 🇭🇺 HUN 🇬🇷 GRC 🇸🇪 SWE 🇩🇰 DNK 🇮🇸 ISL 🇦🇱 ALB 🇷🇸 SRB 🇲🇰 MKD 🇽🇰 XKX 🇬🇪 GEO 🇦🇲 ARM 🇦🇿 AZE 🇮🇱 ISR 🇰🇿 KAZ 🇫🇷 FRA 🇫🇮 FIN

Across these markets we've hit every edge case Wolt can throw at a scraper: right-to-left scripts (Hebrew in Israel, Arabic in mixed-Arabic restaurants), five-language menus (Aroma Coffee in Tbilisi serves ka + en + ru + de + tr), zero-decimal currencies (ISK, JPY-ready), de-facto integer currencies (KZT, AMD, HUF, ALL), and machine-translation quirks like Wolt rendering "Brownie" as "Lutin" in French — all preserved 1:1.

What we extract from every Wolt restaurant

Other Wolt scrapers give you the obvious stuff: name, price, address. We extract everything Wolt exposes, including endpoints other scrapers don't know exist.

Restaurant card (always)

  • Name, slug, internal venue ID
  • Full address (multi-line), coordinates (lat/lon), Google Maps link
  • Phone, slogan, tags ("Burger", "Mexican", "Steak"…)
  • Delivery hours per day of week
  • Delivery methods + estimates (homedelivery / takeaway / eatin)
  • Minimum order amount, delivery fee
  • Open/closed status with next open/close timestamp
  • Country, city, primary language, currency
  • Breadcrumbs (helps you map the restaurant into Wolt's taxonomy)

Menu items — the meat of the data

  • Item name, description, category
  • Price in correct currency formatting (we handle ISK/JPY/HUF/KZT properly)
  • Discount fields: old_price, has_discount, discount_pct
  • Photos (primary + all extras), with content-hashed local file names
  • Popular badge, Age-restricted flag, delivery-only flag
  • Available-times window (some items only sold 11:30–14:00)
  • Allowed delivery methods per item
  • Restrictions (alcohol-age limit, etc.)
  • Out-of-stock disabled_info when applicable

Options & combos — the hard part nobody else does

Wolt items can be combos: Burger + Side + Drink, each with its own choice tree. We don't flatten these into ugly strings — we keep the full structure with option_id, prerequisites (X choice unlocks Y options), prices per choice, and nested prodinfo per variant (a "Beef" combo option has its own allergens from the prodinfo endpoint, not just inherited from the parent).

prodinfo — allergens, nutrition, GTIN, origin

Most Wolt scrapers ignore this endpoint or don't even know it exists. For every menu item with has_extra_info=true (typically all packaged goods, alcohol, and many regular dishes), we fetch prodinfo.wolt.com/{locale}/{venue_id}/{item_id} and parse:

  • Allergens as a plain list ("gluten, milk, eggs, soya")
  • Ingredients full list
  • Nutrition table per 100g — kcal, protein, carbs, fat, salt, sugars
  • GTIN (barcode) — invaluable for retail/inventory integrations
  • Unit info — "330 ml", "500 g"
  • Unit price — "€8.40/litre" calculated by Wolt
  • Country of origin, producer, importer
  • Storage instructions, warnings, more_info text
  • Alcohol permille for beer/wine/spirits

And we do this in every language the restaurant offers, not just the URL locale. If Aroma Tbilisi has menu in ka + en + ru + de + tr, you get five complete allergen lists per item.

Multilingual menus — every translation, not just one

Wolt exposes a translation API at consumer-assortment/v1/venues/slug/{slug}/assortment?language={lang}. Generic scrapers fetch one language (usually the URL locale, like English). We iterate through available_languages and fetch them all.

Each menu item gets a translations.{lang} object with the item's name, description, and allergens in that language. Plus we mark which translations are autotranslated: true (machine) vs false (human-authored) so your downstream system can decide whether to trust them.

Real example: a Georgian café we verified — Aroma Coffee & Tea, Batumi — serves menu in 5 languages: Georgian (ka, primary), English (en), Russian (ru), German (de), Turkish (tr). All five fully available in our response. RTL languages (Hebrew, Arabic) handled correctly as-is — your frontend sets direction: rtl and it works.

Currency edge cases — ISK/JPY/KZT/HUF formatted right

Wolt stores prices in minor units (cents). For EUR, USD, GBP — that's 100 cents per major unit. But for ISK (Iceland), öre haven't existed since the 90s. For JPY (Japan) and KRW (Korea), there's no sub-unit at all. Wolt still returns these as "minor units" but the minor unit happens to be the whole krona/yen.

Generic scrapers blindly divide by 100, so an Icelandic burger that costs 3490 ISK (kr3,490 ≈ €25) becomes "34.90 ISK" in their output — a 100× error. We auto-detect zero-decimal ISO 4217 currencies and de-facto integer currencies (KZT, HUF, AMD, ALL, MKD, MNT, UZS) and render the correct value.

Try it: search "Iceland Wolt scraper" on any marketplace, look at their output. Most are off by 100×. We aren't.

How we compare to other Wolt scrapers

We've looked at every Wolt scraper publicly listed on Apify and elsewhere. Here's an honest comparison:

Feature restoapi.org Apify Wolt actors DIY scripting Generic scraping API
Restaurant name + address + hours
Menu items + prices (any currency) ✓ all 16 currencies EUR/USD only DIY needed N/A
ISK/JPY/KZT correct (no 100× bug) Off by 100× Easy bug N/A
All translations (every language) ✓ all 5 URL locale only Hard N/A
Allergens (per item, from prodinfo) No Hidden endpoint No
Nutrition + GTIN + unit price No No No
Combo items with nested variants ✓ full tree Flattened or skipped No N/A
Photos archived locally in ZIP ✓ de-duplicated URLs only URLs only URLs only
RTL languages (Hebrew, Arabic) ✓ preserved Untested DIY DIY
Discount fields (old_price, discount_pct) Often missing DIY N/A
Auto-refund on failure Pay anyway N/A N/A
Batch (200 URLs per request) ✓ DIY Per-request
Async job model (no holding connection) ✓ poll-based Sync, holds run DIY Sync
Full billing receipt in response ✓ txn-ID + balance Just charged N/A No
Per-restaurant price $0.15 full media $0.005–$0.05 Free (your time) $0.005–$0.015 / req

Why we cost more than $0.005

Cheap Wolt actors hit Wolt's public endpoints with no extras. We do everything a "premium" scraper does — multilingual fetch, prodinfo per item, media archival, content de-duplication, currency-aware formatting, zero-decimal handling — all in one call. The work behind one $0.15 request is what a DIY engineer would spend a day building correctly.

If you need only the basics — restaurant name + price — use one of the cheap actors and save money. If you need the complete picture (allergens, translations, nutrition, photos, edge cases), the math works out in your favour at $0.15.

What people build with Wolt data

Our users use Wolt extracts for:

  • Price tracking — daily snapshots of competitor restaurants in their city. A burger that costs €8.90 today, €9.50 next week, €8.50 on Sunday. The pattern tells you when to do promotions.
  • Allergen-friendly bots — a Telegram bot that filters Wolt restaurants by "no gluten" or "vegan-friendly". With our normalised allergens_normalized field (translates "qumësht" / "Milch" / "leite" all to "milk") — instant filtering.
  • ML training data — labelled food photos with category, allergens, and nutrition tags. We've delivered datasets of 1000+ restaurants × 15+ photos each for image classification models.
  • Multilingual menus in your CRM — tourism platforms showing the same restaurant in 5 languages depending on visitor's locale. All translations come from one API call.
  • Franchise monitoring — chain owners tracking their 50 locations daily, detecting when an outlet has different prices than the rest, or photos that haven't been refreshed in 6 months.
  • Catalog SEO — public-facing "best Wolt restaurants in Vienna" sites with full schema.org markup. Our computed.flat gives 47 scalars per restaurant ready for Google rich snippets.

Data we extract — annotated examples

Below are real excerpts from a Wolt scrape we ran on Centrum Kitchen & Bar, Akureyri, Iceland — a 15-item, 3-language (is/en/pl) restaurant. Every field shown is what you get in your result.json.

1. Restaurant identification (always present)

{
  "name": "Centrum Kitchen & Bar",
  "slug": "centrum-kitchen-bar",
  "venue_id": "6569f2e7f947f35fcbf27951",
  "country": "ISL",
  "city": "Akureyri",
  "currency": "ISK",
  "primary_language": "is",
  "available_languages": [
    {"language": "en", "name": "English", "autotranslated": true},
    {"language": "is", "name": "Icelandic", "autotranslated": false},
    {"language": "pl", "name": "Polish", "autotranslated": true}
  ],
  "translated_languages": ["en", "pl"],
  "phone": "+3546666078",
  "address": ["Hafnarstræti 102", "600 Akureyri"],
  "maps_url": "https://maps.google.com/?q=65.6818,-18.0905",
  "slogan": "Framandi & fjölbreyttur matseðill fyrir hvern sem er!",
  "tags": ["Burger", "Meat & fish", "Steak", "Mexican", "Salad"],
  "is_open": true,
  "open_status": "Closing at 23:45",
  "min_order_eur": 2500.0,
  "share_url": "https://wolt.com/is/isl/akureyri/restaurant/..."
}

2. Delivery details (per-day hours, multiple methods)

"delivery_methods": [
  {
    "method": "homedelivery",
    "label": "Standard",
    "estimate_label": "25-35 min",
    "estimate_min": 25,
    "estimate_max": 35
  },
  {
    "method": "takeaway",
    "label": "Standard",
    "estimate_label": "10-15 min",
    "estimate_min": 10,
    "estimate_max": 15
  }
],
"delivery_hours": {
  "monday":    "11:30–21:00",
  "tuesday":   "11:30–21:00",
  "wednesday": "11:30–21:00",
  "thursday":  "11:30–21:00",
  "friday":    "11:30–21:00",
  "saturday":  "11:30–22:00",
  "sunday":    "12:00–22:00"
}

3. Menu item — basic data straight from Wolt

{
  "platform_id": "68a3df1f97e1...",
  "local_id":    "wlt:cent:8f3a",        // stable hash — our addition
  "name":        "Kjúklinga takkó",
  "description": "Mexican chicken taco with avocado, chipotle...",
  "category":    {"name": "Mexican", "local_id": "cat:mex01"},
  "pricing": {
    "amount":          3450,
    "currency":        "ISK",
    "currency_symbol": "kr",
    "formatted":       "kr3450"        // no .00 — ISK is zero-decimal
  },
  "photo": {
    "url":       "https://imageproxy.wolt.com/assets/68a3df.../w=4096",
    "local_url": "photos/menu_photos/3fb776fbc34f.jpg"
  },
  "image_urls":  ["...primary", "...alternate1"],
  "image_local_urls": ["photos/menu_photos/3fb776fbc34f.jpg", "..."],
  "popular":        true,
  "age_restricted": false,
  "old_price":      null,
  "discount_pct":   null,
  "delivery_only":  false,
  "available_times": []
}

4. Multilingual translations — same item in 3 languages

"translations": {
  "is": {
    "name": "Kjúklinga takkó",
    "description": "Mexikóskt taco með kjúklingi, avocado..."
  },
  "en": {
    "name": "Chicken taco",
    "description": "Mexican chicken taco with avocado, chipotle..."
  },
  "pl": {
    "name": "Taco z kurczakiem",
    "description": "Meksykańskie taco z kurczakiem, awokado..."
  }
}

5. prodinfo result — allergens, nutrition, GTIN

For packaged-goods items (drinks, snacks, alcohol), Wolt exposes additional info via prodinfo.wolt.com. Example for a Coca-Cola 0.33L can in a German Wolt market shop:

{
  "name": "Coca-Cola Dose 0,33l",
  "gtin": "5449000000996",
  "barcode_gtin": "5449000000996",
  "unit_info": "330 ml",
  "unit_price": {
    "price": 8.79,
    "unit":  "litre",
    "base":  "1 l"
  },
  "allergens":     ["glutenfrei", "laktosefrei"],
  "ingredients":   "Wasser, Zucker, Kohlensäure, Farbstoff E150d...",
  "additives":     "E150d, E338, E330, E950, E951",
  "nutrition": [
    ["", "per 100 ml"],
    ["Energy", "180 kJ / 42 kcal"],
    ["Fat",            "0 g"],
    ["of which sugars", "10.6 g"],
    ["Salt",           "0.01 g"]
  ],
  "origin":     "Belgien",
  "producer":   "Coca-Cola European Partners Deutschland...",
  "importer":   "Coca-Cola GmbH, Bornheim",
  "storage":    "Kühl und lichtgeschützt lagern.",
  "warnings":   [],
  "alcohol_permille": null
}

6. Combo item with nested variants

A combo "Burger Menu" — pick a burger, a side, a drink. Each option group has its own values, each value has its own prodinfo (allergens differ between beef and chicken combos). Generic scrapers flatten this into a single string; we keep the tree:

"options_groups": [
  {
    "option_id": "main-burger",
    "name": "Choose your burger",
    "min": 1, "max": 1,
    "values": [
      {
        "id":    "v-beef",
        "name":  "Centrum Beef Burger",
        "price": 0,                // base price
        "dietary_preferences": []
      },
      {
        "id":    "v-chicken",
        "name":  "Chicken Burger",
        "price": -200             // 2 ISK cheaper
      }
    ]
  },
  {
    "option_id": "side",
    "name": "Side",
    "prerequisite_values": [],
    "values": [
      {"name": "Fries", "price": 0},
      {"name": "Truffle fries", "price": 800}
    ]
  }
]

What WE add on top — the computed.* namespace

Wolt gives raw data. We add derived, normalised, statistical fields that make downstream code easier. Everything we calculate goes into a clearly-marked computed.* namespace so you always know what came from Wolt vs from us.

7. Per-item flags (boolean quick filters)

"computed": {
  "flags": {
    "has_photo":           true,
    "has_multi_photos":    false,
    "has_description":     true,
    "has_allergens":        true,
    "has_real_allergens":   true,   // from prodinfo, not just bracket-parse
    "has_ingredients":      false,
    "has_nutrition":        false,
    "has_producer":         false,
    "has_warnings":         false,
    "has_gtin":             false,
    "has_unit_info":        false,
    "is_alcoholic":         false,
    "is_packaged_good":     false,
    "is_combo":             false,
    "is_popular":           true,
    "has_discount":         false,
    "delivery_only":        false,
    "age_restricted":       false,
    "is_available_always":  true,
    "has_translations":     true
  },
  ...
}

8. Normalised & derived per-item data

"computed": {
  "derived": {
    "food_category": "taco",                  // our classifier
    "allergens_normalized": ["milk", "wheat"],  // EN words, any input lang
    "searchable_text": "Kjúklinga takkó | Mexican chicken taco | Chicken taco | Taco z kurczakiem | popular",
    "alcohol_pct": null                       // permille/10 if alcoholic
  }
}

allergens_normalized is our magic — it takes whatever language the allergen string came in ("gluten, qumësht ose produkte të tij" in Albanian, "glutenfrei, laktosefrei" in German) and maps them all to English keywords: ["gluten", "milk"]. Your code can filter by allergens without caring about language.

searchable_text is one big string concatenating name+description+translations — ready for full-text search indexing (Postgres tsvector, Elasticsearch, SQLite FTS5).

9. Per-item stats & pricing helpers

"computed": {
  "stats": {
    "price":                3450,
    "currency":             "ISK",
    "old_price":            null,
    "discount_pct":         null,
    "unit_price_formatted": "kr8/100g",   // e.g. "kr8/100g" for groceries
    "photo_count":          1,
    "languages_count":      3
  }
}

10. Restaurant-level menu stats

"computed": {
  "menu_stats": {
    "items_total":        15,
    "items_popular":      5,
    "items_with_photo":   15,
    "items_with_desc":    10,
    "items_alcoholic":    0,
    "items_combo":        0,
    "items_packaged":     0,
    "items_with_discount": 0,
    "price_min":          500,
    "price_max":          3850,
    "price_avg":          2433.33,
    "price_median":       2400,
    "top_cuisines":       ["other", "salad", "pasta"],
    "top_allergens":      ["milk", "wheat"],
    "food_categories_distribution": {
      "taco": 2, "burger": 2, "salad": 3, "pasta": 2, "other": 6
    }
  }
}

11. The computed.flat — 47-scalar restaurant card for catalogs

This is the killer feature for anyone building catalogs, spreadsheets, SQL tables, CSV exports. One flat object per restaurant, no nesting, ready for direct insertion into any tabular format:

{
  // Identity
  "name": "Centrum Kitchen & Bar",
  "slug": "centrum-kitchen-bar",
  "venue_id": "6569f2e7...",
  "country": "ISL",
  "city": "Akureyri",
  "currency": "ISK",

  // Languages
  "primary_language": "is",
  "languages": ["en", "is", "pl"],
  "languages_count": 3,

  // Status
  "is_open": true,
  "phone": "+3546666078",
  "has_logo": false,
  "brand_slug": null,
  "slogan": "Framandi & fjölbreyttur...",
  "tags": ["Burger", "Meat & fish", "Steak", "Mexican", "Salad"],

  // Menu counts
  "items_count":        15,
  "items_with_photo":   15,
  "items_with_desc":    10,
  "items_with_allergens": 0,
  "items_packaged":     0,
  "items_alcoholic":    0,
  "items_combo":        0,
  "items_popular":      5,
  "items_with_discount": 0,

  // Price stats
  "price_min":  500,
  "price_max":  3850,
  "price_avg":  2433.33,
  "price_median": 2400,

  // Distributions
  "top_cuisines":  ["other", "salad", "pasta"],
  "top_allergens": [],

  // Delivery
  "min_order": 2500.0,
  "delivery_eta_mean": 30,
  "delivery_methods": ["homedelivery", "takeaway"],

  // Media
  "cover_url":        "https://imageproxy.wolt.com/...",
  "cover_local_url":  "photos/venue_photos/abc.jpg",
  "logo_url":         null,
  "logo_local_url":   null,
  "photos_count":     21,

  // Coordinates
  "lat": 65.6818,
  "lon": -18.0905,
  "address_line": "Hafnarstræti 102, 600 Akureyri",
  "maps_url": "https://maps.google.com/?q=65.6818,-18.0905"
}

Want a CSV of 1000 restaurants? Run a batch, take computed.flat from each, write to CSV. Done. Want a SQL restaurants table? Same fields, direct mapping.

12. Searchable text — instant full-text indexing

"Kjúklinga takkó | Mexican chicken taco with avocado, chipotle, jalapeños | Mexican | Chicken taco | Mexican chicken taco with avocado | Taco z kurczakiem | Meksykańskie taco z kurczakiem, awokado | popular"

Every menu item gets a single searchable string with name + description + translations + flags. Drop into Postgres' tsvector, Meilisearch, Elasticsearch — works out of the box. No tokenisation logic needed on your side.

13. Stable IDs that survive re-scrapes

Wolt's platform_id changes if they restructure their catalog. We add a local_id calculated as sha1(platform | slug | normalized_name)[:12]. This is stable: the same item gets the same local_id across runs, even if Wolt rotates its internal IDs. Perfect for diff/change detection.

Code example: scrape a Wolt restaurant in 10 lines

import requests, time

KEY = "rk_live_xxx"
H   = {"Authorization": f"Bearer {KEY}"}

job = requests.post("https://restoapi.org/v1/jobs", headers=H, json={
    "source_url": "https://wolt.com/en/aut/wien/restaurant/foo",
    "platform":   "wolt",
    "export_type": "full_media",
}).json()
print(f"job: {job['job_id']}, charged {job['billing']['charged_cents']}c")

while True:
    time.sleep(10)
    s = requests.get(f"https://restoapi.org/v1/jobs/{job['job_id']}/status", headers=H).json()
    if s["status"] == "completed":
        url = s["downloads"]["full_export_zip"]["url"]
        open("wolt.zip", "wb").write(requests.get(url).content)
        break

That's literally it. One POST, one polling loop, one ZIP. Inside the ZIP you get result.json (full canonical data), restaurant.json, menu.json, computed.json, and photos/ with all images organised by type.

Ready to try?

Sign up with email (OTP, no password), get $0.50 free credit — enough for 3+ Basic tasks. Run your first Wolt scrape in under 2 minutes.

Start scraping Wolt — claim $0.50 free