variantId (never just a productId).
The V3 Variants API lets you retrieve individual variants by ID and check their availability across countries.
To list all variants for a specific product, use
GET /v3/products/{productId}/variants - this is part of the Products API since it’s scoped to a product.The Variant Object
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier of the variant - required when placing an order |
title | string | Display name of the variant |
productId | string | Parent product identifier |
selectedOptions | object | Key-value option values for this variant (e.g. {"color": "Black", "size": "M"}) |
taxable | boolean | Whether the variant is taxable |
media | array | Variant-specific media items |
personalization | object | Personalization metadata (whether personalization is supported, available template fields). Nullable when unavailable. |
descriptionHtml | string | Full narrative HTML description |
price | object | Variant price in {amount, currency}. Returned only when fields includes price. |
priceBreakdown | object | Detailed pricing breakdown. Returned only when fields includes priceBreakdown (implies price). |
partnerPrice | object | Partner-specific price for the requested location. Returned only for partner companies when pricing is requested. |
details | object | Structured details wrapper (description, features, specifications). Returned only when fields includes details. |
brand | object | Returned only when include=brand. Nullable. |
Key Concepts & Business Rules
Default response is lean
By default, variant responses omitprice, priceBreakdown, partnerPrice, and details. Use fields to request these when you need them:
fields=price- addsprice(andpartnerPricefor partner companies)fields=priceBreakdown- addspriceBreakdownand impliespricefields=details- adds the structureddetailswrapper
Pricing is per country
Variant pricing depends on the recipient’s shipping country. Two ways to retrieve it:- For a specific country - use
GET /v3/variants/{variantId}withlocation(defaultUS) andfields=price(orpriceBreakdown) - Across all countries - use
GET /v3/variants/{variantId}/availabilityto retrieve the full per-country availability map
partnerPrice is partner-only
The partnerPrice field is returned only for partner companies, and only when pricing is requested via fields=price (or fields=priceBreakdown). For non-partner companies, this field is omitted from the response entirely.
Personalization data
Thepersonalization object indicates whether the variant supports custom personalization (e.g. a printed name or message) and what template fields are configurable. It is null when personalization isn’t available for the variant.
Availability vs pricing
The availability endpoint returns a map of countries the variant ships to, with country-specific pricing inline. Country codes not present in the response should be treated asisAvailable: false - only supported countries are returned.
For per-recipient validation, the typical pattern is: check availability once via GET /v3/variants/{variantId}/availability, then place an order with the appropriate location parameter on POST /v3/orders.
Account scoping
OptionalSnappy-Account-Id and Snappy-Company-Id headers scope queries to a specific Account or Company - primarily for swag validation and filtering.
Permissions
All V3 Variants endpoints require theproducts:read scope. (The Variants API shares the products:read scope with the Products API since they’re part of the same catalog domain.)
How to Work with Variants
Get a single variantfields to expand pricing and details, and include=brand to inline the brand object.
Get variant availability
Looking for swag base variants (variations of branded merchandise templates) instead of marketplace variants? See the Swag page.