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/checkout?cart=cart_…", "amount": { "subtotal": 1598, "fulfillment": 499, "card_processing": 94, "tax": 0, "total": 2191 } } }
# 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 and 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 and 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 through 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, and 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.