--- title: Manage metaobject definitions description: 'Learn how to create, read, update, and delete metaobject definitions.' source_url: html: >- https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions md: >- https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md --- ExpandOn this page * [Requirements](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#requirements) * [Creating definitions](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#creating-definitions) * [Reading definitions](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#reading-definitions) * [Updating definitions](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#updating-definitions) * [Deleting definitions](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#deleting-definitions) * [Error handling](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#error-handling) * [Best practices](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#best-practices) * [TOML reference](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#toml-reference) * [TOML limitations](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#toml-limitations) * [Next steps](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#next-steps) # 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. *** ## Requirements * Your app can make [authenticated requests](https://shopify.dev/docs/api/usage/authentication) to the GraphQL Admin API. * Your app has the `read_metaobject_definitions` and `write_metaobject_definitions` [access scopes](https://shopify.dev/docs/api/usage/access-scopes). *** ## Creating 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. ### TOML (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 ```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 ```bash 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. ### Graph​QL 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. ##### Merchant-owned (editable in Shopify admin) ```graphql # 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 } } } ``` ##### App-owned (app controlled) ```graphql # 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. ### Dynamic 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 ```graphql mutation CreateDynamicMetaobject($input: MetaobjectDefinitionCreateInput!) { metaobjectDefinitionCreate(definition: $input) { metaobjectDefinition { id name type fieldDefinitions { key name type { name } } } userErrors { field message } } } ``` ## Variables ```json { "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" } ] } } ``` *** ## Reading definitions Query metaobject definitions to retrieve their structure and configuration. ### Querying 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 ```graphql query GetAllDefinitions { metaobjectDefinitions(first: 50) { edges { node { id type name description access { admin storefront } fieldDefinitions { key name type { name } required } } } } } ``` ### Querying 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 ```graphql query GetDefinitionByType { metaobjectDefinitionByType(type: "size_chart") { id type name description fieldDefinitions { key name type { name } required validations { name value } } access { admin storefront } } } ``` *** ## Updating 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. ### Updating 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 ```graphql 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 } } } ``` ### Adding a new field 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 ```graphql 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 } } } ``` ### Updating 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 ```graphql mutation UpdateDefinitionAccess { metaobjectDefinitionUpdate( id: "gid://shopify/MetaobjectDefinition/123" definition: { access: { admin: MERCHANT_READ_WRITE storefront: NONE } } ) { metaobjectDefinition { id access { admin storefront } } userErrors { field message } } } ``` *** ## Deleting definitions Remove definitions that are no longer needed. Deleting the definition also deletes all related metaobjects, metafield definitions, and metafields asynchronously. ### Deleting with TOML For app-owned definitions created with TOML, remove the definition block from your `shopify.app.toml` file and redeploy: ## Terminal ```bash shopify app deploy ``` ### Deleting with Graph​QL Use the GraphQL Admin API to delete metaobject definitions. ## GraphQL POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json ```graphql mutation DeleteDefinition { metaobjectDefinitionDelete( id: "gid://shopify/MetaobjectDefinition/123" ) { deletedId userErrors { field message } } } ``` *** ## Error handling Common errors when managing metaobject definitions: | Error | Cause | Solution | | - | - | - | | `TAKEN` | Type has already been taken | Use a different type identifier or update the existing definition | | `INVALID` | Type contains invalid characters | Use only alphanumeric characters, underscores, and dashes | | `NOT_AUTHORIZED` | Type is reserved for another app or Shopify | For app-owned types, use `$app:`. Don't use `shopify--` or other reserved prefixes. | | `DUPLICATE_FIELD_INPUT` | A field with this key already exists in the definition | Use a different field key for each field | *** ## Best practices * **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. *** ## TOML reference Metaobjects are declared in `shopify.app.toml` using the format `[metaobjects.app.]`. For example, `[metaobjects.app.author]` declares a metaobject named `author` with type `$app:author`. ### Metaobject definition properties | Property | Description | | - | - | | `name` | Human-readable name displayed in the Shopify admin. | | `description` | Descriptive text that explains the purpose of the metaobject. | | `display_name_field` | Key of a field to reference as the display name for each entry. | | `access.admin` | Admin API access control: `merchant_read` or `merchant_read_write`. | | `access.storefront` | Storefront access control: `public_read`, `private_read`, or `none`. | | `capabilities.publishable` | When `true`, enables draft/active status for content workflow. See [metaobject capabilities](https://shopify.dev/docs/apps/build/metaobjects/use-metaobject-capabilities). | | `capabilities.translatable` | When `true`, enables translation support for fields. See [translatable content](https://shopify.dev/docs/apps/build/metaobjects/use-metaobject-capabilities#make-your-metaobjects-translatable). | | `capabilities.renderable` | When `true`, enables metaobject SEO fields on Liquid and the Storefront API. See [metaobjects as web pages](https://shopify.dev/docs/apps/build/metaobjects/use-metaobject-capabilities#render-metaobjects-as-web-pages). | ### Metaobject field properties Fields are declared using the format `[metaobjects.app..fields.]`. For example, `[metaobjects.app.author.fields.birthday]` declares a field named `birthday` on the `author` metaobject. | Property | Description | | - | - | | `type` | Data type for the field. Uses the same types as metafields. See [metafield data types](https://shopify.dev/docs/apps/build/metafields/list-of-data-types). | | `name` | Human-readable name displayed in the Shopify admin. | | `description` | Descriptive text that explains the purpose of the field. | | `required` | When `true`, the field must have a value when saving the metaobject. | | `validations` | Rules to validate field values based on the field type. See [validation options](https://shopify.dev/docs/apps/build/metafields/list-of-validation-options). | *** ## TOML limitations When using TOML-based declarative definitions, be aware of these constraints: ### App-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. ### App-scoped limits | Limit | Value | | - | - | | Metaobject definitions | 32 | | Field definitions per metaobject | 64 | | Changes per deploy | 25 | 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. ### Read-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. ### Capability support | Capability | Supported in TOML | | - | - | | [Publishable](https://shopify.dev/docs/apps/build/metaobjects/use-metaobject-capabilities#draft-custom-content) | ✅ | | [Translatable](https://shopify.dev/docs/apps/build/metaobjects/use-metaobject-capabilities#make-your-metaobjects-translatable) | ✅ | | [Renderable](https://shopify.dev/docs/apps/build/metaobjects/use-metaobject-capabilities#render-metaobjects-as-web-pages) | ✅ | | [Online Store](https://shopify.dev/docs/apps/build/metaobjects/use-metaobject-capabilities#make-your-metaobjects-render-web-pages-in-the-online-store) | ❌ | *** ## Next steps * Learn how to [work with metaobject entries](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobjects). * Learn how to [enable advanced features](https://shopify.dev/docs/apps/build/metaobjects/use-metaobject-capabilities). *** * [Requirements](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#requirements) * [Creating definitions](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#creating-definitions) * [Reading definitions](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#reading-definitions) * [Updating definitions](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#updating-definitions) * [Deleting definitions](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#deleting-definitions) * [Error handling](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#error-handling) * [Best practices](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#best-practices) * [TOML reference](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#toml-reference) * [TOML limitations](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#toml-limitations) * [Next steps](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions.md#next-steps)