Skip to content

Metaobjects

PUT /custom-data/metaobjects/{type}/entries/{handle} — scope write_metaobjects.

A metaobject is a record of a type the merchant defines in the admin (Settings → Custom data): a “second-hand car”, a “store event”, a “size chart”. Your app fills entries of that type; the store’s theme renders them. This is how the Zugo app publishes vehicle listings.

PUT creates the entry if {handle} does not exist in {type} and replaces it entirely if it does. Choose handles from your own stable ids — the same source record always maps to the same entry, so re-running a sync updates rather than duplicates.

PUT /custom-data/metaobjects/ikinci-el-arac/entries/zugo-48213
Content-Type: application/json
{
"fields": {
"marka": "Renault",
"yil": 2021,
"gorseller": ["<mediaAssetId>", "<mediaAssetId>"]
},
"publishedAt": "2026-09-22T09:00:00+00:00",
"seoTitle": "2021 Renault Clio",
"translations": { "en": { "marka": "Renault" } }
}
Field Meaning
fields Object keyed by the type’s field keys; values are any JSON the field type accepts.
publishedAt When the entry becomes visible. Only for types marked publishable; otherwise 400.
seoTitle, seoDescription At most 256 and 512 characters.
translations { locale: { fieldKey: text } }. For a file_reference field the value is the media id of that language’s own file ("" = no file in that language); the file must be in your media library.

Handles are lowercase letters, digits, - and _, at most 128 characters.

Status Meaning
200 { "id", "handle", "publishedAt", "seoTitle", "seoDescription" }
400 Validation problem — an invalid handle, a field key the type does not define, a value its field type rejects, a reference to a record that does not exist, or a text over its limit.
404 No metaobject type {type} in this store. The merchant must create it first.

The field keys and their types come from the merchant’s type definition, not from the platform. Agree on them with the store before you build — they are the contract between your app and the theme.

This route does not take an Idempotency-Key; it does not need one, because repeating the same PUT produces the same entry.

entries[type] is every published entry of the type, for loops and lists. When a template needs ONE entry it knows the handle of, use entries.by_handle[type][handle]: it loads only that entry (or nothing), instead of the whole type.

{%- assign car = entries.by_handle['ikinci-el-arac']['zugo-48213'] -%}
{%- if car -%}<h1>{{ car.title.value }}</h1>{%- endif -%}