Install

Search restaurants that deliver to an address.

Lists Lieferando restaurants (and shops) that deliver to, or offer pickup near, an address: rating, delivery time, delivery fee, minimum order, free-delivery threshold, cuisines, deals and menu link. Filters by cuisine, name and open-now. Paid sponsored placements are removed by default, so the order is Lieferando's organic ranking.

No reports yetRead-only, no login
Site
Lieferando, Germany
Version
v1
Runs, last 7 days
No reports yet
sha256
beda032a2e7a…

Requests

sent from your browser, in order
  1. 1GETrest.api.eu-central-1.production.jet-external.com/autocomplete/addresses/de?input&limit&typeFree text to a Google place id. Without a session param the API mints one and returns it.no cookies
  2. 2GETrest.api.eu-central-1.production.jet-external.com/autocomplete/addresses/de/{{steps.address.place_id | urlencode}}?sessionno cookies
  3. 3GETrest.api.eu-central-1.production.jet-external.com/discovery/de/restaurants/enriched?latitude&longitude&ratingsOutOfFive&serviceType&verticalDiscovery API v3 (the version the site uses): all restaurants for the point in one ~3 MB response, fees and sponsored placements in top-level maps.no cookies

Parameters

from your agent
addressstringrequiredDelivery address or postcode, e.g. 'Alexanderplatz 1, Berlin' or '80331'
cuisinestringCuisine filter, matched against Lieferando's cuisine names, e.g. 'sushi', 'pizza', 'döner', 'vegan'
include_sponsoredbooleanKeep paid sponsored placements (marked sponsored: true) = false
limitenumMaximum restaurants returned (5, 10, 25 or 50) 5 | 10 | 25 | 50 = 25
namestringOnly restaurants whose name contains this text
open_nowbooleanOnly restaurants open now for the chosen service = true
serviceenumdelivery or collection (pickup) "delivery" | "collection" = "delivery"
sortenumdefault = Lieferando's organic ranking; rating = best rated first, weighted by number of reviews; distance = closest first "default" | "rating" | "distance" = "default"

Returns

to your agent
addressstringAddress actually used (first autocomplete match)
areastring
postal_codestring
restaurantsobject[]address, cuisines, deals, delivery_fee_eur, distance_m, eta_min_from, eta_min_to, free_delivery_from_eur, id, min_order_eur, name, new, open_now, rating, rating_count, sponsored, url
totalintegerMatching restaurants before limit

Where it can send

  • rest.api.eu-central-1.production.jet-external.com

Anything else is blocked by the extension.

Reads from your session

Nothing. Your browser attaches the site's cookies by itself.

Used only in requests to the addresses on the left. Never sent to wield.run or your agent.

Checks

a run passes when
  • length(output.restaurants) > `0`
  • output.total >= length(output.restaurants)
  • contains(output.address, 'Berlin')
  • length(output.restaurants[?sponsored]) == `0`
  • length(output.restaurants[?!open_now]) == `0`
  • starts_with(output.restaurants[0].url, 'https://www.lieferando.de/speisekarte/')
  • output.restaurants[0].min_order_eur != `null`

Raw recipe

Served as canonical JSON from /api/v1/recipes/lieferando.de/search-restaurants, so its sha256 matches the ETag and the index.

Check it yourself
curl -s https://wield.run/api/v1/recipes/lieferando.de/search-restaurants | shasum -a 256
# beda032a2e7aafc56645891d663d4abfb53eefbb5a94382a8962d95834f9b9d0
lieferando.de/search-restaurants.json, v1
{
  "description": "Lists Lieferando restaurants (and shops) that deliver to, or offer pickup near, an address: rating, delivery time, delivery fee, minimum order, free-delivery threshold, cuisines, deals and menu link. Filters by cuisine, name and open-now. Paid sponsored placements are removed by default, so the order is Lieferando's organic ranking.",
  "effect": "read",
  "id": "lieferando.de/search-restaurants",
  "keywords": [
    "lieferando",
    "essen bestellen",
    "lieferdienst",
    "restaurant",
    "pizza",
    "sushi",
    "döner",
    "lieferung",
    "takeaway",
    "food delivery",
    "order food",
    "restaurants near me",
    "just eat"
  ],
  "output": {
    "schema": {
      "properties": {
        "address": {
          "description": "Address actually used (first autocomplete match)",
          "type": "string"
        },
        "area": {
          "type": [
            "string",
            "null"
          ]
        },
        "postal_code": {
          "type": [
            "string",
            "null"
          ]
        },
        "restaurants": {
          "items": {
            "properties": {
              "address": {
                "type": "string"
              },
              "cuisines": {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "deals": {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              "delivery_fee_eur": {
                "description": "Fee at the minimum order value",
                "type": [
                  "number",
                  "null"
                ]
              },
              "distance_m": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "eta_min_from": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "eta_min_to": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "free_delivery_from_eur": {
                "description": "Order value from which delivery is free, if any",
                "type": [
                  "number",
                  "null"
                ]
              },
              "id": {
                "type": "string"
              },
              "min_order_eur": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "name": {
                "type": "string"
              },
              "new": {
                "type": "boolean"
              },
              "open_now": {
                "type": "boolean"
              },
              "rating": {
                "description": "0-5 stars; 0 when unrated",
                "type": [
                  "number",
                  "null"
                ]
              },
              "rating_count": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "sponsored": {
                "type": "boolean"
              },
              "url": {
                "format": "uri",
                "type": "string"
              }
            },
            "type": "object"
          },
          "type": "array"
        },
        "total": {
          "description": "Matching restaurants before limit",
          "type": "integer"
        }
      },
      "required": [
        "address",
        "area",
        "total",
        "restaurants"
      ],
      "type": "object"
    },
    "value": "let $s = steps.restaurants, $c = lower(params.cuisine || ''), $n = lower(params.name || ''), $open = params.open_now, $svc = params.service, $inc = params.include_sponsored in let $m = $s.all[?(!$open || (($svc == 'delivery' && open_delivery) || ($svc == 'collection' && open_collection))) && !offline && ($c == '' || length(cuisines[?contains(lower(@), $c)]) > `0` || length(cuisine_keys[?contains(@, $c)]) > `0`) && ($n == '' || contains(lower(name), $n)) && ($inc || !contains($s.sponsored_ids, id))] in let $o = (params.sort == 'rating' && reverse(sort_by($m, &(((rating || `0`) * (rating_count || `0`) + `80`) / ((rating_count || `0`) + `20`))))) || (params.sort == 'distance' && sort_by($m, &distance_m || `999999`)) || $m in {address: steps.address.label, area: $s.area, postal_code: $s.postal_code, total: length($m), restaurants: ((params.limit == `5` && $o[:5]) || (params.limit == `10` && $o[:10]) || (params.limit == `50` && $o[:50]) || $o[:25])[].let $f = (let $id2 = id in $s.fees[?restaurantId == $id2] | [0]) in {id: id, name: name, url: url, cuisines: cuisines, rating: rating, rating_count: rating_count, open_now: $svc == 'delivery' && open_delivery || ($svc == 'collection' && open_collection), eta_min_from: eta_min_from, eta_min_to: eta_min_to, distance_m: distance_m, delivery_fee_eur: $f.bands[0].fee != `null` && $f.bands[0].fee / `100` || `null`, min_order_eur: $f.minimumOrderValue != `null` && $f.minimumOrderValue / `100` || `null`, free_delivery_from_eur: ($f.bands[?fee == `0`] | [0].minimumAmount) != `null` && ($f.bands[?fee == `0`] | [0].minimumAmount) / `100` || `null`, address: address, deals: deals, new: new, sponsored: contains($s.sponsored_ids, id)}}"
  },
  "params": {
    "additionalProperties": false,
    "properties": {
      "address": {
        "description": "Delivery address or postcode, e.g. 'Alexanderplatz 1, Berlin' or '80331'",
        "maxLength": 120,
        "minLength": 3,
        "type": "string"
      },
      "cuisine": {
        "description": "Cuisine filter, matched against Lieferando's cuisine names, e.g. 'sushi', 'pizza', 'döner', 'vegan'",
        "maxLength": 40,
        "type": "string"
      },
      "include_sponsored": {
        "default": false,
        "description": "Keep paid sponsored placements (marked sponsored: true)",
        "type": "boolean"
      },
      "limit": {
        "default": 25,
        "description": "Maximum restaurants returned (5, 10, 25 or 50)",
        "enum": [
          5,
          10,
          25,
          50
        ],
        "type": "integer"
      },
      "name": {
        "description": "Only restaurants whose name contains this text",
        "maxLength": 60,
        "type": "string"
      },
      "open_now": {
        "default": true,
        "description": "Only restaurants open now for the chosen service",
        "type": "boolean"
      },
      "service": {
        "default": "delivery",
        "description": "delivery or collection (pickup)",
        "enum": [
          "delivery",
          "collection"
        ],
        "type": "string"
      },
      "sort": {
        "default": "default",
        "description": "default = Lieferando's organic ranking; rating = best rated first, weighted by number of reviews; distance = closest first",
        "enum": [
          "default",
          "rating",
          "distance"
        ],
        "type": "string"
      }
    },
    "required": [
      "address"
    ],
    "type": "object"
  },
  "provenance": {
    "method": "browser-inspect",
    "notes": "spikes/lieferando.md. Just Eat Takeaway public gateway, cross-origin from www.lieferando.de; no cookies, tokens or custom headers needed (credentials omit). The autocomplete mints its own Google billing session when none is sent; the detail call reuses it. Discovery v3 has no paging (~3.6 MB for central Berlin, 1,586 restaurants) with fees (cents) in deliveryFees.restaurants and paid placements in sponsored.all.lists (73 in central Berlin, interleaved at ranks 0,1,2,4,6,...). Cloudflare is in front but did not challenge API reads.",
    "recorded_at": "2026-11-07T12:00:00+01:00",
    "recorded_by": "C4"
  },
  "requires_login": false,
  "schema": "https://wield.run/schema/recipe/v1.json",
  "site": {
    "country": "DE",
    "id": "lieferando.de",
    "language": "de",
    "name": "Lieferando",
    "origin": "https://www.lieferando.de",
    "origins": [
      "https://rest.api.eu-central-1.production.jet-external.com"
    ]
  },
  "steps": [
    {
      "description": "Free text to a Google place id. Without a session param the API mints one and returns it.",
      "expect": {
        "assert": "length(body.data) > `0`",
        "content_type": "json",
        "status": [
          200
        ]
      },
      "extract": {
        "json": {
          "label": "data[0].description",
          "place_id": "data[0].id",
          "session": "session"
        }
      },
      "id": "address",
      "request": {
        "credentials": "omit",
        "headers": {
          "Accept": "application/json",
          "x-jet-application": "OneWeb"
        },
        "method": "GET",
        "query": {
          "input": "{{params.address}}",
          "limit": "5",
          "type": "any"
        },
        "url": "https://rest.api.eu-central-1.production.jet-external.com/autocomplete/addresses/de"
      }
    },
    {
      "expect": {
        "assert": "length(body.features[0].geometry.coordinates) == `2`",
        "content_type": "json",
        "status": [
          200
        ]
      },
      "extract": {
        "json": {
          "lat": "features[0].geometry.coordinates[1]",
          "lng": "features[0].geometry.coordinates[0]"
        }
      },
      "id": "geocode",
      "request": {
        "credentials": "omit",
        "headers": {
          "Accept": "application/json",
          "x-jet-application": "OneWeb"
        },
        "method": "GET",
        "query": {
          "session": "{{steps.address.session}}"
        },
        "url": "https://rest.api.eu-central-1.production.jet-external.com/autocomplete/addresses/de/{{steps.address.place_id | urlencode}}"
      }
    },
    {
      "description": "Discovery API v3 (the version the site uses): all restaurants for the point in one ~3 MB response, fees and sponsored placements in top-level maps.",
      "expect": {
        "assert": "body.restaurants != null",
        "content_type": "json",
        "status": [
          200
        ]
      },
      "extract": {
        "json": {
          "all": "sort_by(restaurants[?isTestRestaurant != `true`], &defaultDisplayRank)[].{id: id, name: name, url: join('', ['https://www.lieferando.de/speisekarte/', uniqueName]), cuisines: keys(from_items(zip(cuisines[].name, cuisines[].name))), cuisine_keys: cuisines[].uniqueName, rating: rating.starRating, rating_count: rating.count, open_delivery: isOpenNowForDelivery, open_collection: isOpenNowForCollection, offline: isTemporarilyOffline, eta_min_from: deliveryEtaMinutes.rangeLower, eta_min_to: deliveryEtaMinutes.rangeUpper, distance_m: driveDistanceMeters, address: join(', ', [address.firstLine || '', join(' ', [address.postalCode || '', address.city || ''])]), deals: keys(from_items(zip(deals[?trim(description) != ''].trim(description), deals[?trim(description) != ''].trim(description)))), new: isNew}",
          "area": "metaData.area",
          "fees": "values(deliveryFees.restaurants || `{}`)",
          "postal_code": "metaData.postalCode",
          "sponsored_ids": "keys(sponsored.all.lists || `{}`)"
        }
      },
      "id": "restaurants",
      "request": {
        "credentials": "omit",
        "headers": {
          "Accept": "application/json;v=3",
          "x-jet-application": "OneWeb"
        },
        "method": "GET",
        "query": {
          "latitude": "{{steps.geocode.lat}}",
          "longitude": "{{steps.geocode.lng}}",
          "ratingsOutOfFive": "true",
          "serviceType": "{{params.service}}",
          "vertical": "all"
        },
        "url": "https://rest.api.eu-central-1.production.jet-external.com/discovery/de/restaurants/enriched"
      }
    }
  ],
  "task": "Search restaurants that deliver to an address",
  "tos": {
    "notes": "Lieferando's terms prohibit scraping and automated systematic retrieval. One user-initiated search at a time from the user's own browser (3 requests). The address lookup is billed to Lieferando by Google, so do not use it for bulk geocoding. Ordering stays on lieferando.de.",
    "reviewed": false
  },
  "verify": {
    "checks": [
      "length(output.restaurants) > `0`",
      "output.total >= length(output.restaurants)",
      "contains(output.address, 'Berlin')",
      "length(output.restaurants[?sponsored]) == `0`",
      "length(output.restaurants[?!open_now]) == `0`",
      "starts_with(output.restaurants[0].url, 'https://www.lieferando.de/speisekarte/')",
      "output.restaurants[0].min_order_eur != `null`"
    ],
    "example_params": {
      "address": "Alexanderplatz 1, Berlin",
      "cuisine": "sushi",
      "limit": 10
    },
    "max_ms": 8000
  },
  "version": 1
}