7.2kā
by cgnl
supermarkt-prijzen ā OpenClaw Skill
supermarkt-prijzen is an OpenClaw Skills integration for coding workflows. Albert Heijn bonuses, product search, multi-store price comparison (12 supermarkets), recipe search by ingredients, and fridge scanner with vision AI.
Skill Snapshot
| 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. OpenClaw Skills integration. |
| owner | cgnl |
| repository | cgnl/supermarkt-prijzen |
| language | Markdown |
| license | MIT |
| topics | |
| security | L1 |
| install | openclaw add @cgnl/supermarkt-prijzen |
| last updated | Feb 7, 2026 |
Maintainer

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"]}}}
Albert Heijn API Skill
Complete AH bonussen + producten + recepten via GraphQL (web) en OAuth (mobile).
Features
ā
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)
Quick Start
1. Bonussen + Producten (GEEN LOGIN NODIG!)
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.
2. OAuth Token Flow (mobile API)
Get initial token:
- Open Appie app
- Tap profiel ā instellingen ā scroll down ā "Developer" (hidden option)
- Tap "OAuth Code" ā copy code
- Run binnen 30 seconden:
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
3. Multi-store price comparison
Search across 12 supermarkets:
./checkjebon-search.py --compare "melk" --top 10
Stores: AH, Jumbo, Lidl, Plus, Dekamarkt, Spar, Dirk, Hoogvliet, Poiesz, Aldi, Vomar, Ekoplaza
Tools
| 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 |
Technical Details
Authentication (NONE NEEDED!)
Previous: Required session cookies from browser
Now: Uses curl-cffi with impersonate='chrome120'
How it works:
- curl-cffi sends real Chrome TLS fingerprints
- AH's bot detection sees it as a normal browser
- No cookies, no login, no setup required! š
Only needed for:
- OAuth mobile API (receipts, personal data) - requires app login
GraphQL Bonuses API
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 aanbiedingen
REST Product Search
Endpoint: 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" }
}
]
}
]
}
OAuth Mobile API
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 search
Note: Some mobile endpoints currently return 500 errors (infrastructure issues).
Why curl-cffi?
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!
Checkjebon Multi-Store Data
Source: https://raw.githubusercontent.com/supermarkt/checkjebon/main/data/supermarkets.json
Stats:
- File size: 10.3MB
- Total products: 106,991
- Daily updates
- 24h local cache
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
Recipe Features (NEW!) š³
Scan Fridge ā Find Recipes ā Shopping List
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
Recipe ID Resolution
How to get recipe IDs:
- From search results: The
searchaction returns titles only. To get full details, you need the recipe ID. - From URL: Recipe URLs contain the ID in format
R-R{ID}:- Example:
https://www.ah.nl/allerhande/recept/R-R1187649/zoete-tortillachips - Extract:
R-R1187649ā ID =1187649
- Example:
- Direct lookup: Use the
urlaction to automatically extract ID and fetch details
Workflow:
# 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
Recipe Search Examples
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
Examples
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
Troubleshooting
"Access Denied" errors:
- Use curl-cffi (not standard requests)
- Check User-Agent header
- Refresh cookies (run
./setup-cookies.sh)
OAuth code expired:
- Codes valid for only 30 seconds!
- Use curl command immediately after generating code
- Or use refresh_token to extend session
GraphQL errors:
- Check date format (YYYY-MM-DD)
- Verify filterSet value (case-sensitive)
- Ensure cookies are fresh
Files
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)
Credits
- AlbertPWN (userlandkernel) - Original mobile API research
- TommasoAmici/ah-bonus-bot - Rust bot with product search endpoint
- jabbink - Comprehensive API documentation gist
- curl-cffi - Chrome fingerprinting library
Status
ā
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)
Changelog
2026-02-02 - MAJOR UPDATE:
- š Removed cookie requirement! All APIs now work WITHOUT login
- ā Bonussen: 200+ items, anonymous access
- ā Product search: 20k+ items, anonymous access
- ā Recipes: Full search, anonymous access
- š§ Uses
curl-cffiwithimpersonate='chrome120'to bypass bot detection - šļø Deprecated:
setup-cookies.sh(no longer needed) - ā ļø OAuth still available for mobile API (receipts, personal data)
2026-02-01:
- Added recipe search by ingredients
- Added fridge scanner workflow
- Multi-store comparison (Checkjebon.nl)
Last updated: 2026-02-02
Albert Heijn Bonuses Skill š
Fetch your Albert Heijn bonuses programmatically! Bypasses bot detection using curl-cffi.
Quick Start
1. Install Dependencies
pip3 install curl-cffi --break-system-packages
2. Setup Cookies
./setup-cookies.sh
Follow the prompts to paste your browser cookies.
3. Fetch Bonuses!
# Get all bonuses
./get-bonuses.py --filter WEB_BONUS_PAGE --pretty
# Get personal bonuses only
./get-bonuses.py --filter APP_PERSONAL
# Save to file
./get-bonuses.py --filter WEB_BONUS_PAGE -o bonuses.json
Example Output
{
"filter": "WEB_BONUS_PAGE",
"count": 326,
"fetched_at": "2026-02-01T20:57:00",
"period": {
"start": "2026-02-01",
"end": "2026-02-08"
},
"bonuses": [
{
"id": "...",
"title": "Innocent: gratis bezorging bij 12.50 euro",
"subtitle": null,
"promotionType": "INCENTIVE",
"periodDescription": "vanaf maandag",
"activationStatus": "NONE",
"price": {
"now": { "amount": 12.50 },
"was": { "amount": 15.00 }
},
"product": {
"title": "Innocent Smoothie",
"category": "Dranken"
}
}
]
}
Usage from OpenClaw
# In your agent, just run:
exec ~/clawd/skills/ah-bonuses/get-bonuses.py --filter WEB_BONUS_PAGE
Then parse the JSON output!
Filters
WEB_BONUS_PAGE- All bonuses (most results)APP_PERSONAL- Your personal offersAPP_BONUS_BOX- Bonus box offersWEB_BONUS_BOX- Web bonus boxCOUPON- CouponsFREE_DELIVERY- Free deliverySPOTLIGHT- Spotlight offers
Cookie Refresh
Cookies expire after ~1 hour. When you get errors:
./setup-cookies.sh
How It Works
- Uses curl-cffi with Chrome TLS fingerprinting to bypass bot detection
- Queries Albert Heijn GraphQL API (
https://www.ah.nl/gql) - Returns structured JSON with all bonus details
Technical Details
See SKILL.md for full documentation.
Troubleshooting
"Access Denied":
ā Cookies expired. Run ./setup-cookies.sh again.
Empty results:
ā Try different filter. WEB_BONUS_PAGE has the most bonuses.
Import error:
ā Install curl-cffi: pip3 install curl-cffi --break-system-packages
Credits
Built by Miel Monteur š ļø (Feb 2026)
Permissions & Security
Security level L1: Low-risk skills with minimal permissions. Review inputs and outputs before running in production.
Requirements
- OpenClaw CLI installed and configured.
- Language: Markdown
- License: MIT
- Topics:
FAQ
How do I install supermarkt-prijzen?
Run openclaw add @cgnl/supermarkt-prijzen in your terminal. This installs supermarkt-prijzen into your OpenClaw Skills catalog.
Does this skill run locally or in the cloud?
OpenClaw Skills execute locally by default. Review the SKILL.md and permissions before running any skill.
Where can I verify the source code?
The source repository is available at https://github.com/openclaw/skills/tree/main/skills/cgnl/supermarkt-prijzen. Review commits and README documentation before installing.
