The Bolder API v2 is a flat, hypermedia-driven REST API that eliminates the deep seller/shop nesting found in v1. Resources are accessible directly from the account root and automatically scoped to the authenticated account via JWT.
All requests require a Bearer JWT token in the Authorization header or as
the access_token query parameter.
Authorization: Bearer <token>
| Scope | Description |
|---|---|
admin |
Account-level admin — auto-scoped to own sellers & shops |
public |
Read-only storefront scope — requires shop_subdomains param |
Responses follow the HAL format.
All links are under _links and use the bld: CURIE namespace.
{
"_links": {
"curies": [{"name": "bld", "href": "https://api.onbolder.com/rels/{rel}", "templated": true}],
"self": {"href": "https://api.onbolder.com/v2/products/123"},
"bld:update_product": {"href": "https://api.onbolder.com/v2/products/123", "method": "put"}
}
}
shop_id passed as a query parameter for transactional resources (orders, contacts)./v2/shops/:shop_id/webhooks (they are inherently shop-specific).Returns the API entry point. Embeds the authenticated account's shops and
provides navigation links (_links) to all v2 resources.
The bld:all_products link is a URI template — expand it with search
parameters to list products.
{- "_class": [
- "root"
], - "account_id": 10,
- "account_status": "active",
- "uid": 42,
- "email": "admin@myshop.com",
- "user_name": "admin",
- "provider": "bolder",
- "scopes": "admin,public",
- "_links": {
- "bld:all_products": {
- "templated": true
}, - "bld:shop_orders": {
- "templated": true
}, - "bld:shop_contacts": {
- "templated": true
}
}, - "_embedded": {
- "shops": [
- {
- "id": 1,
- "name": "My Shop",
- "subdomain": "myshop",
- "url": "myshop.onbolder.com",
- "status": "active"
}
]
}
}Returns products scoped to the authenticated account.
Scope behaviour:
admin tokens: automatically scoped to the account's own sellers — no extra params needed.public tokens: shop_subdomains is required (prevents enumeration).| q | string Example: q=summer dress Full-text search query across product name and description. |
| status | string Default: "visible" Enum: "visible" "hidden" "all" Example: status=visible Filter by visibility. |
| page | integer >= 1 Default: 1 Example: page=1 |
| per_page | integer [ 1 .. 200 ] Default: 20 Example: per_page=20 |
| ids | string Example: ids=101,102,103 Comma-separated product IDs. |
| collections | string Example: collections=summer,featured Comma-separated collection slugs. Returns products belonging to all listed collections. |
| tags | string Example: tags=sale,new-arrival Comma-separated product tags to filter by. |
| sku | string Example: sku=SKU-001 Filter by exact variant SKU. |
| product_type_id | integer Example: product_type_id=5 Filter by product type ID. |
| price_gte | number Example: price_gte=10 Minimum sale price (inclusive). |
| price_lte | number Example: price_lte=100 Maximum sale price (inclusive). |
| stock_gte | integer Example: stock_gte=1 Minimum stock quantity (inclusive). Use |
| stock_lte | integer Example: stock_lte=50 Maximum stock quantity (inclusive). |
| created_on_gte | string <date-time> Example: created_on_gte=2024-01-01T00:00:00Z Products created on or after this ISO 8601 timestamp. |
| created_on_lte | string <date-time> Example: created_on_lte=2024-12-31T23:59:59Z Products created on or before this ISO 8601 timestamp. |
| updated_on_gte | string <date-time> Example: updated_on_gte=2024-06-01T00:00:00Z Products updated on or after this ISO 8601 timestamp. |
| updated_on_lte | string <date-time> Example: updated_on_lte=2024-12-31T23:59:59Z Products updated on or before this ISO 8601 timestamp. |
| sort | string Default: "created_on_desc" Enum: "created_on_asc" "created_on_desc" "updated_on_asc" "updated_on_desc" "price_asc" "price_desc" "model_asc" "model_desc" Example: sort=created_on_desc Sort order for results. |
| currency | string Example: currency=USD ISO 4217 currency code to filter by. |
| price_list_id | integer Example: price_list_id=7 Return prices from this price list instead of the default. |
| shop_subdomains | string Example: shop_subdomains=myshop Comma-separated shop subdomains.
Required for |
| suggest | boolean Default: false Return lightweight suggestion objects for autocomplete (fewer fields rendered). |
| exact | boolean Default: false When |
{- "_class": [
- "results",
- "products"
], - "total_items": 2,
- "per_page": 20,
- "page": 1,
- "_links": {
}, - "_embedded": {
- "items": [
- {
- "id": 101,
- "model": "Summer Dress",
- "slug": "summer-dress",
- "status": "visible",
- "price": 49.99,
- "regular_price": 69.99,
- "currency": "USD",
- "created_on": "2024-03-15T10:00:00Z",
- "_links": {
}
}, - {
- "id": 102,
- "model": "Linen Shirt",
- "slug": "linen-shirt",
- "status": "visible",
- "price": 35,
- "regular_price": 35,
- "currency": "USD",
- "created_on": "2024-02-10T08:30:00Z",
}
]
}
}Creates a product in the specified shop. shop_id must be a shop belonging to the authenticated account.
| shop_id required | integer ID of the shop (required on create) |
| title required | string Product name. Also accepted as |
| slug | string URL slug. Auto-generated from title if omitted. |
| status | string Default: "hidden" Enum: "visible" "hidden" "blocked" |
| class | string Default: "Product" Enum: "Product" "ProductBundle" "Subscription" "GiftCard" Product class. Defaults to |
| description | string |
| short_description | string |
| deliverable | boolean Whether the product requires physical delivery. Defaults to |
| tracks_stock | boolean Whether stock is tracked for this product's variants. |
| has_prices_per_variant | boolean Required when variants have different prices. Must be |
| has_weights_per_variant | boolean Whether variants carry individual weights. |
| regular_price | integer Regular price in cents, applied to all variants (for non-bundle products). Use per-variant |
| sale_price | integer Sale price in cents, applied to all variants. |
| sale_price_starts_at | string <date-time> ISO 8601 datetime when the sale price activates. |
| sale_price_ends_at | string <date-time> ISO 8601 datetime when the sale price expires. |
| product_type_name | string Product type name. Created automatically if it doesn't exist. |
| vendor_name | string Vendor name. Created automatically if it doesn't exist. |
| tags | Array of strings Tag names. Replaces all existing tags unless |
| cart_quantity_multiple | integer Enforces cart quantities to be multiples of this value. |
object Names for up to 3 variant option axes (e.g. "Color", "Size"). | |
Array of objects (VariantInput) Variant definitions. By default, variants not present in the array are removed; set | |
Array of objects Collections to assign the product to. Pass | |
Array of objects Custom meta-field attributes. | |
object Control update behaviour. All flags default to |
{- "shop_id": 1,
- "model": "Organic Cotton Tee",
- "slug": "organic-cotton-tee",
- "status": "visible",
- "variant_sale_price": 29.99,
- "variant_regular_price": 39.99
}{- "id": 103,
- "model": "Organic Cotton Tee",
- "slug": "organic-cotton-tee",
- "status": "visible",
- "price": 29.99,
- "regular_price": 39.99,
- "currency": "USD",
- "created_on": "2024-06-20T14:22:00Z",
- "_links": {
}
}{- "id": 101,
- "title": "Wireless Headphones",
- "slug": "wireless-headphones",
- "status": "public",
- "price": 89.99,
- "compare_at_price": 119.99,
- "currency": "USD",
- "description": "Premium wireless headphones with noise cancellation.",
- "tags": [
- "electronics",
- "audio"
], - "_links": {
}
}Updates the product. If a product with the given ID/slug does not exist and
dont_create is not set, a new product will be created (upsert).
| id required | string Product ID or slug |
| shop_id required | integer ID of the shop (required on create) |
| title required | string Product name. Also accepted as |
| slug | string URL slug. Auto-generated from title if omitted. |
| status | string Default: "hidden" Enum: "visible" "hidden" "blocked" |
| class | string Default: "Product" Enum: "Product" "ProductBundle" "Subscription" "GiftCard" Product class. Defaults to |
| description | string |
| short_description | string |
| deliverable | boolean Whether the product requires physical delivery. Defaults to |
| tracks_stock | boolean Whether stock is tracked for this product's variants. |
| has_prices_per_variant | boolean Required when variants have different prices. Must be |
| has_weights_per_variant | boolean Whether variants carry individual weights. |
| regular_price | integer Regular price in cents, applied to all variants (for non-bundle products). Use per-variant |
| sale_price | integer Sale price in cents, applied to all variants. |
| sale_price_starts_at | string <date-time> ISO 8601 datetime when the sale price activates. |
| sale_price_ends_at | string <date-time> ISO 8601 datetime when the sale price expires. |
| product_type_name | string Product type name. Created automatically if it doesn't exist. |
| vendor_name | string Vendor name. Created automatically if it doesn't exist. |
| tags | Array of strings Tag names. Replaces all existing tags unless |
| cart_quantity_multiple | integer Enforces cart quantities to be multiples of this value. |
object Names for up to 3 variant option axes (e.g. "Color", "Size"). | |
Array of objects (VariantInput) Variant definitions. By default, variants not present in the array are removed; set | |
Array of objects Collections to assign the product to. Pass | |
Array of objects Custom meta-field attributes. | |
object Control update behaviour. All flags default to |
{- "title": "Wireless Headphones Pro",
- "price": 99.99,
- "compare_at_price": 129.99,
- "status": "public",
- "description": "Updated premium wireless headphones.",
- "tags": [
- "electronics",
- "audio",
- "wireless"
]
}{- "id": 101,
- "title": "Wireless Headphones Pro",
- "slug": "wireless-headphones-pro",
- "status": "public",
- "price": 99.99,
- "compare_at_price": 129.99,
- "currency": "USD",
}Returns product types for a shop. shop_id is required.
| shop_id required | integer Example: shop_id=1 |
{- "_class": [
- "results",
- "productTypes"
], - "total_items": 3,
- "_embedded": {
- "items": [
- {
- "id": 1,
- "name": "Clothing",
- "slug": "clothing"
}
]
}
}Returns collections for a shop. shop_id is required.
| shop_id required | integer Example: shop_id=1 ID of the shop whose collections to list. |
| page | integer Default: 1 Example: page=1 |
| per_page | integer Default: 20 Example: per_page=20 |
{- "_class": [
- "results",
- "collections"
], - "total_items": 2,
- "per_page": 20,
- "page": 1,
- "_embedded": {
- "items": [
- {
- "id": 5,
- "name": "Summer Collection",
- "slug": "summer",
- "status": "active",
}
]
}
}Returns price lists for the authenticated account. A price list lets you override variant prices for specific customer groups or channels.
| seller_id | integer Example: seller_id=7 Filter price lists by seller ID. |
| currency | string Example: currency=EUR Filter price lists by currency code (ISO 4217). |
| page | integer >= 1 Default: 1 Example: page=1 |
| per_page | integer [ 1 .. 200 ] Default: 20 Example: per_page=20 |
{- "_class": [
- "results",
- "price_lists"
], - "total_items": 1,
- "per_page": 20,
- "page": 1,
- "_links": {
}, - "_embedded": {
- "items": [
- {
- "id": 10,
- "title": "Wholesale EUR",
- "currency": "EUR",
- "created_on": "2024-01-15T10:00:00Z",
}
]
}
}| seller_id required | integer The seller this price list belongs to. |
| title required | string Human-readable label for this price list. |
| currency | string ISO 4217 currency code (e.g. |
{- "seller_id": 7,
- "title": "Wholesale EUR",
- "currency": "EUR"
}{- "id": 10,
- "title": "Wholesale EUR",
- "currency": "EUR",
- "created_on": "2024-01-15T10:00:00Z",
- "_links": {
}
}{- "id": 10,
- "title": "Wholesale EUR",
- "currency": "EUR",
- "items_count": 42,
- "created_on": "2024-01-15T10:00:00Z",
- "_links": {
- "bld:add_price_item": {
- "method": "post"
},
}
}| id required | integer |
| title | string |
| currency | string |
{- "title": "Wholesale EUR - Revised"
}{- "id": 10,
- "title": "Wholesale EUR - Revised",
- "currency": "EUR",
}Returns shops belonging to the authenticated account.
| q | string Example: q=mystore Search shops by name or subdomain. |
| status | string Default: "all" Enum: "active" "inactive" "all" Example: status=active Filter by shop status. |
| page | integer >= 1 Default: 1 Example: page=1 |
| per_page | integer [ 1 .. 200 ] Default: 20 Example: per_page=20 |
{- "_class": [
- "results",
- "shops"
], - "total_items": 1,
- "per_page": 20,
- "page": 1,
- "_embedded": {
- "items": [
- {
- "id": 1,
- "name": "My Store",
- "subdomain": "mystore",
- "status": "active",
- "currency": "USD",
}
]
}
}{- "id": 1,
- "name": "My Store",
- "subdomain": "mystore",
- "status": "active",
- "currency": "USD",
- "country": "US",
- "_links": {
}
}{- "id": 1,
- "name": "My Store",
- "subdomain": "mystore",
- "currency": "USD",
- "country": "US",
- "tax_rate": 0.21,
- "shipping_zones": [
- "domestic",
- "international"
], - "payment_methods": [
- "credit_card",
- "paypal"
],
}| shop_id required | integer |
| topic | string Default: "all" Enum: "order_created" "order_updated" "order_cancelled" "product_created" "product_updated" "product_deleted" "contact_created" "contact_updated" "all" Example: topic=order_created Filter webhooks by subscribed event topic. |
| status | string Default: "all" Enum: "active" "failed" "all" Example: status=active Filter by webhook status. |
| page | integer >= 1 Default: 1 Example: page=1 |
| per_page | integer [ 1 .. 200 ] Default: 20 Example: per_page=20 |
{- "_class": [
- "results",
- "subscriptions"
], - "total_items": 1,
- "per_page": 20,
- "page": 1,
- "_links": {
}, - "_embedded": {
- "items": [
- {
- "id": 42,
- "topic": "order_created",
- "status": "active",
- "created_on": "2024-01-10T08:00:00Z",
}
]
}
}| shop_id required | integer |
| topic required | string Supported topics: |
| url required | string |
| notify_origin | boolean Default: true |
object |
{- "topic": "order_created",
- "secret": "mysecrettoken"
}{- "id": 42,
- "topic": "order_created",
- "status": "active",
- "created_on": "2024-01-10T08:00:00Z",
- "_links": {
}
}Sets a failed webhook back to active status.
| shop_id required | integer |
| id required | integer |
{- "id": 42,
- "topic": "order_created",
- "status": "active",
- "created_on": "2024-01-10T08:00:00Z",
}Returns orders for a shop. shop_id is required — it is passed as a
query parameter rather than being part of the URL path.
| shop_id required | integer Example: shop_id=1 ID of the shop whose orders to list. |
| status | string Default: "all" Enum: "open" "closed" "cancelled" "shipped" "all" Example: status=open Filter by order status. |
| page | integer >= 1 Default: 1 Example: page=1 |
| per_page | integer [ 1 .. 200 ] Default: 20 Example: per_page=20 |
| contact_email | string Example: contact_email=customer@example.com Filter orders by customer email address. |
| code | string Example: code=ORD-00042 Filter by exact order code (e.g. |
| created_on_gte | string <date-time> Example: created_on_gte=2024-01-01T00:00:00Z Orders placed on or after this ISO 8601 timestamp. |
| created_on_lte | string <date-time> Example: created_on_lte=2024-12-31T23:59:59Z Orders placed on or before this ISO 8601 timestamp. |
| updated_on_gte | string <date-time> Example: updated_on_gte=2024-06-01T00:00:00Z Orders last updated on or after this ISO 8601 timestamp. |
| sort | string Default: "created_on_desc" Enum: "created_on_asc" "created_on_desc" "updated_on_asc" "updated_on_desc" "total_asc" "total_desc" Example: sort=created_on_desc Sort order for results. |
{- "_class": [
- "results",
- "orders"
], - "total_items": 1,
- "per_page": 20,
- "page": 1,
- "_links": {
}, - "_embedded": {
- "items": [
- {
- "id": 5001,
- "code": "ORD-5001",
- "permalink": "ord-5001-abc123",
- "status": "open",
- "total": 84.99,
- "currency": "USD",
- "contact_email": "customer@example.com",
- "created_on": "2024-06-15T09:45:00Z",
- "_links": {
}
}
]
}
}| shop_id required | integer |
| contact_email | string |
| status | string |
Array of objects |
{- "shop_id": 1,
- "contact_email": "customer@example.com",
- "status": "open",
- "items": [
- {
- "product_id": 101,
- "quantity": 2
}, - {
- "product_id": 205,
- "quantity": 1
}
]
}{- "id": 5002,
- "code": "ORD-5002",
- "permalink": "ord-5002-xyz789",
- "status": "open",
- "total": 179.97,
- "currency": "USD",
- "contact_email": "customer@example.com",
- "created_on": "2024-06-20T14:30:00Z",
- "_links": {
}
}Direct access to an order by ID or permalink. No shop_id needed in the URL —
authorization is verified via the token's account ownership.
| id required | string Order ID or permalink |
{- "id": 5001,
- "code": "ORD-5001",
- "permalink": "ord-5001-abc123",
- "status": "open",
- "total": 84.99,
- "currency": "USD",
- "contact_email": "customer@example.com",
- "shipping_address": {
- "name": "Jane Smith",
- "address1": "123 Main St",
- "city": "Austin",
- "state": "TX",
- "zip": "78701",
- "country": "US"
}, - "created_on": "2024-06-15T09:45:00Z",
- "updated_on": "2024-06-15T09:45:00Z",
- "_links": {
}
}| id required | string Order ID or permalink |
| status | string Enum: "open" "closed" "cancelled" "shipped" |
| tracking_number | string |
| shipping_provider | string |
| notes | string |
{- "status": "shipped",
- "tracking_number": "1Z9999W99999999999",
- "shipping_provider": "UPS"
}{- "id": 5001,
- "code": "ORD-5001",
- "status": "shipped",
- "tracking_number": "1Z9999W99999999999",
- "shipping_provider": "UPS",
}shop_id is required as a query parameter.
| shop_id required | integer Example: shop_id=1 ID of the shop whose contacts to list. |
| q | string Example: q=jane Full-text search across name and email. |
string Example: email=jane@example.com Filter by exact email address. | |
| status | string Default: "all" Enum: "public" "private" "pending" "all" Example: status=private Filter by customer account status. |
| page | integer >= 1 Default: 1 Example: page=1 |
| per_page | integer [ 1 .. 200 ] Default: 20 Example: per_page=20 |
| created_on_gte | string <date-time> Example: created_on_gte=2024-01-01T00:00:00Z Contacts created on or after this ISO 8601 timestamp. |
| created_on_lte | string <date-time> Example: created_on_lte=2024-12-31T23:59:59Z Contacts created on or before this ISO 8601 timestamp. |
| sort | string Default: "created_on_desc" Enum: "created_on_asc" "created_on_desc" "name_asc" "name_desc" Example: sort=created_on_desc Sort order for results. |
{- "_class": [
- "results",
- "contacts"
], - "total_items": 1,
- "per_page": 20,
- "page": 1,
- "_links": {
- "bld:authenticate_customer": {
- "method": "post"
}, - "bld:reset_customer_password": {
- "method": "post"
}
}, - "_embedded": {
- "items": [
- {
- "id": 3001,
- "email": "jane@example.com",
- "first_name": "Jane",
- "last_name": "Smith",
- "status": "private",
- "phone_validated": false,
- "created_on": "2024-03-10T11:00:00Z",
- "_links": {
}
}
]
}
}| shop_id required | integer |
| email required | string |
| first_name | string |
| last_name | string |
| password | string |
{- "shop_id": 1,
- "email": "newcustomer@example.com",
- "first_name": "Jane",
- "last_name": "Smith"
}{- "id": 3001,
- "email": "newcustomer@example.com",
- "first_name": "Jane",
- "last_name": "Smith",
- "status": "public",
- "phone_validated": false,
- "created_on": "2024-06-20T14:00:00Z",
- "_links": {
- "orders": {
}
}
}{- "id": 3001,
- "email": "jane@example.com",
- "first_name": "Jane",
- "last_name": "Smith",
- "status": "private",
- "phone": "+15551234567",
- "phone_validated": true,
- "created_on": "2024-03-10T11:00:00Z",
- "_links": {
}
}| id required | integer |
| first_name | string |
| last_name | string |
string | |
| phone | string |
| notes | string |
{- "first_name": "Janet",
- "last_name": "Smith-Jones",
- "phone": "+15559876543"
}{- "id": 3001,
- "email": "jane@example.com",
- "first_name": "Janet",
- "last_name": "Smith-Jones",
- "phone": "+15559876543",
}Validates email + password credentials for a shop's customer account. Returns the contact entity with a session token on success. Does not require a merchant Bearer token — this endpoint is typically called from a storefront.
| shop_id required | integer ID of the shop the customer belongs to. |
| email required | string |
| password required | string |
{- "shop_id": 1,
- "email": "jane@example.com",
- "password": "s3cr3tpassword"
}{- "id": 3001,
- "email": "jane@example.com",
- "first_name": "Jane",
- "last_name": "Smith",
- "status": "private",
- "token": "eyJhbGciOiJIUzI1NiJ9...",
}Sends a password-reset email to the customer's address.
Returns 200 even if the email is not found, to avoid user enumeration.
Use the 422 response only for missing shop_id.
| shop_id required | integer |
| email required | string |
{- "shop_id": 1,
- "email": "jane@example.com"
}{- "message": "If that email is registered, a reset link has been sent."
}Completes the customer account activation flow by setting the initial
password. The token is sent to the customer's email after the
merchant triggers bld:start_customer_activation.
| token required | string Example: abc123def456ghi789 Activation token from the email link. |
| password required | string The new password for the account (min 8 chars). |
{- "password": "newSecureP@ss1"
}{- "id": 3001,
- "email": "jane@example.com",
- "status": "private",
}Returns discount promotions for a shop. Promotions apply percentage or
fixed-amount discounts via coupon codes or automatic rules.
shop_id is required.
| shop_id required | integer Example: shop_id=1 ID of the shop whose promotions to list. |
| status | string Default: "all" Enum: "active" "expired" "all" Example: status=active Filter by promotion status. |
| q | string Example: q=SUMMER20 Search by promotion name or code. |
| page | integer >= 1 Default: 1 Example: page=1 |
| per_page | integer [ 1 .. 200 ] Default: 20 Example: per_page=20 |
{- "_class": [
- "results",
- "promotions"
], - "total_items": 1,
- "per_page": 20,
- "page": 1,
- "_embedded": {
- "items": [
- {
- "id": 20,
- "title": "Summer Sale 20%",
- "code": "SUMMER20",
- "discount_type": "percentage",
- "discount_value": 20,
- "status": "active",
- "starts_at": "2024-06-01T00:00:00Z",
- "ends_at": "2024-08-31T23:59:59Z",
}
]
}
}Creates a new promotion for a shop. Promotions apply percentage or fixed-amount
discounts via coupon codes or automatic rules.
shop_id is required in the body.
| shop_id required | integer ID of the shop (required on create) |
| name required | string |
| status | string Default: "active" Enum: "active" "inactive" |
| cumulative | boolean Default: true Whether this promotion can stack with others. Defaults to |
| discount_type required | string Enum: "fixed" "percentage" "free-shipping" |
| discount required | number Discount value — a percentage (0–100) or a fixed amount in cents. |
| activation_mode required | string Enum: "code" "auto" "fulfillment" "payment" How the promotion is activated. |
| code | string Coupon code (required when |
| fulfillment_method | integer Fulfillment method ID (required when |
| payment_method_id | integer Payment method ID (required when |
| usage_limit | integer Maximum total redemptions. Unlimited if omitted. |
| per_user_limit | integer Maximum redemptions per customer. Unlimited if omitted. |
| starts_at | string <date-time> |
| expires_at | string <date-time> |
| price_range_from | integer Minimum order subtotal in cents for the promotion to apply. |
| price_range_to | integer Maximum order subtotal in cents for the promotion to apply. |
| product_range_from | integer Minimum number of qualifying products required in the cart. |
| product_range_to | integer Maximum number of qualifying products allowed in the cart. |
| product_discount_group_id | integer ID of the group whose products receive the discount. |
| product_discount_group_type | string Enum: "AllProducts" "AllBundles" "Collection" "ProductType" "Vendor" "Tag" "Product" |
| product_discount_group_filter_mode | string Enum: "all" "all_except" "single_cheapest" "single_most_expensive" "all_but_cheapest" "all_but_most_expensive" "cheapest_half" "most_expensive_half" "cheapest_third" "most_expensive_third" "cheapest_fourth" "most_expensive_fourth" "single_cheapest_from_count_group" "single_most_expensive_from_count_group" "cheapest_half_from_count_group" "most_expensive_half_from_count_group" "cheapest_third_from_count_group" "most_expensive_third_from_count_group" "cheapest_fourth_from_count_group" "most_expensive_fourth_from_count_group" Which items within the discount group receive the discount. |
| product_count_group_id | integer Group used to count qualifying products (for count-gated discounts). |
| product_count_group_type | string Enum: "AllProducts" "AllBundles" "Collection" "ProductType" "Vendor" "Tag" "Product" |
| price_list_id | integer Restrict the promotion to orders using this price list. |
| apply_tag | string Tag to apply to the order when this promotion is used. |
{- "shop_id": 1,
- "name": "Summer Sale",
- "code": "SUMMER20",
- "discount_type": "percentage",
- "discount": 20,
- "activation_mode": "code",
- "starts_at": "2024-06-01T00:00:00Z",
- "expires_at": "2024-08-31T23:59:59Z"
}{- "id": 20,
- "name": "Summer Sale",
- "code": "SUMMER20",
- "discount_type": "percentage",
- "discount": 20,
- "status": "active",
- "starts_at": "2024-06-01T00:00:00Z",
- "expires_at": "2024-08-31T23:59:59Z",
}Returns a single promotion by ID.
| id required | integer Example: 20 ID of the promotion to retrieve. |
{- "id": 20,
- "name": "Summer Sale",
- "code": "SUMMER20",
- "discount_type": "percentage",
- "discount": 20,
- "status": "active",
- "starts_at": "2024-06-01T00:00:00Z",
- "expires_at": "2024-08-31T23:59:59Z",
- "usage_count": 0,
}Updates an existing promotion.
| id required | integer Example: 20 ID of the promotion to update. |
| shop_id required | integer ID of the shop (required on create) |
| name required | string |
| status | string Default: "active" Enum: "active" "inactive" |
| cumulative | boolean Default: true Whether this promotion can stack with others. Defaults to |
| discount_type required | string Enum: "fixed" "percentage" "free-shipping" |
| discount required | number Discount value — a percentage (0–100) or a fixed amount in cents. |
| activation_mode required | string Enum: "code" "auto" "fulfillment" "payment" How the promotion is activated. |
| code | string Coupon code (required when |
| fulfillment_method | integer Fulfillment method ID (required when |
| payment_method_id | integer Payment method ID (required when |
| usage_limit | integer Maximum total redemptions. Unlimited if omitted. |
| per_user_limit | integer Maximum redemptions per customer. Unlimited if omitted. |
| starts_at | string <date-time> |
| expires_at | string <date-time> |
| price_range_from | integer Minimum order subtotal in cents for the promotion to apply. |
| price_range_to | integer Maximum order subtotal in cents for the promotion to apply. |
| product_range_from | integer Minimum number of qualifying products required in the cart. |
| product_range_to | integer Maximum number of qualifying products allowed in the cart. |
| product_discount_group_id | integer ID of the group whose products receive the discount. |
| product_discount_group_type | string Enum: "AllProducts" "AllBundles" "Collection" "ProductType" "Vendor" "Tag" "Product" |
| product_discount_group_filter_mode | string Enum: "all" "all_except" "single_cheapest" "single_most_expensive" "all_but_cheapest" "all_but_most_expensive" "cheapest_half" "most_expensive_half" "cheapest_third" "most_expensive_third" "cheapest_fourth" "most_expensive_fourth" "single_cheapest_from_count_group" "single_most_expensive_from_count_group" "cheapest_half_from_count_group" "most_expensive_half_from_count_group" "cheapest_third_from_count_group" "most_expensive_third_from_count_group" "cheapest_fourth_from_count_group" "most_expensive_fourth_from_count_group" Which items within the discount group receive the discount. |
| product_count_group_id | integer Group used to count qualifying products (for count-gated discounts). |
| product_count_group_type | string Enum: "AllProducts" "AllBundles" "Collection" "ProductType" "Vendor" "Tag" "Product" |
| price_list_id | integer Restrict the promotion to orders using this price list. |
| apply_tag | string Tag to apply to the order when this promotion is used. |
{- "name": "Summer Sale Extended",
- "discount": 25
}{- "id": 20,
- "name": "Summer Sale Extended",
- "discount": 25,
}Returns volume discount rules for a shop. Volume discounts automatically
apply tiered pricing when a customer orders above a quantity threshold.
shop_id is required.
| shop_id required | integer Example: shop_id=1 ID of the shop whose volume discounts to list. |
| page | integer >= 1 Default: 1 Example: page=1 |
| per_page | integer [ 1 .. 200 ] Default: 20 Example: per_page=20 |
{- "_class": [
- "results",
- "volume_discounts"
], - "total_items": 1,
- "per_page": 20,
- "page": 1,
- "_embedded": {
- "items": [
- {
- "id": 30,
- "title": "Buy 5+ get 10% off",
- "discount_type": "percentage",
- "discount_value": 10,
- "minimum_quantity": 5,
- "status": "active",
}
]
}
}Creates a new volume discount for a shop. Volume discounts automatically
apply tiered pricing when a customer orders above a quantity threshold.
shop_id is required in the body.
| shop_id required | integer ID of the shop to create the volume discount in |
| name required | string |
| discount_type | string Enum: "percentage" "fixed_amount" |
| apply_mode | string Enum: "each" "all" |
| repeating_tier | boolean |
Array of objects | |
| cumulative | boolean |
| cumulative_mode | string Enum: "compound" "flat" |
{- "shop_id": 1,
- "name": "Buy 5+ get 10% off",
- "discount_type": "percentage",
- "apply_mode": "each",
- "repeating_tier": false,
- "tiers": [
- {
- "quantity": 5,
- "discount": 10
}, - {
- "quantity": 10,
- "discount": 15
}, - {
- "quantity": 20,
- "discount": 20
}
]
}{- "id": 30,
- "name": "Buy 5+ get 10% off",
- "discount_type": "percentage",
- "apply_mode": "each",
- "tiers": [
- {
- "quantity": 5,
- "discount": 10
}, - {
- "quantity": 10,
- "discount": 15
}
], - "status": "active",
}Returns a single volume discount by ID.
| id required | integer Example: 30 ID of the volume discount to retrieve. |
{- "id": 30,
- "name": "Buy 5+ get 10% off",
- "discount_type": "percentage",
- "apply_mode": "each",
- "tiers": [
- {
- "quantity": 5,
- "discount": 10
}
], - "cumulative": false,
- "status": "active",
}Updates an existing volume discount.
| id required | integer Example: 30 ID of the volume discount to update. |
| shop_id required | integer ID of the shop to create the volume discount in |
| name required | string |
| discount_type | string Enum: "percentage" "fixed_amount" |
| apply_mode | string Enum: "each" "all" |
| repeating_tier | boolean |
Array of objects | |
| cumulative | boolean |
| cumulative_mode | string Enum: "compound" "flat" |
{- "tiers": [
- {
- "quantity": 5,
- "discount": 15
}
]
}{- "id": 30,
- "tiers": [
- {
- "quantity": 5,
- "discount": 15
}
],
}