Skip to main content

Get Product Draft Variants

Retrieve a paginated list of variants on a product's unpublished overlay.

The list includes unpublished overlay variants that do not appear on Get Product Variants. Archived overlay variants are omitted — fetch one by ID at Get Product Draft Variant. When no overlay exists, the list is the live projection — the same variants nested on Get Product Draft. Each item uses the live Product Variant shape — there is no draft_version or preview_url on the item. See Status.

Filters and pagination match Get Product Variants. Omitting sort leaves variants in overlay order. amount and name sort as on the live list. created_at orders by when a variant was created, which a variant that exists only on the overlay does not have yet: those sort last on created_at and first on -created_at, keeping them together at one end of the list either way.

Request

GET /products/{productId}/draft/variants

Path Parameters

ParameterTypeRequiredDescription
productIdstringYesProduct UUID

Query Parameters

ParameterTypeRequiredDefaultDescription
pageintegerNo1Page number for pagination
per_pageintegerNo10Items per page (min: 1, max: 100).
sortstringNoSort order: created_at, amount, or name. Prefix with - for descending.
typestringNoFilter by variant type. One of one_time or recurring.
is_hiddenbooleanNoFilter by checkout visibility. true returns only variants hidden from checkout; false returns only visible ones. Accepts true/false or 1/0.
querystringNoSearch term. Partial, case-insensitive match on the variant name or custom_id.

Omitting a filter or passing it empty means "no filter on that field". All filters combine with AND. Passing a non-empty but unparseable value — an unknown sort field, an invalid type, a non-boolean is_hidden, or an out-of-range per_page — returns a 400. The query term is matched loosely and never returns a 400.

Every response includes the total in pagination.total. An out-of-range page returns empty items and current_page set to that page. total and total_pages still describe the full result set.

Example Request

curl -X GET "https://cart.easy.tools/api/v1/products/0632bef5-c308-42cd-9cba-89a7a4f722bb/draft/variants" \
-H "Authorization: Bearer YOUR_API_TOKEN"

Response

Success Response (200)

Returns { items, pagination }. Unpublished overlay variants have checkout_url: null.

{
"items": [
{
"id": "d91c65aa-b221-4aa4-b626-cf0d8a198749",
"status": "published",
"type": "one_time",
"recurring_options": null,
"name": "250g Package",
"amount": 1999,
"currency": "usd",
"checkout_url": "https://cart.easy.tools/checkout/premium-coffee?plan=price_123",
"custom_id": "SKU-250G",
"is_hidden": false,
"trial_period_days": null,
"active_cycles": null,
"cancel_early": false,
"keep_access_after_expiring": false,
"allow_multiple_subscriptions": false,
"active_days": 365,
"quantity": 100,
"has_quantity": true,
"old_price": 29,
"active_from": "2026-01-01T00:00:00+00:00",
"active_until": "2026-12-31T23:59:59+00:00",
"access_until": null,
"show_active_until_counter": true,
"tax_behavior": "exclusive",
"refund_days": 14,
"redirect_url": "https://mysite.com/thank-you",
"redirect_time": 5,
"file": null,
"files": [],
"invoice_remarks": null,
"has_shipping": false,
"delivery_enabled": false,
"delivery_service": null,
"delivery_address_optional": true,
"delivery_options": null,
"shipping_phone_required": false,
"phone_tooltip": null,
"mandatory_consent": null,
"optional_consent": null,
"digital_consent": null,
"newsletter_consent": null,
"newsletter_consent_required": false,
"newsletter_discount": null,
"vat_rate": null,
"gtu_code": null,
"flat_rate": null,
"exempt_tax_kind": null,
"tax_category": null,
"dashboard_header": null,
"long_description": null,
"cta_text": null,
"cta_url": null,
"credits": null,
"show_net_price": false,
"pay_what_you_want": null,
"purchase_button_text": null,
"upsells": [],
"custom_fields": null
},
{
"id": "5272bfcf-4e92-458d-b513-80ca474a16e4",
"status": "published",
"type": "one_time",
"recurring_options": null,
"name": "100g Sample",
"amount": 999,
"currency": "usd",
"checkout_url": null,
"custom_id": null,
"is_hidden": false,
"trial_period_days": null,
"active_cycles": null,
"cancel_early": false,
"keep_access_after_expiring": false,
"allow_multiple_subscriptions": false,
"active_days": null,
"quantity": null,
"has_quantity": false,
"old_price": null,
"active_from": null,
"active_until": null,
"access_until": null,
"show_active_until_counter": null,
"tax_behavior": "exclusive",
"refund_days": null,
"redirect_url": null,
"redirect_time": null,
"file": null,
"files": [],
"invoice_remarks": null,
"has_shipping": false,
"delivery_enabled": false,
"delivery_service": null,
"delivery_address_optional": true,
"delivery_options": null,
"shipping_phone_required": false,
"phone_tooltip": null,
"mandatory_consent": null,
"optional_consent": null,
"digital_consent": null,
"newsletter_consent": null,
"newsletter_consent_required": false,
"newsletter_discount": null,
"vat_rate": null,
"gtu_code": null,
"flat_rate": null,
"exempt_tax_kind": null,
"tax_category": null,
"dashboard_header": null,
"long_description": null,
"cta_text": null,
"cta_url": null,
"credits": null,
"show_net_price": false,
"pay_what_you_want": null,
"purchase_button_text": null,
"upsells": [],
"custom_fields": null
}
],
"pagination": {
"current_page": 1,
"total_pages": 1,
"per_page": 10,
"total": 2
}
}

Each entry in items has the same shape as the response of Get Product Variant. There is no include on this list, so custom_fields stays null. Expand it on Get Product Draft Variant.

Pagination Object

FieldTypeDescription
current_pageintegerThe requested page. May be greater than total_pages when items is empty.
total_pagesintegerTotal number of pages
per_pageintegerEffective page size (echoes the per_page request parameter)
totalintegerTotal number of non-archived overlay variants for the product, across all pages

Error Responses

Bad Request (400)

Returned when the product ID is invalid, per_page is out of range, sort names an unknown field, type is not one_time or recurring, or is_hidden is not a boolean. The message describes the problem.

{
"message": "Invalid product ID"
}

Product Not Found (404)

{
"message": "Product with ID 0632bef5-c308-42cd-9cba-89a7a4f722bb not found"
}