Skip to main content

Custom Fields

Checkout and waitlist forms can collect extra answers from buyers. Each answer definition is a custom field: a named input with a type, label, and optional validation.

Identity is name — a slug such as size, never a UUID. Nested collections live under a product (checkout or waitlist) or under a variant (checkout override).

Overview

Each operation has live and draft twins, and three parent collections. Paths are listed on the endpoint pages.

Collections

A product has two independent arrays:

  • Checkout/products/{productId}/custom-fields (and /draft/custom-fields). Shown on the checkout form.
  • Waitlist/products/{productId}/waitlist-custom-fields (and /draft/waitlist-custom-fields). Shown on the waitlist form only. These do not appear at checkout.

A variant may store its own checkout array at /product-variants/{id}/custom-fields (live) or /products/{productId}/draft/variants/{id}/custom-fields (overlay):

  • An empty array means inherit the product checkout fields.
  • A non-empty array wholesale-replaces the product checkout fields for that price. Creating the first variant field drops the product-level checkout fields for buyers of that variant.
  • There is no way to force “no fields” on a variant when the product has some.
  • Variants have no waitlist collection.

Live writes while a draft exists

When the parent product has has_draft: true, live nested writes return 409 and change nothing. Edit the overlay instead (/products/{productId}/draft/…). See Live writes while a draft exists.

Draft writes require draft_version from Get Product Draft. Create and update on the overlay also return a fresh preview_url. Overlay delete returns 204 with no body.

Include on parent GETs

Get Product and Get Product Draft always include custom_fields and waitlist_custom_fields keys. The value is null unless you pass ?include=custom_fields and/or ?include=waitlist_custom_fields. When requested, the value is the stored array (possibly empty) — not the { items, pagination } list envelope.

Get Product Variant and Get Product Draft Variant always include custom_fields. The value is null unless ?include=custom_fields. Nested variants[] on a product leave this key null. GET /products list items omit the keys.

Product and draft GET also accept include=styles,settings,media — see Checkout appearance.

Writes are the nested collection endpoints. Sending custom_fields on product or variant PATCH is ignored.

Order

order is the field's 0-based position in its collection, and the order the fields appear at checkout. A collection is always numbered 0..n-1 with no gaps.

Create appends the new field to the end. Delete closes the gap. Patching order moves that field to the given position and renumbers the rest, so one write can change the order of fields you did not send — a value past the last position lands the field last. There is no reorder endpoint, so ordering n fields takes n calls.

Types

type is one of text, textarea, checkbox, integer, decimal, select, date, datetime. select requires options with at least one { value, label }. checkbox is a field type, not a checkout consent string (mandatory_consent lives on the product).

Custom Field Object

FieldTypeNullableDescription
namestringNoIdentity slug. Pattern ^[a-z0-9_-]+$, max 50. Immutable after create. Path {name}.
typestringNoOne of the types above.
labelstringNoBuyer-facing copy, max 255.
placeholderstringYesForm-hint copy, max 255.
enabledbooleanNofalse hides the field without deleting it. Disabled fields are skipped at checkout.
requiredbooleanNoInert when enabled is false.
orderintegerNo0-based position in the collection. See Order.
validationobjectYes{ min, max } for integer / decimal answers. null means no min/max. precision is not public and is refused.
validation.minintegerYesMinimum.
validation.maxintegerYesMaximum.
optionsarrayNoSelect choices. Empty when the type is not select.
options[].valuestringNoStored choice value, max 100.
options[].labelstringNoBuyer-facing choice label, max 255.
sync_easymailbooleanNoMarks the definition for Easymail contact sync when the field is also enabled. Does not create Easymail catalog fields.

Draft create/update responses add:

FieldTypeNullableDescription
draft_versionintegerNoNew overlay version after the write. Minimum 1.
preview_urlstringNoTemporary signed checkout preview. Expires after about one hour. See Draft preview.

The internal UUID minted on create is never returned.