Get Product Variants
Retrieve a list of a product's variants from your store.
Only published variants are returned — unpublishing is how a variant is archived, so unpublished variants are excluded from this list. To fetch a single variant regardless of its published state, use Get Product Variant.
Request
GET /products/{productId}/variants
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
productId | string | Yes | Product UUID |
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
page | integer | No | 1 | Page number for pagination |
per_page | integer | No | 10 | Items per page (min: 1, max: 100). |
sort | string | No | — | Sort order: created_at, amount, or name. Prefix with - for descending. |
type | string | No | — | Filter by variant type. One of one_time or recurring. |
is_hidden | boolean | No | — | Filter by checkout visibility. true returns only variants hidden from checkout; false returns only visible ones. Accepts true/false or 1/0. |
query | string | No | — | Search 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 (see
Bad Request). The query term is matched loosely and never returns a 400.
Ordering: When sort is omitted, variants are returned in the store's configured variant
display order. Supply sort to order by created_at, amount, or name instead; prefix
with - for descending.
Every response includes the total in pagination.total.
Example Request
curl -X GET "https://cart.easy.tools/api/v1/products/550e8400-e29b-41d4-a716-446655440000/variants" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Response
Success Response (200)
Returns a paginated list of the product's published variants.
{
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440002",
"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": 2499,
"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
}
],
"pagination": {
"current_page": 1,
"total_pages": 1,
"per_page": 10,
"total": 1
}
}
Each entry in items has the same shape as the response of
Get Product Variant.
Pagination Object
| Field | Type | Description |
|---|---|---|
current_page | integer | Current page number |
total_pages | integer | Total number of pages |
per_page | integer | Effective page size (echoes the per_page request parameter) |
total | integer | Total number of published 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"
}
Unauthorized (401)
{
"message": "Unauthenticated."
}