Headless commerce API
Use Bazaar as the backend for your own storefront (e.g. a Next.js site on Vercel): real catalog & live inventory, a server-side cart, embedded Stripe checkout, order status, and admin writes — all over REST + JSON. Prices and stock are always computed server-side; orders are only marked paid by Stripe's webhook.
Base URL is your Bazaar platform URL, e.g. https://app.buildbazaar.io. Create keys in Dashboard → Settings → API keys.
Authentication
Two key types, sent as a bearer token. Publishable keys (pk_…) are safe in browser code and power the storefront API (catalog, cart, checkout, order status). Secret keys (sk_…) must stay on your server and power the admin API. The full key is shown once at creation.
curl https://app.buildbazaar.io/api/storefront/products \
-H "Authorization: Bearer pk_your_publishable_key"CORS & origins
Storefront (publishable) endpoints are browser-callable. Add your site's origins to the key's allowlist in the dashboard; requests from other origins are blocked (an empty allowlist allows any origin, since publishable keys are public by design). Admin (secret) endpoints are server-to-server only and send no CORS headers — never call them from a browser.
Rate limits
Limits are per API key, per endpoint group, in a fixed 60-second window (e.g. catalog 120/min, checkout 10/min). Exceeding a limit returns 429 with a Retry-After header. Every response is { "ok": true, "data": … } or { "ok": false, "error": "code" }.
Storefront API
Publishable key. The cart is keyed by a returned cartId (no cookies).
| Method | Path | Description |
|---|---|---|
| GET | /api/storefront/products | List products (live inventory). ?limit&cursor&collection |
| GET | /api/storefront/products/{slug} | Product detail + variants |
| GET | /api/storefront/collections | List collections |
| GET | /api/storefront/collections/{slug} | Collection + its products |
| POST | /api/storefront/carts | Create a cart → { cartId } |
| GET | /api/storefront/carts/{cartId} | Cart with lines + totals |
| POST | /api/storefront/carts/{cartId}/items | Add item { productId, variantId?, quantity } |
| PATCH | /api/storefront/carts/{cartId}/items/{itemId} | Update quantity (0 removes) |
| POST | /api/storefront/carts/{cartId}/discount | Apply { code } |
| POST | /api/storefront/checkout/payment-intent | Start embedded checkout |
| POST | /api/storefront/subscriptions | Start a subscribe & save subscription → { clientSecret } |
| GET | /api/storefront/orders/{accessToken} | Order status by token |
| GET | /api/storefront/products/{slug}/reviews | Approved reviews for a product |
| POST | /api/storefront/products/{slug}/reviews | Submit a review (lands as pending) |
| POST | /api/storefront/uploads | Upload an image (multipart file) → { url } |
Embedded checkout
- Build a cart with the cart endpoints; keep the
cartId. POST /checkout/payment-intentwith the cart, email, and shipping address.- Mount Stripe Elements with the returned
clientSecret+publishableKeyand callstripe.confirmPayment— card entry stays on your site. - Stripe's webhook finalizes the order (paid, inventory, customer). Poll
GET /orders/{accessToken}for status.
POST /api/storefront/checkout/payment-intent
{ "cartId": "…", "email": "a@b.com",
"shippingAddress": { "line1": "1 Main St", "city": "NYC", "country": "US" } }
→ { "ok": true, "data": {
"clientSecret": "pi_…_secret_…",
"publishableKey": "pk_test_… (Stripe)",
"orderId": "…", "accessToken": "…",
"breakdown": { "totalCents": 4200, "currency": "USD" } } }Note: embedded checkout doesn't support stores with automatic tax enabled yet (Stripe Tax runs in hosted Checkout only). Such stores get a 422 tax_not_supported_embedded. Use hosted checkout, or disable store tax, until Stripe Tax for embedded ships.
Full Next.js + Stripe Elements example: examples/headless-next/ in the repo.
Admin API
Secret key, server-side only. Manage products, stock, and orders.
| Method | Path | Description |
|---|---|---|
| GET | /api/admin/products | List products. ?status&limit&cursor |
| POST | /api/admin/products | Create a product |
| GET | /api/admin/products/{id} | Product + variants + images |
| PATCH | /api/admin/products/{id} | Update product fields |
| DELETE | /api/admin/products/{id} | Delete a product |
| POST | /api/admin/products/{id}/inventory | Adjust stock { variantId?, set?|delta? } |
| GET | /api/admin/orders | List orders. ?status&limit&cursor |
| GET | /api/admin/orders/{id} | Order + items |
| POST | /api/admin/orders/{id}/fulfillment | Set fulfillment + tracking |
| GET | /api/admin/reviews | List reviews. ?status&productId&limit&cursor |
| PATCH | /api/admin/reviews/{id} | Moderate a review { status: approved|rejected } |
| DELETE | /api/admin/reviews/{id} | Delete a review |
curl -X POST https://app.buildbazaar.io/api/admin/products/PID/inventory \
-H "Authorization: Bearer sk_your_secret_key" \
-H "Content-Type: application/json" \
-d '{ "delta": -3 }'