---
title: Manage entries
description: >-
  Learn how to create, update, and delete metaobjects using the GraphQL Admin
  API.
source_url:
  html: 'https://shopify.dev/docs/apps/build/metaobjects/manage-metaobjects'
  md: 'https://shopify.dev/docs/apps/build/metaobjects/manage-metaobjects.md'
api_name: admin
---

# Manage entries

Metaobjects let you store structured data with multiple related field values. This guide shows you how to create, read, update, and delete metaobject entries using 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_metaobjects` and `write_metaobjects` [access scopes](https://shopify.dev/docs/api/usage/access-scopes#authenticated-access-scopes).
* You've created a [metaobject definition](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions) for your metaobject. The definition specifies the fields, validations, and permissions.

***

## Creating entries

Create metaobject entries to store instances of structured data based on your metaobject definitions.

### Create a basic entry

This example creates a size chart metaobject entry with basic field values. Both the field keys and `type` must match the existing metaobject definition.

## GraphQL

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

```graphql
mutation CreateSizeChartEntry {
  metaobjectCreate(metaobject: {
    type: "size_chart"
    fields: [
      { key: "size", value: "Medium" }
      { key: "chest_inches", value: "38" }
      { key: "waist_inches", value: "32" }
      { key: "hip_inches", value: "36" }
    ]
  }) {
    metaobject {
      id
      handle
      displayName
      fields {
        key
        value
      }
    }
    userErrors {
      field
      message
    }
  }
}
```

### Create an entry with capabilities

If your metaobject definition has [capabilities](https://shopify.dev/docs/apps/build/metaobjects/use-metaobject-capabilities) enabled (such as publishable), set their initial state when creating entries. This example creates an author metaobject with publishable status set to active.

## GraphQL

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

```graphql
mutation CreatePublishableEntry {
  metaobjectCreate(metaobject: {
    type: "$app:author"
    capabilities: {
      publishable: {
        status: ACTIVE
      }
    }
    fields: [
      { key: "full_name", value: "Jane Smith" }
      { key: "bio", value: "Award-winning author with 20 years of experience..." }
      { key: "email", value: "jane@example.com" }
    ]
  }) {
    metaobject {
      id
      handle
      displayName
      capabilities {
        publishable {
          status
        }
      }
    }
    userErrors {
      field
      message
    }
  }
}
```

### Create entries in batch

When you need to create many metaobject entries, use bulk operations for better performance. This is more efficient than making separate requests for each entry.

## GraphQL

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

```graphql
mutation CreateBulkEntries {
  bulkOperationRunMutation(
    mutation: """
      mutation createMetaobject($input: MetaobjectCreateInput!) {
        metaobjectCreate(metaobject: $input) {
          metaobject { id }
          userErrors { field message }
        }
      }
    """
    stagedUploadPath: "bulk_ops/metaobjects_create.jsonl"
  ) {
    bulkOperation {
      id
      status
    }
    userErrors {
      field
      message
    }
  }
}
```

***

## Reading entries

Query metaobject entries to retrieve their data using various approaches.

### Query entries by type

Retrieve all metaobject entries of a specific type. This is useful when you need to list all entries, such as displaying all size charts or author profiles.

## GraphQL

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

```graphql
query GetSizeCharts {
  metaobjects(type: "size_chart", first: 10) {
    edges {
      node {
        id
        handle
        displayName
        fields {
          key
          value
        }
      }
    }
  }
}
```

### Query a specific entry by handle

Retrieve a single metaobject using its handle. Handles are URL-friendly identifiers for referencing specific entries.

## GraphQL

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

```graphql
query GetMetaobjectByHandle {
  metaobjectByHandle(handle: {
    type: "size_chart"
    handle: "medium"
  }) {
    id
    handle
    displayName
    fields {
      key
      value
    }
    updatedAt
  }
}
```

### Query a specific entry by ID

Retrieve a metaobject entry using its global ID. This is useful when you have the ID stored and need to fetch the entry's current state.

## GraphQL

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

```graphql
query GetMetaobjectById {
  metaobject(id: "gid://shopify/Metaobject/123") {
    id
    handle
    displayName
    type
    fields {
      key
      value
      type
    }
    capabilities {
      publishable {
        status
      }
    }
  }
}
```

### Query specific fields

Optimize queries by requesting only the fields you need.

## GraphQL

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

```graphql
query GetSpecificFields {
  metaobject(id: "gid://shopify/Metaobject/123") {
    field(key: "full_name") {
      value
    }
    emailField: field(key: "email") {
      value
    }
  }
}
```

### Query with filters

Filter metaobject entries based on field values. This is useful for finding entries that match specific criteria, such as all size charts for "Large" sizes.

## GraphQL

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

```graphql
query GetFilteredMetaobjects {
  metaobjects(
    type: "size_chart"
    first: 10
    query: "size:Large"
  ) {
    edges {
      node {
        id
        displayName
        fields {
          key
          value
        }
      }
    }
  }
}
```

***

## Updating entries

Modify existing metaobject entries to change field values or capability states.

### Update field values

Update one or more field values in a metaobject entry. Optimize the operation by including only the fields you want to change.

## GraphQL

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

```graphql
mutation UpdateSizeChart {
  metaobjectUpdate(
    id: "gid://shopify/Metaobject/123"
    metaobject: {
      fields: [
        { key: "chest_inches", value: "40" }
        { key: "waist_inches", value: "34" }
      ]
    }
  ) {
    metaobject {
      id
      fields {
        key
        value
      }
      updatedAt
    }
    userErrors {
      field
      message
    }
  }
}
```

**Note:**

You can't change the metaobject `type` after it's created. Field keys must match those defined in the metaobject definition, and field values must match their defined types.

### Update published status

For metaobjects with the publishable capability enabled, change their published status to control visibility on the storefront.

## GraphQL

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

```graphql
mutation PublishMetaobject {
  metaobjectUpdate(
    id: "gid://shopify/Metaobject/123"
    metaobject: {
      capabilities: {
        publishable: {
          status: ACTIVE
        }
      }
    }
  ) {
    metaobject {
      id
      capabilities {
        publishable {
          status
        }
      }
    }
    userErrors {
      field
      message
    }
  }
}
```

### Bulk update entries

When you need to update many metaobject entries, use bulk operations for better performance.

## GraphQL

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

```graphql
mutation BulkUpdateMetaobjects {
  bulkOperationRunMutation(
    mutation: """
      mutation updateMetaobject($id: ID!, $metaobject: MetaobjectUpdateInput!) {
        metaobjectUpdate(id: $id, metaobject: $metaobject) {
          metaobject { id }
          userErrors { field message }
        }
      }
    """
    stagedUploadPath: "bulk_ops/metaobjects_update.jsonl"
  ) {
    bulkOperation {
      id
      status
    }
    userErrors {
      field
      message
    }
  }
}
```

***

## Deleting entries

Remove metaobject entries that are no longer needed using the GraphQL Admin API.

### Delete a single entry

Delete a metaobject entry using its global ID.

## GraphQL

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

```graphql
mutation DeleteMetaobject {
  metaobjectDelete(
    id: "gid://shopify/Metaobject/123"
  ) {
    deletedId
    userErrors {
      field
      message
    }
  }
}
```

### Bulk delete entries

When you need to delete many metaobject entries, use bulk operations for better performance.

## GraphQL

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

```graphql
mutation BulkDeleteMetaobjects {
  bulkOperationRunMutation(
    mutation: """
      mutation deleteMetaobject($id: ID!) {
        metaobjectDelete(id: $id) {
          deletedId
          userErrors { field message }
        }
      }
    """
    stagedUploadPath: "bulk_ops/metaobjects_delete.jsonl"
  ) {
    bulkOperation {
      id
      status
    }
    userErrors {
      field
      message
    }
  }
}
```

***

## Connecting metaobjects to resources

One of the most powerful patterns with metaobjects is connecting them to Shopify resources using metafields. [Reference type metafields](https://shopify.dev/docs/apps/build/metafields/list-of-data-types#reference-types) store links to metaobject entries, enabling you to create reusable structured data that can be attached to products, orders, and other resources.

**How it works:**

1. Create definitions (metaobject + metafield) in your TOML configuration and deploy
2. Create metaobject entries (such as "Waterproof", "Eco-friendly", "Durable")
3. Attach entries to products by setting the metafield value

**Why use this pattern:**

* **Reusability**: Create a feature (such as 'Waterproof') once, reference it from 100 products
* **Maintainability**: Update the feature entry, and it updates everywhere it's referenced
* **Structure**: Features have consistent fields (title, description, icon) defined by the metaobject definition

**Reference types available:**

* `metaobject_reference` - Link to a single metaobject entry
* `list.metaobject_reference` - Link to multiple entries of the same metaobject type
* `mixed_reference` - Link to entries from different metaobject types

### Step 1: Create definitions

Define the metaobject structure and the metafield that references it:

## TOML

shopify.app.toml

```toml
# Metaobject definition
[metaobjects.app.product_feature]
name = "Product Feature"


[metaobjects.app.product_feature.fields.title]
type = "single_line_text_field"
name = "Title"


[metaobjects.app.product_feature.fields.description]
type = "multi_line_text_field"
name = "Description"


[metaobjects.app.product_feature.fields.icon]
type = "file_reference"
name = "Icon"


# Metafield definition that references the metaobject
[product.metafields.product_info.features]
type = "list.metaobject_reference<$app:product_feature>"
name = "Product Features"
```

Deploy the definitions:

```bash
shopify app deploy
```

### Step 2: Create metaobject entries

## GraphQL

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

```graphql
mutation CreateWaterproofFeature {
  metaobjectCreate(metaobject: {
    type: "product_feature"
    fields: [
      { key: "title", value: "Waterproof" }
      { key: "description", value: "Protected against water damage" }
    ]
  }) {
    metaobject {
      id  # gid://shopify/Metaobject/789
      handle
    }
    userErrors {
      field
      message
    }
  }
}
```

### Step 3: Attach metaobject entries to a product

## GraphQL

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

```graphql
mutation AttachFeaturesToProduct {
  productUpdate(input: {
    id: "gid://shopify/Product/456"
    metafields: [{
      namespace: "product_info"
      key: "features"
      type: "list.metaobject_reference"
      value: "[\"gid://shopify/Metaobject/789\", \"gid://shopify/Metaobject/790\"]"
    }]
  }) {
    product {
      metafield(namespace: "product_info", key: "features") {
        references(first: 10) {
          nodes {
            ... on Metaobject {
              handle
              fields { key value }
            }
          }
        }
      }
    }
    userErrors {
      field
      message
    }
  }
}
```

***

## Handle management

Metaobject handles are URL-friendly identifiers used to reference entries.

### Auto-generated handles

By default, Shopify generates handles from the display name:

## GraphQL

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

```graphql
mutation CreateWithAutoHandle {
  metaobjectCreate(metaobject: {
    type: "size_chart"
    fields: [
      { key: "size", value: "Extra Large" }
    ]
  }) {
    metaobject {
      handle  # Will be "extra-large"
      displayName
    }
  }
}
```

### Custom handles

Specify a custom handle for more control:

## GraphQL

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

```graphql
mutation CreateWithCustomHandle {
  metaobjectCreate(metaobject: {
    type: "size_chart"
    handle: "xl-size-chart"
    fields: [
      { key: "size", value: "Extra Large" }
    ]
  }) {
    metaobject {
      handle
      displayName
    }
    userErrors {
      field
      message
    }
  }
}
```

***

## Error handling

Common errors when managing metaobject entries:

| Error | Cause | Solution |
| - | - | - |
| `UNDEFINED_OBJECT_TYPE` | No metaobject definition exists for this type | Create the definition first or check the type identifier |
| `OBJECT_FIELD_REQUIRED` | A required field value is not provided | Include all required fields in the mutation |
| `UNDEFINED_OBJECT_FIELD` | Field key doesn't exist in the definition | Verify field keys match the definition |
| `CAPABILITY_NOT_ENABLED` | Trying to use a capability not enabled on the definition | Enable the capability on the definition first |

***

## Best practices

* Use meaningful handles: Choose handles that clearly identify the entry's purpose.
* Validate before creating: Check that all required fields are provided and values match expected types.
* Use bulk operations for scale: When creating, updating, or deleting many entries, use bulk operations for better performance.
* Query only needed fields: Optimize API usage by requesting only the fields you need.
* Handle errors gracefully: Check `userErrors` in responses and provide clear feedback.
* Consider capability states: Set appropriate published/unpublished states for publishable metaobjects.

***

## Troubleshooting

Common issues and solutions when working with metaobject entries:

| Issue | Possible Causes | Solution |
| - | - | - |
| Entry not appearing on storefront | Missing storefront access, unpublished entry, or incorrect query | Verify the definition has `storefront: PUBLIC_READ` access, check if the entry is published (for publishable metaobjects), and ensure your storefront query includes the correct type |
| Unable to update entry | Missing permissions, incorrect ID, or invalid field keys | Confirm you have write access to the metaobject type, check that the entry ID is correct and the entry still exists, and verify field keys match the definition |
| Bulk operation failing | Invalid JSONL format, missing required fields, or file size issues | Validate your JSONL file format, check that all entries have required fields, ensure file size is within limits, and review bulk operation status for specific error details |

***

## Next steps

* Learn how to [work with metaobject definitions](https://shopify.dev/docs/apps/build/metaobjects/manage-metaobject-definitions).
* Learn how to [enable advanced features](https://shopify.dev/docs/apps/build/metaobjects/use-metaobject-capabilities).
* Learn about [metaobject limits](https://shopify.dev/docs/apps/build/metaobjects/metaobject-limits).

***
