Discount Groups

Group B2B customers and apply automatic percentage discounts

GET /admin/api/discount-groups

List every discount group ordered by name, each annotated with its member and rule counts. Rules and members themselves are not expanded here — fetch a single group for those.

GET /admin/api/discount-groups/{id}

Fetch a single discount group with its per-category rules (joined to category name and slug) and its customer members fully expanded.

POST /admin/api/discount-groups

Create a discount group. The optional default_percent_off_bp applies storewide unless overridden by a per-category rule. Returns only the new id; fetch the group to read it back.

PUT /admin/api/discount-groups/{id}

Partial update of a discount group. Omitted fields are left unchanged. For the nullable fields description and default_percent_off_bp, sending an explicit null clears the stored value, while omitting the key leaves it as-is. Returns the full updated group detail.

DELETE /admin/api/discount-groups/{id}

Permanently delete a discount group.

PUT /admin/api/discount-groups/{id}/rules

Full-replace the per-category discount rules for a group. The supplied list becomes the complete rule set — existing rules not present are removed, and an empty list clears all rules. Each rule overrides the group's default for products in that category. Read the rules back via GET /admin/api/discount-groups/{id}.

POST /admin/api/discount-groups/{id}/members

Add a customer to a discount group. This also flips the customer's is_b2b flag to true. List a group's current members via GET /admin/api/discount-groups/{id}.

DELETE /admin/api/discount-groups/{id}/members/{customer_id}

Remove a customer from a discount group. The customer's is_b2b flag stays true so they can be re-assigned to another group without losing B2B status — only the group assignment is cleared.

GET /admin/api/discount-groups

List every discount group ordered by name, each annotated with its member and rule counts. Rules and members themselves are not expanded here — fetch a single group for those.

Response 200

{
  "groups": [
    {
      "id": 1,
      "name": "Wholesale",
      "slug": "wholesale",
      "description": "Standard B2B reseller pricing.",
      "default_percent_off_bp": 1500,
      "member_count": 12,
      "rule_count": 3,
      "created_at": "2026-04-15T09:00:00Z",
      "updated_at": "2026-04-15T09:00:00Z"
    },
    {
      "id": 2,
      "name": "VIP Partners",
      "slug": "vip-partners",
      "description": null,
      "default_percent_off_bp": null,
      "member_count": 4,
      "rule_count": 0,
      "created_at": "2026-04-20T11:15:00Z",
      "updated_at": "2026-04-20T11:15:00Z"
    }
  ]
}

Example

curl "https://yourshop.zeroshop.io/admin/api/discount-groups" \
  -H "Authorization: Bearer zspat_..."
GET /admin/api/discount-groups/{id}

Fetch a single discount group with its per-category rules (joined to category name and slug) and its customer members fully expanded.

Response 200

{
  "id": 1,
  "name": "Wholesale",
  "slug": "wholesale",
  "description": "Standard B2B reseller pricing.",
  "default_percent_off_bp": 1500,
  "created_at": "2026-04-15T09:00:00Z",
  "updated_at": "2026-04-15T09:00:00Z",
  "rules": [
    {
      "category_id": 10,
      "category_name": "Footwear",
      "category_slug": "footwear",
      "percent_off_bp": 2000
    },
    {
      "category_id": 11,
      "category_name": "Accessories",
      "category_slug": "accessories",
      "percent_off_bp": 1000
    }
  ],
  "members": [
    {
      "id": 501,
      "name": "Acme Retail Ltd",
      "email": "orders@acme-retail.example"
    },
    {
      "id": 502,
      "name": "Globex Trading",
      "email": "buyer@globex.example"
    }
  ]
}

Example

curl "https://yourshop.zeroshop.io/admin/api/discount-groups/1" \
  -H "Authorization: Bearer zspat_..."
POST /admin/api/discount-groups

Create a discount group. The optional default_percent_off_bp applies storewide unless overridden by a per-category rule. Returns only the new id; fetch the group to read it back.

Request Body

{
  "name": "Wholesale",
  "slug": "wholesale",
  "description": "Standard B2B reseller pricing.",
  "default_percent_off_bp": 1500
}

Response 201

{
  "id": 7
}

Example

curl -X POST "https://yourshop.zeroshop.io/admin/api/discount-groups" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Wholesale",
    "slug": "wholesale",
    "description": "Standard B2B reseller pricing.",
    "default_percent_off_bp": 1500
  }'
PUT /admin/api/discount-groups/{id}

Partial update of a discount group. Omitted fields are left unchanged. For the nullable fields description and default_percent_off_bp, sending an explicit null clears the stored value, while omitting the key leaves it as-is. Returns the full updated group detail.

Request Body

{
  "default_percent_off_bp": 2000
}

Response 200

{
  "id": 1,
  "name": "Wholesale",
  "slug": "wholesale",
  "description": "Standard B2B reseller pricing.",
  "default_percent_off_bp": 2000,
  "created_at": "2026-04-15T09:00:00Z",
  "updated_at": "2026-05-03T10:05:00Z",
  "rules": [
    {
      "category_id": 10,
      "category_name": "Footwear",
      "category_slug": "footwear",
      "percent_off_bp": 2000
    }
  ],
  "members": [
    {
      "id": 501,
      "name": "Acme Retail Ltd",
      "email": "orders@acme-retail.example"
    }
  ]
}

Example

curl -X PUT "https://yourshop.zeroshop.io/admin/api/discount-groups/1" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{"default_percent_off_bp": 2000}'
DELETE /admin/api/discount-groups/{id}

Permanently delete a discount group.

Response 204

Example

curl -X DELETE "https://yourshop.zeroshop.io/admin/api/discount-groups/1" \
  -H "Authorization: Bearer zspat_..."
PUT /admin/api/discount-groups/{id}/rules

Full-replace the per-category discount rules for a group. The supplied list becomes the complete rule set — existing rules not present are removed, and an empty list clears all rules. Each rule overrides the group's default for products in that category. Read the rules back via GET /admin/api/discount-groups/{id}.

Request Body

{
  "rules": [
    {
      "category_id": 10,
      "percent_off_bp": 2000
    },
    {
      "category_id": 11,
      "percent_off_bp": 1000
    }
  ]
}

Response 204

Example

curl -X PUT "https://yourshop.zeroshop.io/admin/api/discount-groups/1/rules" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{
    "rules": [
      {"category_id": 10, "percent_off_bp": 2000},
      {"category_id": 11, "percent_off_bp": 1000}
    ]
  }'
POST /admin/api/discount-groups/{id}/members

Add a customer to a discount group. This also flips the customer's is_b2b flag to true. List a group's current members via GET /admin/api/discount-groups/{id}.

Request Body

{
  "customer_id": 501
}

Response 204

Example

curl -X POST "https://yourshop.zeroshop.io/admin/api/discount-groups/1/members" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{"customer_id": 501}'
DELETE /admin/api/discount-groups/{id}/members/{customer_id}

Remove a customer from a discount group. The customer's is_b2b flag stays true so they can be re-assigned to another group without losing B2B status — only the group assignment is cleared.

Response 204

Example

curl -X DELETE "https://yourshop.zeroshop.io/admin/api/discount-groups/1/members/501" \
  -H "Authorization: Bearer zspat_..."

We value your privacy

We use cookies for essential site functionality and, with your consent, analytics to understand how our platform is used. No personal data is shared with third parties. See our Privacy Policy for details.