Skip to main content

Metafield value formats for CSV import

When you import metafields from a CSV file, every value must end up in the format Shopify expects for the metafield's type: a date as 2025-12-31, a weight as {"value":2.5,"unit":"KILOGRAMS"}, a product reference as gid://shopify/Product/123. You don't have to type those formats by hand: the import recognizes and converts the usual human-friendly ways of writing a value (2.5 kg, 31.12.2025, a product handle). For how to lay out the file itself - columns, headers, and the "rows" and "columns" formats - see How to prepare a CSV file for import.

The Quick reference below is a one-screen summary. The rest of the page describes every type in detail, grouped as in the app's type selector (Text, Reference, Number, Measurement, Link, Date and time, Other, Advanced), base types first and then list types.

Quick reference​

Basic rules​

  1. The recommended format is always sent unchanged. If you aren't sure how to write a value, export a few metafields of the same type and copy the format from the Metafield value column: an export always produces importable values (except the readable column of the Readable mode).
  2. Numbers: use a dot for decimals and no thousands separators: 1234.56. Other styles work too, but 1,500 (and, in some files, 1.500) is ambiguous.
  3. Dates: YYYY-MM-DD. Times without an offset are UTC; add one for local time: 2025-12-31 13:45+02:00.
  4. Lists: a JSON array (["Red","Blue"]), one item per line, or items separated by semicolons or commas (Red; Blue, Red, Blue). Separators are handy but need care: an item must not contain the separator itself, otherwise it is split into several items (Red, dark, Blue is three items, not two). Use line breaks or ; when items contain commas, and a JSON array when you can't be sure - see How list values are read. If any item can't be read, the whole list isn't imported.
  5. References: a handle, SKU, email or file URL works instead of a GID, but the referenced item must already exist in the store.
  6. Check the Warning column of the import report: it explains every rejected value and every value the import had to interpret (an ambiguous number or date, a completed URL, repaired JSON).

Formats by type​

TypeRecommendedAlso accepted
single_line_text_fieldCottonAny text. Preset choices in any case: small → Small
multi_line_text_fieldText with line breaks-
rich_text_field<p>Hello <strong>world</strong></p>Shopify rich text JSON, plain text (an empty line starts a new paragraph)
product_referencegid://shopify/Product/123Handle: classic-cotton-tee
collection_reference, page_reference, article_referenceGIDHandle: summer-sale, about-us
variant_referencegid://shopify/ProductVariant/123SKU: TEE-RED-M
customer_referencegid://shopify/Customer/123Email: jane@example.com
company_reference, order_referenceGIDName: Acme Inc, #1001
metaobject_referencegid://shopify/Metaobject/123brand/acme, or just acme
file_referencegid://shopify/MediaImage/123Public file URL (the file is uploaded): https://example.com/photo.jpg
number_integer421 250, 1,234,567, $42. Decimals are cut off: 12.9 → 12
number_decimal19.9919,99, 1,234.56, 1.234,56, $19.99, 7.2e-3
money{"amount":"19.99","currency_code":"USD"} (store currency only)19.99, $1,299.00, 19,99 (saved in the store currency)
rating{"scale_min":"0.0","scale_max":"5.0","value":"4.5"}4.5, 4,5 (the definition's scale, or 0-5)
idSKU-001Any text. Requires a metafield definition
Measurement types{"value":2.5,"unit":"KILOGRAMS"}2.5 kg, 2,5kg, 5 lbs, 10", 22 °C, 60 km/h; 2.5 gets the default unit
urlhttps://example.comHTTPS://example.com; with a warning: example.com, www.example.com, support@example.com (→ mailto:)
link{"text":"Size guide","url":"https://example.com/size"}Size guide https://example.com/size; with a warning: Size guide (example.com/size)
date2025-12-3131.12.2025, 31/12/2025, 12/31/2025, Dec 31, 2025, 31st December 2025
date_time2025-12-31T13:45:00+00:002025-12-31 13:45, 31.12.2025 13:45, Dec 31 2025 1:45 PM, 2025-12-31T13:45+02:00
booleantrue / falseyes/no, 1/0, y/n, on/off, t/f, in any case
color#ff0000#F00, ff0000, rgb(255, 0, 0), hsl(0, 100%, 50%), red, Dark Blue
languageen, pt-BREN-us, German, Portuguese (Brazil)
json{"key":"value"}{key:'value'} (repaired, with a warning). Text must be quoted: "hello"
mixed_referencegid://shopify/Metaobject/123brand/acme. Requires a metafield definition
product_taxonomy_value_referencegid://shopify/TaxonomyValue/123-
list.*["Red","Blue"], [1,2]One item per line, Red; Blue, Red, Blue. Each item takes the base type's formats: 1 kg, 500 g

How the import processes a value​

For every cell, the import does the following:

  1. Trims leading and trailing whitespace.
  2. Checks if the value is already valid for the metafield type (canonical Shopify format). If so, it's sent to Shopify as is.
  3. Otherwise, it tries to normalize the value using the type-specific rules described below (parse a number, a date, a unit, convert HTML to rich text, repair broken JSON, etc.).
  4. For reference types, it resolves identifiers (handles, SKUs, emails, file URLs) into Shopify GIDs, and uploads files from URLs to your store's Files.
  5. If the value can't be normalized, the original value is sent as is and the Warning column says why it couldn't be read. Shopify usually rejects such a value, and its error appears in the import report for that row; if Shopify accepts it, it's saved the way Shopify reads it, so check the warning. Nothing is silently replaced with an empty value.
  6. The Warning column of the import report explains what the parser did with the value: why it couldn't be read (for example, an unknown unit or text that isn't a number), or how an imported value was interpreted (for example, an ambiguous number).

Other general rules:

  • Empty cells are skipped and don't change existing data. If the Empty metafields option is set to Delete, an empty cell deletes the metafield instead. You can't store an empty value in Shopify.
  • Type comes from the file mapping. In the "rows" format, it's the Metafield type column (if it's empty, the type is taken from the metafield's definition or set, or multi_line_text_field is used); in the "columns" format, it's the type you pick for the column during mapping. The value is parsed according to that type.
  • The definition type wins. If the metafield has a definition (or set), its type is used even when the Metafield type column says otherwise, and the row gets a note in the Warning column. An unknown type in that column (a typo like numbr_integer) is replaced the same way - with the definition's type, or with multi_line_text_field if there's no definition - and is noted in the Warning column too. The row is still imported.
  • Definition settings are respected. If the metafield has a definition (or is part of a metafield set), the import uses its rating scale and its list of allowed choices for text fields.
  • Metaobject imports use exactly the same rules for each metaobject field.

JSON inside a CSV file​

Many canonical values are JSON ({"amount":"19.99","currency_code":"USD"}). A CSV cell that contains double quotes must itself be wrapped in double quotes, with every inner quote doubled:

"Metafield namespace","Metafield key","Metafield type","Metafield value"
"custom","price_ref","money","{""amount"":""19.99"",""currency_code"":""USD""}"

Spreadsheet apps (Excel, Google Sheets, Numbers) do this escaping automatically when they save a CSV - just type {"amount":"19.99","currency_code":"USD"} into the cell. Only take care of it if you generate CSV files with your own code: use a proper CSV library instead of joining strings.

The import also repairs slightly broken JSON for JSON-based types: single quotes, unquoted keys, a missing closing bracket. For example, {'value':42,'unit':'KILOGRAMS'} and {value:42,"unit":"KILOGRAMS"} are both accepted. For the json type, every repair is noted in the Warning column. Don't rely on it for complex data - valid JSON is always the safest option.

How numbers are read​

All number-based types (integer, decimal, money, rating, every measurement) use the same number parser. Both the US/UK style (1,234.56) and the European style (1.234,56) are supported - the parser works out which character is the decimal separator from the structure of the number:

InputRead asWhy
19.99 / 19,9919.99A single separator not followed by exactly 3 digits is decimal
1,234.56 / 1.234,561234.56When both . and , are present, the last one is decimal and the other one separates thousands
1,234,567 / 1.234.5671234567A separator that appears several times separates thousands
1 250 / 30 000 000 / 1'2341250 / 30000000 / 1234Spaces (including non-breaking ones) and apostrophes between digits separate thousands
1 234,5671234.567If thousands are already separated by spaces, the comma is decimal
0,500 / ,050.500 / 0.05A separator after 0 (or with no integer part) is decimal
1,500 / 1.500depends on the columnAmbiguous - see below
$1,005.07 / 1,005.07 € / ₡ 1,005.071005.07Currency symbols and other text around the number are removed
8,71972E+12 / 7.2e-38719720000000 / 0.0072Scientific notation (as produced by Excel) is supported
-1.005,07-1005.07Negative numbers are supported
1,234,5 / 10-20 / 4.5 / 5not a numberInvalid digit grouping or extra characters between digits - the value is rejected
abcnot a numberThe value is rejected

Ambiguous numbers​

A number with a single separator followed by exactly three digits - 1,500 or 1.500 - can mean either one and a half or fifteen hundred. The import resolves it by looking at the other values of the same metafield in the file (the same column in the "columns" format, the same namespace and key in the "rows" format):

  • if other values clearly use a comma as the decimal separator (19,99, 1.234,56), 1,500 is read as 1.5 and 1.500 as 1500;
  • if other values clearly use a dot (19.99, 1,234.56), 1,500 is read as 1500 and 1.500 as 1.5;
  • if the file doesn't tell (or mixes both styles), a comma is treated as a thousands separator (1,500 → 1500) and a dot as a decimal separator (1.500 → 1.5). A value with a comma is still imported, and the row gets a note in the Warning column of the import report, so you can check it. A value with a dot gets no warning: 1.500 is already a valid decimal number in Shopify's format, so it's sent unchanged.

The same applies to list items: 1,000, 2,000 in a list.number_integer is read as [1000,2000], with a warning for each item.

The safest way to write numbers

Use a dot as the decimal separator and no thousands separators: 1234.56, 1.5. Such values never depend on the rest of the file.

Base types​

Text​

Single line text - single_line_text_field​

  • Accepts: any text.
  • Line breaks are replaced with spaces, since a single line field can't contain them.
  • Choices: if the definition limits the field to a list of allowed values ("Limit to preset choices"), the value is matched to a choice ignoring letter case and extra spaces, and the choice's exact spelling is saved.
InputConverted to
CottonCotton
Line one + line break + line twoLine one line two
small (choices: Small, Medium)Small
extra LARGE (choices: Extra large)Extra large

Multi-line text - multi_line_text_field​

  • Accepts: any text; line breaks are preserved. Put the value in a quoted CSV cell (spreadsheet apps do it for you) so the line breaks don't split the row.

Rich text - rich_text_field​

Shopify stores rich text as a JSON document. The import accepts three formats:

  1. Shopify's rich text JSON - sent as is: {"type":"root","children":[{"type":"paragraph","children":[{"type":"text","value":"Hello"}]}]}
  2. HTML - any value that starts with an HTML tag is converted. Supported tags: <p>, <div>, <h1>-<h6>, <ul>, <ol>, <li>, <a href="..."> (with title and target), <strong> (bold), <em> (italic), <br>. Other tags (<span>, <b>, <i>, <table>, ...) are dropped but their text is kept - use <strong>/<em> instead of <b>/<i>.
  3. Plain text - each block separated by an empty line becomes a paragraph; a single line break stays inside the paragraph.
InputConverted to
Hello world{"type":"root","children":[{"type":"paragraph","children":[{"type":"text","value":"Hello world"}]}]}
<p>Hello <strong>bold</strong></p>{"type":"root","children":[{"type":"paragraph","children":[{"type":"text","value":"Hello "},{"type":"text","value":"bold","bold":true}]}]}
<ul><li>One</li><li>Two</li></ul>{"type":"root","children":[{"type":"list","listType":"unordered","children":[{"type":"list-item","children":[{"type":"text","value":"One"}]},{"type":"list-item","children":[{"type":"text","value":"Two"}]}]}]}

Reference​

Reference metafields store Shopify GIDs (global IDs), for example gid://shopify/Product/8123456789. You can always import a GID, but GIDs differ between stores, so the import also accepts a human-readable identifier for most types and looks up the GID in your store. This is how the migration between stores works.

TypeGID formatAlternative identifier
product_referencegid://shopify/Product/123Product handle: classic-cotton-tee
variant_referencegid://shopify/ProductVariant/123Variant SKU: TEE-RED-M
collection_referencegid://shopify/Collection/123Collection handle: summer-sale
page_referencegid://shopify/Page/123Page handle: about-us
article_referencegid://shopify/Article/123Blog post handle: how-to-choose-a-size
customer_referencegid://shopify/Customer/123Customer email: jane@example.com
company_referencegid://shopify/Company/123Company name: Acme Inc
order_referencegid://shopify/Order/123Order name: #1001
metaobject_referencegid://shopify/Metaobject/123type/handle: brand/acme, or just the handle acme (see below)
file_referencegid://shopify/MediaImage/123 (also Video, GenericFile, Model3d, ExternalVideo)Public file URL: https://example.com/images/photo.jpg
product_taxonomy_value_referencegid://shopify/TaxonomyValue/123- (GID only)

Details:

  • The referenced item must already exist in the store, and the app needs read access to it (for example, the customers permission for customer_reference). Otherwise, the row fails with a "not found" or a missing-permission error.
  • Handle lookups ignore letter case and surrounding spaces. Product handles are also normalized the way Shopify creates them, so Classic Cotton Tee is looked up as classic-cotton-tee.
  • metaobject_reference requires a metafield definition that specifies the metaobject type. Thanks to the definition, the handle alone is enough: acme is looked up as <definition type>/acme. You can also write brand/acme explicitly.
  • file_reference with a URL: the file is downloaded from the URL and uploaded to your store's Files, and the new file's GID is saved. The URL must be publicly accessible. For files with an existing name, see the Duplicated images option.
  • A JSON array with a single item is accepted for a single reference: ["gid://shopify/Product/123"] is saved as gid://shopify/Product/123.
  • Old-style page GIDs (gid://shopify/OnlineStorePage/123) are converted to gid://shopify/Page/123 automatically.

Number​

Integer - number_integer​

  • Accepts: any number (see How numbers are read).
  • Decimals are cut off, not rounded: 12.9 → 12, -3.7 → -3.
InputConverted to
4242
1 2501250
12.912
$1,005.071005

Decimal - number_decimal​

  • Accepts: any number; the decimal part is kept as written.
InputConverted to
19.9919.99
19,9919.99
1,234.561234.56
7.2e-30.0072

Money - money​

  • Canonical format: {"amount":"19.99","currency_code":"USD"}.
  • A plain number is saved in your store's currency.
  • Only the store currency is accepted. Shopify rejects money values in other currencies (must match shop currency), even as a JSON object with another currency_code. Convert amounts to your store's currency before importing.
Input (store currency: USD)Converted to
19.99{"amount":"19.99","currency_code":"USD"}
$1,299.00{"amount":"1299.00","currency_code":"USD"}
{"amount":"19.99","currency_code":"USD"}sent as is
{"amount":"19.99","currency_code":"EUR"}rejected by Shopify - the store currency is USD
A currency symbol doesn't set the currency

Symbols are removed from plain numbers, not interpreted: €19.99 in a USD store is saved as 19.99 USD, without converting the amount.

Rating - rating​

  • Canonical format: {"scale_min":"0.0","scale_max":"5.0","value":"4.5"}. Shopify stores the numbers with a decimal part ("1" is saved as "1.0"), but whole numbers are accepted too.
  • A plain number is saved with the scale from the metafield definition (scale_min/scale_max validations). Without a definition, the scale is 0-5.
  • The value must fit the scale: 7 on a 0-5 scale is rejected by Shopify.
InputSaved as
4.5 (no definition){"scale_min":"0.0","scale_max":"5.0","value":"4.5"}
8 (definition scale 1-10){"scale_min":"1.0","scale_max":"10.0","value":"8.0"}
{"scale_min":"1","scale_max":"10","value":"8"}{"scale_min":"1.0","scale_max":"10.0","value":"8.0"}

ID - id​

  • Accepts: any text, sent as is (for example, SKU-001 or ext-48213). Shopify requires the value to be unique among metafields with the same definition.
  • Requires a metafield definition. Shopify doesn't allow id metafields without one (type: 'id' cannot be used without a definition).

Measurement​

Measurement types store a number together with a unit: {"value":2.5,"unit":"KILOGRAMS"}. This group includes weight, volume, dimension, and all the extended Shopify measurement types (temperature, voltage, speed, and so on - see the full table below).

The import accepts:

  1. A number with a unit: 2.5 kg, 2.5kg, 2.5 KG, 30 cm, 22 °C, 60 km/h, 512 GB. The unit is matched against the unit's symbol, short label, alias, or Shopify key - all listed in the table below - and the matching is forgiving:
    • letter case and a trailing dot don't matter: KG, lb.;
    • a plural s is accepted: lbs, kgs;
    • the degree sign is optional: 22 C, 22 deg C, 22 ℃;
    • u can replace µ: 10 uF;
    • 2/3 can replace ²/³: 10 m2, 5 ft3/h;
    • spaces can replace underscores: 60 kilometers per hour;
    • common full names, British spellings, and symbols are recognized: kilo, gram, pound, ounce, litre, centimetre, inch or ", foot or ', sq ft, sq m, kmh, kph, hr, sec, and so on.
  2. A plain number: 2.5 - saved with the default unit of the type. For weight, volume, and dimension, the default unit is the one chosen in the app settings (falling back to the table below); for other types, it's the default from the table.
  3. JSON: {"value":2.5,"unit":"KILOGRAMS"} - the unit can be written in any of the ways above (KILOGRAMS, kg, kgs).
TypeInputConverted to
weight2.5 kg{"value":2.5,"unit":"KILOGRAMS"}
weight2.5 (default unit: grams){"value":2.5,"unit":"GRAMS"}
weight{"value":2.5,"unit":"kg"}{"value":2.5,"unit":"KILOGRAMS"}
dimension30 cm{"value":30,"unit":"CENTIMETERS"}
volume1.5 L{"value":1.5,"unit":"LITERS"}
temperature-40 °F{"value":-40,"unit":"FAHRENHEIT"}
speed60 km/h{"value":60,"unit":"KILOMETERS_PER_HOUR"}
data_storage_capacity512 GB{"value":512,"unit":"GIGABYTES"}
weight5 lbs{"value":5,"unit":"POUNDS"}
dimension10"{"value":10,"unit":"INCHES"}
area10 m2{"value":10,"unit":"SQUARE_METERS"}
weight5 banana / 5 kg (net)rejected - unknown unit
An unknown unit is an error

If the text after the number isn't a unit of the metafield's type - a typo, an unsupported unit, or extra words like 5 kg (net) - the value is not imported. The row fails, and the Warning column of the import report lists the units the type supports, for example: Unknown unit "banana" for Weight. Supported units: oz, lb, g, kg. A unit is never replaced with the default unit silently; only a plain number without any unit gets the default unit.

Measurement types and units​

Each unit is listed as SHOPIFY_KEY followed by the symbols and aliases the import recognizes.

TypeLabelDefault unitUnits
weightWeightGRAMSOUNCES (oz), POUNDS (lb), GRAMS (g), KILOGRAMS (kg)
volumeVolumeMILLILITERSMILLILITERS (ml), CENTILITERS (cl), LITERS (L/l), CUBIC_METERS (m³/m3), FLUID_OUNCES (fl oz/fo/us_fl_oz), PINTS (pt/us_pt), QUARTS (qt/us_qt), GALLONS (gal/us_gal), IMPERIAL_FLUID_OUNCES (imp fl oz/ifo/imp_fl_oz), IMPERIAL_PINTS (imp pt/ip/imp_pt), IMPERIAL_QUARTS (imp qt/iq/imp_qt), IMPERIAL_GALLONS (imp gal/ig/imp_gal)
dimensionDimensionMILLIMETERSINCHES (in), FEET (ft), YARDS (yd), MILLIMETERS (mm), CENTIMETERS (cm), METERS (m)
antenna_gainAntenna gainDECIBELS_ISOTROPICDECIBELS_ISOTROPIC (dBi/decibels_isotropic), DECIBELS_DIPOLE (dBd/decibels_dipole)
areaAreaSQUARE_METERSSQUARE_CENTIMETERS (cm²/square_centimeters), SQUARE_FEET (ft²/square_feet), SQUARE_INCHES (in²/square_inches), SQUARE_METERS (m²/square_meters), SQUARE_YARDS (yd²/square_yards)
battery_charge_capacityBattery charge capacityMILLIAMP_HOURSMILLIAMP_HOURS (mAh/milliamp_hours)
battery_energy_capacityBattery energy capacityWATT_HOURSWATT_HOURS (Wh/watt_hours)
capacitanceCapacitanceFARADSPICOFARADS (pF/picofarads), NANOFARADS (nF/nanofarads), MICROFARADS (µF/microfarads), FARADS (F/farads)
concentrationConcentrationMILLIGRAMS_PER_MILLILITERMILLIGRAMS_PER_GRAM (mg/g/milligrams_per_gram), MILLIGRAMS_PER_MILLILITER (mg/ml/milligrams_per_milliliter)
data_storage_capacityData storage capacityBYTESBYTES (B/bytes), KILOBYTES (KB/kilobytes), MEGABYTES (MB/megabytes), GIGABYTES (GB/gigabytes), TERABYTES (TB/terabytes)
data_transfer_rateData transfer rateBITS_PER_SECONDBITS_PER_SECOND (bps/bits_per_second), KILOBITS_PER_SECOND (kbps/kilobits_per_second), MEGABITS_PER_SECOND (Mbps/megabits_per_second), GIGABITS_PER_SECOND (Gbps/gigabits_per_second)
display_densityDisplay densityPIXELS_PER_INCHPIXELS_PER_INCH (ppi/pixels_per_inch), DOTS_PER_INCH (dpi/dots_per_inch)
distanceDistanceKILOMETERSKILOMETERS (km/kilometers), MILES (mi/miles)
durationDurationSECONDSNANOSECONDS (ns/nanoseconds), MICROSECONDS (µs/microseconds), MILLISECONDS (ms/milliseconds), SECONDS (s/seconds), MINUTES (min/minutes), HOURS (h/hours), DAYS (d/days), MONTHS (mo/months), YEARS (yr/years)
electric_currentElectric currentAMPERESMILLIAMPERES (mA/milliamperes), AMPERES (A/amperes), KILOAMPERES (kA/kiloamperes)
electrical_resistanceElectrical resistanceOHMSOHMS (Ω/ohms), KILOOHMS (kΩ/kiloohms)
energyEnergyJOULESJOULES (J/joules), CALORIES (cal/calories), KILOJOULES (kJ/kilojoules), KILOCALORIES (kcal/kilocalories)
frequencyFrequencyHERTZHERTZ (Hz/hertz), KILOHERTZ (kHz/kilohertz), MEGAHERTZ (MHz/megahertz), GIGAHERTZ (GHz/gigahertz)
illuminanceIlluminanceLUXLUX (lx/lux), FOOT_CANDLES (fc/foot_candles)
inductanceInductanceHENRIESMICROHENRIES (µH/microhenries), MILLIHENRIES (mH/millihenries), HENRIES (H/henries)
luminous_fluxLuminous fluxLUMENSLUMENS (lm/lumens)
mass_flow_rateMass flow rateKILOGRAMS_PER_SECONDGRAMS_PER_DAY (g/d), GRAMS_PER_HOUR (g/h), GRAMS_PER_MINUTE (g/min), GRAMS_PER_SECOND (g/s), OUNCES_PER_DAY (oz/d), OUNCES_PER_HOUR (oz/h), OUNCES_PER_MINUTE (oz/min), OUNCES_PER_SECOND (oz/s), POUNDS_PER_DAY (lb/d), POUNDS_PER_HOUR (lb/h), POUNDS_PER_MINUTE (lb/min), POUNDS_PER_SECOND (lb/s), KILOGRAMS_PER_DAY (kg/d), KILOGRAMS_PER_HOUR (kg/h), KILOGRAMS_PER_MINUTE (kg/min), KILOGRAMS_PER_SECOND (kg/s), TONS_PER_DAY (ton/d), TONS_PER_HOUR (ton/h), TONS_PER_MINUTE (ton/min), TONS_PER_SECOND (ton/s), TONNES_PER_DAY (t/d), TONNES_PER_HOUR (t/h), TONNES_PER_MINUTE (t/min), TONNES_PER_SECOND (t/s); each also accepts its lowercase key as an alias, e.g. grams_per_hour
powerPowerWATTSMILLIWATTS (mW/milliwatts), WATTS (W/watts), HORSEPOWER (hp/horsepower), KILOWATTS (kW/kilowatts)
pressurePressureBARSPOUNDS_PER_SQUARE_INCH (psi/pounds_per_square_inch), BARS (bar/bars)
resolutionResolutionPIXELSPIXELS (px/pixels), MEGAPIXELS (MP/megapixels)
rotational_speedRotational speedREVOLUTIONS_PER_MINUTEREVOLUTIONS_PER_MINUTE (rpm/revolutions_per_minute)
sound_levelSound levelDECIBELSDECIBELS (dB/decibels)
speedSpeedMETERS_PER_SECONDKILOMETERS_PER_HOUR (km/h/kilometers_per_hour), FEET_PER_SECOND (ft/s/feet_per_second), MILES_PER_HOUR (mph/miles_per_hour), METERS_PER_SECOND (m/s/meters_per_second)
temperatureTemperatureCELSIUSCELSIUS (°C/celsius), FAHRENHEIT (°F/fahrenheit), KELVIN (K/kelvin)
thermal_powerThermal powerKILOWATTSBRITISH_THERMAL_UNITS_PER_HOUR (BTU/h/british_thermal_units_per_hour), KILOWATTS (kW/kilowatts), TONS_OF_REFRIGERATION (TR/tons_of_refrigeration)
voltageVoltageVOLTSVOLTS (V/volts)
volumetric_flow_rateVolumetric flow rateLITERS_PER_SECONDLITERS_PER_HOUR (L/h), LITERS_PER_MINUTE (L/min), LITERS_PER_SECOND (L/s), GALLONS_PER_HOUR (gal/h), GALLONS_PER_MINUTE (gal/min), GALLONS_PER_SECOND (gal/s), CUBIC_FEET_PER_HOUR (ft³/h), CUBIC_FEET_PER_MINUTE (ft³/min), CUBIC_FEET_PER_SECOND (ft³/s), CUBIC_METERS_PER_HOUR (m³/h), CUBIC_METERS_PER_MINUTE (m³/min), CUBIC_METERS_PER_SECOND (m³/s); each also accepts its lowercase key as an alias, e.g. liters_per_minute

URL - url​

  • Canonical format: a full URL starting with https:, http:, mailto:, tel:, or sms: - for example https://example.com/size-guide, mailto:support@example.com, tel:+15551234567.
  • Cleaned up automatically: an uppercase scheme (HTTPS:// → https://), and quotes or angle brackets around the value (<https://example.com>). Spaces in the path and non-Latin domains (https://приклад.укр) are kept as is; Shopify accepts them.
  • Completed, with a note in the Warning column:
    • a domain without a scheme gets https://: example.com, www.example.com/size, shop.example.co.uk:8080;
    • a protocol-relative URL gets https:: //example.com/a;
    • an email address gets mailto:: support@example.com.
  • Rejected, with the reason in the Warning column:
    • relative paths like /pages/size-guide (the import doesn't know which domain you mean - add it);
    • other schemes (ftp:, javascript:);
    • https:// without a domain, or with a space in the domain;
    • anything else that isn't a URL, including phone numbers without tel:.
InputConverted to
https://example.com/size-guidehttps://example.com/size-guide
HTTPS://Example.comhttps://Example.com
example.com/sizehttps://example.com/size (warning)
support@example.commailto:support@example.com (warning)
+15551234567rejected - write tel:+15551234567
/pages/size-guiderejected - write https://your-store.com/pages/size-guide

A link is a URL with a label: {"text":"Size guide","url":"https://example.com/size-guide"}. Besides the JSON, the import accepts text followed or preceded by a URL; the URL can be in parentheses. The URL follows the URL type rules: the scheme is lowercased, and a missing one is completed with a warning. A URL without a scheme is recognized only where it can't be part of the label:

  • the whole value is the URL: example.com;
  • it's in parentheses: Size guide (example.com/size);
  • it starts with www.: Shop now www.example.com/sale.

Otherwise a dotted word stays in the label (Node.js guide has no URL, so it's rejected with a warning). In a JSON link object, a URL without a scheme is completed the same way: {"text":"Shop","url":"example.com"} → {"text":"Shop","url":"https://example.com"}.

InputConverted to
https://example.com{"url":"https://example.com","text":""}
Shop now https://example.com/sale{"url":"https://example.com/sale","text":"Shop now"}
Size guide (https://example.com/size-guide){"url":"https://example.com/size-guide","text":"Size guide"}
Call us (tel:+15551234567){"url":"tel:+15551234567","text":"Call us"}
{"text":"Shop","url":"https://example.com"}sent as is
Size guide (example.com/size){"url":"https://example.com/size","text":"Size guide"} (warning)
Contact us (support@example.com){"url":"mailto:support@example.com","text":"Contact us"} (warning)

Date and time​

Date - date​

  • Canonical format: YYYY-MM-DD, for example 2025-12-31.
  • Also accepts:
    • year first: 2025/12/31, 2025.12.31, 2025 12 31;
    • day and month as numbers: 31.12.2025, 31-12-2025, 31/12/2025, 12/31/2025, 31/12/25 (see Day or month first below);
    • English month names, full or short, with an optional ordinal suffix: Dec 31 2025, 31 Dec 2025, December 31, 2025, 31-Dec-2025, 31st December 2025;
    • a date with a time (2025-12-31T10:00:00Z → 2025-12-31; the time is dropped);
    • a label or brackets around the date: Date: 2025-12-31, (31.12.2025).
  • Two-digit years 00-68 mean 2000-2068, 69-99 mean 1969-1999.
  • Not recognized: Unix timestamps and Excel serial dates (1704067200, 45657), dates without a year (31.12), and dates that don't exist (2025-13-01, 31/02/2025, 2025-02-29). The Warning column of the import report explains why, and the value is sent to Shopify as is. Shopify rejects most of them, but it can read some numbers as a date of its own: 1704067200 is saved as 2017-04-06. Convert such values to YYYY-MM-DD before importing.

Day or month first​

When the day and the month are written as numbers, the import works out which one comes first:

  1. From the value itself, if one of the numbers is greater than 12: 31/12/2025 and 12/31/2025 are both December 31.
  2. Dotted dates are always day first: 02.01.2025 is January 2.
  3. From the other values of the same metafield in the file (the same column in the "columns" format, the same namespace and key in the "rows" format): if any of them is written like 31/12/2025, 02/01/2025 is read as January 2; if like 12/31/2025 - as February 1.
  4. From your store's country, if the file doesn't tell: month first for stores in the United States, the Philippines, and US territories; day first for all other countries. The value is imported, and the row gets a note in the Warning column, so you can check it.
InputConverted to
2025-12-312025-12-31
31.12.20252025-12-31
December 31, 20252025-12-31
31st Dec 20252025-12-31
02.01.20252025-01-02
02/01/2025 (US store, nothing else in the column)2025-02-01 + warning
02/01/2025 (UK store, nothing else in the column)2025-01-02 + warning
02/01/2025 (the column also has 31/12/2025)2025-01-02
31/02/2025rejected (warning)
1704067200not recognized (warning); Shopify saves it as 2017-04-06

Date and time - date_time​

  • Canonical format: YYYY-MM-DDTHH:mm:ss+00:00, for example 2025-12-31T13:45:00+00:00.
  • Also accepts: any date format followed by a time: 2025-12-31T13:45, 2025-12-31 13:45:30, 31.12.2025 13:45, 12/31/2025 07:30, Dec 31 2025 1:45 PM. Seconds are optional, milliseconds are dropped, and a date without a time means midnight. The day/month order is resolved the same way as for dates.
  • Times without an offset are taken as UTC: 2025-12-31 13:45 is saved as 13:45 UTC, not in your store's time zone. If the time is in your local time zone, add the offset: 2025-12-31 13:45+02:00.
  • Explicit offsets are converted to UTC: Z, +03:00, -0500, +05 are all supported - 2025-12-31T23:59:59+03:00 is saved as 2025-12-31T20:59:59+00:00.
  • Overflowing values are rolled over, the same way Shopify does it: a day up to 31 in a shorter month moves to the next month (2025-02-30 10:00 → 2025-03-02T10:00:00+00:00), and 24:00 or a leap second (23:59:60) moves to the next day or minute (2025-12-31 24:00 → 2026-01-01T00:00:00+00:00). This applies only to date_time: a date that doesn't exist is rejected.
  • Other impossible values (2025-12-32 10:00, 2025-13-01 10:00, 24:30, 10:60, 13:45 PM) are rejected with a warning.
InputConverted to
2025-12-31T13:45:002025-12-31T13:45:00+00:00
31.12.2025 13:452025-12-31T13:45:00+00:00
Dec 31 2025 1:45 PM2025-12-31T13:45:00+00:00
2025-12-312025-12-31T00:00:00+00:00
2025-12-31T23:59:59+03:002025-12-31T20:59:59+00:00
2025-12-31T23:30:00-02:002026-01-01T01:30:00+00:00
2025-12-31 24:002026-01-01T00:00:00+00:00
2025-02-30 10:002025-03-02T10:00:00+00:00
2025-12-32 10:00rejected (warning)

Other​

True or false - boolean​

InputConverted to
true, 1, yes, y, on, ttrue
false, 0, no, n, off, ffalse
maybe, 2, any other textrejected

Letter case and surrounding spaces don't matter: TRUE, Yes, N are all accepted.

Other values are an error

A value that isn't in the table is not imported: the row fails, and the Warning column of the import report lists the accepted values. Convert values in other languages or formats (ja/nein, ✓) to true/false before importing.

Color - color​

  • Canonical format: a 6-digit lowercase hex code, #ff0000.
  • Also accepts:
    • hex in any letter case, with or without #: #FF0000, ff0000;
    • the 3-digit shorthand: f00 → #ff0000;
    • hex with transparency (#ff000080, #f008);
    • rgb() and rgba() with numbers 0-255 or percentages, separated by commas or spaces: rgb(255, 0, 0), rgb(100% 50% 0%), rgba(255, 0, 0, 0.5), rgb(255 0 0 / 50%);
    • hsl() and hsla(): hsl(0, 100%, 50%), hsl(120deg 100% 25%);
    • the 148 CSS color names, in any letter case and with optional spaces or dashes: red, Navy, Dark Blue, rebeccapurple.
  • Transparency is dropped, because Shopify colors can't be transparent: #ff000080 and rgba(255, 0, 0, 0.5) are saved as #ff0000, and the import report shows a warning.
  • Not accepted: hex codes of other lengths (ff, #12345), transparent, color names in other languages, and out-of-range values (rgb(300, 0, 0)). Such values are rejected, and the Warning column of the import report explains why.
InputConverted to
#FF0000#ff0000
f00#ff0000
rgb(0, 128, 255)#0080ff
hsl(120deg 100% 25%)#008000
Navy#000080
#ff000080#ff0000 + warning
reddishrejected

Language - language​

  • Canonical format: an ISO 639-1 language code with an optional region: en, de, pt-BR.
  • Also accepts: any letter case (EN-us → en-US) and the English language name (German → de, Portuguese (Brazil) → pt-BR, Chinese (Simplified) → zh-CN).
  • Three-letter codes (haw) and unknown names are rejected, and the Warning column explains why.

Deprecated types - string, integer, json_string​

These legacy types are still imported: string as any text, integer as an integer, and json_string with the same rules as json. Use their modern equivalents (single_line_text_field/multi_line_text_field, number_integer, json) for new metafields.

Advanced​

JSON - json​

  • Accepts: any valid JSON value, sent as is: an object, an array, a number, a string in double quotes ("hello"), true, false, null.
  • true, false and null in any case (TRUE, Null) are lowercased.
  • Repaired, with a note in the Warning column: a value that starts like JSON (with {, [ or a quote) but isn't valid. Unquoted keys and single quotes are fixed, missing brackets are closed, and several objects on separate lines become an array. The warning shows the result, because a repair can hide lost data - for example, a cell cut off by a spreadsheet's length limit.
  • Rejected, with the reason in the Warning column: plain text (hello, a: 1), numbers with a decimal comma (1,5), None, and JSON followed by extra text ({"a":1} trailing). To store text, wrap it in double quotes ("hello") or use a text type.
InputConverted to
{"size":"M","fit":"slim"}sent as is
"hello"sent as is
TRUEtrue
{size:'M'}{"size":"M"} (warning)
{"size":"M"{"size":"M"} (warning)
'hello'"hello" (warning)
hellorejected - write "hello"
1,5rejected - write 1.5

Mixed reference - mixed_reference​

  • Accepts: a metaobject GID (gid://shopify/Metaobject/123) or type/handle (brand/acme). Unlike metaobject_reference, the handle alone isn't enough, since the field can reference several metaobject types.
  • Requires a metafield definition that lists the allowed metaobject types, just like metaobject_reference.

List types​

Most types have a list version, named with the list. prefix: list.single_line_text_field, list.product_reference, list.weight, etc. Shopify stores a list as a JSON array, and every item follows the rules of its base type described above.

The types without a list version are: multi_line_text_field, rich_text_field, money, id, boolean, language, and json.

How list values are read​

A list cell can be written in these ways:

  1. A JSON array (recommended, never ambiguous): ["Red","Green","Blue"]. Single quotes and small mistakes are repaired: ['Red','Blue'] works too.
  2. One item per line:
    Red, dark
    Blue
    If the value has line breaks, every line is an item and commas or semicolons inside a line stay part of the item: the example above is ["Red, dark","Blue"].
  3. Semicolon-separated values: Red, dark; Blue. Used when the value has no line breaks but has a semicolon; commas inside items are kept.
  4. Comma-separated values: Red, Green, Blue. Used when the value has neither line breaks nor semicolons.

Spaces around items are trimmed. Separators inside parentheses, brackets or braces never split items: rgb(255, 0, 0), red is two items.

One unreadable item rejects the whole list

Every item must be readable. If any item can't be read - an unknown color, a date that doesn't exist, text in a number list - the whole list is not imported, and the Warning column names the item and says how many items failed (The list was not imported because 1 of 3 items could not be read.). The import never saves a partial list, because it would replace the full list already stored in the metafield.

Empty items are dropped: red,,blue becomes ["#ff0000","#0000ff"], and ["red",""] becomes ["#ff0000"]. A list with no items left ([], [""]) is treated as an empty cell: skipped, or deleted if the Empty metafields option is set to Delete.

Items are sent to Shopify in the form it stores them: measurements, ratings and links as objects, integers as numbers, decimals and everything else as strings.

Items of these types can contain a comma themselves (1,5, 1,000, https://example.com/?ids=1,2, Dec 31, 2025), so comma-separated lists of them are split more carefully:

  1. If the value has a comma followed by a space, items are split only at a comma followed by a space: 1,5, 2,5 → 1,5 and 2,5; 1,000, 2,000 → 1,000 and 2,000.
  2. Otherwise numbers and measurements are split at commas that aren't between two digits: 1,5kg,2kg → 1,5kg and 2kg.
  3. If every comma is between two digits (1,2,3, 1,5,2,5), the other values of the same metafield in the file decide (see Ambiguous numbers):
    • if they don't use a decimal comma, every comma separates items: 1,2,3 → 1, 2, 3;
    • if they use a decimal comma, a single comma is a decimal one (1,5 → [1.5]), and a value with several commas can't be split: it is rejected, and the Warning column explains why.

Each item is then read with the rules of its base type, so 1,5 becomes 1.5 and 1,000 becomes 1000 exactly as in a single-value metafield.

Dates with month names need another separator

Dec 31, 2025, Jan 1, 2026 can't be split by commas: the comma inside each date looks like an item separator. Put each date on its own line, separate them with ; (Dec 31, 2025; Jan 1, 2026), or use a JSON array.

Text lists​

list.single_line_text_field​

Each item is a single line text value. Allowed choices from the definition are matched for every item, ignoring case and extra spaces.

InputConverted to
Red, Green, Blue["Red","Green","Blue"]
["Red, dark","Blue"]["Red, dark","Blue"]
small, LARGE (choices: Small, Large)["Small","Large"]
Red, dark; Blue["Red, dark","Blue"]
Red, dark + line break + Blue["Red, dark","Blue"]

Reference lists​

list.product_reference, list.variant_reference, list.collection_reference, list.page_reference, list.article_reference, list.customer_reference, list.company_reference, list.order_reference, list.metaobject_reference, list.file_reference, list.product_taxonomy_value_reference.

Each item can be a GID or the same alternative identifier as the base reference type. GIDs and identifiers can be mixed in one list.

TypeInputConverted to
list.product_referenceclassic-cotton-tee, wool-hoodie["gid://shopify/Product/111","gid://shopify/Product/222"]
list.product_reference["gid://shopify/Product/111","gid://shopify/Product/222"]sent as is
list.variant_referenceTEE-RED-M, TEE-BLUE-L["gid://shopify/ProductVariant/333","gid://shopify/ProductVariant/444"]
list.metaobject_referenceacme, brewly["gid://shopify/Metaobject/555","gid://shopify/Metaobject/666"]
list.file_referencehttps://example.com/1.jpg, https://example.com/2.jpg["gid://shopify/MediaImage/777","gid://shopify/MediaImage/888"] (files uploaded)

If one item can't be resolved (for example, a handle doesn't exist), the whole row fails with a "not found" error.

Number lists​

list.number_integer and list.number_decimal​

TypeInputConverted to
list.number_integer1, 2, 3[1,2,3]
list.number_integer[1,2,3][1,2,3]
list.number_decimal1.5, 2, 3.25["1.5","2.0","3.25"]
list.number_decimal[1.5,2,3.25]["1.5","2.0","3.25"]
list.number_decimal1,5; 2,5["1.5","2.5"]
list.number_decimal1,5, 2,5["1.5","2.5"]
list.number_integer1,000, 2,000[1000,2000] + warning (ambiguous numbers)

Decimal commas work when items are separated by ; , , (comma and space) or line breaks. Without spaces (1,5,2,5) the items can't be told apart; see Commas in numbers, measurements, links and dates.

list.rating​

Plain numbers get the definition's scale (or 0-5), just like a single rating.

Input (no definition)Converted to
4, 3.5[{"scale_min":"0.0","scale_max":"5.0","value":"4.0"},{"scale_min":"0.0","scale_max":"5.0","value":"3.5"}]
[{"scale_min":"0","scale_max":"5","value":"4"}][{"scale_min":"0.0","scale_max":"5.0","value":"4.0"}]

Measurement lists​

list.weight, list.volume, list.dimension, and the list. version of every other measurement type. Each item is a number with a unit, a plain number (default unit), or a {"value":...,"unit":...} object.

TypeInputConverted to
list.weight1 kg, 500 g[{"value":1,"unit":"KILOGRAMS"},{"value":500,"unit":"GRAMS"}]
list.weight["1 kg","500 g"][{"value":1,"unit":"KILOGRAMS"},{"value":500,"unit":"GRAMS"}]
list.weight[{"value":1,"unit":"KILOGRAMS"},{"value":500,"unit":"GRAMS"}]sent as is
list.dimension10 cm, 20 cm[{"value":10,"unit":"CENTIMETERS"},{"value":20,"unit":"CENTIMETERS"}]
list.weight1,5 kg, 2 kg[{"value":1.5,"unit":"KILOGRAMS"},{"value":2,"unit":"KILOGRAMS"}]

list.url​

InputConverted to
https://a.example.com, https://b.example.com["https://a.example.com","https://b.example.com"]
https://example.com/?ids=1,2, https://b.example.com["https://example.com/?ids=1,2","https://b.example.com"]

Each item is text plus a URL, or a link object. Put each link on its own line or separate them with ; if the link texts contain commas; otherwise commas work too.

InputConverted to
Size guide https://example.com/size, Care https://example.com/care[{"url":"https://example.com/size","text":"Size guide"},{"url":"https://example.com/care","text":"Care"}]
[{"text":"Size guide","url":"https://example.com/size"}][{"text":"Size guide","url":"https://example.com/size"}]

Date and time lists​

list.date and list.date_time​

Each item accepts the same formats as date / date_time.

TypeInputConverted to
list.date2025-01-01, 2025-12-31["2025-01-01","2025-12-31"]
list.date["2025-01-01","31.12.2025"]["2025-01-01","2025-12-31"]
list.dateDec 31, 2025; Jan 1, 2026["2025-12-31","2026-01-01"]
list.date_time2025-01-01 10:00, 2025-12-31T18:30:00["2025-01-01T10:00:00+00:00","2025-12-31T18:30:00+00:00"]

Other lists​

list.color​

InputConverted to
#ff0000, #00ff00["#ff0000","#00ff00"]
["f00","0f0"]["#ff0000","#00ff00"]
rgb(255, 0, 0), navy["#ff0000","#000080"]

Advanced lists​

list.mixed_reference​

Each item is a metaobject GID or type/handle: brand/acme, material/cotton.

Common pitfalls​

  • 1,500 and 1.500 are ambiguous. They're read according to the other values of the same metafield in the file; if the file doesn't tell, 1,500 is fifteen hundred (with a warning) and 1.500 is one and a half (without one). Use a dot for decimals and no thousands separators.
  • Unknown units make the row fail. Typos and extra words after the unit (5 kg (net)) aren't guessed; the report's Warning column lists the supported units. Check the measurement table.
  • Booleans accept only true/false, 1/0, yes/no, y/n, on/off, t/f. Anything else makes the row fail.
  • 02/01/2025 depends on the file and your store's country. Use YYYY-MM-DD to avoid ambiguity.
  • Numbers aren't dates. Unix timestamps and Excel serial dates aren't converted; Shopify may still save them as some other date (1704067200 → 2017-04-06). Check the Warning column.
  • date_time values without an offset are UTC, not your store's time zone. Add an offset (+02:00) for local times.
  • An overflowing date_time is rolled over, not rejected: 2025-02-30 10:00 becomes March 2 and 24:00 becomes midnight of the next day, as in Shopify. A date must exist.
  • One bad item rejects the whole list. Check the Warning column for the item that couldn't be read.
  • List items are split by line breaks first, then ;, then commas. Items with commas (text, month-name dates) need line breaks, ; or a JSON array; decimal commas need ; or , between items.
  • Colors must be opaque. Transparency in #rrggbbaa, rgba() and hsla() is dropped with a warning; unknown color names are rejected.
  • json values must be JSON. Plain text is rejected - wrap it in double quotes. Repaired JSON is imported with a warning; check that nothing was cut off.
  • URLs without a scheme get https:// (emails get mailto:) with a warning; relative paths like /pages/size-guide are rejected. Write full URLs.
  • Referenced items must exist in the store before the import, and the app needs access to them.
  • Some types need a definition: id, metaobject_reference and mixed_reference can't be imported without a metafield definition.
  • Money is saved in the store currency only. Values in other currencies are rejected by Shopify.
  • The definition type wins over the Metafield type column; a different or unknown type is replaced with a warning.
  • Integers are truncated (12.9 → 12), not rounded.