Skip to main content

Manage metaobject definitions

Metaobject definitions are schemas that specify the structure, fields, and rules for metaobject types. This guide shows you how to create, read, update, and delete metaobject definitions using TOML configuration or the GraphQL Admin API.



Anchor to Creating definitionsCreating definitions

There are two ways to set up metaobject definitions:

  • TOML: TOML configurations in shopify.app.toml create app-owned definitions. Your app maintains control while optionally allowing edits in the Shopify admin.
  • GraphQL: The GraphQL Admin API provides programmatic control for creating merchant-owned metaobjects (editable in the Shopify admin and accessible to all installed apps) and dynamically generating definitions based on user configuration.

Anchor to TOML (app-owned) exampleTOML (app-owned) example

This example creates an app-owned metaobject definition for author profiles. Because the app controls the author data structure, it uses the app's TOML configuration file to ensure that the definition is consistently deployed across all installations.

File

shopify.app.toml
[metaobjects.app.author]
name = "Author"
access.admin = "merchant_read_write"
access.storefront = "public_read"

[metaobjects.app.author.fields.full_name]
name = "Full Name"
type = "single_line_text_field"

[metaobjects.app.author.fields.bio]
name = "Biography"
type = "multi_line_text_field"

[metaobjects.app.author.fields.email]
name = "Email"
type = "single_line_text_field"

[metaobjects.app.author.fields.photo]
name = "Profile Photo"
type = "file_reference"

Deploy the changes with your app:

Terminal

shopify app deploy

Benefits of TOML:

  • Definitions are version-controlled as part of your app.
  • Automatic creation and updates on deploy.
  • Works with shopify app dev to safely test out changes.
  • Consistent across all shops - when you update your app's data structure, it deploys to every installation automatically.
  • The app maintains ownership.

Anchor to GraphQL Admin API exampleGraphQL Admin API example

These examples show how to create metaobject definitions using GraphQL. The first creates a merchant-owned definition that all apps can access. The second creates an app-owned definition that only your app controls.

# POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

mutation CreateSizeChartDefinition {
metaobjectDefinitionCreate(definition: {
type: "size_chart"
name: "Size Chart"
description: "Product sizing information"
access: {
storefront: PUBLIC_READ
}
fieldDefinitions: [
{
key: "size"
name: "Size"
type: "single_line_text_field"
required: true
}
{
key: "chest_inches"
name: "Chest (inches)"
type: "number_decimal"
}
{
key: "waist_inches"
name: "Waist (inches)"
type: "number_decimal"
}
]
}) {
metaobjectDefinition {
id
type
name
fieldDefinitions {
key
name
type { name }
}
}
userErrors {
field
message
}
}
}
# POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

mutation CreateAppOwnedDefinition {
metaobjectDefinitionCreate(definition: {
type: "$app:warranty_info"
name: "Warranty Information"
description: "Extended warranty details"
access: {
admin: MERCHANT_READ_WRITE
storefront: PUBLIC_READ
}
fieldDefinitions: [
{
key: "coverage_period"
name: "Coverage Period"
type: "single_line_text_field"
}
{
key: "terms"
name: "Terms and Conditions"
type: "multi_line_text_field"
}
]
}) {
metaobjectDefinition {
id
type
name
}
userErrors {
field
message
}
}
}

Key differences:

  • Merchant-owned: Use a simple type name without any prefix (like size_chart or author). This provides full control over both the definition and entries in the Shopify admin. access.admin isn't required. Only access.storefront is used to control customer visibility.
  • App-owned: Use the reserved $app: prefix in the type. The app controls the definition. Use access.admin to grant merchant write permissions for the entries.

Use GraphQL when:

  • Merchants define their own custom metaobjects through your app's UI.
  • Field structure varies per merchant or changes frequently.
  • Building form builders, CMS-like tools, or content managers.
  • You're creating merchant-owned metaobjects that other apps can access.

Anchor to Dynamic definition creation exampleDynamic definition creation example

This example shows how to programmatically create definitions based on user input, such as in a content manager app where custom metaobject types are configured through your app's UI.

Your app would collect metaobject configuration (using a form or UI), validate the input, construct the variables object, and then execute the mutation. This enables the creation of custom metaobjects through your app's interface without editing code or configuration files.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL mutation

mutation CreateDynamicMetaobject($input: MetaobjectDefinitionCreateInput!) {
metaobjectDefinitionCreate(definition: $input) {
metaobjectDefinition {
id
name
type
fieldDefinitions {
key
name
type { name }
}
}
userErrors {
field
message
}
}
}

Variables

{
"input": {
"type": "custom_content_block",
"name": "Custom Content Block",
"description": "User-defined content block",
"fieldDefinitions": [
{
"key": "title",
"name": "Title",
"type": "single_line_text_field"
},
{
"key": "content",
"name": "Content",
"type": "rich_text_field"
}
]
}
}

Query metaobject definitions to retrieve their structure and configuration.

Anchor to Querying all definitionsQuerying all definitions

Retrieve all metaobject definitions to discover what types exist and their configurations. Use this to find available type identifiers when building admin interfaces or before creating entries.

GraphQL

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
query GetAllDefinitions {
metaobjectDefinitions(first: 50) {
edges {
node {
id
type
name
description
access {
admin
storefront
}
fieldDefinitions {
key
name
type { name }
required
}
}
}
}
}

Anchor to Querying a specific definition by typeQuerying a specific definition by type

Retrieve a single definition using its type identifier. This is useful when you need to check a definition's structure before creating entries or to verify field configurations.

GraphQL

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
query GetDefinitionByType {
metaobjectDefinitionByType(type: "size_chart") {
id
type
name
description
fieldDefinitions {
key
name
type { name }
required
validations {
name
value
}
}
access {
admin
storefront
}
}
}

Anchor to Updating definitionsUpdating definitions

Modify existing definitions to add fields, update access, or change configuration. To update definitions declared in TOML, simply update the configuration file, test with shopify app dev and deploy a new version of your app.

Anchor to Updating name and descriptionUpdating name and description

Update the display name and description of a metaobject definition. This is useful for improving clarity or correcting information without affecting the underlying structure.

GraphQL

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
mutation UpdateDefinitionDetails {
metaobjectDefinitionUpdate(
id: "gid://shopify/MetaobjectDefinition/123"
definition: {
name: "Updated Size Chart"
description: "Comprehensive sizing information for all products"
}
) {
metaobjectDefinition {
id
name
description
}
userErrors {
field
message
}
}
}

Add new fields to an existing metaobject definition. This enables you to extend the data structure as your app's requirements evolve.

GraphQL

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
mutation AddFieldToDefinition {
metaobjectDefinitionUpdate(
id: "gid://shopify/MetaobjectDefinition/123"
definition: {
fieldDefinitions: [
{
key: "hip_inches"
name: "Hip (inches)"
type: "number_decimal"
}
]
}
) {
metaobjectDefinition {
id
fieldDefinitions {
key
name
type { name }
}
}
userErrors {
field
message
}
}
}

Anchor to Updating access permissionsUpdating access permissions

Modify access permissions to control who can read or write metaobject entries. This is useful for adjusting visibility or editing rights as your requirements change.

GraphQL

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
mutation UpdateDefinitionAccess {
metaobjectDefinitionUpdate(
id: "gid://shopify/MetaobjectDefinition/123"
definition: {
access: {
admin: MERCHANT_READ_WRITE
storefront: NONE
}
}
) {
metaobjectDefinition {
id
access {
admin
storefront
}
}
userErrors {
field
message
}
}
}

Anchor to Deleting definitionsDeleting definitions

Remove definitions that are no longer needed. Deleting the definition also deletes all related metaobjects, metafield definitions, and metafields asynchronously.

For app-owned definitions created with TOML, remove the definition block from your shopify.app.toml file and redeploy:

Terminal

shopify app deploy

Anchor to Deleting with GraphQLDeleting with GraphQL

Use the GraphQL Admin API to delete metaobject definitions.

GraphQL

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
mutation DeleteDefinition {
metaobjectDefinitionDelete(
id: "gid://shopify/MetaobjectDefinition/123"
) {
deletedId
userErrors {
field
message
}
}
}

Common errors when managing metaobject definitions:

ErrorCauseSolution
TAKENType has already been takenUse a different type identifier or update the existing definition
INVALIDType contains invalid charactersUse only alphanumeric characters, underscores, and dashes
NOT_AUTHORIZEDType is reserved for another app or ShopifyFor app-owned types, use $app:. Don't use shopify-- or other reserved prefixes.
DUPLICATE_FIELD_INPUTA field with this key already exists in the definitionUse a different field key for each field

  • Use TOML for app-owned definitions: Declarative configuration ensures consistency across deployments and enables version control.
  • Plan your type identifiers carefully: Type identifiers can't be changed after creation.
  • Document field purposes: Use clear names and descriptions to help merchants understand each field's purpose.
  • Set appropriate access levels: Start with restrictive access and expand as needed.
  • Test definition changes: Verify that field additions or updates work correctly before deploying to production.

Metaobjects are declared in shopify.app.toml using the format [metaobjects.app.<metaobject_name>]. For example, [metaobjects.app.author] declares a metaobject named author with type $app:author.

Anchor to Metaobject definition propertiesMetaobject definition properties

PropertyDescription
nameHuman-readable name displayed in the Shopify admin.
descriptionDescriptive text that explains the purpose of the metaobject.
display_name_fieldKey of a field to reference as the display name for each entry.
access.adminAdmin API access control: merchant_read or merchant_read_write.
access.storefrontStorefront access control: public_read, private_read, or none.
capabilities.publishableWhen true, enables draft/active status for content workflow. See metaobject capabilities.
capabilities.translatableWhen true, enables translation support for fields. See translatable content.
capabilities.renderableWhen true, enables metaobject SEO fields on Liquid and the Storefront API. See metaobjects as web pages.

Anchor to Metaobject field propertiesMetaobject field properties

Fields are declared using the format [metaobjects.app.<metaobject_name>.fields.<field_name>]. For example, [metaobjects.app.author.fields.birthday] declares a field named birthday on the author metaobject.

PropertyDescription
typeData type for the field. Uses the same types as metafields. See metafield data types.
nameHuman-readable name displayed in the Shopify admin.
descriptionDescriptive text that explains the purpose of the field.
requiredWhen true, the field must have a value when saving the metaobject.
validationsRules to validate field values based on the field type. See validation options.

When using TOML-based declarative definitions, be aware of these constraints:

Anchor to App-reserved namespaceApp-reserved namespace

You can only declare metaobject definitions in the app-reserved namespace ($app:) to ensure that only the owning app can make changes to definitions. This constraint allows Shopify to guarantee a consistent state between all shops your app is installed on.

LimitValue
Metaobject definitions32
Field definitions per metaobject64
Changes per deploy25

To ensure Shopify can quickly and reliably distribute definitions across shops, you can't make more than 25 metaobject changes (creation, update, or deletion) in a single deploy. If you need to make more than 25 changes, do so over multiple deploys.

Anchor to Read-only through Admin APIRead-only through Admin API

Declarative definitions are read-only through the Admin API, and can only be updated or deleted through the TOML configuration file. You can query declarative definitions through the Admin API, but mutations will return an error.

CapabilitySupported in TOML
Publishable
Translatable
Renderable
Online Store


Was this page helpful?