Skip to content

Public API v2: Discount Code

B2B discount codes with conditions, a minimum purchase, usage limits and a shareable link.

Scopes discount-code:read, discount-code:write
Plan Every plan with Public API; otherwise 403
Takes effect Works at checkout as soon as it is saved; the code box updates at the next upload.

Every response has the same envelope (success, status, data, meta; see Responses). Returns below describes data. The examples are real calls; the rules were created disabled.

  • code is unique in the store, any case; a share-link path is unique among enabled links.
  • A code works at checkout as soon as it is saved; the code box and the share page update at the next upload.
  • Deleting a code is permanent and removes its usage report.

What every read returns. Lists come back as [] when empty, never null.

idstringread-only

Rule id.

namestring

Rule name.

statusenum

disabled rules are kept but not applied. One of disabled, enabled.

codestring

case_sensitiveboolean

value_typeenum

One of fixed, percentage.

discount_valuestring

discount_scopeenum

One of product, order, free_shipping.

CustomersCommon object

Who gets the rule.

Show fields

apply_toenum

all everyone, logged in or not · logged_in any logged-in customer · non_logged_in visitors who are not logged in · customer_ids the listed customers · customer_tags customers with any of the tags · company_location the listed B2B company locations. Accepted here: all, logged_in, non_logged_in, customer_ids, customer_tags.

customer_ids[string]

Used when apply_to is customer_ids; required and not empty then.

customer_tags[string]

Used when apply_to is customer_tags; required and not empty then.

exclude_fromenum

none (default) · customer_tags · customer_ids · company_location. Excluded customers stay out even when apply_to includes them. Accepted here: none, customer_tags, customer_ids.

exc_customer_tags[string]

Used when exclude_from is customer_tags.

exc_customers[string]

Used when exclude_from is customer_ids.

ProductsCommon object

Which products the rule covers.

Show fields

product_condition_typeenum

all every product · by_ids · by_collections · by_tags · by_variants. Accepted here: all, by_ids, by_collections, by_tags.

product_ids[string]

Used when the type is by_ids; required and not empty then.

product_collections[string]

Used when the type is by_collections; required and not empty then.

product_tags[string]

Used when the type is by_tags; required and not empty then.

minimum_purchaseobject

Show fields

typeenum

One of none, amount, quantity.

valuestring or null

usage_limitobject

Show fields

totalinteger or null

per_customerinteger or null

show_remainingboolean

total_usedintegerread-only

Orders that used the code. Read-only.

total_remaininginteger or nullread-only

Uses left under usage_limit.total, null without one. Read-only: every save resets it.

share_linkobject

Show fields

enabledboolean

pathstring or null

redirect_urlstring or null

ScheduleCommon object

When the rule applies.

Show fields

start_atstring

UTC date and time ending in Z; null or left out: starts at once.

end_atstring

After start_at; null or left out: never ends.

created_atstring or nullread-only

UTC, ending in Z.

updated_atstring or nullread-only

UTC, ending in Z.

The rule object
{
"id": "15",
"name": "VIP 10%",
"status": "disabled",
"code": "VIP10",
"case_sensitive": false,
"value_type": "percentage",
"discount_value": "10.00",
"discount_scope": "product",
"apply_to": "customer_tags",
"customer_ids": [],
"customer_tags": [
"vip"
],
"exclude_from": "customer_ids",
"exc_customer_tags": [],
"exc_customers": [
"7001"
],
"product_condition_type": "by_collections",
"product_ids": [],
"product_collections": [
"3001"
],
"product_tags": [],
"minimum_purchase": {
"type": "amount",
"value": "100.50"
},
"usage_limit": {
"total": 100,
"per_customer": 2,
"show_remaining": true
},
"total_used": 0,
"total_remaining": 100,
"share_link": {
"enabled": true,
"path": "b2b-discount/vip",
"redirect_url": "owner.myshopify.com/cart"
},
"start_at": "2026-11-01T00:00:00.000Z",
"end_at": "2026-12-01T00:00:00.000Z",
"created_at": "2026-10-21T09:35:14.000Z",
"updated_at": "2026-10-21T09:35:14.000Z"
}

List rules

GET/api/v2/discount-code/rules

Scope discount-code:readCost 10

List discount codes, newest first.

limitinteger

1–250, default 50. See Paging.

cursorstring

next_cursor or prev_cursor of the last page; leave out for the first page. Keep the same filters on every page.

filter_statusenum

One of disabled, enabled.

filter_namestring

Part of the name, any case. 1–200 characters.

filter_codestring

Part of the code, any case. 1–100 characters.

data[Rule]

The rules of this page; [] when there are none.

meta.paginationobject

limit, next_cursor, prev_cursor and links to the next and previous pages.

cURL
curl -X GET "https://solution-public-api.bss-b2b.solutions/api/v2/discount-code/rules?limit=2&filter_name=VIP" \
-H "X-API-Key: $B2B_API_KEY" \
-H "X-Shop-Domain: your-store.myshopify.com"

Create a rule

POST/api/v2/discount-code/rules

Scope discount-code:writeCost 11

Create a discount code.

The body of POST /rules, PUT /rules/{id} and each element of bulk-upsert (add id to replace a rule). PUT replaces the whole rule: optional fields left out go back to their defaults. Fields not listed here are refused with 422.

namestringrequired

Rule name. 1–200 characters.

statusenumrequired

disabled rules are kept but not applied. One of disabled, enabled.

codestringrequired

Unique in the shop, in any case. Changing it drops its per-customer usage. 1–100 characters.

case_sensitiveboolean

Default false.

value_typeenumrequired

  • fixed: A fixed amount off.
  • percentage: A percentage off (at most 100).

discount_valuestring

A percentage (0–100) or an amount. Not used, and optional, with free_shipping. Decimal string, up to 2 decimals.

discount_scopeenumrequired

  • product: The discount goes to the matching products.
  • order: The discount goes to the whole order.
  • free_shipping: Free shipping; no discount_value needed.

CustomersCommon objectrequired

Who gets the rule.

Show fields

apply_toenum

all everyone, logged in or not · logged_in any logged-in customer · non_logged_in visitors who are not logged in · customer_ids the listed customers · customer_tags customers with any of the tags · company_location the listed B2B company locations. Accepted here: all, logged_in, non_logged_in, customer_ids, customer_tags.

customer_ids[string]

Used when apply_to is customer_ids; required and not empty then.

customer_tags[string]

Used when apply_to is customer_tags; required and not empty then.

exclude_fromenum

none (default) · customer_tags · customer_ids · company_location. Excluded customers stay out even when apply_to includes them. Accepted here: none, customer_tags, customer_ids.

exc_customer_tags[string]

Used when exclude_from is customer_tags.

exc_customers[string]

Used when exclude_from is customer_ids.

ProductsCommon objectrequired

Which products the rule covers.

Show fields

product_condition_typeenum

all every product · by_ids · by_collections · by_tags · by_variants. Accepted here: all, by_ids, by_collections, by_tags.

product_ids[string]

Used when the type is by_ids; required and not empty then.

product_collections[string]

Used when the type is by_collections; required and not empty then.

product_tags[string]

Used when the type is by_tags; required and not empty then.

minimum_purchaseobject

Left out: none.

Show fields

typeenumrequired

One of none, amount, quantity.

valuestring

An amount in the shop currency, or a quantity. Required unless type is none. Decimal string, up to 2 decimals.

usage_limitobject

Left out: no limit.

Show fields

totalinteger

Uses of the code in all; null or left out: no limit. 0–2,147,483,647.

per_customerinteger

Uses per logged-in customer; null or left out: no limit. 0–2,147,483,647.

show_remainingboolean

Tell the customer how many uses are left. Default false.

share_linkobject

Left out: no share link.

Show fields

enabledbooleanrequired

pathstring

Required when enabled. Must be unique among the active links.

redirect_urlstring

Where the link lands. Required when enabled.

ScheduleCommon object

When the rule applies.

Show fields

start_atstring

UTC date and time ending in Z; null or left out: starts at once.

end_atstring

After start_at; null or left out: never ends.

dataRule

The new rule.

cURL
curl -X POST "https://solution-public-api.bss-b2b.solutions/api/v2/discount-code/rules" \
-H "X-API-Key: $B2B_API_KEY" \
-H "X-Shop-Domain: your-store.myshopify.com" \
-H "Content-Type: application/json" \
-d '{
"name": "VIP 10%",
"status": "disabled",
"code": "VIP10",
"value_type": "percentage",
"discount_value": "10",
"discount_scope": "product",
"apply_to": "customer_tags",
"customer_tags": [
"vip"
],
"exclude_from": "customer_ids",
"exc_customers": [
"7001"
],
"product_condition_type": "by_collections",
"product_collections": [
"3001"
],
"minimum_purchase": {
"type": "amount",
"value": "100.5"
},
"usage_limit": {
"total": 100,
"per_customer": 2,
"show_remaining": true
},
"share_link": {
"enabled": true,
"path": "b2b-discount/vip",
"redirect_url": "owner.myshopify.com/cart"
},
"start_at": "2026-11-01T00:00:00Z",
"end_at": "2026-12-01T00:00:00Z"
}'

Get a rule

GET/api/v2/discount-code/rules/{id}

Scope discount-code:readCost 10

Get a discount code.

idstringrequired

Rule id.

dataRule

The rule. An id that does not exist answers 404 RESOURCE_NOT_FOUND.

cURL
curl -X GET "https://solution-public-api.bss-b2b.solutions/api/v2/discount-code/rules/15" \
-H "X-API-Key: $B2B_API_KEY" \
-H "X-Shop-Domain: your-store.myshopify.com"

Replace a rule

PUT/api/v2/discount-code/rules/{id}

Scope discount-code:writeCost 11

Replace a discount code; optional fields left out go back to their defaults.

idstringrequired

Rule id.

The same fields as Create a rule.

dataRule

The rule after the change.

cURL
curl -X PUT "https://solution-public-api.bss-b2b.solutions/api/v2/discount-code/rules/15" \
-H "X-API-Key: $B2B_API_KEY" \
-H "X-Shop-Domain: your-store.myshopify.com" \
-H "Content-Type: application/json" \
-d '{
"name": "VIP 10% (updated)",
"status": "disabled",
"code": "VIP10",
"value_type": "percentage",
"discount_value": "10",
"discount_scope": "product",
"apply_to": "customer_tags",
"customer_tags": [
"vip"
],
"exclude_from": "customer_ids",
"exc_customers": [
"7001"
],
"product_condition_type": "by_collections",
"product_collections": [
"3001"
],
"minimum_purchase": {
"type": "amount",
"value": "100.5"
},
"usage_limit": {
"total": 100,
"per_customer": 2,
"show_remaining": true
},
"share_link": {
"enabled": true,
"path": "b2b-discount/vip",
"redirect_url": "owner.myshopify.com/cart"
},
"start_at": "2026-11-01T00:00:00Z",
"end_at": "2026-12-01T00:00:00Z"
}'

Delete a rule

DEL/api/v2/discount-code/rules/{id}

Scope discount-code:writeCost 11

Delete a discount code and its usage report.

idstringrequired

Rule id.

data.idstring

Id of the deleted rule.

data.deletedboolean

true.

cURL
curl -X DELETE "https://solution-public-api.bss-b2b.solutions/api/v2/discount-code/rules/15" \
-H "X-API-Key: $B2B_API_KEY" \
-H "X-Shop-Domain: your-store.myshopify.com"

Create or replace rules in bulk

POST/api/v2/discount-code/rules/bulk-upsert

Scope discount-code:writeCost ceil(10 + 0.4 × rules)

Create or replace up to 250 discount codes; each one succeeds or fails on its own.

See Bulk & idempotency.

rules[object]required

1–250 rules, each with the fields of Create a rule.

Show fields

idstring

Set it to replace that rule, as Replace a rule does; leave it out to create one.

data.results[object]

One entry per rule, in the order sent.

Show fields

indexinteger

Position of the rule in rules.

idstring

Rule id.

resultenum

created, updated or error.

errorobject

code and message, only when result is error.

data.summaryobject

total, succeeded, failed.

cURL
curl -X POST "https://solution-public-api.bss-b2b.solutions/api/v2/discount-code/rules/bulk-upsert" \
-H "X-API-Key: $B2B_API_KEY" \
-H "X-Shop-Domain: your-store.myshopify.com" \
-H "Content-Type: application/json" \
-d '{
"rules": [
{
"name": "VIP 10% B",
"status": "disabled",
"code": "VIP10",
"value_type": "percentage",
"discount_value": "10",
"discount_scope": "product",
"apply_to": "customer_tags",
"customer_tags": [
"vip"
],
"exclude_from": "customer_ids",
"exc_customers": [
"7001"
],
"product_condition_type": "by_collections",
"product_collections": [
"3001"
],
"minimum_purchase": {
"type": "amount",
"value": "100.5"
},
"usage_limit": {
"total": 100,
"per_customer": 2,
"show_remaining": true
},
"share_link": {
"enabled": true,
"path": "b2b-discount/vip",
"redirect_url": "owner.myshopify.com/cart"
},
"start_at": "2026-11-01T00:00:00Z",
"end_at": "2026-12-01T00:00:00Z"
},
{
"name": "VIP 10% (bulk)",
"status": "disabled",
"code": "VIP10",
"value_type": "percentage",
"discount_value": "10",
"discount_scope": "product",
"apply_to": "customer_tags",
"customer_tags": [
"vip"
],
"exclude_from": "customer_ids",
"exc_customers": [
"7001"
],
"product_condition_type": "by_collections",
"product_collections": [
"3001"
],
"minimum_purchase": {
"type": "amount",
"value": "100.5"
},
"usage_limit": {
"total": 100,
"per_customer": 2,
"show_remaining": true
},
"share_link": {
"enabled": true,
"path": "b2b-discount/vip",
"redirect_url": "owner.myshopify.com/cart"
},
"start_at": "2026-11-01T00:00:00Z",
"end_at": "2026-12-01T00:00:00Z",
"id": "15"
}
]
}'

Delete rules in bulk

POST/api/v2/discount-code/rules/bulk-delete

Scope discount-code:writeCost ceil(10 + 0.4 × rules)

Delete up to 250 discount codes; an unknown id fails on its own.

See Bulk & idempotency.

ids[string]required

1–250 rule ids.

data.results[object]

One entry per id: index, id, result (deleted or error) and error (code, message) when it failed.

data.summaryobject

total, succeeded, failed.

cURL
curl -X POST "https://solution-public-api.bss-b2b.solutions/api/v2/discount-code/rules/bulk-delete" \
-H "X-API-Key: $B2B_API_KEY" \
-H "X-Shop-Domain: your-store.myshopify.com" \
-H "Content-Type: application/json" \
-d '{
"ids": [
"999999999"
]
}'

Upload rules to the storefront

POST/api/v2/discount-code/rules/upload

Scope discount-code:writeCost 20

Upload the rules to the storefront, as the app does.

The body is empty. See Upload.

data.statusenum

uploaded, or partial_success when some rules did not reach the storefront.

data.skippedobject

capacity_exceeded, write_failed and rule_id_range; see Upload.

cURL
curl -X POST "https://solution-public-api.bss-b2b.solutions/api/v2/discount-code/rules/upload" \
-H "X-API-Key: $B2B_API_KEY" \
-H "X-Shop-Domain: your-store.myshopify.com"