grocery.freeze2k.net

API reference ← back to search

All endpoints are GET against /aldi.php with an ?action=… query param. Responses are JSON and include Access-Control-Allow-Origin: *.

Base URL: https://grocery.freeze2k.net/aldi.php

categories

GET/aldi.php?action=categories
Static list of category slugs that action=browse accepts.
try it →
{
  "success": true,
  "action": "categories",
  "count": 25,
  "data": ["fresh-produce", "dairy-and-eggs", "meat-seafood", …]
}

stores

GET/aldi.php?action=stores&zip=NNNNN[&limit=N]
Find ALDI stores near a US ZIP, distance-sorted (haversine). Backed by Uberall's public storefinder + zippopotam.us for ZIP geocoding.
ParamRequiredDefaultNotes
zipyes5-digit US ZIP
limitno101–50
try it: 75001 →
{
  "success": true,
  "action": "stores",
  "count": 5,
  "data": [
    {
      "id": 5766226,
      "name": "ALDI",
      "street": "3632 Frankford Rd Ste 200C",
      "city": "Dallas", "state": "Texas", "zip": "75287",
      "lat": 32.99597, "lng": -96.85424,
      "phone": "+1 855-955-2534",
      "openNow": false,
      "hours": [{ "dayOfWeek": 1, "from1": "09:00", "to1": "20:00" }, …],
      "distanceMi": 2.65
    }
  ],
  "meta": { "zip": "75001", "totalKnown": 2690 }
}

browse

GET/aldi.php?action=browse&zip=NNNNN&category=SLUG[&limit=N]
All products and prices for one category at one store (determined by ZIP). Source is the ALDI/Instacart whitelabel SSR HTML, parsed server-side.
ParamRequiredDefaultNotes
zipyes5-digit US ZIP
categoryyesslug from action=categories
limitno501–200
nocachenoset 1 to force upstream refetch
cache_ttlno86400seconds
max_triesno4upstream retry budget on empty SSR
try it: dairy-and-eggs →
{
  "success": true,
  "action": "browse",
  "count": 5,
  "data": [
    {
      "itemId": "16902710",
      "name": "Friendly Farms Whole Milk",
      "price": 4.05,
      "priceFormatted": "$4.05",
      "imageUrl": "https://www.instacart.com/image-server/…/large_….jpg",
      "productUrl": "https://www.aldi.us/store/aldi/products/16902710-…",
      "stockStatus": "Many in stock"
    },
    {
      "itemId": "22014511",
      "name": "Friendly Farms Greek Yogurt, Vanilla",
      "price": 0.85,
      "priceFormatted": "$0.85",
      "originalPrice": 1.19,
      "originalPriceFormatted": "$1.19",
      "onSale": true,
      "savings": 0.34,
      …
    }
  ],
  "meta": {
    "zip": "75001", "category": "dairy-and-eggs",
    "totalFound": 25, "cached": true, "stale": false,
    "tries": 0, "bodySize": 1450607
  }
}
GET/aldi.php?action=search&zip=NNNNN&q=TERM[&limit=N]
Search across a fixed set of high-coverage categories (fresh-produce, dairy-and-eggs, meat-seafood, frozen-foods, bakery-bread, beverages, breakfast-cereals, household-essentials, prepared-foods, deli) and return matching products. Scoring: exact substring (100), all tokens (70), any token (30); deduped by item id.
ParamRequiredDefaultNotes
zipyes5-digit US ZIP
qyesfree-text query
limitno201–100
try it: milk →
{
  "success": true,
  "action": "search",
  "count": 5,
  "data": [
    {
      "itemId": "16902710",
      "name": "Friendly Farms Whole Milk",
      "price": 4.05, "priceFormatted": "$4.05",
      "imageUrl": "…", "productUrl": "…",
      "matchScore": 100,
      "matchedInCategory": "dairy-and-eggs"
    }
  ],
  "meta": {
    "zip": "75001", "query": "milk",
    "source": "fallback_categories",
    "categoriesScanned": ["fresh-produce", "dairy-and-eggs", …],
    "cacheHits": 9
  }
}

Response schema

Every response is one of:

{ "success": true,  "action": "…", "count": N, "data": […], "meta": { … } }
{ "success": false, "error":  "code", "message": "human-readable explanation" }

HTTP status codes mirror common REST conventions: 200 on success, 400 on bad input, 404 for unknown category, 502 when an upstream provider (Uberall, ALDI, zippopotam.us) fails or returns nothing parseable.

Caching & freshness

ALDI/Instacart serves their category SSR non-deterministically — the same URL sometimes returns the full page with products, sometimes an empty shell. To work around this:

Examples

Command line

curl -s 'https://grocery.freeze2k.net/aldi.php?action=search&zip=75001&q=eggs&limit=5' | jq

JavaScript (browser)

const r = await fetch('https://grocery.freeze2k.net/aldi.php?' +
  new URLSearchParams({ action: 'search', zip: '75001', q: 'milk' }));
const { data } = await r.json();
for (const p of data) console.log(p.priceFormatted, p.name);

Python

import requests
r = requests.get('https://grocery.freeze2k.net/aldi.php',
                 params={'action': 'search', 'zip': '75001', 'q': 'pizza'})
for p in r.json()['data']:
    print(p['priceFormatted'], p['name'])