BazaarOn.ai Developers
Live spec Get a key Quickstart

Developer docs

Build an agent that shops.

BazaarOn speaks the open agentic-commerce protocols — UCP (Universal Commerce Protocol) and ACP (Agentic Commerce Protocol). Point ChatGPT, Gemini, OpenClaw, or your own code at us to discover the catalog, build a cart, and check out — programmatically.

Start building View the live spec

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 agentCreate 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_here

Discovery 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 pay

Payment 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, or pm_card_chargeDeclined (forces a 402 to 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.token

Live 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_address in 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 agentCreate 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/checkout

If 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-Key on session creation so retries don't double-order.
  • Limits: per-IP rate limits apply; back off on 429 (honor Retry-After).
  • Control: the owner can revoke the key anytime from their account — the agent's access stops immediately.

Endpoint reference

Discovery open

GET/.well-known/ucpCapabilities + auth descriptor
POST/ucp/v1/catalog/searchSearch products by text
POST/ucp/v1/recipe-matchMap recipe ingredients → products
GET/ucp/v1/orders/:idPublic order status
GET/acp/feed.jsonlProduct feed (JSONL; .gz variant)
GET/acp/v1/productsProduct list (JSON)
GET/schemas/recipe-ingredient-match.jsonJSON Schema for recipe match

UCP — cart & checkout key

POST/ucp/v1/cartsCreate a cart from line items
GET/ucp/v1/carts/:idRead a cart (owner only)
PATCH/ucp/v1/carts/:idUpdate items / fulfillment
DELETE/ucp/v1/carts/:idCancel a cart
POST/ucp/v1/checkout-sessionsGet a checkout_url for handoff

ACP — agentic checkout key

POST/acp/v1/checkout_sessionsCreate a session (supports Idempotency-Key)
GET/acp/v1/checkout_sessions/:idRead a session
PATCH/acp/v1/checkout_sessions/:idUpdate items / buyer / fulfillment
POST/acp/v1/checkout_sessions/:id/completeCharge + place the order
POST/acp/v1/checkout_sessions/:id/cancelCancel a session

Full request/response field shapes are in the live spec and the JSON schemas.

Conventions & gotchas

  • Line items are flexible. Send items (with product_id or id + quantity) or a bare product_ids array — duplicates are summed server-side.
  • Money is integer cents. amount/subtotalCents/total are whole cents (USD).
  • Weight-sold items. Products have a unit of each, lb, or kg; weight items accept fractional quantity snapped to a step.
  • Idempotency. Send an Idempotency-Key header on ACP session creation to make retries safe.
  • Rate limits. ~240 reads and ~40 writes per minute per IP. Over the limit returns 429 with a Retry-After header.
  • 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: 400 bad request · 401 missing/invalid key · 402 payment declined · 403 not your cart/session · 404 not found · 409 inventory conflict · 429 rate limited.

Next steps