Overview
BazaarOn is an international-grocery marketplace with a first-class agentic interface. Two things matter before you write any code:
- Discovery is open. Browsing the catalog, searching, matching recipe ingredients, reading the product feed, and looking up an order need no key.
- Buying needs a key. Creating carts and checking out require an agent API key (
bzk_…) — so any agent can evaluate the catalog, but only an authorized one can transact.
Base URL for every example on this page: https://bazaaron.ai
Quickstart — your first shopping agent
From zero to a placed order in three steps.
1 Get an API key
Sign in as a shopper at /shop → open your account → Your shopping agent → Create key. You'll get a secret like bzk_a1b2c3… — copy it once; it's never shown again. (Store operators can also issue keys from the admin.) Send it on write requests as a bearer token:
Authorization: Bearer bzk_your_key_hereDiscovery calls below need no key — try them right now.
2 Discover products
POST https://bazaaron.ai/ucp/v1/catalog/search
Content-Type: application/json
{ "query": "basmati rice" }Response (trimmed) — note amount is in integer cents and id is the product id you'll add to a cart:
{
"capability": "dev.ucp.shopping.catalog",
"query": "basmati rice",
"results": [
{
"id": "prod_8f3…",
"title": "Basmati Rice",
"brand": "Royal",
"price": { "currency": "USD", "amount": 999 },
"inventory": { "available": true, "quantity": 100 },
"seller": { "id": "store_1a…", "name": "Test Bazaar" },
"attributes": { "category": "Rice", "size": "5 lb", "tags": ["rice"] }
}
]
}3 Build a cart & check out
Two ways to finish. Pick by who pays:
ACP — fully agentic (the agent supplies a delegated payment and completes the order):
# 1) create a session
POST https://bazaaron.ai/acp/v1/checkout_sessions
Authorization: Bearer bzk_your_key_here
Content-Type: application/json
Idempotency-Key: 7b1f… # safe retries
{
"items": [{ "product_id": "prod_8f3…", "quantity": 2 }],
"buyer": { "name": "Ada", "email": "[email protected]" },
"fulfillment_option_id": "pickup"
}
# → { "id": "acp_checkout_…", "status": "ready_for_payment", "totals": [...] }
# 2) complete it (charges the delegated payment, places the order)
POST https://bazaaron.ai/acp/v1/checkout_sessions/acp_checkout_…/complete
Authorization: Bearer bzk_your_key_here
Content-Type: application/json
{ "payment_data": { "token": "pm_card_visa" } }
# → { "status": "completed", "order": { "id": "order_…", "permalink_url": "…" } }In test mode (no Stripe key configured) payment_data is optional and payments return mock_authorized, so you can complete an order end-to-end without a real card.
UCP — hand off to a human (build the cart, then a person pays in the browser):
POST https://bazaaron.ai/ucp/v1/carts
Authorization: Bearer bzk_your_key_here
Content-Type: application/json
{ "items": [{ "product_id": "prod_8f3…", "quantity": 2 }] }
# → { "cart": { "id": "cart_…", "subtotalCents": 1998, … } }
POST https://bazaaron.ai/ucp/v1/checkout-sessions
Authorization: Bearer bzk_your_key_here
Content-Type: application/json
{ "cart_id": "cart_…" }
# → { "checkout_session": { "checkout_url": "https://bazaaron.ai/shop?cart=cart_…#checkout" } }
# hand checkout_url to your user to payPayment tokens for the ACP flow
The payment_data.token you pass to /complete is a Stripe PaymentMethod id — BazaarOn charges it directly. BazaarOn never stores a shopper's card; the agent presents payment per order. How you get a token depends on the mode:
- Omit it — the order completes as
mock_authorized(no charge). Best while you're wiring up the flow. - Test mode — use one of Stripe's built-in test PaymentMethods; no setup, they exist on every Stripe test account:
pm_card_visa(succeeds),pm_card_mastercard, orpm_card_chargeDeclined(forces a402to test declines). - Mint your own test token — create a PaymentMethod from a test card and pass the returned
pm_…id:
# Using your Stripe TEST secret key (sk_test_…)
POST https://api.stripe.com/v1/payment_methods
Authorization: Bearer sk_test_your_stripe_key
Content-Type: application/x-www-form-urlencoded
type=card&card[token]=tok_visa
# → { "id": "pm_1abc…" } ← pass this as payment_data.tokenLive cards are out of scope here. A real charge needs a PaymentMethod valid on BazaarOn's own Stripe account — i.e. a delegated / "shared" payment token from the shopper's wallet (the model ChatGPT and agent wallets use), not a card you tokenize yourself. BazaarOn runs in Stripe test mode, so use the test tokens above — no real money moves.
Try it live no key needed
These call the real, open discovery endpoints on this site. Type a product and search:
Behind the scenes this is POST /ucp/v1/catalog/search and GET /acp/v1/products — the same calls your agent makes.
UCP vs ACP — which do I use?
UCP
Cart + human handoff
Your agent assembles a cart and gets a checkout_url. A human finishes payment in the browser. Best when a person is in the loop and you don't hold payment credentials.
ACP
Fully agentic checkout
Your agent supplies a delegated payment token and calls /complete — the order is placed without a browser. Best for autonomous, end-to-end purchasing.
Both share the same catalog and product ids. You can start with discovery (open), then choose a checkout path per use case.
Authentication
Discovery is open. Cart and checkout require one of:
1 · Agent API key (most agents)
Send your key as a bearer token (or the X-API-Key header):
Authorization: Bearer bzk_your_key_here
# or
X-API-Key: bzk_your_key_here- Shoppers self-issue keys at /shop → account → Your shopping agent. A shopper's key shops "for them": the order links to their account, and buyer details — name, email, phone, and the saved delivery address — prefill from their profile, so delivery is hands-off. Your agent can still pass
buyer/fulfillment_addressin the ACP session to override. - Store operators issue keys from the admin for partner agents.
- Keys are shown once and stored only as a hash. Revoke anytime — access stops immediately. Carts/sessions are private to the key that created them (cross-key access is
403; buyer PII is redacted from non-owners).
2 · Partner signature (server-to-server)
For platform partners, ACP write requests can be signed instead. When the merchant sets ACP_SIGNING_SECRET, send an HMAC-SHA256 of {timestamp}.{rawBody} with a fresh timestamp (5-minute window):
Timestamp: 1718830000
Signature: <hex hmac-sha256( "{timestamp}.{rawBody}", ACP_SIGNING_SECRET )>The machine-readable auth descriptor lives in the UCP profile under ucp.auth.
Connect OpenClaw (or any agent)
OpenClaw and other AI shopping agents speak plain HTTPS — our open protocols (UCP + ACP), no SDK required. To let an agent shop on its owner's behalf, give it three things: the base URL, an API key the owner issued, and (optionally) the discovery URL. Discovery is open; only cart & checkout use the key.
Teaching your agent the flow? Point it at the hosted skill file — a portable, copy-paste playbook of the full order flow: https://bazaaron.ai/skills/order-on-bazaaron.md
1 The owner issues a key
The shopper signs in at /shop → account → Your shopping agent → Create key. The key is bound to that account, so orders the agent places link back to the owner and their saved buyer details + delivery address fill in automatically.
2 Configure the agent
Point OpenClaw at BazaarOn with two settings (name them however your agent expects):
BAZAARON_BASE_URL = https://bazaaron.ai # discovery: GET {BASE_URL}/.well-known/ucp
BAZAARON_API_KEY = bzk_your_key_here # send as: Authorization: Bearer {API_KEY} on cart/checkoutIf your agent is LLM-driven, this system-prompt line is usually enough:
You can shop for the user at BazaarOn (https://bazaaron.ai). Search the catalog at
/ucp/v1/catalog/search, then create and complete an ACP checkout session
(/acp/v1/checkout_sessions [+ /complete]) using BAZAARON_API_KEY as a Bearer token.
The user's saved name, email and delivery address are applied automatically — only
pass buyer/fulfillment_address if you need to override them.3 Shop on the owner's behalf
A full run — discover (no key), build the cart, and complete the purchase. Note the agent sends no buyer or address: both come from the owner's account.
# 1) find a product (open, no key)
POST https://bazaaron.ai/ucp/v1/catalog/search
Content-Type: application/json
{ "query": "basmati rice" }
# → results[].id e.g. "prod_8f3…"
# 2) create an ACP checkout session with the owner's key — buyer + delivery
# address are auto-filled from the owner's saved profile
POST https://bazaaron.ai/acp/v1/checkout_sessions
Authorization: Bearer bzk_your_key_here
Content-Type: application/json
Idempotency-Key: 7b1f…
{ "items": [{ "product_id": "prod_8f3…", "quantity": 2 }],
"fulfillment_option_id": "local_delivery" }
# → { "id": "acp_checkout_…", "fulfillment_address": { …owner's saved address… },
# "buyer": { "name": "…", "email": "…" }, "status": "ready_for_payment" }
# 3) complete it (test mode: payment_data optional → mock_authorized)
POST https://bazaaron.ai/acp/v1/checkout_sessions/acp_checkout_…/complete
Authorization: Bearer bzk_your_key_here
Content-Type: application/json
{ "payment_data": { "token": "pm_card_visa" } }
# → { "status": "completed", "order": { "id": "order_…", "permalink_url": "…" } }
# the order shows up in the owner's "My orders".Pickup needs no address; delivery uses the owner's saved one. The agent can always pass its own buyer or fulfillment_address to override, and an explicit payment_data.token to charge a real card.
- Idempotency: send an
Idempotency-Keyon session creation so retries don't double-order. - Limits: per-IP rate limits apply; back off on
429(honorRetry-After). - Control: the owner can revoke the key anytime from their account — the agent's access stops immediately.
Endpoint reference
Discovery open
/.well-known/ucpCapabilities + auth descriptor/ucp/v1/catalog/searchSearch products by text/ucp/v1/recipe-matchMap recipe ingredients → products/ucp/v1/orders/:idPublic order status/acp/feed.jsonlProduct feed (JSONL; .gz variant)/acp/v1/productsProduct list (JSON)/schemas/recipe-ingredient-match.jsonJSON Schema for recipe matchUCP — cart & checkout key
/ucp/v1/cartsCreate a cart from line items/ucp/v1/carts/:idRead a cart (owner only)/ucp/v1/carts/:idUpdate items / fulfillment/ucp/v1/carts/:idCancel a cart/ucp/v1/checkout-sessionsGet a checkout_url for handoffACP — agentic checkout key
/acp/v1/checkout_sessionsCreate a session (supports Idempotency-Key)/acp/v1/checkout_sessions/:idRead a session/acp/v1/checkout_sessions/:idUpdate items / buyer / fulfillment/acp/v1/checkout_sessions/:id/completeCharge + place the order/acp/v1/checkout_sessions/:id/cancelCancel a sessionFull request/response field shapes are in the live spec and the JSON schemas.
Conventions & gotchas
- Line items are flexible. Send
items(withproduct_idorid+quantity) or a bareproduct_idsarray — duplicates are summed server-side. - Money is integer cents.
amount/subtotalCents/totalare whole cents (USD). - Weight-sold items. Products have a
unitofeach,lb, orkg; weight items accept fractionalquantitysnapped to astep. - Idempotency. Send an
Idempotency-Keyheader on ACP session creation to make retries safe. - Rate limits. ~240 reads and ~40 writes per minute per IP. Over the limit returns
429with aRetry-Afterheader. - Privacy. Buyer email/phone on a session are visible only to the owning key; others see them redacted.
- CORS. Allowed request headers:
Content-Type, Authorization, X-API-Key, Signature, Timestamp, Idempotency-Key, Request-Id, API-Version. - Errors. JSON body with an
error/code+message; status codes you'll see:400bad request ·401missing/invalid key ·402payment declined ·403not your cart/session ·404not found ·409inventory conflict ·429rate limited.
Next steps
- UCP discovery profile — capabilities, endpoints, and the auth descriptor.
- ACP product feed — the full catalog as JSONL.
- Recipe-match schema & docs.
- Send your AI assistant to shop — create a key in your shopper account.