> Documentation index: [Saleor](/llms.txt) · [This section](/api-usage/llms.txt)
> Source: https://docs.saleor.io/api-usage/metadata

# Metadata

Saleor gives you the possibility to customize your shop without modifying the core. You can extend most of the common models using the metadata API.

Metadata allows you to store additional information about each object, for example, external identifiers for items synchronized with a third-party platform. You can also use metadata to customize how your storefront looks and behaves.

warning

Never store sensitive information, including financial data such as credit card details.

<a id="supported-object-types"></a>

## Supported object types

Metadata is available in all GraphQL types that implement the `ObjectWithMetadata` interface. See the [Implemented by](/api-reference/miscellaneous/interfaces/object-with-metadata.md#implemented-by) section of the `ObjectWithMetadata` interface for the full list of supported types.

<a id="private-and-public-metadata"></a>

## Private and public metadata

All objects support two sets of metadata:

-   `metadata` is public and visible to the unauthenticated users.
-   `privateMetadata` is protected and visible only to the staff users, plugins, and Apps with appropriate permissions.

info

Modifying both requires permission to manage the item that metadata is attached to.

<a id="querying-metadata"></a>

## Querying metadata

All of the object types listed above implement the same interface:

```graphql
interface ObjectWithMetadata {
  privateMetadata: [MetadataItem]!
  privateMetafield(key: String!): String
  privateMetafields(keys: [String!]): Metadata
  metadata: [MetadataItem]!
  metafield(key: String!): String
  metafields(keys: [String!]): Metadata
}
```

Each `MetadataItem` is a key-value pair:

```graphql
type MetadataItem {
  key: String!
  value: String!
}
```

There is a special `Metadata` scalar that returns an object literal with keys as fields.

The following example fetches the metadata of the first product using both approaches to show the resulting data structures:

```graphql
{
  products(first: 1) {
    edges {
      node {
        id
        name
        metadata {
          key
          value
        }
        metafields
      }
    }
  }
}
```

Response:

```json
{
  "data": {
    "products": {
      "edges": [
        {
          "node": {
            "id": "UHJvZHVjdDo3Mg==",
            "name": "Apple Juice",
            "metadata": [
              {
                "key": "tax.group",
                "value": "Food products"
              }
            ],
            "metafields": {
              "tax.group": "Food products"
            }
          }
        }
      ]
    }
  }
}
```

<a id="selecting-fields-to-return"></a>

## Selecting fields to return

By default, `metafields` (`privateMetafields`) will return all metadata assigned to an object. You can use the optional `keys` argument to select the fields you want to return. We highly recommend that you only fetch the fields your application understands as it limits the amount of information being needlessly transferred.

The following example returns only the `tax.group` field:

```graphql
{
  products(first: 1) {
    edges {
      node {
        id
        name
        metafields(keys: ["tax.group"])
      }
    }
  }
}
```

If you only care about a single field, use `metafield` (`privateMetafield`) together with field aliasing:

```graphql
{
  products(first: 1) {
    edges {
      node {
        id
        name
        taxGroup: metafield(key: "tax.group")
      }
    }
  }
}
```

<a id="updating-metadata"></a>

## Updating metadata

The following GraphQL mutations allow you to update and remove metadata:

```graphql
type Mutation {
  updateMetadata(id: ID!, input: [MetadataInput!]!): UpdateMetadata
  updatePrivateMetadata(
    id: ID!
    input: [MetadataInput!]!
  ): UpdatePrivateMetadata
  deleteMetadata(id: ID!, keys: [String!]!): DeleteMetadata
  deletePrivateMetadata(id: ID!, keys: [String!]!): DeletePrivateMetadata
}
```

All resulting types have the same shape:

```graphql
type UpdateMetadata {
  metadataErrors: [MetadataError!]!
  item: ObjectWithMetadata
}
```

<a id="examples"></a>

## Examples

Here's an example of how a product's metadata could be updated:

```graphql
mutation {
  updateMetadata(
    id: "UHJvZHVjdDo3Mg=="
    input: [{ key: "special_product", value: "true" }]
  ) {
    metadataErrors {
      field
      code
    }
    item {
      metadata {
        key
        value
      }
    }
  }
}
```

And the same field being removed:

```graphql
mutation {
  deleteMetadata(id: "UHJvZHVjdDo3Mg==", keys: ["special_product"]) {
    metadataErrors {
      field
      code
    }
    item {
      metadata {
        key
        value
      }
    }
  }
}
```

<a id="filtering-by-metadata"></a>

## Filtering by metadata

Objects with metadata interface can be filtered by their values. Filtering is only available for public metadata.

```graphql
query FavoriteProducts {
  products(
    filter: { metadata: { key: "isFavorite", value: "true" } }
    first: 10
    channel: "default-channel"
  ) {
    edges {
      node {
        id
        name
      }
    }
  }
}
```

Response:

```json
{
  "data": {
    "products": {
      "edges": [
        {
          "node": {
            "id": "UHJvZHVjdDoxNDA=",
            "name": "Super Shirt"
          }
        }
      ]
    }
  }
}
```
