Storefront API
API overview
One base path, one auth header, one error format. The surface is deliberately small: everything a storefront reads or writes, and nothing a merchant dashboard does.
Base URL & versioning
All endpoints live under /storefront/v1. The version is a literal path prefix and the contract is additive-only: fields are added, never renamed or removed, within a major version. Your integration should ignore fields it does not recognize.
Authentication
Every request carries a publishable key — see Authentication for key management, allowed origins, and CORS behavior.
Money
Monetary values are integers in minor units (paise, cents) and always travel with an explicit currency code. There are no floats anywhere on the wire. 79900 + INR is ₹799.00.
Pagination
Every list endpoint is cursor-paginated with the same envelope — no offsets, no totals:
▸ GET /storefront/v1/products?limit=24&cursor=eyJjcmVhdGVkQXQi…◂ 200 OK{ "items": [ … ], "nextCursor": null# nextCursor null → you have the last page}
| Envelope | Type | Description |
|---|---|---|
| items | array | The page of results. |
| nextCursor | string | null | Opaque. Pass back as ?cursor= for the next page; null means the end. |
Errors
Errors are application/problem+json (RFC 9457). The title is a stable machine-readable code; detail is for humans.
▸ GET /storefront/v1/products/not-a-uuid▸ X-Publishable-Key: pk_live_9f2…◂ 400 Bad Request · application/problem+json{ "type": "about:blank", "title": "validation_failed", "status": 400, "detail": "id must be a UUID"}
Rate limits
Limits are applied per key in two tiers: reads (public-read) and cart/checkout writes (public-write). A limited request returns 429 in the problem+json shape above — back off and retry.
Caching: catalog reads are safe to cache on your side. Product data changes emit domain events you can use for invalidation.