Make your store negotiable in five minutes
This page walks through the hosted onboarding flow at negotiate.pier39.ai/store_onboarding/start. It's for store owners who don't want to write code, install Python libraries, or read setup guides. You fill out a short form, drop in your product CSV, and walk away with a zipped folder ready to run.
The whole flow takes about five minutes. Three of them are filling in form fields.
Before you start
You need three things ready:
- Your store name and city. Two text fields. That's it.
- A product CSV. Either a Shopify product export (Admin → Products → Export → CSV), or any spreadsheet you save as CSV with the columns
id, name, list_price, category, description. If you don't have one yet, you can pick "Skip — use 4 sample Dyson products" to test the flow first. - An Anthropic API key. Get one at console.anthropic.com. Costs about $0.05–$0.15 per negotiation. The form doesn't store your key — it gets written into a file inside the zip you download, and never travels anywhere else.
The five steps
1. Open the form
Visit negotiate.pier39.ai/store_onboarding/start. You'll see a single page with three sections: Store, Products, API key.
2. Tell us about your store
Four short fields:
| Field | Example |
|---|---|
| Store name | Atlas Premium Appliance |
| City | Atlanta, GA |
| Sales rep name | Casey (this is the persona the AI takes on when chatting with shoppers) |
| Tagline | Authorized partner. Outlet pricing. |
These show up in the chat agent's introduction and on your store's discovery file.
3. Drop in your products
Drag your CSV onto the dashed box (or click to browse). Then choose two things:
- CSV format:
- Shopify export — pick this if you exported from Shopify Admin. The form parses the standard Shopify columns (
Handle, Title, Body (HTML), Vendor, Variant Price, Variant Inventory Qty, Tags). - Generic CSV — pick this if your spreadsheet has the columns
id, name, list_price, category, description, in_stock, days_on_lot. -
Skip — use sample — pick this to test the flow with 4 sample Dyson products. Useful if you want to see what the bundle looks like before preparing your own data.
-
Default category — every product gets tagged into one of these "negotiation profiles," which sets the floor (lowest acceptable price):
| Category | Floor | When to use |
|---|---|---|
outlet |
85% of list | Standard outlet/overstock items |
standard_new |
88% | Regular new inventory |
premium_new |
95% | High-demand, low-discount items |
open_box |
78% | Open-box / display units |
aged_30plus |
75% | Items aged 30+ days |
clearance |
65% | End-of-life, get-it-out-the-door |
The form applies the default category to every product unless your CSV already has a category column or your Shopify Tags contain a matching name.
4. Add your API key
Paste your ANTHROPIC_API_KEY (starts with sk-ant-...). If you haven't got one yet, leave this blank — the bundle will include a placeholder you can fill in later.
5. Build and download
Click Build my store bundle. The form does its work in about a second and your browser auto-downloads yourstore-negotiable.zip.
If anything goes wrong, you'll see a red error message right under the button (typically: "CSV had no usable rows" — usually means the file format dropdown doesn't match the file you uploaded).
What's inside the zip
yourstore-negotiable/
├── catalog.json Your full product catalog with floors and concession levers per item
├── serve.py Six-line script to start the merchant backend
├── .env Your Anthropic API key (don't commit this to git)
├── Dockerfile For deploying to any cloud
├── fly.toml Pre-configured for Fly.io with your store-slug app name
└── README.md Quickstart for running locally and deploying
Open catalog.json in a text editor before going live and check two things per product:
floor— is this really the lowest price you'd take? The agent will close at this number. If you'd be unhappy at that price, raise it.levers— are the bundled accessories and warranties accurate for your store? The defaults assume you sell physical goods with manufacturer warranties.
Run it locally
After unzipping, in your terminal:
cd yourstore-negotiable
pip install pier39-merchant-server
python serve.py
That starts the merchant backend on http://localhost:8000. In another terminal, sanity-check:
curl http://localhost:8000/negotiate.json
curl http://localhost:8000/api/store/catalog
If both return JSON, you're live. Try a chat session:
curl "http://localhost:8000/api/store/chat/start?product_id=<your-product-id>"
Deploy to the cloud
Fly.io is the fastest path. Three commands:
fly launch --no-deploy --copy-config --yes
fly secrets set ANTHROPIC_API_KEY=$(grep ANTHROPIC_API_KEY .env | cut -d= -f2)
fly deploy
That gets you a working URL like yourstore-negotiate.fly.dev. To use your own domain:
- At your DNS provider, add a CNAME from
negotiate.yourstore.com(or whatever subdomain you want) to your Fly app. - Run
fly certs add negotiate.yourstore.com— Fly handles TLS automatically.
Render, Railway, or your existing app server work too — anywhere that runs Python and stays alive between requests.
Get found by AI shoppers
Once your store is live at a real domain, list yourself in the negotiate-directory at github.com/sanjana-pier39/negotiate-directory. It's a one-PR process — fork the repo, add an entry to registry.json, open the PR.
Within five minutes of the PR merging, every AI shopper using the protocol can find you. Their flow becomes:
"Find me a store that sells [your category] and negotiate."
→ Their AI calls find_stores(query=...) → gets your store back → calls start_negotiation(your_domain, product_id) → drives the negotiation through your chat agent.
No coordination with shoppers needed. The directory is the matchmaker.
What you can change later
Everything in the bundle is plain text. You can edit any of it after the fact:
- Add or remove products — edit
catalog.jsondirectly, then redeploy. - Change floors and levers — same file. The agent rereads the catalog on every chat session, so changes apply immediately on next deploy.
- Tune the merchant agent's behavior — set
PIER39_MERCHANT_SKILL_PATHto a path with your own version of the merchant skill (defaults to the one bundled with the library). - Switch to a cheaper or smarter model — pass
model="claude-haiku-4-5"(cheaper) ormodel="claude-opus-4-6"(sharper) intoserve()inserve.py.
Common questions
Do I have to use Fly.io?
No. The bundle's Dockerfile works on any container host (Render, Railway, Google Cloud Run, AWS Fargate, your own VM). The fly.toml is just a convenience.
Can I use this without an API key?
You can build and download the bundle without one, but the chat agent won't work until you set ANTHROPIC_API_KEY in .env or as a Fly secret.
Will the form save my data? No. The form is stateless. Your CSV, your store info, and your API key get processed in memory to build the zip, then thrown away.
What if my CSV has weird columns?
Pick "Generic CSV" and make sure your file has at least id, name, list_price, category, description. Other columns are ignored. If your column names don't match, rename them in your spreadsheet before uploading.
What if my products don't fit any of the default categories?
Pick the closest one as your default and let it apply to everything. After you download the bundle, edit catalog.json and adjust the floor and levers for any product that needs a tighter or looser policy.
How much will this cost me to run? Roughly $0.30 per six-turn negotiation in Anthropic API fees. A store handling 100 negotiations a day costs about $30/day. The protocol library and the directory are free; hosting costs depend on where you deploy (Fly.io's free tier is enough for low traffic).
Can I get help?
Email sanjana@pier39.ai. Or open an issue at github.com/sanjana-pier39/pier39-skills.