I built a CLI that buys things on Alza for me
Every month I order the same things from Alza. Coffee capsules, laundry detergent, toiletries. Nothing exciting, nothing that requires browsing. Just the same products, same checkout, same AlzaBox delivery. Open the website, search, click through five pages, confirm. Repeat.
For recurring purchases, I don’t want to shop. I want things to be bought.
So I built a CLI that my AI assistant can use to search Alza, compare options, and prepare the order. I confirm, and it’s done.
What it looks like in practice
The full flow, from search to order:
$ alza search "nespresso capsules" -n 5
1. [5765432] Nespresso Vertuo Pop Barista Variety Pack
Price: 5,49 € | In stock
2. [5834521] Starbucks by Nespresso Blonde Espresso Roast
Price: 4,29 € | In stock
3. [5612098] Nespresso Original Ispirazione Roma
Price: 3,99 € | In stock
...
Check details and reviews before deciding:
$ alza product 5612098
[5612098] Nespresso Original Ispirazione Roma
Price: 3,99 €
Rating: ★★★★½ 4.6/5 (238 ratings, 45 reviews)
92% recommend | 1200+ sold
Availability: In stock
Parameters:
Capsule type: Nespresso Original
Intensity: 8/13
Quantity: 10 pcs
Then either add to cart for a normal checkout, or use QuickBuy for one-click ordering:
$ alza quickbuy 5612098 --quote
⏳ Creating price quote...
╔═══════════════════════════════════════════════╗
║ ✅ QUOTE CREATED ║
╠═══════════════════════════════════════════════╣
║ Total: 3,99 € ║
╚═══════════════════════════════════════════════╝
QuickBuy skips the entire cart and checkout flow. It creates an order directly with your saved payment card and preferred AlzaBox. One command, order placed. The --quote flag lets you check the price without actually ordering - removing it (with -y confirmation) charges your card.
The agent never places blind orders. It always creates a quote first, shows the exact product, price, and delivery method, and waits for my explicit confirmation. For ambiguous searches where multiple similar products come back, it stops and asks which one I mean. The point isn’t full autonomy - it’s skipping the boring parts.
Why a CLI and not browser automation
I tried browser automation first. It worked, but it was the wrong abstraction.
Browser agents (tools that control a real browser to click through websites) are universal - they work on any site. But they’re slow, fragile when UI changes, and hard to audit. You’re watching a robot click buttons, hoping it clicks the right ones. When the UI changes, browser automation tends to fail in weird, hard-to-debug ways.
A dedicated CLI talks directly to the backend APIs. It’s faster, predictable, and every step is traceable. When something breaks, it breaks loudly - an API returns an error, not a screenshot of the wrong page.
The tradeoff is scope. A browser agent works on any e-shop. My CLI only works on Alza. For recurring purchases from a single store, that tradeoff is worth it.
How it works under the hood
Alza doesn’t have a public API. Everything in this tool is reverse-engineered from browser network traffic - I opened Chrome DevTools, went through the shopping flow, and mapped out the endpoints.
The real blocker was Cloudflare. Normal HTTP clients never even reached Alza’s API. I ended up using a Go TLS fingerprinting library to imitate Chrome’s TLS handshake closely enough to pass the check.
Authentication piggybacks on your existing Chrome session. You log into Alza normally in your browser, and the CLI reads the session cookies, exchanges them for a short-lived API token, and uses that token for the actual calls. Tokens expire after about 90 minutes, but the CLI auto-refreshes transparently. It never asks for your password - it only uses short-lived tokens derived from your existing browser session.
The AI agent layer
The CLI itself is just plumbing. The interesting part is what sits on top.
I use it through a chat interface with an AI assistant. The assistant has access to the CLI as a tool. When I say “order coffee capsules, the usual ones”, it:
- Checks my order history (
alza orders --query "nespresso") - Finds the product I usually buy
- Runs
alza quickbuy <id> --quoteto get the current price - Asks me to confirm
- Executes the order
For new products, it searches, compares ratings and prices, and presents options. The agent handles the research; I make the final call.
This is where the CLI approach shines over browser automation. The agent can call alza search, alza product, and alza reviews in rapid succession, parsing structured JSON output. No waiting for pages to render, no dealing with popups, no cookie consent dialogs.
# Agent's actual flow (JSON mode for structured parsing)
alza orders --query "detergent" --format=json
alza search "persil washing powder" -n 5 --format=json
alza product 7816725 --format=json
alza reviews 7816725 --stats --format=json
alza quickbuy 7816725 --quote --format=json
# ... waits for my confirmation ...
alza quickbuy 7816725 -y --no-coupon
What I learned building this
Reverse engineering is fragile by definition. Alza can change their API anytime and break everything. In practice, backend APIs change far less often than frontend UI. I’ve been using this since late 2025 and the core endpoints haven’t changed. When they do, the tool breaks loudly - clear error messages, not silent failures.
E-commerce sites really don’t want you automating. Cloudflare protection, token rotation, fingerprinting - there’s a reason this requires TLS fingerprinting and cookie extraction rather than simple HTTP requests. This is firmly in the gray area of “technically possible, officially unsupported.”
The checkout flow is the hardest part. Search and product details were straightforward to reverse-engineer. The order placement flow (QuickBuy) involved mapping 30+ fields in the request body, many of them seemingly meaningless but required for the request to succeed. Fields like IsTretinka, IsBusinessCardSelected, ShowPaymentCards - all set to specific values that mirror what the browser sends.
Agent-friendly tools need JSON output. The --format=json flag was an afterthought initially, but it turned out to be essential. AI agents parse JSON reliably. They struggle with formatted terminal output. Every command supports both human-readable and machine-readable output. Human-friendly output is for me. JSON is for the agent. Once I added structured output to every command, the tool stopped feeling like a terminal hack and started feeling like infrastructure.
Routine shopping doesn’t need a website
Building this convinced me of something simple: for routine purchases, the website is often the wrong interface.
For a specific category of purchases - recurring, commodity items where you’re optimizing on price, availability, and past satisfaction rather than discovery - the traditional browse-and-click flow is overhead. You don’t need product photography for laundry detergent. You don’t need to scroll through recommendations. You need the thing you always buy, at a good price, delivered to your usual pickup point.
I already use chat as the interface for a chunk of my routine shopping. That sounds futuristic until you try it once. The gap between “I need coffee capsules” and “they’re in your AlzaBox tomorrow” doesn’t need 15 clicks in between.
Not for everything, obviously. When I’m buying headphones or a gift, I want to browse, compare, read reviews in detail. But for a big chunk of purchases that are genuinely routine? A sentence in a chat is a better interface than a website.
Patterns that transfer beyond Alza
Even if you never touch Alza, three patterns from this project are broadly useful:
- Use APIs over browser automation when possible. Direct API calls are faster, more reliable, and easier for agents to work with. Browser automation is the fallback, not the default.
- Design tool output for both humans and agents. Every command should have a human-readable default and a
--format=jsonmode. This is cheap to add and dramatically expands what can consume your tool. - Put destructive actions behind quote-first confirmation. Any tool that spends money or makes irreversible changes should have a dry-run or quote mode. Let the agent preview consequences before committing.
Try it yourself
The code is open source: github.com/kuringer/alza-cli
Fair warning: this is a hobby project built for my specific workflow. It only works with Alza.sk (Slovakia), requires Chrome for authentication, and can break if Alza changes their backend. But the patterns inside it are useful well beyond Alza.
If you’re interested in how agent-assisted commerce works in practice - not as a concept deck but as actual running code - it might be worth a look.
If you’ve built something similar for a different e-shop, or if you’re thinking about agent-based purchasing from the retailer side, I’d like to hear about it. Reach out at hello@andrejkostal.sk.