Optimization Guide
Shopify Made-to-Order Product Schema for AI Shopping Agents
AI shopping agents answer "handmade leather wallets," "custom furniture under 6 weeks," and "bespoke jewelry made after order" by reading structured data — not your product description. Shopify's default JSON-LD treats made-to-order products identically to in-stock items, corrupting lead time expectations and production method signals for every AI shopping index.
availability: PreOrder for made-to-order products (not InStock). Add deliveryLeadTime as a QuantitativeValue on the Offer specifying production time. Add additionalProperty: madeToOrder: true and productionMethod for handmade/artisan signals. For genuinely bespoke one-offs, use LimitedAvailability with inventoryLevel: 1. Drive everything via product metafields in Shopify Liquid with a tag gate.
The Made-to-Order Visibility Problem
Made-to-order, custom, and handmade products represent a significant and growing segment of Shopify's merchant base — from artisan furniture makers to personalized jewelry brands to bespoke clothing ateliers. These products have fundamentally different fulfillment semantics than stocked inventory: they do not exist until ordered, production time is the primary lead time signal, and each unit may be unique.
Shopify's default product JSON-LD has no concept of "made-to-order." If your inventory policy allows "continue selling when out of stock" (the standard setting for made-to-order stores), Shopify outputs InStock for every product regardless of your actual production model. An AI shopping agent receiving a query for "custom wallets delivered in under 2 weeks" would see your store claiming InStock with no lead time signal — it has no way to know the true fulfillment timeline.
Made-to-order query types that require structured data
| Query type | Example | Required signal | AI shopping behavior |
|---|---|---|---|
| Production method filter | "handmade leather wallets" | additionalProperty: productionMethod: handmade |
Filters products declaring handmade/artisan production method |
| Lead time constraint | "custom furniture delivered in under 6 weeks" | deliveryLeadTime: {value: 6, unitCode: "WEE"} |
Filters made-to-order products by maximum production time |
| Bespoke / custom fit | "bespoke suits with custom measurements" | additionalProperty: madeToOrder: true + customization signals |
Identifies products that can be specified per-customer |
| Gift deadline | "handmade gifts that arrive before December 20" | deliveryLeadTime + availabilityEnds for order cutoff |
Calculates whether order + lead time + shipping meets the deadline |
| One-of-a-kind / artisan | "one of a kind ceramic vases" | LimitedAvailability + inventoryLevel: 1 + isHandmade: true |
Surfaces items declared as unique or limited-run handmade pieces |
Shopify default vs. made-to-order JSON-LD
{
"@type": "Offer",
"price": "280.00",
"availability": "InStock"
// implies immediate dispatch
// actual lead time: 14 days
// no production method
}
{
"@type": "Offer",
"price": "280.00",
"availability": "PreOrder",
"deliveryLeadTime": {
"@type":
"QuantitativeValue",
"value": 14,
"unitCode": "DAY"
},
"additionalProperty": [{
"propertyID": "madeToOrder",
"value": "true"
}]
}
Made-to-Order JSON-LD Patterns
Minimum viable — PreOrder + lead time
The essential made-to-order signal is PreOrder availability combined with a deliveryLeadTime declaration. This is sufficient for lead-time-constrained queries and correctly signals that the product is not immediately dispatchable:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Handstitched Leather Bifold Wallet",
"description": "Made to order in 10-14 business days. Each wallet is hand-cut and hand-stitched from full-grain vegetable-tanned leather.",
"offers": {
"@type": "Offer",
"price": "95.00",
"priceCurrency": "USD",
"availability": "https://schema.org/PreOrder",
"deliveryLeadTime": {
"@type": "QuantitativeValue",
"minValue": 10,
"maxValue": 14,
"unitCode": "DAY"
}
}
}
Full handmade / artisan declaration
For products where the handmade nature is itself a value signal — artisan ceramics, hand-forged tools, hand-knit textiles — add productionMethod and isHandmade additionalProperty blocks alongside the availability signals:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Hand-thrown Stoneware Mug — 12oz",
"description": "Each mug is individually thrown on a kick wheel, bisque fired, glazed by hand, and cone-10 fired. No two are identical. Production: 3 weeks.",
"keywords": "handmade, artisan, hand-thrown, stoneware, unique",
"offers": {
"@type": "Offer",
"price": "42.00",
"priceCurrency": "USD",
"availability": "https://schema.org/PreOrder",
"deliveryLeadTime": {
"@type": "QuantitativeValue",
"value": 3,
"unitCode": "WEE"
},
"additionalProperty": [
{
"@type": "PropertyValue",
"propertyID": "madeToOrder",
"name": "Made to order",
"value": "true"
},
{
"@type": "PropertyValue",
"propertyID": "productionMethod",
"name": "Production method",
"value": "handmade"
},
{
"@type": "PropertyValue",
"propertyID": "isHandmade",
"name": "Handmade",
"value": "true"
},
{
"@type": "PropertyValue",
"propertyID": "producedBy",
"name": "Made by",
"value": "Single artisan — Portland, Oregon"
}
]
}
}
One-of-a-kind artisan piece
For unique or extremely limited handmade items — gallery-quality ceramics, bespoke one-off furniture — use LimitedAvailability with an explicit inventoryLevel of 1 and declare the unique nature via additionalProperty:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Hand-forged Copper Pendant Light — No. 47",
"description": "One-of-a-kind hand-forged copper pendant. Each piece is unique. This is piece No. 47 in the studio series.",
"offers": {
"@type": "Offer",
"price": "680.00",
"priceCurrency": "USD",
"availability": "https://schema.org/LimitedAvailability",
"inventoryLevel": {
"@type": "QuantitativeValue",
"value": 1,
"unitCode": "C62"
},
"additionalProperty": [
{
"@type": "PropertyValue",
"propertyID": "isHandmade",
"value": "true"
},
{
"@type": "PropertyValue",
"propertyID": "isOneOfAKind",
"name": "One of a kind",
"value": "true"
},
{
"@type": "PropertyValue",
"propertyID": "productionMethod",
"value": "hand-forged"
}
]
}
}
Bespoke / custom specification product
For made-to-measurement or fully custom products where buyers specify dimensions, materials, or configurations, combine madeToOrder with a customizationOptions declaration and the customization lead time impact. Pair with the product customization schema for full coverage:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Custom Walnut Floating Shelf",
"description": "Made to your specified width (12–72 inches), depth (8–16 inches), and finish. Production: 4–6 weeks after measurement confirmation.",
"offers": {
"@type": "Offer",
"price": "185.00",
"priceCurrency": "USD",
"availability": "https://schema.org/PreOrder",
"deliveryLeadTime": {
"@type": "QuantitativeValue",
"minValue": 4,
"maxValue": 6,
"unitCode": "WEE"
},
"additionalProperty": [
{
"@type": "PropertyValue",
"propertyID": "madeToOrder",
"value": "true"
},
{
"@type": "PropertyValue",
"propertyID": "customizable",
"value": "true"
},
{
"@type": "PropertyValue",
"propertyID": "customizationOptions",
"name": "Customization options",
"value": "Width: 12–72 inches, Depth: 8–16 inches, Finish: natural / oiled / stained"
},
{
"@type": "PropertyValue",
"propertyID": "productionMethod",
"value": "made-to-measure"
}
]
}
}
Shopify Liquid implementation
Override Shopify's default availability output with a metafield-driven or tag-driven conditional. Use a made_to_order product tag as the gate:
{% comment %}Made-to-order availability override{% endcomment %}
{% assign is_mto = false %}
{% for tag in product.tags %}
{% if tag == 'made-to-order' or tag == 'custom' or tag == 'handmade' %}
{% assign is_mto = true %}
{% endif %}
{% endfor %}
{% assign lead_days = product.metafields.mto.lead_days | default: '' %}
{% assign lead_weeks = product.metafields.mto.lead_weeks | default: '' %}
{% assign production_method = product.metafields.mto.production_method | default: 'handmade' %}
"availability": {% if is_mto %}"https://schema.org/PreOrder"{% elsif variant.available %}"https://schema.org/InStock"{% else %}"https://schema.org/OutOfStock"{% endif %},
{% if is_mto and lead_days != '' %}
"deliveryLeadTime": {
"@type": "QuantitativeValue",
"value": {{ lead_days }},
"unitCode": "DAY"
},
"additionalProperty": [
{
"@type": "PropertyValue",
"propertyID": "madeToOrder",
"value": "true"
},
{
"@type": "PropertyValue",
"propertyID": "productionMethod",
"value": {{ production_method | json }}
}
],
{% elsif is_mto and lead_weeks != '' %}
"deliveryLeadTime": {
"@type": "QuantitativeValue",
"value": {{ lead_weeks }},
"unitCode": "WEE"
},
"additionalProperty": [
{
"@type": "PropertyValue",
"propertyID": "madeToOrder",
"value": "true"
}
],
{% endif %}
Availability state reference for made-to-order scenarios
| Scenario | Correct availability | Additional signals | AI agent behavior |
|---|---|---|---|
| Standard made-to-order (one fixed product, built after purchase) | PreOrder |
deliveryLeadTime |
Surfaces in lead-time-aware queries; signals build-after-purchase model |
| Handmade / artisan product (standard design, handcrafted) | PreOrder |
productionMethod: handmade + deliveryLeadTime |
Matches "handmade" filters and lead-time queries simultaneously |
| One-of-a-kind unique piece (single existing item) | LimitedAvailability |
inventoryLevel: 1 + isOneOfAKind: true |
Shows urgency signal (only 1 available) alongside handmade signals |
| Bespoke / custom specification (fully specified per order) | PreOrder |
madeToOrder: true + customizable: true + lead time |
Signals customization availability; AI agents cite in bespoke/custom queries |
| Seasonal batch / limited production run | LimitedAvailability or PreOrder |
productionRun count + availabilityEnds for order cutoff |
Combines scarcity signal with production-model context |
Common Mistakes
1. Using InStock for made-to-order products
The most damaging mistake. If your inventory policy is "continue selling when out of stock," Shopify outputs InStock for your made-to-order products. AI agents surfacing these products in "in-stock, ships today" queries will damage conversion when buyers discover the actual 2-4 week production time. Override InStock with PreOrder for all made-to-order products using a tag gate in product.liquid.
2. No deliveryLeadTime on PreOrder products
Using PreOrder without a deliveryLeadTime tells AI agents the product is not immediately available, but gives no information about when it will be. An AI agent answering "handmade gifts for Christmas" with a December 20 deadline needs the production time to calculate whether an order placed today will arrive on time. Always add deliveryLeadTime when using PreOrder.
3. Declaring productionMethod without a null-guard
If you add productionMethod: handmade to your product.liquid template without a tag or metafield gate, mass-produced products on the same store will inherit the handmade claim. This is both inaccurate and a trust signal mismatch — AI agents that see "handmade" on obviously mass-produced product descriptions will penalize the claim's credibility. Gate production method signals strictly on product-specific tags or metafields.
4. Using OutOfStock instead of PreOrder for made-to-order
OutOfStock signals to AI agents that the product cannot currently be purchased. Made-to-order products can absolutely be purchased — they simply need production time. Using OutOfStock removes these products from AI shopping recommendation results entirely. The correct signal is PreOrder, which means "orderable but not immediately available."
5. Forgetting to flip PreOrder back to InStock for stocked products
If you occasionally stock some made-to-order items (buying a run for anticipated demand), products with PreOrder in your JSON-LD but physical inventory available will mislead buyers about their ship date. If your product transitions between made-to-order and in-stock states, use a metafield boolean (product.metafields.mto.is_mto) that you toggle explicitly rather than relying solely on product tags.
Implementation Checklist
- Override Shopify's default availability with
PreOrderfor all made-to-order products using a product tag gate inproduct.liquid - Add
deliveryLeadTimeQuantitativeValue with production time in days or weeks - Add
additionalProperty: madeToOrder: trueon the Offer - Add
additionalProperty: productionMethodfor handmade, hand-forged, hand-thrown, etc. - For one-of-a-kind items, use
LimitedAvailabilitywithinventoryLevel: 1 - For bespoke custom products, add
customizable: trueandcustomizationOptionsdescribing available specifications - Use
minValueandmaxValueindeliveryLeadTimewhen lead time is a range - Gate all made-to-order signals with a null-guard so mass-produced products are not affected
- Run CatalogScan to verify availability and lead time signals appear correctly in your AI readiness report
Frequently Asked Questions
What availability status should made-to-order products use in Shopify JSON-LD?
Use https://schema.org/PreOrder. PreOrder is the correct schema.org availability for items that exist in the catalog but are built only after purchase — they are not physically stocked. Do not use InStock (implies immediate fulfillment) or OutOfStock (implies the product cannot be ordered). Pair PreOrder with a deliveryLeadTime QuantitativeValue specifying production time.
How do I declare production lead time in Shopify product structured data?
Use the deliveryLeadTime property on the Offer with a QuantitativeValue: value (number) and unitCode ("DAY" for days, "WEE" for weeks, "MON" for months). For a range, use minValue and maxValue instead of value. AI agents parse this to answer deadline queries like "can I get a handmade gift by December 20?"
Does Shopify differentiate made-to-order from in-stock products in its default JSON-LD?
No. Shopify outputs InStock for any product with inventory policy set to "continue selling" — which most made-to-order stores use. You must override this with a tag-gate or metafield conditional in product.liquid that outputs PreOrder for made-to-order products.
How do I mark up handmade or artisan products for AI shopping agents?
Add additionalProperty with propertyID: productionMethod and value handmade (or hand-thrown, hand-forged, etc.). Add a second additionalProperty with propertyID: isHandmade and value true. For unique one-of-a-kind items, use LimitedAvailability with inventoryLevel: 1 and add isOneOfAKind: true.
Should made-to-order products have a GTIN in their structured data?
Genuinely unique bespoke products (custom dimensions, unique specifications) typically do not have GS1-issued GTINs — omit the gtin property and use sku instead. For made-to-order products that are standardized designs with a fixed lead time, include a GTIN if your category typically carries one. The absence of a GTIN on genuinely bespoke products is expected and will not penalize your AI readiness score.