Discover/Lidl API
live

Lidl APIlidl.com

Search Lidl US grocery products, browse category trees, and retrieve current prices, promotions, and stock status by store location via 3 REST endpoints.

This API takes change requests — .
Endpoints
3
Updated
2d ago

What is the Lidl API?

The Lidl US API covers 3 endpoints for searching and browsing grocery products across Lidl store locations. The search_products endpoint accepts a keyword and optional store ID to return paginated product results including current price, stock status, promotion details, aisle categories, and a base price text field. Two additional endpoints expose the full category tree and per-category product listings, making it straightforward to build store-aware grocery tools.

This call costs1 credit / call— charged only on success
Try it
Maximum number of results to return per page.
Search term for products (e.g. 'milk', 'bread', 'chicken').
Number of results to skip for pagination.
Lidl store ID in format US followed by digits (e.g. 'US01053' for Culpeper VA). Determines product availability and pricing.
api.parse.bot/scraper/8abf1be8-d321-484a-bcef-d3cf82535ebd/<endpoint>
Ready to send
Fill in the parameters and hit sign in to send to see live response data here.
Call it over HTTPgrab a free API key at signup
curl -X GET 'https://api.parse.bot/scraper/8abf1be8-d321-484a-bcef-d3cf82535ebd/search_products' \
  -H 'X-API-Key: $PARSE_API_KEY'
Python SDK · recommended

Typed, relational, agent-ready

A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.

  • Fully typed · autocompletes
  • Objects link to objects
  • Typed errors & pagination

Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:

uv add parse-sdk
uv run parse init
uv run parse add --marketplace lidl-com-api

uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.

"""
Lidl US Grocery API Client

Search and browse grocery products, prices, and categories at Lidl US stores.
Get your API key from: https://parse.bot/settings
"""

import os
import requests
from typing import Optional, Any, Dict, List
from dataclasses import dataclass


@dataclass
class Product:
    """Represents a grocery product from Lidl."""
    id: str
    name: str
    description: str
    price: float
    currency: str
    base_price_text: str
    stock_status: str
    image_url: str
    aisle: int
    section: str
    promotion: Optional[str] = None


class ParseClient:
    """Client for interacting with the Lidl US Grocery API."""

    def __init__(self, api_key: Optional[str] = None):
        """
        Initialize the Parse API client.

        Args:
            api_key: API key for authentication. If not provided, reads from PARSE_API_KEY env var.
        """
        self.base_url = "https://api.parse.bot"
        self.scraper_id = "8abf1be8-d321-484a-bcef-d3cf82535ebd"
        self.api_key = api_key or os.getenv("PARSE_API_KEY")

        if not self.api_key:
            raise ValueError("API key must be provided or set in PARSE_API_KEY environment variable")

    def _call(self, endpoint: str, method: str = "POST", **params) -> Dict[str, Any]:
        """
        Make a request to the Parse API.

        Args:
            endpoint: The API endpoint name (e.g., 'search_products')
            method: HTTP method ('GET' or 'POST')
            **params: Query or body parameters

        Returns:
            Response JSON as a dictionary

        Raises:
            requests.RequestException: If the API request fails
        """
        url = f"{self.base_url}/scraper/{self.scraper_id}/{endpoint}"
        headers = {
            "X-API-Key": self.api_key,
            "Content-Type": "application/json"
        }

        if method == "GET":
            response = requests.get(url, headers=headers, params=params)
        elif method == "POST":
            response = requests.post(url, headers=headers, json=params)
        else:
            raise ValueError(f"Unsupported HTTP method: {method}")

        response.raise_for_status()
        return response.json()

    def search_products(
        self,
        query: str,
        store_id: str = "US01053",
        limit: int = 20,
        offset: int = 0
    ) -> Dict[str, Any]:
        """
        Search for grocery products by keyword at a specific Lidl store.

        Args:
            query: Search term for products (e.g., 'milk', 'bread', 'chicken')
            store_id: Lidl store ID (default: US01053 for Culpeper VA)
            limit: Maximum number of results to return per page
            offset: Number of results to skip for pagination

        Returns:
            Dictionary with 'total_results' and 'results' array of products
        """
        return self._call(
            "search_products",
            method="GET",
            query=query,
            store_id=store_id,
            limit=limit,
            offset=offset
        )

    def get_categories(self, store_id: str = "US01053") -> Dict[str, Any]:
        """
        List all product categories available at a specific Lidl store.

        Args:
            store_id: Lidl store ID (default: US01053 for Culpeper VA)

        Returns:
            Dictionary with 'categories' array containing category objects
        """
        return self._call("get_categories", method="GET", store_id=store_id)

    def get_category_products(
        self,
        category_code: str,
        store_id: str = "US01053",
        limit: int = 20,
        offset: int = 0
    ) -> Dict[str, Any]:
        """
        Get all products in a specific category at a Lidl store.

        Args:
            category_code: Category code from get_categories (e.g., 'OCI2000110')
            store_id: Lidl store ID (default: US01053 for Culpeper VA)
            limit: Maximum number of results to return per page
            offset: Number of results to skip for pagination

        Returns:
            Dictionary with 'total_results' and 'results' array of products
        """
        return self._call(
            "get_category_products",
            method="GET",
            category_code=category_code,
            store_id=store_id,
            limit=limit,
            offset=offset
        )


def display_product(product_data: Dict[str, Any]) -> None:
    """Display product information in a readable format."""
    product = Product(
        id=product_data["id"],
        name=product_data["name"],
        description=product_data["description"],
        price=product_data["price"],
        currency=product_data["currency"],
        base_price_text=product_data["base_price_text"],
        stock_status=product_data["stock_status"],
        image_url=product_data["image_url"],
        aisle=product_data["aisle"],
        section=product_data["section"],
        promotion=product_data.get("promotion")
    )

    status_icon = "✓" if product.stock_status == "INSTOCK" else "✗"
    print(f"  [{status_icon}] {product.name}")
    print(f"      Description: {product.description}")
    print(f"      Price: ${product.price:.2f} ({product.base_price_text})")
    print(f"      Location: Aisle {product.aisle}, {product.section}")
    if product.promotion:
        print(f"      Promotion: {product.promotion}")
    print()


if __name__ == "__main__":
    # Initialize the client
    client = ParseClient()

    print("=" * 60)
    print("Lidl US Grocery API - Practical Usage Example")
    print("=" * 60)
    print()

    # Step 1: Get available categories at the store
    print("Step 1: Fetching product categories...")
    categories_response = client.get_categories(store_id="US01053")
    categories = categories_response["categories"]

    # Find the dairy category
    dairy_category = next((c for c in categories if c["name"] == "dairy"), None)
    if dairy_category:
        print(f"Found category: {dairy_category['name']} ({dairy_category['code']})")
        print(f"  Total products in category: {dairy_category['product_count']}")
    print()

    # Step 2: Search for a specific product
    print("Step 2: Searching for 'milk' products...")
    search_response = client.search_products(
        query="milk",
        store_id="US01053",
        limit=5
    )
    print(f"Found {search_response['total_results']} results for 'milk'")
    print("Top 5 results:")
    print()

    # Display search results
    for i, product in enumerate(search_response["results"], 1):
        print(f"Result {i}:")
        display_product(product)

    # Step 3: Browse products by category (milk & creamers)
    print("Step 3: Browsing 'Milk & Creamers' category...")
    milk_category = next((c for c in categories if c.get("name") == "milk & creamers"), None)

    if milk_category:
        category_response = client.get_category_products(
            category_code=milk_category["code"],
            store_id="US01053",
            limit=3
        )
        print(f"Category: {milk_category['name']}")
        print(f"Total products: {category_response['total_results']}")
        print("First 3 products:")
        print()

        for i, product in enumerate(category_response["results"], 1):
            print(f"Product {i}:")
            display_product(product)

        # Step 4: Find best deals (in-stock items)
        print("Step 4: Analyzing in-stock items by price...")
        in_stock_products = [
            p for p in category_response["results"]
            if p["stock_status"] == "INSTOCK"
        ]

        if in_stock_products:
            # Sort by price
            sorted_products = sorted(in_stock_products, key=lambda x: x["price"])

            print(f"In-stock items (sorted by price):")
            print()
            for i, product in enumerate(sorted_products, 1):
                print(f"  {i}. {product['name']} - ${product['price']:.2f}")
                print(f"     ({product['base_price_text']})")
            print()

            # Calculate average price
            avg_price = sum(p["price"] for p in sorted_products) / len(sorted_products)
            cheapest = sorted_products[0]
            print(f"Average price: ${avg_price:.2f}")
            print(f"Cheapest option: {cheapest['name']} at ${cheapest['price']:.2f}")

    print()
    print("=" * 60)
    print("Example completed successfully!")
    print("=" * 60)
All endpoints · 3 totalmissing one? ·

Search for grocery products by keyword at a specific Lidl store. Returns paginated results with prices, stock status, promotions, and aisle/section information.

Input
ParamTypeDescription
limitintegerMaximum number of results to return per page.
queryrequiredstringSearch term for products (e.g. 'milk', 'bread', 'chicken').
offsetintegerNumber of results to skip for pagination.
store_idstringLidl store ID in format US followed by digits (e.g. 'US01053' for Culpeper VA). Determines product availability and pricing.
Response
{
  "type": "object",
  "fields": {
    "results": "array of product objects with id, name, description, price, currency, base_price_text, stock_status, image_url, categories, promotion, aisle, section",
    "total_results": "integer"
  },
  "sample": {
    "results": [
      {
        "id": "1067979",
        "name": "2% reduced fat milk",
        "aisle": 1,
        "price": 1.88,
        "section": "Chiller",
        "currency": "USD",
        "image_url": "https://production-endpoint.azureedge.net/images/A14KQNQ9DLGMEPA3DTMMIRJ7ADNMURHEE1N6ENPL60O7GD9G60/0a61e8c4-9324-49de-b5ae-cb9da5abc285/PIM_ImageComingSoon.png_500x500.jpg",
        "promotion": null,
        "categories": [
          "OCI1000079",
          "OCI2000110"
        ],
        "description": "half gallon",
        "stock_status": "INSTOCK",
        "base_price_text": "2.94 ¢ per fl.oz."
      }
    ],
    "total_results": 288
  }
}

About the Lidl API

What the API Returns

All three endpoints return product objects sharing a consistent shape: id, name, description, price, currency, base_price_text, stock_status, image_url, categories, and promotion fields. The search_products endpoint accepts a query string (e.g. 'milk', 'chicken') alongside an optional store_id in the format US followed by digits (e.g. US01053 for the Culpeper, VA location). Pagination is controlled with limit and offset parameters, and the response includes a total_results integer so you can implement accurate page counts.

Browsing by Category

The get_categories endpoint returns a hierarchical category tree scoped to a given store, with each category object exposing a code, name, parents array, and product_count. Those code values (e.g. OCI2000110 for milk & creamers, OCI1000079 for dairy) feed directly into get_category_products, which returns the same paginated product listing format as search_products but filtered to a specific department or sub-department.

Store-Level Scoping

The store_id parameter appears on all three endpoints and is what makes results location-specific. Lidl's US inventory, promotions, and stock status can vary by store, so passing a store_id ensures the price and availability data matches what a shopper would actually see at that location. Omitting it returns a default catalog view. The base_price_text field in product responses often conveys unit pricing (e.g. per lb or per oz), which is useful for unit-price comparison logic.

Reliability & maintenance

The Lidl API is a managed, monitored endpoint for lidl.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when lidl.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.

This isn't an official lidl.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.

Will this API break when the source site changes?+
It's built not to. Every endpoint is health-checked on a schedule with automated test probes. When the source site changes and a check fails, the API is automatically queued for repair and re-verified — that's the self-healing layer. Each API page shows when its endpoints were last verified. And because marketplace APIs are shared, any fix reaches everyone using it.
Is this an official API from the source site?+
No — Parse APIs are independent, managed REST wrappers over publicly available data. That is the point: where a site has no official API (or only a limited one), Parse gives you a maintained, monitored endpoint for that data and keeps it working as the site changes — so you get a stable contract over a source that never promised one.
Can I fix or extend this API myself if I need a new endpoint or field?+
Yes — and you don't have to wait on us. This API was generated by the Parse agent, which stays attached. Describe the change in plain English ("add an endpoint that returns reviews", "fix the price field") in the revise box on the API page or via the revise_api MCP tool, and the agent rebuilds it against the live site in minutes. Contributing the change back to the public API is free.
What happens if I call an endpoint that has an issue?+
Errors are machine-readable: a bad call returns a clean status with the list of available endpoints and a repair hint, so an agent (or you) can recover or trigger a fix instead of failing silently. Confirmed failures feed the automatic repair queue.
Common use cases
  • Build a grocery price tracker that monitors Lidl product prices and promotion changes by store over time.
  • Populate a meal planning app with current in-stock Lidl products filtered by category using get_category_products.
  • Compare Lidl shelf prices against other retailers using the price and base_price_text fields from search_products.
  • Create a store-specific shopping list tool that validates stock_status before surfacing items to users.
  • Index Lidl's full product catalog by walking the category tree from get_categories and paginating through each category.
  • Alert shoppers when a searched product has an active promotion by monitoring the promotions field in search_products results.
  • Build a dietary filter layer on top of category browsing by combining category codes with product name and description fields.
Pricing & limitsSee full pricing →
TierPriceCredits/monthRate limit
Free$0/mo1005 req/min
Hobby$30/mo1,00020 req/min
Developer$100/mo5,000100 req/min

One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.

Frequently asked questions
Does Lidl have an official developer API?+
Lidl does not publish a public developer API for its US store data. There is no documented REST or GraphQL API available to external developers at this time.
What does the stock_status field in product results actually distinguish?+
The stock_status field indicates whether a product is currently available at the specified store. Because Lidl runs rotating weekly promotions and limited-quantity specials, stock_status values can differ significantly between store IDs and across time. Always pass a store_id to get a location-accurate status rather than relying on a default catalog response.
Does the API return nutritional information or ingredient lists for products?+
Not currently. Product objects include name, description, price, stock_status, image_url, categories, and promotion fields, but nutritional facts and ingredient data are not part of the response. You can fork this API on Parse and revise it to add an endpoint that retrieves per-product detail pages where that information may be available.
Can I look up a store ID for a specific city or ZIP code?+
The three current endpoints do not include a store locator — they accept a store_id you already know (e.g. US01053 for Culpeper, VA) but do not resolve addresses or ZIP codes to store IDs. You can fork this API on Parse and revise it to add a store-search endpoint that returns store IDs from a location query.
How does pagination work across search_products and get_category_products?+
Both endpoints accept integer limit and offset parameters and return a total_results integer alongside the results array. To page through all results, increment offset by limit on each subsequent call until offset exceeds total_results. There is no cursor-based pagination; offset arithmetic is the only supported pattern.
Page content last updated . Spec covers 3 endpoints from lidl.com.
Related APIs in Food DiningSee all →
resy.com API
Search for restaurants across cities and check real-time availability to find open reservation slots on Resy. Discover trending and top-rated venues with detailed information about dining options, menus, and available time slots across selected dates.
opentable.com API
Search for restaurants across the US with ratings, reviews, photos, and pricing information, plus get real-time availability and autocomplete suggestions as you type. Check reservation openings and explore detailed restaurant features to find and book your perfect dining experience.
fdc.nal.usda.gov API
Search across thousands of foods to get detailed nutritional information, serving sizes, and ingredient data from USDA's comprehensive food database. Find nutrition facts for branded products, legacy foods, and foundation foods all in one place.
guide.michelin.com API
Access data from guide.michelin.com.
flipp.com API
Search for grocery deals and weekly advertisements across multiple retailers by keyword, store location, or zip code to find the best prices on items you need. Browse flyer items and current promotions to plan your shopping and save money on groceries.
waitrose.com API
Search Waitrose & Partners' online grocery catalog to find products with detailed information including pricing, current promotions, and availability. Get autocomplete suggestions for faster browsing and access complete product details to compare items and find the best deals.
carrefour.es API
Access data from carrefour.es.
opentable.ca API
Search and discover restaurants on OpenTable, view detailed information like menus and reviews, and check real-time dining availability across metro areas. Find top-rated restaurants in your location and instantly see which tables are open for your preferred date and time.