REST API
Two surfaces, one shape. Public endpoints are public and safe to call from the browser. Private endpoints are authenticated with a secret key and live on your server.
Introduction
The Shoprocket REST API is split into two surfaces. The Public API powers the widget and any custom storefront you build. The Private API powers your dashboard and any server-side integration.
Both APIs speak JSON. Both follow the same key casing, error, pagination, and timestamp conventions. The only real differences are the base URL, the auth key, and what you are allowed to do.
curl https://api.shoprocket.io/v3/public/pk_live_.../cart \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: any-random-string"
curl https://api.shoprocket.io/v3/private/stores/str_.../products \
-H "Authorization: Bearer sk_live_..."
Base URLs
Public endpoints are scoped to a store via your publishable key in the URL path. Private endpoints identify the store via your secret key in the Authorization header.
Path examples in this document omit the base URL and the publishable key segment, e.g. GET /cart means GET https://api.shoprocket.io/v3/public/{publishable_key}/cart.
https://api.shoprocket.io/v3/public/{publishable_key}
https://api.shoprocket.io/v3/private
Authentification
Every request needs an Authorization header. Use a public key (pk_) for the Public API, a secret key (sk_) for the Private API.
Public cart endpoints additionally require an X-Cart-Token header to identify the visitor session. See the authentication guide for full detail.
Authorization: Bearer {your_key}
X-Cart-Token: {visitor_cart_token} # Public cart endpoints only
Conventions
The same conventions apply across both API surfaces.
Keys are camelCase
All request and response keys use camelCase (per the Google JSON Style Guide). Timestamps are camelCase too: createdAt, updatedAt, paidAt.
Money is a nested object
Every monetary value in a response is a Money object with a minor-units integer amount, an ISO 4217 currency code, and a pre-formatted display string. See the Money object reference.
On requests, money inputs are plain integers in minor units. The currency is implied by the cart or store context. "amount": 2400 means £24.00 when the cart currency is GBP, $24.00 in USD, and so on.
Identifiers
Every resource has a prefixed NanoID (e.g. prod_01HXY..., ord_01HXY...). Ids are opaque strings, not sequential numbers. Never parse them for meaning beyond the prefix.
Timestamps
All timestamps are ISO 8601 strings in UTC, e.g. 2026-04-20T13:24:11Z.
"total": {
"amount": 2400,
"currency": "GBP",
"formatted": "£24.00"
}
{
"id": "prod_01HXYZ...",
"createdAt": "2026-04-20T13:24:11Z",
"updatedAt": "2026-04-20T15:02:44Z"
}
Errors
Errors follow a consistent shape regardless of which API surface you are calling.
| Statut | Meaning |
|---|---|
200 | OK |
201 | Créé |
204 | No content (successful delete or void action) |
400 | Bad request, malformed JSON |
401 | Missing or invalid API key |
403 | Authenticated but not allowed |
404 | Resource not found |
409 | Conflict (e.g. out-of-stock on add-to-cart) |
422 | Validation failed (see fields) |
429 | Rate limit hit |
500 | Server error, retry with backoff |
{
"error": {
"code": "validation_failed",
"message": "The price field is required.",
"fields": {
"price": ["The price field is required."]
}
}
}
Pagination
List endpoints accept page and perPage query params. The response wraps the array in a data field with a meta block.
Maximum perPage is 100. Defaults to 20 if omitted.
GET /products?page=2&perPage=50
{
"data": [
{
"id": "prod_01HXY...",
"slug": "hand-poured-candle",
"name": "Hand-poured candle",
"price": {
"amount": 2400,
"currency": "GBP",
"formatted": "£24.00"
},
"inStock": true
}
],
"meta": {
"currentPage": 2,
"perPage": 50,
"total": 318,
"lastPage": 7
}
}
Versioning
The API is versioned in the URL path: /v3/.... Breaking changes ship behind a new major version. We maintain the previous major version for at least 12 months after a new one ships, so you have a year to migrate at your own pace.
What counts as additive (safe within a version)
- New endpoints
- New optional request fields
- New response fields
- New enum values
- New optional headers
What counts as breaking (next major version only)
- Removing or renaming an endpoint, field, or enum value
- Changing a field type or making an optional field required
- Tightening validation in a way that rejects previously-valid requests
- Changing the meaning of an existing field
Deprecation policy
When a field or endpoint is going away in the next major version, we mark it deprecated in the docs and announce it in the changelog at least six months before removal. Deprecated items keep working until the major version is bumped, so you can plan the migration.
Forward-compatible client patterns
To stay compatible across additive changes:
- Ignore unknown fields in responses (do not throw on unexpected keys).
- Do not switch on string values without a default case (new enum values may appear).
- Never assume the absence of a field implies its removal. Fields can be conditionally present.
- Pin to specific endpoint paths and HTTP methods, not auto-discovered URLs.
/v3/public/{publishable_key}/...
/v3/private/stores/{store_id}/...
Public, publishable key
API publique
The Public API powers the widget and any custom storefront you build. It is safe to call from a browser. Authenticate with a publishable key (pk_live_... or pk_test_...) and, for cart endpoints, an X-Cart-Token header that identifies the visitor session.
Base URL: https://api.shoprocket.io/v3/public/{publishable_key}
Authentication: Authorization: Bearer pk_live_...
Cart context: X-Cart-Token: {any random string, reused per visitor}
/
PUBLIC
120/min
Fetch public store metadata: name, currency, supported locales, enabled features. Typically called once at widget bootstrap to configure the client.
curl https://api.shoprocket.io/v3/public/pk_live_... \
-H "Authorization: Bearer pk_live_..."
{
"data": {
"id": "str_01HXY...",
"name": "Acme Candles",
"currency": "GBP",
"supportedCurrencies": ["GBP", "USD", "EUR"],
"supportedLocales": ["en", "fr", "de"],
"defaultLocale": "en",
"features": {
"reviews": true,
"discounts": true,
"multiCurrency": false
},
"branding": {
"primaryColor": "#FF5C00",
"logoUrl": "https://cdn.shoprocket.io/..."
}
}
}
/cart
PUBLIC
120/min
Fetch the current cart for the supplied X-Cart-Token. Returns an empty cart registered to that token if none exists, so this endpoint is also the idiomatic "start a cart" call.
Headers
| Champ | Type | Description |
|---|---|---|
X-Cart-Token
|
string · required | Visitor cart identifier. Generate any string client-side (a UUID is fine) and persist it in a cookie or local storage for the session. |
Returns a Cart object.
curl https://api.shoprocket.io/v3/public/pk_live_.../cart \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..."
{
"data": {
"id": "ord_01CXYZ...",
"type": "cart",
"currency": "GBP",
"visitorCountry": "GB",
"hasCheckoutData": false,
"hasBillingAddress": false,
"hasShippingAddress": false,
"requiresShipping": true,
"discountCode": null,
"discountType": null,
"discountValue": null,
"isAuthenticated": false,
"updatedAt": "2026-04-20T12:05:13Z",
"items": [
{
"id": "oitm_01HXYZ...",
"productId": "prod_01HXY...",
"variantId": null,
"productName": "Hand-poured candle",
"productSlug": "hand-poured-candle",
"variantName": null,
"quantity": 2,
"price": { "amount": 2400, "currency": "GBP", "formatted": "£24.00" },
"subtotal": { "amount": 4800, "currency": "GBP", "formatted": "£48.00" },
"image": { "id": "1234", "path": "uuid/hand-poured-candle.jpg", "alt": "Hand-poured candle" },
"trackInventory": true,
"inStock": true,
"inventoryCount": 47,
"productType": "physical"
}
],
"totals": {
"subtotal": { "amount": 4800, "currency": "GBP", "formatted": "£48.00" },
"tax": { "amount": 960, "currency": "GBP", "formatted": "£9.60" },
"shipping": { "amount": 0, "currency": "GBP", "formatted": "£0.00" },
"discount": { "amount": 0, "currency": "GBP", "formatted": "£0.00" },
"total": { "amount": 5760, "currency": "GBP", "formatted": "£57.60" }
},
"taxInclusive": false,
"taxBreakdown": [],
"messages": []
}
}
/cart/items
PUBLIC
120/min
Add an item to the cart. If the same product/variant is already in the cart, the existing line quantity is incremented rather than a new line being created.
Body
| Champ | Type | Description |
|---|---|---|
productId
|
string · required | The product to add. Accepts either the product id or slug. |
variantId
|
string · optional | Required if the product has variants. Omit for simple products. |
quantity
|
integer · optional | Defaults to 1. Capped at the product stock level. A 409 is returned if stock is insufficient. |
Returns the updated Cart object.
curl -X POST https://api.shoprocket.io/v3/public/pk_live_.../cart/items \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..." \
-H "Content-Type: application/json" \
-d '{
"productId": "prod_01HXY...",
"quantity": 1
}'
{
"data": {
"id": "ord_01CXYZ...",
"type": "cart",
"items": [
{
"id": "oitm_01HXYZ...",
"productId": "prod_01HXY...",
"productName": "Hand-poured candle",
"quantity": 3,
"price": { "amount": 2400, "currency": "GBP", "formatted": "£24.00" },
"subtotal": { "amount": 7200, "currency": "GBP", "formatted": "£72.00" }
}
],
"totals": {
"subtotal": { "amount": 7200, "currency": "GBP", "formatted": "£72.00" },
"tax": { "amount": 1440, "currency": "GBP", "formatted": "£14.40" },
"shipping": { "amount": 0, "currency": "GBP", "formatted": "£0.00" },
"discount": { "amount": 0, "currency": "GBP", "formatted": "£0.00" },
"total": { "amount": 8640, "currency": "GBP", "formatted": "£86.40" }
},
"updatedAt": "2026-04-20T12:07:01Z"
}
}
/cart/items/{item}
PUBLIC
120/min
Update a line item, typically to change quantity. Set quantity to 0 to remove the line (equivalent to calling DELETE on the item).
Body
| Champ | Type | Description |
|---|---|---|
quantity
|
integer · required | New quantity. 0 removes the line. Capped at available stock. |
Returns the updated Cart object.
curl -X PUT https://api.shoprocket.io/v3/public/pk_live_.../cart/items/oitm_01HXYZ... \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..." \
-H "Content-Type: application/json" \
-d '{"quantity": 5}'
{
"data": {
"id": "ord_01CXYZ...",
"items": [
{
"id": "oitm_01HXYZ...",
"productId": "prod_01HXY...",
"quantity": 5,
"price": { "amount": 2400, "currency": "GBP", "formatted": "£24.00" },
"subtotal": { "amount": 12000, "currency": "GBP", "formatted": "£120.00" }
}
],
"totals": {
"subtotal": { "amount": 12000, "currency": "GBP", "formatted": "£120.00" },
"total": { "amount": 14400, "currency": "GBP", "formatted": "£144.00" }
}
}
}
/cart/items/{item}
PUBLIC
120/min
Remove a single line item from the cart.
Returns the updated Cart object.
curl -X DELETE https://api.shoprocket.io/v3/public/pk_live_.../cart/items/oitm_01HXYZ... \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..."
{
"data": {
"id": "ord_01CXYZ...",
"items": [],
"totals": {
"subtotal": { "amount": 0, "currency": "GBP", "formatted": "£0.00" },
"total": { "amount": 0, "currency": "GBP", "formatted": "£0.00" }
}
}
}
/cart/discount
PUBLIC
60/min
Apply a discount code to the cart. Validates the code against the store configuration (expiry, usage limits, product restrictions) and returns a 422 if rejected.
Body
| Champ | Type | Description |
|---|---|---|
code
|
string · required | The discount code string the customer entered. |
curl -X POST https://api.shoprocket.io/v3/public/pk_live_.../cart/discount \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..." \
-H "Content-Type: application/json" \
-d '{"code": "SPRING20"}'
{
"data": {
"id": "ord_01CXYZ...",
"discountCode": "SPRING20",
"discountType": "percentage",
"discountValue": 20,
"totals": {
"subtotal": { "amount": 7200, "currency": "GBP", "formatted": "£72.00" },
"discount": { "amount": 1440, "currency": "GBP", "formatted": "£14.40" },
"tax": { "amount": 1152, "currency": "GBP", "formatted": "£11.52" },
"shipping": { "amount": 0, "currency": "GBP", "formatted": "£0.00" },
"total": { "amount": 6912, "currency": "GBP", "formatted": "£69.12" }
}
}
}
/cart/discount
PUBLIC
60/min
Remove any applied discount from the cart.
curl -X DELETE https://api.shoprocket.io/v3/public/pk_live_.../cart/discount \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..."
{
"data": {
"id": "ord_01CXYZ...",
"discountCode": null,
"discountType": null,
"discountValue": null,
"totals": {
"subtotal": { "amount": 7200, "currency": "GBP", "formatted": "£72.00" },
"discount": { "amount": 0, "currency": "GBP", "formatted": "£0.00" },
"total": { "amount": 8640, "currency": "GBP", "formatted": "£86.40" }
}
}
}
/cart/estimate
PUBLIC
120/min
Estimate tax and shipping totals for the cart given a destination, without committing any data. Useful for showing a running total as the customer types their address.
Body
| Champ | Type | Description |
|---|---|---|
countryCode
|
string · required | ISO 3166-1 alpha-2 country code (e.g. GB, US). |
postcode
|
string · optional | Postcode or ZIP, if known. Improves tax accuracy for destination-based jurisdictions. |
state
|
string · optional | ISO 3166-2 state/region code where applicable. |
curl -X POST https://api.shoprocket.io/v3/public/pk_live_.../cart/estimate \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..." \
-H "Content-Type: application/json" \
-d '{
"countryCode": "GB",
"postcode": "NW1 6XE"
}'
{
"data": {
"totals": {
"subtotal": { "amount": 7200, "currency": "GBP", "formatted": "£72.00" },
"tax": { "amount": 1440, "currency": "GBP", "formatted": "£14.40" },
"shipping": { "amount": 495, "currency": "GBP", "formatted": "£4.95" },
"total": { "amount": 9135, "currency": "GBP", "formatted": "£91.35" }
},
"taxRate": 0.20,
"shippingOptionsCount": 3
}
}
/cart/shipping-options
PUBLIC
120/min
List shipping options available for the current cart and saved destination address. Requires that the checkout address has been set via Save checkout data first.
curl https://api.shoprocket.io/v3/public/pk_live_.../cart/shipping-options \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..."
{
"data": [
{
"id": "shm_01HXY...",
"name": "Royal Mail · Tracked 48",
"description": "2-3 working days",
"price": { "amount": 395, "currency": "GBP", "formatted": "£3.95" },
"estimatedMinDays": 2,
"estimatedMaxDays": 3
},
{
"id": "shm_02WQR...",
"name": "Royal Mail · Tracked 24",
"description": "1-2 working days",
"price": { "amount": 595, "currency": "GBP", "formatted": "£5.95" },
"estimatedMinDays": 1,
"estimatedMaxDays": 2
}
]
}
/cart/shipping-option
PUBLIC
120/min
Select one of the shipping options returned by the list endpoint. The selected option is stored on the cart and applied to the total.
Body
| Champ | Type | Description |
|---|---|---|
shippingOptionId
|
string · required | The id of the shipping option to select. |
curl -X POST https://api.shoprocket.io/v3/public/pk_live_.../cart/shipping-option \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..." \
-H "Content-Type: application/json" \
-d '{"shippingOptionId": "shm_01HXY..."}'
{
"data": {
"id": "ord_01CXYZ...",
"shippingOption": {
"id": "shm_01HXY...",
"name": "Royal Mail · Tracked 48",
"price": { "amount": 395, "currency": "GBP", "formatted": "£3.95" }
},
"totals": {
"shipping": { "amount": 395, "currency": "GBP", "formatted": "£3.95" },
"total": { "amount": 9135, "currency": "GBP", "formatted": "£91.35" }
}
}
}
/cart/checkout-data
PUBLIC
120/min
Read back any checkout data (email, addresses, notes) previously saved for this cart. Used to repopulate the checkout form on page reload.
curl https://api.shoprocket.io/v3/public/pk_live_.../cart/checkout-data \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..."
{
"data": {
"email": "[email protected]",
"shippingAddress": {
"firstName": "Sam",
"lastName": "Buyer",
"line1": "221B Baker Street",
"line2": null,
"city": "London",
"postcode": "NW1 6XE",
"countryCode": "GB",
"state": null,
"phone": "+447700900123"
},
"billingAddress": null,
"sameAsShipping": true,
"notes": null
}
}
/cart/checkout-data
PUBLIC
120/min
Save checkout data (email, shipping and billing addresses, notes) against the cart. Validates each field; returns 422 with field-level errors if any are invalid.
Body
| Champ | Type | Description |
|---|---|---|
email
|
string · optional | Customer email for the order and post-purchase communication. |
shippingAddress
|
object · optional | A full Address object. Required before submitting checkout. |
billingAddress
|
object · optional |
A full Address object. Omit or send sameAsShipping: true to reuse the shipping address.
|
sameAsShipping
|
boolean · optional | When true, the shipping address is copied to billing at checkout time. |
notes
|
string · optional | Free-form notes from the customer (gift message, delivery instructions). |
curl -X PUT https://api.shoprocket.io/v3/public/pk_live_.../cart/checkout-data \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..." \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"shippingAddress": {
"firstName": "Sam",
"lastName": "Buyer",
"line1": "221B Baker Street",
"city": "London",
"postcode": "NW1 6XE",
"countryCode": "GB"
},
"sameAsShipping": true
}'
{
"data": {
"email": "[email protected]",
"shippingAddress": {
"line1": "221B Baker Street",
"city": "London",
"postcode": "NW1 6XE",
"countryCode": "GB"
},
"sameAsShipping": true,
"notes": null
}
}
/cart/checkout
PUBLIC
30/min
Submit the cart for checkout. Creates an order, charges the payment method, and returns the completed order. Requires that email, shipping address, and a shipping option have already been saved.
Body
| Champ | Type | Description |
|---|---|---|
paymentMethod
|
string · required | Stripe payment method id (pm_...) collected client-side via Stripe Elements, or one of the supported alternative method ids (apple_pay, google_pay, bank_transfer, etc.). |
returnUrl
|
string · optional | URL to redirect to for 3DS or redirect-based payment flows. |
curl -X POST https://api.shoprocket.io/v3/public/pk_live_.../cart/checkout \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..." \
-H "Content-Type: application/json" \
-d '{
"paymentMethod": "pm_1XyZ...",
"returnUrl": "https://yoursite.com/thanks"
}'
{
"data": {
"orderId": "ord_01HXYZ...",
"orderNumber": "1024",
"status": "paid",
"paymentStatus": "succeeded",
"requiresAction": false,
"nextActionUrl": null,
"redirectUrl": "https://yoursite.com/thanks?order=ord_01HXYZ..."
}
}
{
"data": {
"orderId": "ord_01HXYZ...",
"status": "pending",
"paymentStatus": "requires_action",
"requiresAction": true,
"nextActionUrl": "https://hooks.stripe.com/redirect/..."
}
}
/cart/check-customer
PUBLIC
30/min
Check whether a customer already exists for the given email. Returns whether a login link can be sent or an account needs to be created. Does not leak whether the email is registered to a different store.
Body
| Champ | Type | Description |
|---|---|---|
email
|
string · required | The email to check. |
curl -X POST https://api.shoprocket.io/v3/public/pk_live_.../cart/check-customer \
-H "Authorization: Bearer pk_live_..." \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'
{
"data": {
"exists": true,
"canSendAuthLink": true
}
}
/cart/send-auth
PUBLIC
10/min
Send a passwordless login link to the email. The link returns a short-lived token the client uses to authenticate via Verify auth.
Body
| Champ | Type | Description |
|---|---|---|
email
|
string · required | Email to send the login link to. |
curl -X POST https://api.shoprocket.io/v3/public/pk_live_.../cart/send-auth \
-H "Authorization: Bearer pk_live_..." \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'
{
"data": {
"sent": true,
"expiresIn": 900
}
}
/cart/verify-auth
PUBLIC
30/min
Exchange a login token (from the emailed link) for an authenticated session. Associates the cart with the customer account.
Body
| Champ | Type | Description |
|---|---|---|
token
|
string · required | The short-lived token delivered via the login email. |
curl -X POST https://api.shoprocket.io/v3/public/pk_live_.../cart/verify-auth \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..." \
-H "Content-Type: application/json" \
-d '{"token": "lnk_01HXY..."}'
{
"data": {
"customerId": "cust_01HXY...",
"email": "[email protected]",
"authenticated": true
}
}
/cart/create-account
PUBLIC
10/min
Create a customer account for a guest checkout. Typically called at the end of checkout when the customer opts to save their details. The cart is associated with the new account.
Body
| Champ | Type | Description |
|---|---|---|
email
|
string · required | Email for the new account. |
firstName
|
string · optional | Customer first name. |
lastName
|
string · optional | Customer last name. |
marketingOptIn
|
boolean · optional | Whether the customer has opted in to marketing email. |
curl -X POST https://api.shoprocket.io/v3/public/pk_live_.../cart/create-account \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..." \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"firstName": "Sam",
"lastName": "Buyer",
"marketingOptIn": false
}'
{
"data": {
"customerId": "cust_01HXY...",
"email": "[email protected]",
"authenticated": true
}
}
/cart/auth-status
PUBLIC
120/min
Check whether the current cart is associated with an authenticated customer. Used by the widget to decide which checkout variant to show.
curl https://api.shoprocket.io/v3/public/pk_live_.../cart/auth-status \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..."
{
"data": {
"authenticated": true,
"customer": {
"id": "cust_01HXY...",
"email": "[email protected]",
"firstName": "Sam",
"lastName": "Buyer"
}
}
}
/account/profile
PUBLIC
Auth required
120/min
Fetch the authenticated customer profile. Requires that the cart session is authenticated via Verify auth or Create account.
Returns a Customer object.
curl https://api.shoprocket.io/v3/public/pk_live_.../account/profile \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..."
{
"data": {
"id": "cust_01HXY...",
"email": "[email protected]",
"firstName": "Sam",
"lastName": "Buyer",
"phone": "+447700900123",
"defaultAddress": {
"line1": "221B Baker Street",
"city": "London",
"postcode": "NW1 6XE",
"countryCode": "GB"
},
"marketingOptIn": false,
"createdAt": "2025-11-02T10:00:00Z"
}
}
/account/profile
PUBLIC
Auth required
30/min
Update the authenticated customer profile. All body fields are optional; only provided fields are changed.
Body
| Champ | Type | Description |
|---|---|---|
firstName
|
string · optional | New first name. |
lastName
|
string · optional | New last name. |
phone
|
string · optional | E.164 phone number. |
marketingOptIn
|
boolean · optional | Marketing email preference. |
curl -X PUT https://api.shoprocket.io/v3/public/pk_live_.../account/profile \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..." \
-H "Content-Type: application/json" \
-d '{"phone": "+447700900999"}'
{
"data": {
"id": "cust_01HXY...",
"phone": "+447700900999",
"updatedAt": "2026-04-20T12:30:00Z"
}
}
/account/orders
PUBLIC
Auth required
120/min
List orders belonging to the authenticated customer, most recent first.
Query params
| Champ | Type | Description |
|---|---|---|
page
|
integer · optional | Page number. |
perPage
|
integer · optional | Items per page (max 100). |
curl https://api.shoprocket.io/v3/public/pk_live_.../account/orders \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..."
{
"data": [
{
"id": "ord_01HXYZ...",
"orderNumber": "1024",
"paymentStatus": "paid",
"fulfillmentStatus": "unfulfilled",
"currency": "GBP",
"totals": {
"total": { "amount": 12400, "currency": "GBP", "formatted": "£124.00" }
},
"itemCount": 2,
"createdAt": "2026-04-20T13:24:11Z"
}
],
"meta": { "currentPage": 1, "perPage": 20, "total": 7, "lastPage": 1 }
}
/account/orders/{order}
PUBLIC
Auth required
120/min
Fetch a single order belonging to the authenticated customer.
Returns an Order object.
curl https://api.shoprocket.io/v3/public/pk_live_.../account/orders/ord_01HXYZ... \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..."
{
"data": {
"id": "ord_01HXYZ...",
"orderNumber": "1024",
"type": "order",
"paymentStatus": "paid",
"fulfillmentStatus": "unfulfilled",
"currency": "GBP",
"totals": {
"subtotal": { "amount": 10400, "currency": "GBP", "formatted": "£104.00" },
"tax": { "amount": 2000, "currency": "GBP", "formatted": "£20.00" },
"shipping": { "amount": 0, "currency": "GBP", "formatted": "£0.00" },
"discount": { "amount": 0, "currency": "GBP", "formatted": "£0.00" },
"total": { "amount": 12400, "currency": "GBP", "formatted": "£124.00" }
},
"items": [
{
"id": "oitm_01HXY...",
"productId": "prod_01HXY...",
"productName": "Hand-poured candle",
"quantity": 2,
"price": { "amount": 2400, "currency": "GBP", "formatted": "£24.00" },
"subtotal": { "amount": 4800, "currency": "GBP", "formatted": "£48.00" }
}
],
"shippingAddress": {
"line1": "221B Baker Street",
"city": "London",
"postcode": "NW1 6XE",
"countryCode": "GB"
},
"createdAt": "2026-04-20T13:24:11Z",
"paidAt": "2026-04-20T13:24:18Z"
}
}
/account/logout
PUBLIC
Auth required
30/min
Log the customer out. The cart session is preserved under the X-Cart-Token but no longer associated with the customer account.
curl -X POST https://api.shoprocket.io/v3/public/pk_live_.../account/logout \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..."
{
"data": { "authenticated": false }
}
/products
PUBLIC
120/min
List published products. Supports filtering, free-text search, sorting, and pagination.
Query params
| Champ | Type | Description |
|---|---|---|
category
|
string · optional | Filter by category slug or id. |
q
|
string · optional | Free-text search across name and description. |
sort
|
string · optional | One of: name, -name, price, -price, createdAt, -createdAt. Prefix with - for descending. Defaults to sortOrder. |
page
|
integer · optional | Page number. Defaults to 1. |
perPage
|
integer · optional | Items per page (max 100). Defaults to 20. |
curl "https://api.shoprocket.io/v3/public/pk_live_.../products?perPage=2" \
-H "Authorization: Bearer pk_live_..."
{
"data": [
{
"id": "prod_01HXY...",
"slug": "hand-poured-candle",
"name": "Hand-poured candle",
"price": { "amount": 2400, "currency": "GBP", "formatted": "£24.00" },
"inStock": true,
"media": [
{ "id": "1234", "path": "uuid/hand-poured-candle.jpg", "alt": "Front", "isVideo": false, "aspectRatio": 0.75 }
]
},
{
"id": "prod_02KLM...",
"slug": "lavender-linen-spray",
"name": "Lavender linen spray",
"price": { "amount": 1200, "currency": "GBP", "formatted": "£12.00" },
"inStock": true,
"media": [
{ "id": "5678", "path": "uuid/lavender-spray.jpg", "alt": "Front", "isVideo": false, "aspectRatio": 0.75 }
]
}
],
"meta": { "currentPage": 1, "perPage": 2, "total": 318, "lastPage": 159 }
}
/products/{product}
PUBLIC
120/min
Fetch a single product by id or slug. Returns the full payload including variants, options, images, and sale information.
Returns a Product object.
curl https://api.shoprocket.io/v3/public/pk_live_.../products/hand-poured-candle \
-H "Authorization: Bearer pk_live_..."
{
"data": {
"id": "prod_01HXY...",
"slug": "hand-poured-candle",
"name": "Hand-poured candle",
"summary": "Soy wax, 60 hours burn time.",
"description": "Hand-poured soy wax candles...",
"status": "published",
"productType": "physical",
"featured": false,
"digital": false,
"trackInventory": true,
"inStock": true,
"inventoryCount": 47,
"shippingType": "required",
"requireDeliveryOrCollection": false,
"fixedShippingRateCents": null,
"minOrderQuantity": 1,
"maxOrderQuantity": null,
"price": {
"amount": 2400,
"originalAmount": 2400,
"currency": "GBP",
"formatted": "£24.00",
"originalFormatted": "£24.00",
"inclusive": false,
"note": "+ tax at checkout",
"isOnSale": false,
"salePrice": null,
"salePriceFormatted": null,
"discountPercentage": null,
"saleName": null
},
"priceMin": 2400,
"priceMax": 2400,
"hasVariants": false,
"hasRequiredOptions": false,
"variantCount": 1,
"quickAddEligible": true,
"defaultVariantId": "var_01HXY...",
"media": [
{ "id": "1234", "path": "uuid/front.jpg", "alt": "Front", "isVideo": false, "aspectRatio": 0.75 },
{ "id": "5678", "path": "uuid/lit.jpg", "alt": "Lit", "isVideo": false, "aspectRatio": 0.75 }
],
"primaryMediaId": "1234",
"options": [],
"variants": [],
"categories": [
{ "id": "cat_01HXY...", "name": "Candles", "slug": "candles" }
],
"reviewCount": 42,
"averageRating": 4.7,
"sortOrder": 0,
"createdAt": "2025-11-02T10:00:00Z",
"updatedAt": "2026-04-20T08:00:00Z"
}
}
/products/{product}/reviews
PUBLIC
120/min
List approved reviews for a product. Ordered most recent first.
Query params
| Champ | Type | Description |
|---|---|---|
page
|
integer · optional | Page number. |
perPage
|
integer · optional | Items per page. |
curl https://api.shoprocket.io/v3/public/pk_live_.../products/prod_01HXY.../reviews \
-H "Authorization: Bearer pk_live_..."
{
"data": [
{
"id": "prev_01HXY...",
"rating": 5,
"title": "Best candle I've bought",
"body": "Smells incredible and the burn is clean.",
"authorName": "Sam B.",
"verifiedPurchase": true,
"createdAt": "2026-03-14T09:00:00Z"
}
],
"meta": {
"currentPage": 1,
"perPage": 20,
"total": 42,
"lastPage": 3,
"averageRating": 4.7,
"ratingCount": 42
}
}
/products/{product}/reviews
PUBLIC
5/min
Submit a review for a product. Reviews enter moderation; they are not public until approved.
Body
| Champ | Type | Description |
|---|---|---|
rating
|
integer · required | 1 to 5. |
title
|
string · optional | Short headline. |
body
|
string · required | Review body. |
authorName
|
string · optional | Display name. Falls back to the authenticated customer name if omitted. |
authorEmail
|
string · optional | Email for guest reviews. Required when not authenticated. |
curl -X POST https://api.shoprocket.io/v3/public/pk_live_.../products/prod_01HXY.../reviews \
-H "Authorization: Bearer pk_live_..." \
-H "Content-Type: application/json" \
-d '{
"rating": 5,
"title": "Love it",
"body": "Smells incredible.",
"authorName": "Sam B.",
"authorEmail": "[email protected]"
}'
{
"data": {
"id": "prev_01HXY...",
"status": "pending_moderation",
"createdAt": "2026-04-20T13:00:00Z"
}
}
/categories
PUBLIC
120/min
List published categories, including nested children.
curl https://api.shoprocket.io/v3/public/pk_live_.../categories \
-H "Authorization: Bearer pk_live_..."
{
"data": [
{
"id": "cat_01HXY...",
"slug": "candles",
"name": "Candles",
"description": "All scented candles.",
"imageUrl": "https://cdn.shoprocket.io/...",
"parentId": null,
"productCount": 34,
"children": [
{
"id": "cat_02KLM...",
"slug": "soy-wax",
"name": "Soy wax",
"parentId": "cat_01HXY...",
"productCount": 12
}
]
}
]
}
/categories/{category}
PUBLIC
120/min
Fetch a single category by id or slug. Use the Products list endpoint with ?category=slug to list products in a category.
curl https://api.shoprocket.io/v3/public/pk_live_.../categories/candles \
-H "Authorization: Bearer pk_live_..."
{
"data": {
"id": "cat_01HXY...",
"slug": "candles",
"name": "Candles",
"description": "All scented candles.",
"imageUrl": "https://cdn.shoprocket.io/...",
"parentId": null,
"productCount": 34,
"metaTitle": "Scented candles | Acme",
"metaDescription": "Hand-poured scented candles."
}
}
/orders/{order}
PUBLIC
60/min
Fetch a public view of an order. Accessible without authentication if the cart token that created the order is presented; used for the post-checkout confirmation page.
Returns a reduced Order object without sensitive internal fields.
curl https://api.shoprocket.io/v3/public/pk_live_.../orders/ord_01HXYZ... \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..."
{
"data": {
"id": "ord_01HXYZ...",
"orderNumber": "1024",
"paymentStatus": "paid",
"fulfillmentStatus": "unfulfilled",
"currency": "GBP",
"totals": {
"total": { "amount": 12400, "currency": "GBP", "formatted": "£124.00" }
},
"items": [
{ "productName": "Hand-poured candle", "quantity": 2, "subtotal": { "amount": 4800, "currency": "GBP", "formatted": "£48.00" } }
],
"shippingAddress": {
"line1": "221B Baker Street", "city": "London", "postcode": "NW1 6XE", "countryCode": "GB"
},
"createdAt": "2026-04-20T13:24:11Z"
}
}
/orders/{order}/status
PUBLIC
120/min
Poll for an order status update. Cheaper than Get order when all you need is the current state. Useful for thank-you pages waiting on 3DS or async payment confirmation.
curl https://api.shoprocket.io/v3/public/pk_live_.../orders/ord_01HXYZ.../status \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..."
{
"data": {
"paymentStatus": "succeeded",
"fulfillmentStatus": "unfulfilled",
"updatedAt": "2026-04-20T13:24:18Z"
}
}
/countries
PUBLIC
120/min
List countries you ship to. Each entry indicates whether states/regions need to be collected.
curl https://api.shoprocket.io/v3/public/pk_live_.../countries \
-H "Authorization: Bearer pk_live_..."
{
"data": [
{ "code": "GB", "name": "United Kingdom", "requiresState": false, "postcodeLabel": "Postcode" },
{ "code": "US", "name": "United States", "requiresState": true, "postcodeLabel": "ZIP code" },
{ "code": "DE", "name": "Germany", "requiresState": false, "postcodeLabel": "PLZ" }
]
}
/countries/{country_code}/states
PUBLIC
120/min
List states or regions for a country. Use the codes returned here for the state field on address inputs.
curl https://api.shoprocket.io/v3/public/pk_live_.../countries/US/states \
-H "Authorization: Bearer pk_live_..."
{
"data": [
{ "code": "CA", "name": "California" },
{ "code": "NY", "name": "New York" },
{ "code": "TX", "name": "Texas" }
]
}
/tax/calculate
PUBLIC
120/min
Calculate tax for an arbitrary basket and destination, without touching the cart. Useful for price-with-tax displays on product and category pages.
Body
| Champ | Type | Description |
|---|---|---|
items
|
array · required |
Array of {'{ productId, variantId?, quantity }'} entries.
|
countryCode
|
string · required | Destination country. |
state
|
string · optional | Destination state or region. |
postcode
|
string · optional | Destination postcode. Improves accuracy for US and Canada. |
curl -X POST https://api.shoprocket.io/v3/public/pk_live_.../tax/calculate \
-H "Authorization: Bearer pk_live_..." \
-H "Content-Type: application/json" \
-d '{
"items": [{"productId": "prod_01HXY...", "quantity": 2}],
"countryCode": "GB"
}'
{
"data": {
"subtotal": { "amount": 4800, "currency": "GBP", "formatted": "£48.00" },
"tax": { "amount": 960, "currency": "GBP", "formatted": "£9.60" },
"taxRate": 0.20,
"taxBreakdown": [
{ "name": "VAT", "rate": 0.20, "amount": { "amount": 960, "currency": "GBP", "formatted": "£9.60" }, "jurisdiction": "GB" }
]
}
}
/payment-methods
PUBLIC
120/min
List payment methods enabled on this store. Order is meaningful: render in the order returned.
curl https://api.shoprocket.io/v3/public/pk_live_.../payment-methods \
-H "Authorization: Bearer pk_live_..."
{
"data": [
{ "id": "card", "label": "Card", "iconUrl": "https://cdn.shoprocket.io/pm/card.svg" },
{ "id": "apple_pay", "label": "Apple Pay", "iconUrl": "https://cdn.shoprocket.io/pm/apple-pay.svg" },
{ "id": "google_pay", "label": "Google Pay", "iconUrl": "https://cdn.shoprocket.io/pm/google-pay.svg" },
{ "id": "bank_transfer", "label": "Bank transfer","iconUrl": "https://cdn.shoprocket.io/pm/bank.svg" }
]
}
/conversations
PUBLIC
10/min
Start a conversation between a visitor and the store inbox. Returns the conversation id, used for subsequent message calls.
Body
| Champ | Type | Description |
|---|---|---|
subject
|
string · optional | Short topic string. Shown in the seller inbox. |
initialMessage
|
string · optional | First message from the visitor. If provided, an initial message is posted immediately. |
curl -X POST https://api.shoprocket.io/v3/public/pk_live_.../conversations \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..." \
-H "Content-Type: application/json" \
-d '{
"subject": "Question about shipping",
"initialMessage": "Do you ship to Norway?"
}'
{
"data": {
"id": "conv_01HXY...",
"subject": "Question about shipping",
"createdAt": "2026-04-20T12:00:00Z"
}
}
/conversations/current
PUBLIC
120/min
Fetch the current (most recent open) conversation for this visitor. Returns 404 if none exists yet.
curl https://api.shoprocket.io/v3/public/pk_live_.../conversations/current \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..."
{
"data": {
"id": "conv_01HXY...",
"subject": "Question about shipping",
"unreadCount": 1,
"lastMessageAt": "2026-04-20T12:05:00Z"
}
}
/conversations/{conversationId}/email
PUBLIC
30/min
Attach a visitor email to a conversation so replies can be emailed when the site is closed.
Body
| Champ | Type | Description |
|---|---|---|
email
|
string · required | Visitor email. |
curl -X POST https://api.shoprocket.io/v3/public/pk_live_.../conversations/conv_01HXY.../email \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..." \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'
{
"data": { "id": "conv_01HXY...", "email": "[email protected]" }
}
/conversations/{conversationId}/messages
PUBLIC
120/min
List messages in a conversation, oldest first.
curl https://api.shoprocket.io/v3/public/pk_live_.../conversations/conv_01HXY.../messages \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..."
{
"data": [
{
"id": "cmsg_01HXY...",
"sender": "visitor",
"body": "Do you ship to Norway?",
"createdAt": "2026-04-20T12:00:00Z"
},
{
"id": "cmsg_02KLM...",
"sender": "seller",
"body": "Yes, 5-7 days by tracked post.",
"createdAt": "2026-04-20T12:05:00Z"
}
]
}
/conversations/{conversationId}/messages
PUBLIC
30/min
Post a new message to a conversation as the visitor.
Body
| Champ | Type | Description |
|---|---|---|
body
|
string · required | Message body. Plain text, max 4000 characters. |
curl -X POST https://api.shoprocket.io/v3/public/pk_live_.../conversations/conv_01HXY.../messages \
-H "Authorization: Bearer pk_live_..." \
-H "X-Cart-Token: 01HXYZABC..." \
-H "Content-Type: application/json" \
-d '{"body": "Great, thanks!"}'
{
"data": {
"id": "cmsg_03XYZ...",
"sender": "visitor",
"body": "Great, thanks!",
"createdAt": "2026-04-20T12:07:00Z"
}
}
/feeds/{platform}.xml
PUBLIC
30/min
Download an XML product feed for an advertising platform. Supported platforms: google, facebook, pinterest, tiktok. Not a REST endpoint in the usual sense; returns an XML document.
Path params
| Champ | Type | Description |
|---|---|---|
platform
|
string · required | One of: google, facebook, pinterest, tiktok. |
curl https://api.shoprocket.io/v3/public/pk_live_.../feeds/google.xml \
-H "Authorization: Bearer pk_live_..."
<?xml version="1.0"?>
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">
<channel>
<title>Acme Candles</title>
<item>
<g:id>prod_01HXY...</g:id>
<g:title>Hand-poured candle</g:title>
<g:price>24.00 GBP</g:price>
<g:availability>in_stock</g:availability>
</item>
</channel>
</rss>
Private, secret key
API privé
The Private API powers your server-side integrations. Authenticate with a secret key (sk_live_... or sk_test_...). Never ship a secret key to a browser.
Most endpoints in this section are marked TODO: the spec is finalised but the endpoints are not yet implemented. They represent the roadmap we are building toward.
Base URL: https://api.shoprocket.io/v3/private
Authentication: Authorization: Bearer sk_live_...
/products
PRIVATE
TODO
Auth required
240/min
List products in the catalogue. Includes unpublished products, drafts, and archived.
Query params
| Champ | Type | Description |
|---|---|---|
status
|
string · optional | One of: draft, published, archived. Omit for all. |
q
|
string · optional | Free-text search. |
updatedAfter
|
string · optional | ISO 8601. Returns products updated at or after this time. Useful for incremental syncs. |
page
|
integer · optional | Page number. |
perPage
|
integer · optional | Items per page (max 100). |
curl "https://api.shoprocket.io/v3/private/products?status=published&perPage=2" \
-H "Authorization: Bearer sk_live_..."
{
"data": [
{
"id": "prod_01HXY...",
"slug": "hand-poured-candle",
"name": "Hand-poured candle",
"status": "published",
"price": { "amount": 2400, "currency": "GBP", "formatted": "£24.00" },
"inStock": true,
"inventoryCount": 47,
"createdAt": "2025-11-02T10:00:00Z",
"updatedAt": "2026-04-20T08:00:00Z"
}
],
"meta": { "currentPage": 1, "perPage": 2, "total": 318, "lastPage": 159 }
}
/products
PRIVATE
TODO
Auth required
120/min
Create a new product. Returns the created product with its server-assigned id.
Body
| Champ | Type | Description |
|---|---|---|
name
|
string · required | Product name. |
description
|
string · optional | Long-form product description. Markdown supported. |
price
|
integer · required | Base price in minor units of the store currency. |
stock
|
integer · optional | Initial stock level. Defaults to 0. |
status
|
string · optional | draft or published. Defaults to draft. |
slug
|
string · optional | URL slug. Auto-generated from name if omitted. |
categoryIds
|
array · optional | Array of category ids to assign. |
metadata
|
object · optional | Arbitrary key/value pairs for your own use. Returned on every fetch. |
curl -X POST https://api.shoprocket.io/v3/private/products \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Hand-poured candle",
"price": 2400,
"stock": 50,
"status": "published"
}'
{
"data": {
"id": "prod_01HXY...",
"slug": "hand-poured-candle",
"name": "Hand-poured candle",
"status": "published",
"price": { "amount": 2400, "currency": "GBP", "formatted": "£24.00" },
"inventoryCount": 50,
"createdAt": "2026-04-20T12:00:00Z"
}
}
/products/{product}
PRIVATE
TODO
Auth required
240/min
Fetch a single product including all internal fields (cost, supplier, draft content).
Returns a private-view Product object.
curl https://api.shoprocket.io/v3/private/products/prod_01HXY... \
-H "Authorization: Bearer sk_live_..."
{
"data": {
"id": "prod_01HXY...",
"slug": "hand-poured-candle",
"name": "Hand-poured candle",
"description": "Soy wax, 60 hours burn time.",
"status": "published",
"price": { "amount": 2400, "currency": "GBP", "formatted": "£24.00" },
"cost": { "amount": 780, "currency": "GBP", "formatted": "£7.80" },
"inventoryCount": 47,
"sku": "CANDLE-001",
"barcode": "5012345678900",
"weightGrams": 340,
"variants": [],
"media": [{ "id": "1234", "path": "uuid/front.jpg", "alt": "Front" }],
"categories": [{ "id": "cat_01HXY...", "slug": "candles" }],
"metadata": {},
"createdAt": "2025-11-02T10:00:00Z",
"updatedAt": "2026-04-20T08:00:00Z"
}
}
/products/{product}
PRIVATE
TODO
Auth required
120/min
Update any subset of product fields. Only fields sent are changed.
curl -X PATCH https://api.shoprocket.io/v3/private/products/prod_01HXY... \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"price": 2600}'
{
"data": {
"id": "prod_01HXY...",
"price": { "amount": 2600, "currency": "GBP", "formatted": "£26.00" },
"updatedAt": "2026-04-20T12:15:00Z"
}
}
/products/{product}
PRIVATE
TODO
Auth required
60/min
Archive a product. Soft-delete only: the product is removed from the storefront but preserved for historical orders. Returns 204.
curl -X DELETE https://api.shoprocket.io/v3/private/products/prod_01HXY... \
-H "Authorization: Bearer sk_live_..."
(no body)
/products/{product}/inventory
PRIVATE
TODO
Auth required
240/min
Set, increment, or decrement stock for a product or variant. Dedicated endpoint so high-frequency inventory syncs do not conflict with product edits.
Body
| Champ | Type | Description |
|---|---|---|
variantId
|
string · optional | Variant to adjust. Omit for simple products. |
operation
|
string · required | One of: set, increment, decrement. |
quantity
|
integer · required | Amount to set, add, or subtract. Non-negative. |
reason
|
string · optional | Audit note (e.g. "stock take", "return"). |
curl -X PATCH https://api.shoprocket.io/v3/private/products/prod_01HXY.../inventory \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"operation": "increment", "quantity": 50, "reason": "Restock"}'
{
"data": {
"productId": "prod_01HXY...",
"stockBefore": 47,
"stockAfter": 97,
"updatedAt": "2026-04-20T12:20:00Z"
}
}
/orders
PRIVATE
TODO
Auth required
240/min
List orders. Defaults to most recent first.
Query params
| Champ | Type | Description |
|---|---|---|
status
|
string · optional | Filter: pending, paid, fulfilled, refunded, cancelled. |
customerId
|
string · optional | Only orders belonging to this customer. |
createdAfter
|
string · optional | ISO 8601. |
createdBefore
|
string · optional | ISO 8601. |
page
|
integer · optional | Page number. |
perPage
|
integer · optional | Items per page (max 100). |
curl "https://api.shoprocket.io/v3/private/orders?status=paid&perPage=2" \
-H "Authorization: Bearer sk_live_..."
{
"data": [
{
"id": "ord_01HXYZ...",
"orderNumber": "1024",
"paymentStatus": "paid",
"fulfillmentStatus": "unfulfilled",
"currency": "GBP",
"totals": { "total": { "amount": 12400, "currency": "GBP", "formatted": "£124.00" } },
"customerEmail": "[email protected]",
"createdAt": "2026-04-20T13:24:11Z"
}
],
"meta": { "currentPage": 1, "perPage": 2, "total": 412, "lastPage": 206 }
}
/orders/{order}
PRIVATE
TODO
Auth required
240/min
Fetch a single order with full detail, including cost, payment gateway response, and internal notes.
Returns a private-view Order object.
curl https://api.shoprocket.io/v3/private/orders/ord_01HXYZ... \
-H "Authorization: Bearer sk_live_..."
{
"data": {
"id": "ord_01HXYZ...",
"orderNumber": "1024",
"type": "order",
"paymentStatus": "paid",
"fulfillmentStatus": "unfulfilled",
"currency": "GBP",
"totals": {
"subtotal": { "amount": 10400, "currency": "GBP", "formatted": "£104.00" },
"tax": { "amount": 2000, "currency": "GBP", "formatted": "£20.00" },
"shipping": { "amount": 0, "currency": "GBP", "formatted": "£0.00" },
"discount": { "amount": 0, "currency": "GBP", "formatted": "£0.00" },
"total": { "amount": 12400, "currency": "GBP", "formatted": "£124.00" }
},
"customer": {
"id": "cust_01HXY...",
"email": "[email protected]",
"firstName": "Sam",
"lastName": "Buyer"
},
"shippingAddress": { "line1": "221B Baker Street", "city": "London", "postcode": "NW1 6XE", "countryCode": "GB" },
"billingAddress": { "line1": "221B Baker Street", "city": "London", "postcode": "NW1 6XE", "countryCode": "GB" },
"items": [
{
"id": "oitm_01HXY...",
"productId": "prod_01HXY...",
"productName": "Hand-poured candle",
"sku": "CANDLE-001",
"quantity": 2,
"price": { "amount": 2400, "currency": "GBP", "formatted": "£24.00" },
"subtotal": { "amount": 4800, "currency": "GBP", "formatted": "£48.00" }
}
],
"payment": {
"gateway": "stripe",
"paymentIntentId": "pi_1XyZ...",
"status": "succeeded"
},
"internalNotes": null,
"metadata": {},
"createdAt": "2026-04-20T13:24:11Z",
"paidAt": "2026-04-20T13:24:18Z"
}
}
/orders/{order}
PRIVATE
TODO
Auth required
120/min
Update metadata, internal notes, or addresses on an order. Cannot change priced quantities: use dedicated fulfil/refund/cancel endpoints for those operations.
Body
| Champ | Type | Description |
|---|---|---|
internalNotes
|
string · optional | Free-text note visible to staff only. |
metadata
|
object · optional | Replace metadata entirely with this object. |
shippingAddress
|
object · optional | Update the shipping address. Allowed only before fulfilment. |
curl -X PATCH https://api.shoprocket.io/v3/private/orders/ord_01HXYZ... \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"internalNotes": "Called customer, confirmed delivery window"}'
{
"data": {
"id": "ord_01HXYZ...",
"internalNotes": "Called customer, confirmed delivery window",
"updatedAt": "2026-04-20T14:00:00Z"
}
}
/orders/{order}/fulfill
PRIVATE
TODO
Auth required
60/min
Mark an order as fulfilled. Optionally attach tracking details; the customer receives a fulfilment email.
Body
| Champ | Type | Description |
|---|---|---|
trackingNumber
|
string · optional | Carrier tracking number. |
trackingUrl
|
string · optional | Public tracking URL. |
carrier
|
string · optional | Carrier name (Royal Mail, UPS, DPD, etc.). |
notifyCustomer
|
boolean · optional | Send the fulfilment email. Default true. |
curl -X POST https://api.shoprocket.io/v3/private/orders/ord_01HXYZ.../fulfill \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"trackingNumber": "JD0002123456",
"carrier": "Royal Mail",
"trackingUrl": "https://royalmail.com/track/JD0002123456"
}'
{
"data": {
"id": "ord_01HXYZ...",
"fulfillmentStatus": "fulfilled",
"fulfilledAt": "2026-04-20T15:00:00Z"
}
}
/orders/{order}/refund
PRIVATE
TODO
Auth required
30/min
Refund all or part of an order. Processes the refund through the original payment gateway. Stock is restocked unless you pass restock: false.
Body
| Champ | Type | Description |
|---|---|---|
amount
|
integer · optional | Partial refund amount in minor units of the order currency. Omit or set equal to the order total for a full refund. |
reason
|
string · optional | One of: customer_request, duplicate, fraudulent, other. |
restock
|
boolean · optional | Whether to restock refunded items. Default true. |
notifyCustomer
|
boolean · optional | Send the refund email. Default true. |
curl -X POST https://api.shoprocket.io/v3/private/orders/ord_01HXYZ.../refund \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"amount": 2400, "reason": "customer_request"}'
{
"data": {
"id": "ord_01HXYZ...",
"paymentStatus": "partially_refunded",
"refunded": { "amount": 2400, "currency": "GBP", "formatted": "£24.00" },
"refund": {
"id": "ref_01HXY...",
"amount": { "amount": 2400, "currency": "GBP", "formatted": "£24.00" },
"reason": "customer_request",
"createdAt": "2026-04-20T16:00:00Z"
}
}
}
/orders/{order}/cancel
PRIVATE
TODO
Auth required
30/min
Cancel an unfulfilled order. Voids the payment (if captured) and restocks items.
Body
| Champ | Type | Description |
|---|---|---|
reason
|
string · optional | Internal note on why the order was cancelled. |
notifyCustomer
|
boolean · optional | Send the cancellation email. Default true. |
curl -X POST https://api.shoprocket.io/v3/private/orders/ord_01HXYZ.../cancel \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"reason": "Out of stock"}'
{
"data": {
"id": "ord_01HXYZ...",
"paymentStatus": "cancelled",
"cancelledAt": "2026-04-20T16:30:00Z"
}
}
/customers
PRIVATE
TODO
Auth required
240/min
List customers.
Query params
| Champ | Type | Description |
|---|---|---|
q
|
string · optional | Search name or email. |
createdAfter
|
string · optional | ISO 8601. |
page
|
integer · optional | Page number. |
perPage
|
integer · optional | Items per page. |
curl "https://api.shoprocket.io/v3/private/customers?q=buyer" \
-H "Authorization: Bearer sk_live_..."
{
"data": [
{
"id": "cust_01HXY...",
"email": "[email protected]",
"firstName": "Sam",
"lastName": "Buyer",
"totalOrders": 3,
"totalSpend": { "amount": 18400, "currency": "GBP", "formatted": "£184.00" },
"createdAt": "2025-11-02T10:00:00Z"
}
],
"meta": { "currentPage": 1, "perPage": 20, "total": 1247, "lastPage": 63 }
}
/customers/{customer}
PRIVATE
TODO
Auth required
240/min
Fetch a single customer with full order history summary and saved addresses.
Returns a private-view Customer object.
curl https://api.shoprocket.io/v3/private/customers/cust_01HXY... \
-H "Authorization: Bearer sk_live_..."
{
"data": {
"id": "cust_01HXY...",
"email": "[email protected]",
"firstName": "Sam",
"lastName": "Buyer",
"phone": "+447700900123",
"addresses": [
{
"id": "addr_01HXY...",
"line1": "221B Baker Street",
"city": "London",
"postcode": "NW1 6XE",
"countryCode": "GB",
"isDefault": true
}
],
"totalOrders": 3,
"totalSpend": { "amount": 18400, "currency": "GBP", "formatted": "£184.00" },
"tags": ["vip"],
"marketingOptIn": false,
"metadata": {},
"createdAt": "2025-11-02T10:00:00Z"
}
}
/customers/{customer}
PRIVATE
TODO
Auth required
120/min
Update a customer. Commonly used for tagging, metadata, and marketing preferences.
Body
| Champ | Type | Description |
|---|---|---|
tags
|
array · optional | Replace tags with this array. |
metadata
|
object · optional | Replace metadata entirely. |
marketingOptIn
|
boolean · optional | Set marketing preference. |
curl -X PATCH https://api.shoprocket.io/v3/private/customers/cust_01HXY... \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"tags": ["vip", "wholesale"]}'
{
"data": {
"id": "cust_01HXY...",
"tags": ["vip", "wholesale"],
"updatedAt": "2026-04-20T17:00:00Z"
}
}
/webhooks
PRIVATE
TODO
Auth required
60/min
List webhook endpoints configured for this store.
curl https://api.shoprocket.io/v3/private/webhooks \
-H "Authorization: Bearer sk_live_..."
{
"data": [
{
"id": "whk_01HXY...",
"url": "https://yoursite.com/hooks/shoprocket",
"events": ["order.paid", "order.refunded"],
"active": true,
"lastDeliveryAt": "2026-04-20T13:24:18Z",
"createdAt": "2025-11-15T10:00:00Z"
}
]
}
/webhooks
PRIVATE
TODO
Auth required
30/min
Register a webhook endpoint. The signing secret is returned once at creation time; store it and use it to verify incoming deliveries.
Body
| Champ | Type | Description |
|---|---|---|
url
|
string · required | HTTPS URL to receive deliveries. |
events
|
array · required | Array of event type strings. See the Webhooks guide. |
active
|
boolean · optional | Defaults to true. Set false to register without delivering. |
curl -X POST https://api.shoprocket.io/v3/private/webhooks \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://yoursite.com/hooks/shoprocket",
"events": ["order.paid", "order.refunded"]
}'
{
"data": {
"id": "whk_01HXY...",
"url": "https://yoursite.com/hooks/shoprocket",
"events": ["order.paid", "order.refunded"],
"active": true,
"signingSecret": "whsec_...",
"createdAt": "2026-04-20T18:00:00Z"
}
}
/webhooks/{webhook}
PRIVATE
TODO
Auth required
30/min
Delete a webhook endpoint. Returns 204.
curl -X DELETE https://api.shoprocket.io/v3/private/webhooks/whk_01HXY... \
-H "Authorization: Bearer sk_live_..."
(no body)
/store
PRIVATE
Auth required
240/min
Fetch the authenticated store configuration. Useful as a ping to verify your secret key is valid.
curl https://api.shoprocket.io/v3/private/store \
-H "Authorization: Bearer sk_live_..."
{
"data": {
"id": "str_01HXY...",
"name": "Acme Candles",
"currency": "GBP",
"timezone": "Europe/London",
"plan": "growth",
"createdAt": "2025-11-02T10:00:00Z"
}
}
/store
PRIVATE
TODO
Auth required
30/min
Update store-level settings (name, default currency, timezone, branding).
curl -X PATCH https://api.shoprocket.io/v3/private/store \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"name": "Acme Candles Ltd"}'
{
"data": {
"id": "str_01HXY...",
"name": "Acme Candles Ltd",
"updatedAt": "2026-04-20T18:30:00Z"
}
}
/health
PRIVATE
Auth required
600/min
Service health check. Returns 200 when all subsystems are operational. Use for integration heartbeats.
curl https://api.shoprocket.io/v3/private/health \
-H "Authorization: Bearer sk_live_..."
{
"data": {
"status": "ok",
"checks": {
"database": "ok",
"redis": "ok",
"queue": "ok",
"storage": "ok"
},
"time": "2026-04-20T18:45:00Z"
}
}
Reference
Objects
Reference of the core objects returned by the API. Endpoint examples above show realistic payloads; this section documents every field field-by-field so you can build typed clients, DB schemas, or mapping layers against a single source of truth. All keys are camelCase. All monetary values are Money objects.
The Money object
Every monetary value in a response is a Money object. The amount is always an integer in minor units (cents, pence, öre, etc.), so you never lose precision to floating point. The formatted string is pre-localised for display, honouring the request Accept-Language header.
Attributes
| Champ | Type | Description |
|---|---|---|
amount
|
integer · optional | Value in minor units of the currency. £1.00 is 100, $42.99 is 4299. Zero-decimal currencies like JPY use whole units (¥1000 is 1000). |
currency
|
string · optional | ISO 4217 currency code, upper-case. |
formatted
|
string · optional | Pre-formatted display string. Honours the Accept-Language header on the request. |
{
"amount": 4299,
"currency": "USD",
"formatted": "$42.99"
}
The Cart object
PUBLICRepresents an in-progress basket tied to a visitor session. Cart and Order share the same underlying model, so cart ids are prefixed ord_. A cart persists for 30 days of inactivity. Personal data (email, addresses) is stripped from API responses if the cart has been idle more than 2 hours, for privacy compliance.
Attributes
| Champ | Type | Description |
|---|---|---|
id
|
string · optional | Identifier, prefixed ord_ (Cart and Order share a model). |
type
|
string · optional | cart or order. Transitions to order on successful checkout. |
currency
|
string · optional | ISO 4217 currency. |
visitorCountry
|
string · optional | Detected visitor country (ISO 3166-1 alpha-2). Used for tax and shipping hints before the address is set. |
hasCheckoutData
|
boolean · optional | True once email and shipping address have been saved and are still within the 2-hour privacy window. |
hasShippingAddress
|
boolean · optional | Whether a shipping address has been attached. |
hasBillingAddress
|
boolean · optional | Whether a separate billing address has been attached. |
requiresShipping
|
boolean · optional | False when the cart is entirely digital. |
discountCode
|
string · optional | Applied discount code, or null. |
discountType
|
string · optional | percentage | fixed | free_shipping, or null. |
discountValue
|
number · optional | The discount value (20 for 20%, 500 for £5.00 off, etc.), or null. |
isAuthenticated
|
boolean · optional | True if the cart is tied to an authenticated customer. |
items
|
array · optional | Array of cart line items. Each has id, productId, variantId, productName, productSlug, variantName, quantity, price (Money), subtotal (Money), image, inStock, inventoryCount. |
totals
|
object · optional | Object with subtotal, tax, shipping, discount, total, each a Money object. |
shippingOption
|
object · optional | The selected shipping option, or null. Only present after the customer picks one. |
taxInclusive
|
boolean · optional | Whether tax is baked into item prices (EU-style) or added at checkout (US-style). |
taxBreakdown
|
array · optional | Per-jurisdiction tax breakdown (name, rate, amount Money, jurisdiction). |
customer
|
object · optional | Customer snapshot when authenticated or when checkout data has been saved. Contains customerId, email, firstName, lastName. |
order
|
object · optional | Only present when type is order, on the payment-return flow. Contains number, paymentStatus, fulfillmentStatus, paymentGateway, placedAt, customerNotes, termsAccepted, marketingOptIn. |
messages
|
array · optional | Warnings or info (stock-limited items, missing address) relevant to the current cart state. |
updatedAt
|
string · optional | ISO 8601 timestamp of the last mutation. |
Endpoints returning this object
GET /cart,POST /cart/items,PUT /cart/items/{id},DELETE /cart/items/{id}POST /cart/discount,DELETE /cart/discountPOST /cart/shipping-option
The Product object
A sellable item in the catalogue. Products can be simple (one SKU, one price), variant-based (multiple SKUs with per-variant price and stock), or bundles. The public view omits internal fields (cost, supplier, draft content) returned by the private view.
Attributes (public view)
| Champ | Type | Description |
|---|---|---|
id
|
string · optional | Product identifier, prefixed prod_. |
slug
|
string · optional | URL-safe identifier. Unique per store. |
name
|
string · optional | Display name. |
summary
|
string · optional | Short tagline. |
description
|
string · optional | Long-form description. Markdown. |
status
|
string · optional | draft | published | archived. |
productType
|
string · optional | physical | digital | bundle | subscription. |
featured
|
boolean · optional | Featured in marketing slots. |
digital
|
boolean · optional | True for purely digital products. |
trackInventory
|
boolean · optional | Whether stock is tracked. |
inStock
|
boolean · optional | Any variant has stock (or simple product stock > 0). |
inventoryCount
|
integer · optional | Total stock across variants. 0 for bundles. |
shippingType
|
string · optional | required | optional | none. |
price
|
object · optional | Rich price object with amount, originalAmount, currency, formatted, originalFormatted, inclusive, note, isOnSale, salePrice, salePriceFormatted, discountPercentage, saleName. |
priceMin
|
integer · optional | Minimum variant price in minor units. Equals price.amount for simple products. |
priceMax
|
integer · optional | Maximum variant price. |
hasVariants
|
boolean · optional | True if more than one variant exists. |
variantCount
|
integer · optional | Total number of variants. |
defaultVariantId
|
string · optional | Id of the default variant for simple products; null when variants require selection. |
variants
|
array · optional | Array of variant objects (id, sku, price, inStock, inventoryCount, optionValues, etc.). Empty for simple products. |
options
|
array · optional | Array of product options (id, name, position, values[]). Empty for simple products. |
media
|
array · optional | Array of media items (id, path, alt, isVideo, aspectRatio). |
primaryMediaId
|
string · optional | Id of the first media item. |
categories
|
array · optional | Categories this product belongs to (id, name, slug). |
reviewCount
|
integer · optional | Count of approved reviews. |
averageRating
|
number · optional | Mean rating across approved reviews, 1-decimal precision. |
minOrderQuantity
|
integer · optional | Minimum purchasable quantity. |
maxOrderQuantity
|
integer · optional | Maximum purchasable quantity, or null for unlimited. |
sortOrder
|
integer · optional | Display order within the catalog. |
createdAt
|
string · optional | ISO 8601 timestamp. |
updatedAt
|
string · optional | ISO 8601 timestamp. |
Private-only additions
| Champ | Type | Description |
|---|---|---|
cost
|
object · optional | Cost price as a Money object. Used for margin reporting. |
sku
|
string · optional | Stock-keeping unit. |
barcode
|
string · optional | UPC / EAN / ISBN. |
weightGrams
|
integer · optional | Physical weight for shipping calculations. |
metadata
|
object · optional | Arbitrary key/value pairs set by the store. |
Endpoints returning this object
- Public:
GET /products,GET /products/{id} - Private:
GET /products,GET /products/{id},POST /products,PATCH /products/{id}
The Order object
A completed or in-progress purchase. Orders originate from a cart and carry the purchased items, payment, shipping, and fulfilment state. The public view omits private-only fields like payment gateway responses and internal notes.
Attributes
| Champ | Type | Description |
|---|---|---|
id
|
string · optional | Order identifier, prefixed ord_. |
orderNumber
|
string · optional | Human-friendly sequential order number displayed to customers. |
type
|
string · optional | Always order (vs cart in the pre-checkout state). |
paymentStatus
|
string · optional | pending | paid | partially_refunded | refunded | failed | cancelled. |
fulfillmentStatus
|
string · optional | unfulfilled | partial | fulfilled. |
currency
|
string · optional | ISO 4217 currency the order was charged in. |
totals
|
object · optional | Object with subtotal, tax, shipping, discount, total, each a Money object. |
customer
|
object · optional | Customer snapshot at time of order (id, email, firstName, lastName). |
items
|
array · optional | Array of order line items. Each has id, productId, productName, sku, quantity, price (Money), subtotal (Money). |
shippingAddress
|
object · optional | An Address object. |
billingAddress
|
object · optional | An Address object. May equal shippingAddress. |
createdAt
|
string · optional | ISO 8601 timestamp. |
paidAt
|
string · optional | When payment was confirmed. Null if pending. |
fulfilledAt
|
string · optional | When the order was marked fulfilled. Null if unfulfilled. |
cancelledAt
|
string · optional | When the order was cancelled, if applicable. |
Private-only additions
| Champ | Type | Description |
|---|---|---|
payment
|
object · optional | Payment gateway details: gateway, paymentIntentId, status. |
refunded
|
object · optional | Total refunded to date as a Money object. |
internalNotes
|
string · optional | Staff-only notes. |
metadata
|
object · optional | Arbitrary key/value pairs. |
Endpoints returning this object
- Public:
GET /orders/{id},GET /account/orders,GET /account/orders/{id} - Private:
GET /orders,GET /orders/{id},PATCH /orders/{id}(and the fulfil/refund/cancel action endpoints)
The Customer object
A registered account. Guests who checkout without creating an account produce a customer record too, with authenticated set to false until they claim it via passwordless login.
Attributes
| Champ | Type | Description |
|---|---|---|
id
|
string · optional | Customer identifier, prefixed cust_. |
email
|
string · optional | Unique per store. |
firstName
|
string · optional | Given name. |
lastName
|
string · optional | Family name. |
phone
|
string · optional | E.164 phone number. |
defaultAddress
|
object · optional | The default shipping Address object, or null. |
marketingOptIn
|
boolean · optional | Marketing email preference. |
createdAt
|
string · optional | ISO 8601 timestamp. |
Private-only additions
| Champ | Type | Description |
|---|---|---|
addresses
|
array · optional | All saved addresses, each with isDefault flag. |
totalOrders
|
integer · optional | Lifetime order count. |
totalSpend
|
object · optional | Lifetime spend as a Money object in store currency. |
tags
|
array · optional | Free-form tag strings for segmentation. |
metadata
|
object · optional | Arbitrary key/value pairs. |
Endpoints returning this object
- Public:
GET /account/profile,PUT /account/profile - Private:
GET /customers,GET /customers/{id},PATCH /customers/{id}
The Address object
A postal address. Used for shipping, billing, and tax calculation. The state field is required for destinations where requiresState: true in the Countries list (e.g. US, CA, AU).
Attributes
| Champ | Type | Description |
|---|---|---|
id
|
string · optional | Address identifier on saved addresses, prefixed addr_. Omitted for single-use addresses on orders. |
firstName
|
string · optional | Recipient first name. |
lastName
|
string · optional | Recipient last name. |
company
|
string · optional | Business name where applicable. |
line1
|
string · optional | Street address, first line. |
line2
|
string · optional | Unit, apartment, building name. |
city
|
string · optional | City or locality. |
state
|
string · optional | ISO 3166-2 state/region code. Required in some countries. |
postcode
|
string · optional | Postcode or ZIP. |
countryCode
|
string · optional | ISO 3166-1 alpha-2 country code. |
phone
|
string · optional | E.164 phone for carrier delivery attempts. |
isDefault
|
boolean · optional | On saved customer addresses, indicates the default for checkout. |
Dernière mise à jour : 27 avril 2026
Full changelog →Stuck on something?
Our dev team replies fast. Email us with code samples or open chat for a quick question.
dev@shoprocket.io