Show HN: CLI to order groceries via reverse-engineered REWE API (Haskell)
Comments
The korb CLI allows using the REWE APIs programmatically to create baskets and order them for pickup to your local REWE market.
The CLI is handwritten in Haskell, but designed to be a CLI mostly used by agents to organise your REWE shopping on your behalf. All output is JSON.
korb_demo.mp4
// My e2e flow
My current E2E flow (I use claude to run korb) is as follows:
-
Add grocery when I think of it A Siri shortcut appends items to a shared markdown file. I say "Add oat milk to the shopping list" in the kitchen and it's on the list.
-
Weekly Order Tell the agent "use korb to buy groceries, I need X,Y,Z". It begins from a default template (my usual items and quantities, created with korb orders history) and checks the shopping list file and my input for anything extra.
-
Adjust template suggestion I tell the agent what to skip, change, or add. It searches products via korb search / korb favorites search and adds them with korb basket add.
-
Review & confirm The agent prints the full basket and a selected timeslot. After I confirm, it runs korb checkout order.
-
Clean shopping list Ordered items get ticked off in the shopping list.
In the directory that store the shopping list file I also have a claude.md explaining this process. The magic is the generated template of what I always order. Just tell an agent to use korb orders history to identify commonly ordered items.
// Installation
Binary (recommended)
Download the latest release from GitHub Releases:
# macOS (Apple Silicon) curl -L https://github.com/yannick-cw/korb/releases/latest/download/korb-aarch64-macos -o korb# macOS (Apple Silicon) curl -L https://github.com/yannick-cw/korb/releases/latest/download/korb-aarch64-macos -o korbmacOS (Intel)
curl -L https://github.com/yannick-cw/korb/releases/latest/download/korb-x86_64-macos -o korb
Linux (x86_64)
curl -L https://github.com/yannick-cw/korb/releases/latest/download/korb-x86_64-linux -o korb`
Then:
chmod +x korb mv korb /usr/local/bin/ # or sudo mv on Linuxchmod +x korb mv korb /usr/local/bin/ # or sudo mv on LinuxFrom source
Requires GHC 9.12+ and Cabal. You also need the REWE mTLS client certificates.
git clone https://github.com/yannick-cw/korb.git cd korbgit clone https://github.com/yannick-cw/korb.git cd korbExtract mTLS certificates from the REWE app
See: https://github.com/ByteSizedMarius/rewerse-engineering/tree/main/docs
Place them at:
certs/mobile-clients-api.rewe.de/private.pem
certs/mobile-clients-api.rewe.de/private.key
cabal install --install-method=copy`
// Getting started
# 1. Authenticate with your REWE account (one-time, use Chrome to get the link, firefox does not work for this) korb login --pretty# 1. Authenticate with your REWE account (one-time, use Chrome to get the link, firefox does not work for this) korb login --pretty2. Find and set your pickup store - stored locally, needs to be done just once
korb store search 80336 # returns market identifier for zip code korb store set 420240 80336
3. Search for products by name or EAN barcode
korb search "milch" --pretty korb search "milch" --organic --pretty korb search "4305615100005" --pretty # search by EAN barcode
Or browse your favorites
korb favorites korb favorites search "avo"
4. Add items to basket
korb basket add 8-6AJQ3RLX-bd7c2a1e-f1c1-3464-8250-900b12c90f70
5. Check your basket
korb basket --pretty
6. Pick a timeslot and checkout
korb timeslots # lists available timeslots for pickup korb checkout create # create checkout - not ordered yet korb checkout order # order it with selected timeslot and payment in market
7. Cancel an order if needed
korb orders korb orders delete `
// Usage
Usage: korb COMMAND [-p|--pretty] [-v|--version] REWE Pickup CLIUsage: korb COMMAND [-p|--pretty] [-v|--version] REWE Pickup CLIAvailable options: -p,--pretty Pretty JSON output -h,--help Show this help text -v,--version Show version
Commands:
korb store Show currently selected store korb store search Find pickup stores near ZIP code korb store set Set active store by market ID and ZIP
korb search Search products by name or EAN barcode (use * to browse all) korb search --organic Filter by attribute (--organic, --regional, --vegan, --vegetarian)*
korb favorites Show all favorite products across all lists korb favorites search Filter favorites by name (case-insensitive, substring match) korb favorites add Add product to default favorites list (listing ID + product ID) korb favorites delete Remove item from default favorites list (item ID from favorites)
korb basket Show current basket with items, totals, and free pickup status korb basket add Set item quantity by listing ID. Overwrites existing quantity. --qty N sets absolute quantity. Default 1. Use --qty 0 to remove.
korb timeslots List available pickup timeslots
korb checkout Show the checkout for current basket. Payment is always in market. korb checkout create Create a checkout for a given timeslot id korb checkout order Place the order. Timeslot must be attached first.
korb orders Show open orders. korb orders history Show all orders. korb orders get Get an order (with details) by id. korb orders delete Cancel an order by order ID - will give 200 on successive calls.
korb suggestion threshold Suggest N items to add to reach free pickup threshold. Ranks by purchase frequency, excludes items already in basket.
korb ebons List digital receipts (eBons). korb ebons download Download eBon PDF. --output FILE (default: ebon.pdf)
korb login Authenticate via REWE PKCE browser flow.
All commands support --pretty for formatted JSON output. Output is JSON for agent consumption.`
// API documentation
Reverse-engineered OpenAPI specs for the REWE mobile API:
-
REWE Product & Checkout API
-
REWE Account / Keycloak API
// Platform support
Currently macOS and linux.
// Formal verification with Lean 4
The suggestion engine (korb suggestion threshold) is re-implemented in Lean 4 with five mathematically proven properties: suggestions have positive frequency, are sorted descending, come from ordered and available products, exclude basket items, and respect the count limit. A Differential Random Testing bridge in the Haskell test suite generates random inputs, runs both implementations, and asserts identical output. If the Lean proofs compile and the DRT passes, the Haskell production code behaves like the proven spec. Inspired by how AWS Cedar verifies their authorization engine.
I also summarised the approach in a Blog post.
Oh and yes, this is complete overkill here and just for fun.
// Prior work & attribution
// Disclaimer
This project is unofficial and not affiliated with REWE. It uses reverse-engineered APIs that may change without notice. Use at your own risk.
Sign in to highlight and annotate this article

Conversation starters
Daily AI Digest
Get the top 5 AI stories delivered to your inbox every morning.
Knowledge Map
Connected Articles — Knowledge Graph
This article is connected to other articles through shared AI topics and tags.
More in Releases
[Side A] Completely Defending Python from OOM Kills: The BytesIO Trap and D-MemFS 'Hard Quota' Design Philosophy
<blockquote> <p><strong>From the Author:</strong><br> Recently, I introduced <strong>D-MemFS</strong> on Reddit. The response was overwhelming, confirming that memory management and file I/O performance are truly universal challenges for developers everywhere. This series is my response to that global interest.</p> </blockquote> <h3> 🧭 About this Series: The Two Sides of Development </h3> <p>To provide a complete picture of this project, I’ve split each update into two perspectives:</p> <ul> <li> <strong>Side A (Practical / from Qiita):</strong> Implementation details, benchmarks, and technical solutions.</li> <li> <strong>Side B (Philosophy / from Zenn):</strong> The development war stories, AI-collaboration, and design decisions.</li> </ul> <h2> Introduction </h2> <p>If you write in-mem
[Side B] Pursuing OSS Quality Assurance with AI: Achieving 369 Tests, 97% Coverage, and GIL-Free Compatibility
<blockquote> <p><strong>From the Author:</strong><br> Recently, I introduced <strong>D-MemFS</strong> on Reddit. The response was overwhelming, confirming that memory management and file I/O performance are truly universal challenges for developers everywhere. This series is my response to that global interest.</p> </blockquote> <h3> 🧭 About this Series: The Two Sides of Development </h3> <p>To provide a complete picture of this project, I’ve split each update into two perspectives:</p> <ul> <li> <strong>Side A (Practical / from Qiita):</strong> Implementation details, benchmarks, and technical solutions.</li> <li> <strong>Side B (Philosophy / from Zenn):</strong> The development war stories, AI-collaboration, and design decisions.</li> </ul> <h2> Testing is a "Contract between the Design

Why Your AI Agent Health Check Is Lying to You
<p>Your monitoring dashboard shows green across the board. Process running. Port responding. CPU normal. Memory stable.</p> <p>But your AI agent hasn't done anything useful in four hours.</p> <h2> The problem with traditional health checks </h2> <p>Traditional health checks answer one question: "Is the process alive?" For web servers, that's usually enough. If Nginx is running and responding on port 80, it's probably serving pages.</p> <p>AI agents are different. An agent can be alive without being productive. The process is running, but the main work loop is stuck on a hung HTTP call, waiting on a deadlocked mutex, or spinning in a retry loop that will never succeed.</p> <h2> Three ways health checks lie </h2> <h3> 1. PID exists ≠ working </h3> <p><code>systemctl status my-agent</code> sa
Google offers researchers early access to Willow quantum processor
The Early Access Program invites researchers to design and propose quantum experiments that push the boundaries of what current hardware can achieve. It is a selective program – the processor will not be publicly available – and Google is setting firm deadlines for participation. Research teams have until May 15,... Read Entire Article
Discussion
Sign in to join the discussion
No comments yet — be the first to share your thoughts!