The current contract is schema version 2. Omit
schema_version for all new integrations. Send schema_version: 1 only from an existing image-only integration that needs legacy update behavior.https://api.virtual.fit.
Choose a sync method
- Management API
- CSV
Push changes as they happen. This is the best option when your backend knows the current variants, prices, or inventory.Keep the API key on your server. Never include it in storefront JavaScript.
Find your site ID
In virtual.fit, open Custom JS → Sync Products and copy the Storefront Site ID from the Storefront Credentials section. The site ID is a UUID used in thesite_id path parameter. It is
different from the public site key, your workspace ID, and any ID from your commerce platform.
For server-side discovery, call the current-site endpoint with your API key and store the returned
site.id value for later requests:
Start with the smallest useful product
You can send the title and image first. Add variants, stock, prices, options, and size charts later under the same product ID.- A stable product ID in the request URL or
product_idCSV column. title.- At least one public product image.
Choose a durable product ID
product_id is the permanent identity of the product inside one site. It is
case-sensitive and can be a numeric ID, UUID, or URL-safe string.
- Prefer an immutable catalog or database ID.
- Keep one ID for the product when prices, images, options, or variants change.
- Do not derive it from the title, URL, handle, or current variant combination.
- Keep it within 255 UTF-8 bytes and URL-encode it in API paths.
product_id. This does not create a second product or require a migration.
Send products with variants
A product holds shared merchandising data. A variant holds one exact purchasable combination, such asFloral / Petite / 2.
Send stock updates
Use the same product upsert endpoint when stock changes. For an existing product, send only the changed variants. You do not need to resend the title, images, prices, or unchanged variants.- Exact variants
- Products without variants
Identify each variant by the same
source_variant_id used during the initial
sync.- Send
available: truewhen the variant can be purchased andfalsewhen it is sold out. - Send
inventory_quantitywhen your source provides an exact count. Quantity alone does not setavailable. - Send
inventory_observed_atas the RFC 3339 time when your source reported the stock. If you omit it, virtual.fit uses the request time. - Keep the timestamp from the source. An older observation does not replace newer stock for the same variant.
- Omit
variants_completefrom a targeted stock update. Set it totrueonly when the request contains the complete authoritative variant list. - Refresh stock regularly. virtual.fit treats stale inventory as unknown instead of claiming that a variant is in stock.
enabled controls whether the product can use the fitting room. It is not a
stock field. Keep enabled unchanged when only inventory changes. For an
existing product, omitting it from an upsert preserves the current state; use
the dedicated enable-state endpoint when changing availability by itself.Field reference
Fields are ordered by how commonly a new integration needs them. Auto-detected when omitted means virtual.fit derives the value from the supplied variants, option names, swatches, or media.Product fields
Product fields
string
required
Stable product ID in the request URL. Keep it unchanged when variants,
prices, inventory, or media change.
string
required
Shopper-facing product name. Required when creating a product.
object[]
required
Shared product media. A new product needs at least one public image. See
the image object reference.
string
Required for most Custom JavaScript storefronts. Send the stable
storefront slug when the site resolves product URLs by handle. You may
omit it only when URL resolution uses
product_id.string
Public canonical product URL. Must use HTTP or HTTPS.
boolean
default:"true"
Whether the product is enabled in the fitting room. This is separate from upstream sale availability.
boolean
Current source-reported sale availability when it is known. Omit or send
null when unknown. Usually derived from exact variants or synced from the
source; variant availability is more precise when variants exist.number
Current overall customer rating on a 0–5 scale. Omit when the source does
not expose an aggregate rating.
number
Number of customer reviews included in the current overall rating. Must
be zero or greater.
object
Product-level selling price. A variant price overrides it for that
variant. Expand for the exact object shape.
object
Product-level original or pre-sale price. Uses the same
amount and
currency shape as price.object[]
Exact purchasable combinations. An empty array is valid. Expand for
variant identity, selections, inventory, pricing, and media fields, or
open the variant object reference.
boolean
default:"false"
When
true, the supplied variant list is authoritative. Omitted variants become inactive. Send true with variants: [] for a genuinely variantless product.object[]
Choice axes, labels, swatches, and size metadata. Auto-detected when
omitted: virtual.fit derives the minimum option structure from
variants[].option_values. Send options when you have source labels,
ordering, swatches, or explicit size metadata. See the
option object reference.object[]
Product-wide or option-scoped size chart references. Stored now for
future size-aware recommendations; they do not change today’s visual
recommendation ranking. See the
size-chart reference.
object[]
Optional measured garment dimensions by size. Use canonical dimension
names such as
bust, chest, waist, hips, shoulder_width,
sleeve_length, total_length, inseam, front_rise, back_rise,
thigh, or leg_opening. Use cm or in.object[]
Optional product-page model or mannequin fit facts. Send the worn size
and any source-reported body measurements. These fields can improve
future size recommendations and remain optional.
string
Brand or designer name.
string
Merchant-facing product type. Usually populated automatically when the
source exposes it.
string
Optional plain-text product description. Useful enrichment, but not
required for fitting-room product matching.
string
Optional product-specific try-on guidance.
string
Optional concise garment naming override used to describe the item during
try-on. Auto-detected when omitted.
boolean
Whether the product still exists and is active in the source catalog.
Send
false for archived or removed products.string
Optional unmodified status from the source system, such as
ACTIVE,
ARCHIVED, or DRAFT. It is preserved for diagnostics and is not a
normalized enum.string
RFC 3339 timestamp for the source record. Usually populated automatically.
number
default:"2"
Omit for the current contract. The only accepted explicit values are
1
for a legacy image-only request and 2 for the current contract.object
Optional ordering and idempotency metadata for multi-worker progressive syncs.
Variant and media behavior
- A product may have no variants. Send
variants_complete: truewithvariants: []. - If variants appear later, keep the same product ID and send the new variant list.
- Size-only variants normally share product media.
- Color, pattern, material, and style variants can reference distinct media.
- Shared media is stored and prepared once even when several variants reference it.
- A swatch image represents the selector. Variant media represents the garment used for display and try-on.
Visual choices
You do not create presentation IDs. virtual.fit derives visual choices from option meaning, swatches, and variant media. Use:presentation_role: "include"when an option changes the visible garment.presentation_role: "exclude"for size, fit, length, and other non-visual choices.presentation_role: "auto"when virtual.fit should infer the behavior.
Size charts
Use one chart withoutapplies_to when it applies to every variant. Use a selector when petite, regular, tall, or another option value uses a different chart.
A chart may contain:
- A public
url. - Extracted structured
content. - Both a URL and structured content.
us + womens + footwear is different
from us + youth + footwear. Petite, regular, and tall remain option values
such as fit, and applies_to selects the chart for each fit.
Reusing the same chart URL or stable external_id across products allows
virtual.fit to share the stored chart document while keeping each product’s
applies_to selector.
Optional review evidence
You do not need to send reviews. virtual.fit can collect public review evidence when it prepares a product. If your backend already receives complete review records, you can sync them after creating the product. The optional review endpoint accepts each review’s stars, full text, purchased variant, customer photos or videos, and source-reported measurements or fit votes. virtual.fit analyzes review text asynchronously, so review enrichment never blocks the product from becoming ready. Use a stable source review ID whenever one exists. Send each review as its complete current record so removing media or structured evidence is unambiguous. See Sync product reviews. The storefront can request the compact fit summary for fast product display and load full paginated reviews only when the shopper asks to inspect the evidence.Partial updates and clearing data
For an existing product:- An omitted field stays unchanged.
- An explicit
nullclears a supported field or collection. variants_complete: truemakes the supplied variant list authoritative.- A plain partial variant update does not remove omitted variants.
handle, preview_image_url, brand, description,
product_type, prices, availability, rating, review count, custom
instructions, images, options, variants, size charts, garment measurements, or
model observations.
options removes your supplied labels and swatches. If active variants remain, virtual.fit retains the minimum option structure required to describe them.
Order updates from multiple workers
Addingest metadata when several workers may update one product or when events
may arrive out of order. The event and sequence fields make the complete update
idempotent and ordered.
Delete catalog data
UseDELETE when the product should be removed from the synced catalog. This
permanently removes the synced product record and its managed product images:
{"enabled":true} to re-enable it. Disabled products remain in the
product count, but do not consume enabled-product slots.
Delete one variant:
CSV format
Each CSV upload is a synchronous import of at most 1,000 rows. Split larger catalogs into multiple files. Product and variant upserts are idempotent, so it is safe to retry a file; if an infrastructure failure occurs after processing starts, rows already saved remain saved.- Current contract
- Delete rows
- Legacy v1
Omit
schema_version; version 2 is the default. Repeat the product ID on
each variant row. Blank product-level cells on later rows inherit the first
row for that product.Legacy JSON compatibility
Use an explicit legacy version only while an existing image-only integration is being migrated:options, variants, prices, inventory, or size charts, it returns a message that lists the incompatible fields and tells you to omit schema_version.
Image requirements
Image URLs must be reachable without shopper cookies, expiring browser sessions, or IP-bound authorization. Use stable HTTPS CDN URLs and clear, high-resolution JPEG, PNG, or WebP images up to 64 MB. Avoid short-lived signed URLs unless they remain available during preparation and later refreshes. Prefer images that show the complete sold product on a model or mannequin. When available, send front, back, and side views. These views provide a more useful fit reference than a flat lay or isolated ghost image and generally produce more accurate try-on results. Flat-lay, ghost, and product-only images are still accepted. virtual.fit automatically analyzes, deduplicates, and selects the strongest prepared views without modifying the originals. When a photo contains several garments, also include a view where the sold item is unambiguous.Input limits
Limits are intentionally generous enough for large catalogs while preventing a single malformed request from consuming unbounded memory or database space. Limits apply equally to JSON and CSV values.
A request that exceeds a byte or collection limit returns
413 with the field
that must be reduced. Invalid values within the limits return 400.