with one click
supermarkt-prijzen
// Albert Heijn bonuses, product search, multi-store price comparison (12 supermarkets), recipe search by ingredients, and fridge scanner with vision AI.
// Albert Heijn bonuses, product search, multi-store price comparison (12 supermarkets), recipe search by ingredients, and fridge scanner with vision AI.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | supermarkt-prijzen |
| description | Albert Heijn bonuses, product search, multi-store price comparison (12 supermarkets), recipe search by ingredients, and fridge scanner with vision AI. |
| homepage | https://www.ah.nl |
| metadata | {"openclaw":{"emoji":"š","requires":{"bins":["python3","curl"]}}} |
Complete AH bonussen + producten + recepten via GraphQL (web) en OAuth (mobile).
ā
Bonussen ophalen (GraphQL, 200+ items, geen login)
ā
Producten zoeken (REST API, 20k+ items, geen login)
ā
Recepten zoeken (GraphQL, geen login)
ā
Multi-supermarkt prijsvergelijking (Checkjebon.nl - 12 supermarkten, 107k producten)
ā
OAuth token flow (mobile API access - alleen voor persoonlijke data)
ā
Fridge scanner (vision AI ā recepten ā shopping list)
Bonussen ophalen (200+ items):
./ah-api.py bonuses --filter WEB_BONUS_PAGE --pretty
Producten zoeken (20.000+ items):
./ah-api.py search --query "melk" --limit 10 --pretty
Recepten zoeken:
./ah-recipes.py search --query "pasta carbonara" --pretty
Recept ophalen via URL:
./ah-recipes.py url --url "https://www.ah.nl/allerhande/recept/R-R1187649/zoete-tortillachips" --pretty
⨠Alles werkt zonder cookies! Gebruikt curl-cffi met Chrome fingerprint.
Get initial token:
curl -X POST 'https://api.ah.nl/mobile-auth/v1/auth/token' \
-H 'Content-Type: application/json' \
-H 'User-Agent: Appie/8.22.3' \
-d '{"clientId":"appie","code":"PASTE_CODE_HERE"}'
Response:
{
"access_token": "USERID_TOKEN",
"refresh_token": "REFRESH_TOKEN",
"expires_in": 604798
}
Save to ~/.ah_tokens.json:
echo '{"access_token":"...","refresh_token":"...","expires_in":604798}' > ~/.ah_tokens.json
Refresh token (na 7 dagen):
./refresh-token.py
Search across 12 supermarkets:
./checkjebon-search.py --compare "melk" --top 10
Stores: AH, Jumbo, Lidl, Plus, Dekamarkt, Spar, Dirk, Hoogvliet, Poiesz, Aldi, Vomar, Ekoplaza
| Tool | Purpose |
|---|---|
ah-api.py | Cookie-based bonussen + producten (GraphQL + REST) |
ah-recipes.py | NEW! Recipe search by text or ingredients |
fridge-scan.sh | NEW! Scan fridge with camera/peekaboo |
smart-cook.sh | NEW! Complete workflow: scan ā recipes ā shopping |
get-bonuses.py | Legacy bonus tool (GraphQL only) |
checkjebon-search.py | Multi-store prijsvergelijking |
refresh-token.py | OAuth token vernieuwen |
setup-cookies.sh | Cookie setup helper |
Previous: Required session cookies from browser
Now: Uses curl-cffi with impersonate='chrome120'
How it works:
Only needed for:
Endpoint: https://www.ah.nl/gql
Query:
query FetchBonusPromotions($periodStart: String, $periodEnd: String) {
bonusPromotions(
filterSet: WEB_BONUS_PAGE
input: {
periodStart: "2026-02-01"
periodEnd: "2026-02-08"
filterUnavailableProducts: false
forcePromotionVisibility: true
}
) {
id title promotionType
price { now { amount } }
product { title category }
}
}
Available filters:
WEB_BONUS_PAGE - Alle bonussen (326 items!)APP_PERSONAL - Persoonlijke aanbiedingenAPP_BONUS_BOX - Bonus boxCOUPON - KortingsbonnenFREE_DELIVERY - Gratis bezorgingSPOTLIGHT - Spotlight aanbiedingenEndpoint: https://www.ah.nl/zoeken/api/products/search
Example:
curl 'https://www.ah.nl/zoeken/api/products/search?query=melk' \
-H 'Cookie: SSOC=...; jsessionid_myah=...' \
--user-agent 'Mozilla/5.0 (compatible; AH-Bot/1.0)'
Response:
{
"cards": [
{
"products": [
{
"id": 441199,
"title": "Campina Halfvolle melk",
"price": { "now": 1.99, "unitSize": "1,5 l" }
}
]
}
]
}
Authorization: https://login.ah.nl/secure/oauth/authorize
Token exchange: https://api.ah.nl/mobile-auth/v1/auth/token
Token refresh: https://api.ah.nl/mobile-auth/v1/auth/token/refresh
Token lifetime: 7 days (604798 seconds)
Known endpoints (from gist):
/mobile-services/v1/receipts - All receipts/mobile-services/v2/receipts/{id} - Specific receipt/mobile-services/product/search/v2 - Product searchNote: Some mobile endpoints currently return 500 errors (infrastructure issues).
AH uses Cloudflare + Akamai bot detection. Normal requests ā 403 Access Denied.
curl-cffi uses real Chrome TLS fingerprints:
from curl_cffi import requests
response = requests.get(url, impersonate="chrome120") # ā Magic!
Source: https://raw.githubusercontent.com/supermarkt/checkjebon/main/data/supermarkets.json
Stats:
Usage:
# Find cheapest
./checkjebon-search.py --compare "bier" --top 5
# Specific store
./checkjebon-search.py --query "campina" --store jumbo
# Show stats
./checkjebon-search.py --stats
1. Scan your fridge:
./fridge-scan.sh
# Opens camera, captures fridge contents
# Output: /tmp/fridge-scan.jpg
2. Extract ingredients (via OpenClaw image tool):
# Ask assistant:
# "Analyze /tmp/fridge-scan.jpg and list all food items as comma-separated"
# ā melk, eieren, tomaten, kaas, broccoli
3. Find recipes:
./ah-recipes.py ingredients --ingredients "melk,eieren,kaas,broccoli" --pretty
4. Get recipe details (by ID):
./ah-recipes.py details --recipe-id 1187649 --pretty
Or get recipe from URL directly:
./ah-recipes.py url --url "https://www.ah.nl/allerhande/recept/R-R1187649/zoete-tortillachips" --pretty
5. Complete workflow:
./smart-cook.sh
# Interactive: scan ā analyze ā find recipes ā shopping list
How to get recipe IDs:
search action returns titles only. To get full details, you need the recipe ID.R-R{ID}:
https://www.ah.nl/allerhande/recept/R-R1187649/zoete-tortillachipsR-R1187649 ā ID = 1187649url action to automatically extract ID and fetch detailsWorkflow:
# Step 1: Search for recipes (returns titles only)
./ah-recipes.py search --query "pasta carbonara" --pretty
# Step 2: If you have the recipe URL (e.g., from browser or website), extract ID
./ah-recipes.py url --url "https://www.ah.nl/allerhande/recept/R-R{ID}/{slug}" --pretty
# Note: Search results don't include recipe IDs (client-side rendered)
# To get full details, you need either:
# - The direct recipe URL (contains R-R{ID})
# - The recipe ID number
Search by text (returns IDs + titles):
./ah-recipes.py search --query "pasta carbonara" --size 10 --pretty
# Output: {"recipes": [{"id": 1200422, "title": "Klassieke spaghetti carbonara"}, ...], "total": 49, "hasMore": true}
Search with detailed info (cook time, ratings, images, servings):
./ah-recipes.py search --query "pasta carbonara" --size 5 --detailed --pretty
# Output: Full recipe summaries with time, ratings, images, servings
Search by ingredients:
./ah-recipes.py ingredients --ingredients "tomaat,ui,knoflook" --size 5 --pretty
Get recipe from URL:
./ah-recipes.py url --url "https://www.ah.nl/allerhande/recept/R-R1187649/zoete-tortillachips" --pretty
# Extracts recipe ID from URL (R-R1187649 ā 1187649) and fetches full details
Cheapest melk across all stores:
./checkjebon-search.py --compare "melk" --top 5
AH bonussen vandaag:
./ah-api.py bonuses --filter WEB_BONUS_PAGE --pretty | \
jq '.bonuses[] | select(.title | contains("Campina"))'
Search AH products:
./ah-api.py search --query "bier" --limit 20 --pretty
"Access Denied" errors:
./setup-cookies.sh)OAuth code expired:
GraphQL errors:
ah-bonuses/
āāā SKILL.md # This file
āāā README.md # Quick start
āāā ah-api.py # Main CLI tool (bonuses + search)
āāā get-bonuses.py # Legacy bonus tool
āāā checkjebon-search.py # Multi-store search
āāā refresh-token.py # OAuth token refresh
āāā setup-cookies.sh # Cookie extractor
āāā ~/.ah_cookies.json # Session cookies (gitignored)
āāā ~/.ah_tokens.json # OAuth tokens (gitignored)
ā
Bonussen API (GraphQL) - 100% working WITHOUT login! (200+ bonussen)
ā
Product search (REST) - 100% working WITHOUT login! (20k+ producten)
ā
Recipe search (GraphQL) - 100% working WITHOUT login!
ā
Multi-store comparison (Checkjebon) - 100% working (107k products, 12 stores)
ā
OAuth token flow - Working (7-day tokens, voor mobile API)
ā ļø Mobile API endpoints - Partial (some 500 errors)
2026-02-02 - MAJOR UPDATE:
curl-cffi with impersonate='chrome120' to bypass bot detectionsetup-cookies.sh (no longer needed)2026-02-01:
Last updated: 2026-02-02