Home
Preorders

Product variants

Per-Shopify-variant reads, metafield administration, and bulk recalculation.

The product-variants resource is the variant-centric inverse of the offer's Products capability — instead of asking "which variants does this offer contain?" you ask "which offers is this variant in?", plus run administrative actions that compose with the variant's Shopify metafields.

URLs use the Shopify variant ID, not Stoq's internal UUID. This is intentional — most callers already have the Shopify variant ID and don't carry Stoq IDs around.

Path prefix: /preorders/product_variants

Reads

MethodPathDescription
GET/preorders/product_variantsList Shopify variants attached to any preorder offer in this shop. Paginated.
GET/preorders/product_variants/:variant_idRead a Shopify variant's preorder context: every offer it's in, aggregate counts, and current metafield state.
GET/preorders/product_variants/:variant_id/offersList the preorder offers a Shopify variant is attached to. Accepts a state filter.

The list endpoint supports page / per_page pagination plus offer_id, product_id, and variant_ids filters. The response key is product_variants:

{
  "product_variants": [ { "shopify_variant_id": 123456, "...": "..." } ],
  "meta": { "total_count": 80, "page": 1, "per_page": 25, "total_pages": 4 }
}

The detail endpoint returns the same context the admin UI uses to render the variant detail page — current counts, metafield drift detection, etc.

Note

Per-offer variant settings (shipping-text and max-count overrides) live on the offer side: see the products/variants sub-resource.

Single-variant administration

These actions compose with Shopify metafield writes. They're the same operations the merchant admin offers behind the "Reset" / "Recalculate" buttons on the variant detail page.

MethodPathDescription
POST/preorders/product_variants/:variant_id/recalculate_preorder_countRecompute preorder_count from active order line items, then push to Shopify.
POST/preorders/product_variants/:variant_id/reset_preorder_countHard-reset preorder_count metafield + DB columns to zero.
POST/preorders/product_variants/:variant_id/sync_metafieldsForce-resync every preorder metafield from local DB state to Shopify. Idempotent.
POST/preorders/product_variants/:variant_id/reset_metafieldsClear all preorder-related Shopify metafields on a variant. Doesn't detach from offers.
POST/preorders/product_variants/:variant_id/detach_from_all_offersRemove a variant from every preorder offer it's attached to. Customer orders are unaffected.

When to use which

  • recalculate_preorder_count — use when count has drifted from reality. Recomputes from real orders.
  • reset_preorder_count — destructive zero. Use only when you need to manually start counting from scratch.
  • sync_metafields — use after a transient Shopify outage to push DB state back into Shopify metafields.
  • reset_metafields — clears Shopify metafields but keeps the offer attachment. The next offer-settings change rewrites them from current state.
  • detach_from_all_offers — destructive; equivalent to the offer's products/remove_variants against every offer the variant is in.

Bulk administration

The bulk variants of the above actions submit a background job and return 202 Accepted with a job_id / status_url / variant_count. Cap is 5000 variants per submission.

MethodPathDescription
POST/preorders/product_variants/bulk_recalculate_preorder_countsRecompute preorder_count for many variants in one job.
POST/preorders/product_variants/bulk_reset_metafieldsReset preorder metafields for many variants in one job.
POST/preorders/product_variants/bulk_sync_metafieldsForce-resync preorder metafields for many variants in one job.

Request body

{ "variant_ids": [123456, 789012, 345678] }

variant_ids are Shopify variant IDs.

Polling

GET /preorders/product_variants/jobs/:job_id

Returns the standard async-job envelope. See Bulk & Async Jobs for the full polling pattern.