Search Documentation

Search for a documentation page...

Bundles API

REST API endpoints for managing product bundles.

Bundles group existing product variants into a single purchasable package, sold at a discount versus buying each item separately. Each bundle is composed of one or more variants with a quantity and display position, plus an optional discountPercentage applied against the sum of the constituent prices.

List Bundles

GET /api/v1/bundles

Returns lightweight bundle list items (no full composition). Fetch a single bundle to get its constituent products.

Query Parameters

ParameterTypeDefaultDescription
limitnumber50Bundles per page (1-100)
offsetnumber0Bundles to skip
curl -H "Authorization: Bearer your_api_key" \
https://your-store.yns.store/api/v1/bundles

Response (200)

{
"data": [
{
"id": "0191abc0-1234-7def-8000-000000000001",
"name": "Starter Kit",
"slug": "starter-kit",
"summary": "Everything you need to get going",
"images": ["https://cdn.example.com/starter-kit.jpg"],
"status": "published",
"discountPercentage": 15,
"productCount": 3
}
],
"meta": {
"count": 1,
"offset": 0,
"limit": 50
}
}

Get Bundle

GET /api/v1/bundles/{id}

Returns a single bundle by UUID, including its constituent products.

curl -H "Authorization: Bearer your_api_key" \
https://your-store.yns.store/api/v1/bundles/0191abc0-1234-7def-8000-000000000001

Response (200)

{
"id": "0191abc0-1234-7def-8000-000000000001",
"name": "Starter Kit",
"slug": "starter-kit",
"summary": "Everything you need to get going",
"content": null,
"seo": {
"title": "Starter Kit",
"description": "Save 15% on the essentials"
},
"images": ["https://cdn.example.com/starter-kit.jpg"],
"status": "published",
"discountPercentage": 15,
"taxRate": {
"id": "0191abc0-0000-7000-8000-0000000000aa",
"name": "VAT 23%",
"rate": 23,
"label": null
},
"products": [
{
"variantId": "0191abc0-0000-7000-8000-000000000100",
"quantity": 1,
"position": 0,
"productId": "0191abc0-0000-7000-8000-000000000200",
"productName": "Classic Tee"
}
],
"createdAt": "2024-06-15T10:30:00.000Z"
}

Tax rate

taxRate is the bundle's own rate — the one a grouped bundle is taxed at, whatever rates its constituent products carry. null means the bundle sells untaxed. Set it with taxRateId on create or update, usually to the rate its items share.

FieldTypeDescription
taxRate.idstringTax rate UUID
taxRate.namestringTax rate name, e.g. VAT 23%
taxRate.ratenumberRate as a 0-100 percentage
taxRate.labelstring | nullOptional label shown to shoppers

Create Bundle

POST /api/v1/bundles

Creates a product bundle composed of existing variants. Slug is auto-generated from the name if omitted and must be unique.

Request Body

FieldTypeRequiredDescription
namestringYesBundle name
slugstringNoURL slug, lowercase (a-z0-9-); auto-generated from name if omitted
summarystringNoShort summary
seoobjectNoSEO metadata (title, description, canonical)
imagesstring[]NoBundle image URLs
discountPercentagenumberNoDiscount vs. the sum of constituent prices (0-100)
taxRateIdstringNoTax rate UUID applied to this bundle (create one with POST /api/v1/tax-rates); pass null to clear. A bundle without one sells untaxed
statusstringNoPublication status: draft, published, or hidden
variantsobject[]NoVariants that make up the bundle (see below)

Variant Object

FieldTypeRequiredDescription
variantIdstringYesVariant UUID to include in the bundle
quantitynumberNoHow many of this variant the bundle contains (default: 1)
positionnumberNoDisplay order within the bundle (default: 0)
curl -X POST \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Starter Kit",
"discountPercentage": 15,
"status": "published",
"variants": [
{ "variantId": "0191abc0-0000-7000-8000-000000000100", "quantity": 1, "position": 0 }
]
}' \
https://your-store.yns.store/api/v1/bundles

Response (201)

Returns the created bundle with full composition (same shape as Get Bundle). Returns 409 if a bundle with the same slug already exists.


Update Bundle

PATCH /api/v1/bundles/{id}

Partially updates a bundle. Provided fields change; omitted fields are preserved. Passing variants replaces the entire composition.

Request Body

All fields from Create Bundle are accepted and optional.

curl -X PATCH \
-H "Authorization: Bearer your_api_key" \
-H "Content-Type: application/json" \
-d '{"discountPercentage": 20, "status": "hidden"}' \
https://your-store.yns.store/api/v1/bundles/0191abc0-1234-7def-8000-000000000001

Response (200)

Returns the updated bundle with full composition.


Delete Bundle

DELETE /api/v1/bundles/{id}

Hard-deletes the bundle by UUID. The composition is cascade-removed; the underlying products and variants are untouched.

curl -X DELETE \
-H "Authorization: Bearer your_api_key" \
https://your-store.yns.store/api/v1/bundles/0191abc0-1234-7def-8000-000000000001

Response (200)

{
"ok": true,
"deleted": 1
}