type Query {
    # Returns a Product resource by ID.
    product(id: ID!): Product

    # Return a product by its handle.
    productByHandle(handle: String!): Product

    # Returns the product resource feedback for the currently authenticated app.
    productResourceFeedback(id: ID!): ProductResourceFeedback

    # Returns a list of the shop's product saved searches.
    productSavedSearches(
        after: String
        before: String
        first: Int
        last: Int
        reverse: Boolean = false
    ): SavedSearchConnection!

    # Returns a ProductVariant resource by ID.
    productVariant(id: ID!): ProductVariant

    # List of the product variants.
    productVariants(
        after: String
        before: String
        first: Int
        last: Int
        query: String
        reverse: Boolean = false
        savedSearchId: ID
        sortKey: ProductVariantSortKeys = ID
    ): ProductVariantConnection!

    # List of products.
    products(
        after: String
        before: String
        first: Int
        last: Int
        query: String
        reverse: Boolean = false
        savedSearchId: ID
        sortKey: ProductSortKeys = ID
    ): ProductConnection!
}

type Mutation {
    # Appends images to a product.
    productAppendImages(input: ProductAppendImagesInput!): ProductAppendImagesPayload

    # Changes the status of a product. This allows you to set the availability of the product across all channels.
    productChangeStatus(productId: ID! status: ProductStatus!): ProductChangeStatusPayload

    # Creates a product.
    #
    # If you need to create a product with many variants that are active at several locations,
    # especially with a lot of collections and tags, then you should first create the product with just the variants.
    #
    # After the product is created, you can activate the variants at locations
    # and add the other related objects to the product. This reduces the size of each mutation and increases the likelihood that it will
    # complete before the operation times out.
    #
    # The following example shows how you might break up product creation and object association into multiple steps:
    #
    # Create the product with variants. Don't specify any tags or collections on the product, and don't specify
    # inventory quantities for each variant.
    #
    # After the product is created, add tags to the product using the tagsAdd mutation, and add collections using the
    # collectionsAddProducts mutation.
    #
    #  Use the inventoryBulkToggleActivation mutation on each inventory item to activate it at the appropriate locations.
    #
    # After activating the variants at the locations, adjust inventory quantities at each location using the
    # inventoryBulkAdjustQuantityAtLocation mutation.
    productCreate(input: ProductInput! media: [CreateMediaInput!]): ProductCreatePayload

    # Creates media for a product
    productCreateMedia(productId: ID! media: [CreateMediaInput!]!): ProductCreateMediaPayload

    # Deletes a product, including all associated variants and media.
    #
    # As of API version 2023-01, if you need to delete a large product, such as one that has many variants
    # that are active at several locations,
    # you may encounter timeout errors. To avoid these timeout errors, you can instead use the asynchronous
    # ProductDeleteAsync mutation.
    productDelete(input: ProductDeleteInput!): ProductDeletePayload

    # Removes product images from the product.
    productDeleteImages(id: ID! imageIds: [ID!]!): ProductDeleteImagesPayload

    # Deletes media for a product.
    productDeleteMedia(productId: ID! mediaIds: [ID!]!): ProductDeleteMediaPayload

    # Duplicates a product.
    #
    # As of API version 2023-01, if you need to duplicate a large product, such as one that has many variants
    # that are active at several locations, you may encounter timeout errors.
    # To avoid these timeout errors, you can instead use the asynchronous ProductDuplicateAsync mutation.
    productDuplicate(
        productId: ID!
        newTitle: String!
        newStatus: ProductStatus
        includeImages: Boolean = false
    ): ProductDuplicatePayload

    # Updates an image of a product.
    productImageUpdate(productId: ID! image: ImageInput!): ProductImageUpdatePayload

    # Adds multiple selling plan groups to a product.
    productJoinSellingPlanGroups(id: ID! sellingPlanGroupIds: [ID!]!): ProductJoinSellingPlanGroupsPayload

    # Removes multiple groups from a product.
    productLeaveSellingPlanGroups(id: ID! sellingPlanGroupIds: [ID!]!): ProductLeaveSellingPlanGroupsPayload

    # Asynchronously reorders a set of images for a given product.
    productReorderImages(id: ID! moves: [MoveInput!]!): ProductReorderImagesPayload

    # Asynchronously reorders the media attached to a product.
    productReorderMedia(id: ID! moves: [MoveInput!]!): ProductReorderMediaPayload

    # Updates a product. If you update a product and only include some variants in the update,
    # then any variants not included will be deleted. To safely manage variants without the risk of
    # deleting excluded variants, use productVariantsBulkUpdate.
    # If you want to update a single variant, then use productVariantUpdate.
    productUpdate(input: ProductInput!): ProductUpdatePayload

    # Updates media for a product.
    productUpdateMedia(productId: ID! media: [UpdateMediaInput!]!): ProductUpdateMediaPayload

    # Appends media from a product to variants of the product.
    productVariantAppendMedia(productId: ID! variantMedia: [ProductVariantAppendMediaInput!]!): ProductVariantAppendMediaPayload

    # Creates a product variant.
    productVariantCreate(input: ProductVariantInput!): ProductVariantCreatePayload

    # Deletes a product variant.
    productVariantDelete(id: ID!): ProductVariantDeletePayload

    # Detaches media from product variants.
    productVariantDetachMedia(productId: ID! variantMedia: [ProductVariantDetachMediaInput!]!): ProductVariantDetachMediaPayload

    # Adds multiple selling plan groups to a product variant.
    productVariantJoinSellingPlanGroups(id: ID! sellingPlanGroupIds: [ID!]!): ProductVariantJoinSellingPlanGroupsPayload

    # Remove multiple groups from a product variant.
    productVariantLeaveSellingPlanGroups(id: ID! sellingPlanGroupIds: [ID!]!): ProductVariantLeaveSellingPlanGroupsPayload

    # Updates a product variant.
    productVariantUpdate(input: ProductVariantInput!): ProductVariantUpdatePayload

    # Creates product variants in bulk. If you want to create a single variant, then use productVariantCreate.
    productVariantsBulkCreate(variants: [ProductVariantsBulkInput!]! productId: ID!): ProductVariantsBulkCreatePayload

    # Deletes product variants in bulk. If you want to delete a single variant, then use productVariantDelete.
    productVariantsBulkDelete(variantsIds: [ID!]! productId: ID!): ProductVariantsBulkDeletePayload

    # Reorder product variants in bulk.
    productVariantsBulkReorder(productId: ID! positions: [ProductVariantPositionInput!]!): ProductVariantsBulkReorderPayload

    # Updates product variants in bulk. If you want to update a single variant, then use
    # productVariantUpdate.
    productVariantsBulkUpdate(variants: [ProductVariantsBulkInput!]! productId: ID!): ProductVariantsBulkUpdatePayload
}

# The Product resource lets you manage products in a merchant’s store.
# You can use ProductVariants to create or update different versions of the same product.
# You can also add or update product Media. Products can be organized by grouping them into a Collection.
type Product
    implements HasMetafieldDefinitions&HasMetafields&HasPublishedTranslations&LegacyInteroperability&Navigable&Node&OnlineStorePreviewable&Publishable
    @key(fields: "id") {

    # The number of publications a resource is published to without feedback errors.
    availablePublicationCount: Int!

    # A list of the collections that include the product.
    collections(
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
        sortKey: CollectionSortKeys = ID
        query: String
    ): CollectionConnection!

    # The pricing that applies for a customer in a given context.
    contextualPricing(context: ContextualPricingContext!): ProductContextualPricing!

    # The date and time (ISO 8601 format) when the product was created.
    createdAt: DateTime!

    # A default cursor that returns the single next record, sorted ascending by ID.
    defaultCursor: String!

    # A stripped description of the product, single line with HTML tags removed.
    description(truncateAt: Int): String!

    # The description of the product, complete with HTML formatting.
    descriptionHtml: HTML!

    # The featured image for the product.
    featuredImage: Image

    # The featured media for the product.
    featuredMedia: Media

    # Information about the product that's provided through resource feedback.
    feedback: ResourceFeedback

    # The theme template used when viewing the gift card in a store.
    giftCardTemplateSuffix: String

    # A unique human-friendly string of the product's title.
    handle: String!

    # Whether the product has only a single variant with the default option and value.
    hasOnlyDefaultVariant: Boolean!

    # Whether the product has out of stock variants.
    hasOutOfStockVariants: Boolean!

    # A globally-unique identifier.
    id: ID!

    # The images associated with the product.
    images(
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
        sortKey: ProductImageSortKeys = POSITION
    ): ImageConnection!

    # Whether the product is in a given collection.
    inCollection(id: ID!): Boolean!

    # Whether the product is a gift card.
    isGiftCard: Boolean!

    # The ID of the corresponding resource in the REST Admin API.
    legacyResourceId: UnsignedInt64!

    # The media associated with the product. This can include images, 3D models, or videos.
    media(
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
        sortKey: ProductMediaSortKeys = POSITION
    ): MediaConnection!

    # Total count of media belonging to a product.
    mediaCount: Int!

    # Returns a metafield by namespace and key that belongs to the resource.
    metafield(namespace: String!key: String!): Metafield

    # List of metafield definitions.
    metafieldDefinitions(
        namespace: String
        pinnedStatus: MetafieldDefinitionPinnedStatus = ANY
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
        sortKey: MetafieldDefinitionSortKeys = ID
        query: String
    ): MetafieldDefinitionConnection!

    # List of metafields that belong to the resource.
    metafields(
        namespace: String
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): MetafieldConnection!

    # The online store preview URL.
    onlineStorePreviewUrl: URL

    # The online store URL for the product.
    # A value of null indicates that the product is not published to the Online Store sales channel.
    onlineStoreUrl: URL

    # A list of product options. The limit is specified by Shop.resourceLimits.maxProductOptions.
    options(first: Int): [ProductOption!]!

    # The price range of the product with prices formatted as decimals.
    priceRangeV2: ProductPriceRangeV2!

    # Returns a private metafield by namespace and key that belongs to the resource.
    privateMetafield(namespace: String!key: String!): PrivateMetafield

    # List of private metafields that belong to the resource.
    privateMetafields(
        namespace: String
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): PrivateMetafieldConnection!

    # The product category specified by the merchant.
    productCategory: ProductCategory

    # The product type specified by the merchant.
    productType: String!

    # The number of publications a resource is published on.
    publicationCount(onlyPublished: Boolean = true): Int!

    # The date and time (ISO 8601 format) when the product was published to the Online Store.
    publishedAt: DateTime

    # Check to see whether the resource is published to the calling app's publication.
    publishedOnCurrentPublication: Boolean!

    # Check to see whether the resource is published to a given publication.
    publishedOnPublication(publicationId: ID!): Boolean!

    # Whether the product can only be purchased with a selling plan (subscription).
    # Products that are sold on subscription (requiresSellingPlan: true) can be updated only for online stores.
    # If you update a product to be subscription only, then the product is unpublished from all channels except the online store.
    requiresSellingPlan: Boolean!

    # The resource that is either published or staged to be published to the calling app's publication.
    # Requires the read_product_listings scope.
    resourcePublicationOnCurrentPublication: ResourcePublicationV2

    # The list of resources that are published to a publication.
    resourcePublications(
        onlyPublished: Boolean = true
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): ResourcePublicationConnection!

    # The list of resources that are either published or staged to be published to a publication.
    resourcePublicationsV2(
        onlyPublished: Boolean = true
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): ResourcePublicationV2Connection!

    # Count of selling plan groups associated with the product.
    sellingPlanGroupCount: Int!

    # A list of all selling plan groups defined in the current shop associated with the product either directly or through any of its variants.
    sellingPlanGroups(
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): SellingPlanGroupConnection!

    # SEO information of the product.
    seo: SEO!

    # The product status. This controls visibility across all channels.
    status: ProductStatus!

    # A comma separated list of tags associated with the product. Updating tags overwrites
    # any existing tags that were previously added to the product. To add new tags without overwriting
    # existing tags, use the tagsAdd mutation.
    tags: [String!]!

    # The theme template used when viewing the product in a store.
    templateSuffix: String

    # The title of the product.
    title: String!

    # The quantity of inventory in stock.
    totalInventory: Int!

    # The number of variants that are associated with the product.
    totalVariants: Int!

    # Whether inventory tracking has been enabled for the product.
    tracksInventory: Boolean!

    # The translations associated with the resource.
    translations(locale: String!marketId: ID): [PublishedTranslation!]!

    # The list of publications that the resource is not published to.
    unpublishedPublications(
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): PublicationConnection!

    # The date and time when the product was last modified.
    # A product's updatedAt value can change for different reasons. For example, if an order
    # is placed for a product that has inventory tracking set up, then the inventory adjustment
    # is counted as an update.
    updatedAt: DateTime!

    # A list of variants associated with the product.
    variants(
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
        sortKey: ProductVariantSortKeys = POSITION
    ): ProductVariantConnection!

    # The name of the product's vendor.
    vendor: String!
}

# Represents a product variant.
type ProductVariant
    implements HasMetafieldDefinitions&HasMetafields&HasPublishedTranslations&LegacyInteroperability&Navigable&Node
    @key(fields: "id") {

    # Whether the product variant is available for sale.
    availableForSale: Boolean!

    # The value of the barcode associated with the product.
    barcode: String

    # The compare-at price of the variant in the default shop currency.
    compareAtPrice: Money

    # The pricing that applies for a customer in a given context.
    contextualPricing(context: ContextualPricingContext!): ProductVariantContextualPricing!

    # The date and time when the variant was created.
    createdAt: DateTime!

    # A default cursor that returns the single next record, sorted ascending by ID.
    defaultCursor: String!

    # The delivery profile for the variant.
    deliveryProfile: DeliveryProfile

    # Display name of the variant, based on product's title + variant's title.
    displayName: String!

    # Whether changes to the fulfillment service for the product variant are allowed.
    fulfillmentServiceEditable: EditableProperty!

    # A globally-unique identifier.
    id: ID!

    # The featured image for the variant.
    image: Image

    # The inventory item, which is used to query for inventory information.
    inventoryItem: InventoryItem!

    # Whether customers are allowed to place an order for the product variant when it's out of stock.
    inventoryPolicy: ProductVariantInventoryPolicy!

    # The total sellable quantity of the variant.
    inventoryQuantity: Int

    # The ID of the corresponding resource in the REST Admin API.
    legacyResourceId: UnsignedInt64!

    # The media associated with the product variant.
    media(
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): MediaConnection!

    # Returns a metafield by namespace and key that belongs to the resource.
    metafield(namespace: String!key: String!): Metafield

    # List of metafield definitions.
    metafieldDefinitions(
        namespace: String
        pinnedStatus: MetafieldDefinitionPinnedStatus = ANY
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
        sortKey: MetafieldDefinitionSortKeys = ID
        query: String
    ): MetafieldDefinitionConnection!

    # List of metafields that belong to the resource.
    metafields(
        namespace: String
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): MetafieldConnection!

    # The order of the product variant in the list of product variants. The first position in the list is 1.
    position: Int!

    # The price of the product variant in the default shop currency.
    price: Money!

    # Returns a private metafield by namespace and key that belongs to the resource.
    privateMetafield(namespace: String!key: String!): PrivateMetafield

    # List of private metafields that belong to the resource.
    privateMetafields(
        namespace: String
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): PrivateMetafieldConnection!

    # The product that this variant belongs to.
    product: Product!

    # List of product options applied to the variant.
    selectedOptions: [SelectedOption!]!

    # The total sellable quantity of the variant for online channels.
    # This doesn't represent the total available inventory or capture
    # limitations based on customer location.
    sellableOnlineQuantity: Int!

    # Count of selling plan groups associated with the product variant.
    sellingPlanGroupCount: Int!

    # A list of all selling plan groups defined in the current shop associated with the product variant.
    sellingPlanGroups(
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): SellingPlanGroupConnection!

    # An identifier for the product variant in the shop. Required in order to connect to a fulfillment service.
    sku: String

    # The tax code for the product variant.
    taxCode: String

    # Whether a tax is charged when the product variant is sold.
    taxable: Boolean!

    # The title of the product variant.
    title: String!

    # The translations associated with the resource.
    translations(locale: String!marketId: ID): [PublishedTranslation!]!

    # The date and time (ISO 8601 format) when the product variant was last modified.
    updatedAt: DateTime!

    # The weight of the product variant in the unit system specified with weight_unit.
    weight: Float

    # The unit of measurement that applies to the product variant's weight.
    # If you don't specify a value for weight_unit, then the shop's default unit of measurement is applied. Valid values: g, kg, oz, lb.
    weightUnit: WeightUnit!
}

# The quantities of an inventory item that are related to a specific location.
type InventoryLevel
    implements Node
    @key(fields: "id") {

    # The quantity of inventory items that are available at the inventory level's associated location.
    available: Int!

    # Whether the inventory items associated with the inventory level can be deactivated.
    canDeactivate: Boolean!

    # The date and time when the inventory level was created.
    createdAt: DateTime!

    # Describes either the impact of deactivating the inventory level, or why the inventory level can't be deactivated.
    deactivationAlert: String

    # Describes, in HTML with embedded URLs, either the impact of deactivating the inventory level or why the inventory level can't be deactivated.
    deactivationAlertHtml: FormattedString

    # A globally-unique identifier.
    id: ID!

    # The quantity of inventory items that are going to the inventory level's associated location.
    incoming: Int!

    # Inventory item associated with the inventory level.
    item: InventoryItem!

    # The location associated with the inventory level.
    location: Location!

    # The date and time when the inventory level was updated.
    updatedAt: DateTime!
}

# The product property names. For example, "Size", "Color", and "Material".
# Variants are selected based on permutations of these options.
# The limit for each product property name is 255 characters.
type ProductOption
    implements HasPublishedTranslations&Node
    @key(fields: "id") {

    # A globally-unique identifier.
    id: ID!

    # The product option’s name.
    name: String!

    # The product option's position.
    position: Int!

    # The translations associated with the resource.
    translations(locale: String!marketId: ID): [PublishedTranslation!]!

    # The corresponding value to the product option name.
    values: [String!]!
}

# Represents a fulfillment service.
# A fulfillment service is a third-party service that prepares and ships orders on behalf of the store owner.
type FulfillmentService
    @key(fields: "id") {

    # The callback URL that the fulfillment service has registered for requests. The following considerations apply:
    #
    # Shopify queries the <code>callback_url/fetch_tracking_numbers</code> endpoint to retrieve tracking numbers
    # for orders, if inventoryManagement is set to true.
    # Shopify queries the <code>callback_url/fetch_stock</code> endpoint to retrieve inventory levels,
    # if trackingSupport is set to true.
    # Shopify uses the <code>callback_url/fulfillment_order_notification</code> endpoint to send
    # fulfillment and cancellation requests,
    # if the fulfillment service has opted in to the fulfillment order based workflow for managing fulfillments
    # (fulfillmentOrdersOptIn is set to true).
    callbackUrl: URL

    # Whether the fulfillment service uses the fulfillment order based workflow for managing fulfillments.
    fulfillmentOrdersOptIn: Boolean!

    # Human-readable unique identifier for this fulfillment service.
    handle: String!

    # The ID of the fulfillment service.
    id: ID!

    # Whether the fulfillment service tracks product inventory and provides updates to Shopify.
    inventoryManagement: Boolean!

    # Location associated with the fulfillment service.
    location: Location

    # Whether the fulfillment service can stock inventory alongside other locations.
    permitsSkuSharing: Boolean!

    # Whether the fulfillment service supports local deliveries.
    productBased: Boolean!

    # The name of the fulfillment service as seen by merchants.
    serviceName: String!

    # Type associated with the fulfillment service.
    type: FulfillmentServiceType!
}

# Represents a group of products that can be displayed in online stores and other sales channels in categories, which makes it easy for customers to find them. For example, an athletics store might create different collections for running attire, shoes, and accessories.
#
# Collections can be defined by conditions, such as whether they match certain product tags.
# These are called smart or automated collections.
#
# Collections can also be created for a custom group of products. These are called custom or manual collections.
type Collection
    implements HasMetafieldDefinitions&HasMetafields&HasPublishedTranslations&Node&Publishable
    @key(fields: "id") {

    # The number of publications a resource is published to without feedback errors.
    availablePublicationCount: Int!

    # A single-line, text-only description of the collection, stripped of any HTML tags and formatting that were included in the description.
    description(truncateAt: Int): String!

    # The description of the collection, including any HTML tags and formatting.
    # This content is typically displayed to customers, such as on an online store, depending on the theme.
    descriptionHtml: HTML!

    # Information about the collection that's provided through resource feedback.
    feedback: ResourceFeedback

    # A unique string that identifies the collection. If a handle isn't specified when a collection is created, it's automatically generated from the collection's original title, and typically includes words from the title separated by hyphens. For example, a collection that was created with the title Summer Catalog 2022 might have the handle summer-catalog-2022.
    #
    # If the title is changed, the handle doesn't automatically change.
    #
    # The handle can be used in themes by the Liquid templating language to refer to the collection, but using the ID is preferred because it never changes.
    handle: String!

    # Whether the collection includes the specified product.
    hasProduct(id: ID!): Boolean!

    # A globally-unique identifier.
    id: ID!

    # The image associated with the collection.
    image: Image

    # The ID of the corresponding resource in the REST Admin API.
    legacyResourceId: UnsignedInt64!

    # Returns a metafield by namespace and key that belongs to the resource.
    metafield(namespace: String!key: String!): Metafield

    # List of metafield definitions.
    metafieldDefinitions(
        namespace: String
        pinnedStatus: MetafieldDefinitionPinnedStatus = ANY
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
        sortKey: MetafieldDefinitionSortKeys = ID
        query: String
    ): MetafieldDefinitionConnection!

    # List of metafields that belong to the resource.
    metafields(
        namespace: String
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): MetafieldConnection!

    # Returns a private metafield by namespace and key that belongs to the resource.
    privateMetafield(namespace: String!key: String!): PrivateMetafield

    # List of private metafields that belong to the resource.
    privateMetafields(
        namespace: String
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): PrivateMetafieldConnection!

    # The products that are included in the collection.
    products(
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
        sortKey: ProductCollectionSortKeys = COLLECTION_DEFAULT
    ): ProductConnection!

    # The number of products in the collection.
    productsCount: Int!

    # The number of publications a resource is published on.
    publicationCount(onlyPublished: Boolean = true): Int!

    # Check to see whether the resource is published to the calling app's publication.
    publishedOnCurrentPublication: Boolean!

    # Check to see whether the resource is published to a given publication.
    publishedOnPublication(publicationId: ID!): Boolean!

    # The list of resources that are published to a publication.
    resourcePublications(
        onlyPublished: Boolean = true
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): ResourcePublicationConnection!

    # The list of resources that are either published or staged to be published to a publication.
    resourcePublicationsV2(
        onlyPublished: Boolean = true
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): ResourcePublicationV2Connection!

    # For a smart (automated) collection, specifies the rules that determine whether a product is included.
    ruleSet: CollectionRuleSet

    # If the default SEO fields for page title and description have been modified, contains the modified information.
    seo: SEO!

    # The order in which the products in the collection are displayed by default in the Shopify admin and in sales channels, such as an online store.
    sortOrder: CollectionSortOrder!

    # The suffix of the Liquid template being used to show the collection in an online store. For example, if the value is custom, then the collection is using the collection.custom.liquid template. If the value is null, then the collection is using the default collection.liquid template.
    templateSuffix: String

    # The name of the collection. It's displayed in the Shopify admin and is typically displayed in sales channels, such as an online store.
    title: String!

    # The translations associated with the resource.
    translations(locale: String!marketId: ID): [PublishedTranslation!]!

    # The list of publications that the resource is not published to.
    unpublishedPublications(
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): PublicationConnection!

    # The date and time (ISO 8601 format) when the collection was last modified.
    updatedAt: DateTime!
}

# Specifies product images to append.
input ProductAppendImagesInput {
    # The ID of the product.
    id: ID!

    # A list of images to be appended to the product.
    images: [ImageInput!]!
}

# Specifies the input fields for an image.
input ImageInput {
    # A globally-unique identifier.
    id: ID

    # A word or phrase to share the nature or contents of an image.
    altText: String

    # The URL of the image. May be a staged upload URL.
    src: String
}

# Specifies the input fields required to create a product.
input ProductInput {
    # The description of the product, complete with HTML formatting.
    descriptionHtml: String


    # Whether a redirect is required after a new handle has been provided.
    # If true, then the old handle is redirected to the new one automatically.
    redirectNewHandle: Boolean

    # A unique, human-friendly string for the product.
    # Automatically generated from the product's title unless otherwise specified.
    handle: String

    # The SEO information associated with the product.
    seo: SEOInput

    # The product type specified by the merchant.
    productType: String

    # The standardized product type in the Shopify product taxonomy.
    standardizedProductType: StandardizedProductTypeInput

    # The product category in the Shopify product taxonomy.
    productCategory: ProductCategoryInput

    # The custom product type specified by the merchant.
    customProductType: String

    # A comma separated list of tags that have been added to the product.
    tags: [String!]

    # The theme template used when viewing the product in a store.
    templateSuffix: String

    # Whether the product is a gift card.
    giftCard: Boolean

    # The theme template used when viewing the gift card in a store.
    giftCardTemplateSuffix: String

    # The title of the product.
    title: String

    # The name of the product's vendor.
    vendor: String

    # The IDs of the collections that this product will be added to.
    collectionsToJoin: [ID!]

    # The IDs of collections that will no longer include the existing product.
    collectionsToLeave: [ID!]

    # Specifies the product to update in productUpdate or creates a new product if absent in productCreate.
    id: ID

    # The images to associate with the product.
    images: [ImageInput!]

    # The metafields to associate with this product.
    metafields: [MetafieldInput!]

    # The private metafields to associate with this product.
    privateMetafields: [PrivateMetafieldInput!]

    # List of custom product options (maximum of 3 per product).
    options: [String!]

    # A list of variants associated with the product.
    variants: [ProductVariantInput!]

    # The status of the product.
    status: ProductStatus

    # Whether the product can only be purchased with a selling plan (subscription).
    # Products that are sold exclusively on subscription can only be created on online stores.
    # If set to true on an already existing product, then the product will be marked unavailable on channels that don't support subscriptions.
    requiresSellingPlan: Boolean
}

# Specifies a product variant to create or update.
input ProductVariantInput {
    # The value of the barcode associated with the product.
    barcode: String

    # The compare-at price of the variant.
    compareAtPrice: Money

    # The Harmonized System code (or HS Tariff code) for the variant.
    harmonizedSystemCode: String

    # Specifies the product variant to update or create a new variant if absent.
    id: ID

    # The ID of the image that's associated with the variant.
    imageId: ID

    # The URL of an image to associate with the variant.
    # This field can only be used through mutations that create product images and must match one of the URLs being created on the product.
    imageSrc: String

    # The URL of the media to associate with the variant.
    # This field can only be used in mutations that create media images and must match one of the URLs being created on the product.
    # This field only accepts one value.
    mediaSrc: [String!]

    # Whether customers are allowed to place an order for the product variant when it's out of stock.
    inventoryPolicy: ProductVariantInventoryPolicy

    # The inventory quantities at each location where the variant is stocked.
    # Used as input only to the productVariantCreate mutation.
    inventoryQuantities: [InventoryLevelInput!]

    # The inventory item associated with the variant. Used for unit cost.
    inventoryItem: InventoryItemInput

    # Additional customizable information about the product variant.
    metafields: [MetafieldInput!]

    # The private metafields associated with the product.
    privateMetafields: [PrivateMetafieldInput!]

    # The custom properties that a shop owner uses to define product variants.
    options: [String!]

    # The order of the product variant in the list of product variants. The first position in the list is 1.
    position: Int

    # The price of the variant.
    price: Money

    # The product to create the variant for. Used as input only to the productVariantCreate mutation.
    productId: ID

    # Whether the variant requires shipping.
    requiresShipping: Boolean

    # The SKU for the variant.
    sku: String

    # Whether the variant is taxable.
    taxable: Boolean

    # The tax code associated with the variant.
    taxCode: String

    # The weight of the variant.
    weight: Float

    # The unit of weight that's used to measure the variant.
    weightUnit: WeightUnit
}

# Specifies the input fields for an inventory level.
input InventoryLevelInput {
    # The available quantity of an inventory item at a location.
    availableQuantity: Int!

    # The ID of a location.
    locationId: ID!
}

# Specifies the input fields for an inventory item.
input InventoryItemInput {
    # Unit cost associated with the inventory item, the currency is the shop's default currency.
    cost: Decimal

    # Whether the inventory item is tracked.
    tracked: Boolean
}

# Return type for productAppendImages mutation.
type ProductAppendImagesPayload {
    # List of new images appended to the product.
    newImages: [Image!]

    # The product object.
    product: Product

    # The list of errors that occurred from executing the mutation.
    userErrors: [UserError!]!
}

# Return type for productChangeStatus mutation.
type ProductChangeStatusPayload {
    # The product object.
    product: Product

    # The list of errors that occurred from executing the mutation.
    userErrors: [ProductChangeStatusUserError!]!
}

# Provides the fields and values to use when adding a standard product type to a product.
# The Shopify product taxonomy contains the full list of available values.
input StandardizedProductTypeInput {
    # The id of the node in the Shopify taxonomy that represents the product type.
    productTaxonomyNodeId: ID!
}

# The input fields to use when adding a product category to a product.
# The Shopify product taxonomy contains the full list of available values.
input ProductCategoryInput {
    # The ID of the node in the Shopify taxonomy that represents the product category.
    productTaxonomyNodeId: ID!
}

# Specifies the input fields required to create a media object.
input CreateMediaInput {
    # The original source of the media object. This might be an external URL or a staged upload URL.
    originalSource: String!

    # The alt text associated with the media.
    alt: String

    # The media content type.
    mediaContentType: MediaContentType!
}

# A single move of an object to a specific position in a set, using a zero-based index.
input MoveInput {
    # The ID of the object to be moved.
    id: ID!

    # The new position of the object in the set.
    newPosition: UnsignedInt64!
}

# Specifies the product to delete.
input ProductDeleteInput {
    # The ID of the product.
    id: ID!
}

# Specifies the input fields required to update a media object.
input UpdateMediaInput {
    # Specifies the media to update.
    id: ID!

    # The source from which to update the media preview image. May be an external URL or staged upload URL.
    previewImageSource: String

    # The alt text associated to the media.
    alt: String
}

# Specifies the input fields required to append media to a single variant.
input ProductVariantAppendMediaInput {
    # Specifies the variant to which media will be appended.
    variantId: ID!

    # Specifies the media to append to the variant.
    mediaIds: [ID!]!
}

# Specifies the input fields required to detach media from a single variant.
input ProductVariantDetachMediaInput {
    # Specifies the variant from which media will be detached.
    variantId: ID!

    # Specifies the media to detach from the variant.
    mediaIds: [ID!]!
}

# Specifies a product variant to create as part of a variant bulk mutation.
input ProductVariantsBulkInput {
    # The value of the barcode associated with the product variant.
    barcode: String

    # The compare-at price of the variant.
    compareAtPrice: Money

    # The Harmonized System code (or HS Tariff code) for the variant.
    harmonizedSystemCode: String

    # Specifies the product variant to update or delete.
    id: ID

    # The ID of the image that's associated with the variant.
    imageId: ID

    # The URL of an image to associate with the variant. This field can only be used through mutations that create product images and must match one of the URLs being created on the product.
    imageSrc: String

    # The URL of the media to associate with the variant.
    mediaSrc: [String!]

    # Whether customers are allowed to place an order for the variant when it's out of stock.
    inventoryPolicy: ProductVariantInventoryPolicy

    # The inventory quantities at each location where the variant is stocked. The number of elements
    # in the array of inventory quantities cannot exceed 10 and the amount specified for the plan.
    # Used as input only to the productVariantCreate mutation.
    inventoryQuantities: [InventoryLevelInput!]

    # The inventory item associated with the variant, used for unit cost.
    inventoryItem: InventoryItemInput

    # The additional customizable information about the product variant.
    metafields: [MetafieldInput!]

    # The private metafields associated with the product.
    privateMetafields: [PrivateMetafieldInput!]

    # The custom properties that a shop owner uses to define product variants.
    options: [String!]

    # The price of the variant.
    price: Money

    # Whether the variant requires shipping.
    requiresShipping: Boolean

    # The SKU for the variant.
    sku: String

    # Whether the variant is taxable.
    taxable: Boolean

    # The tax code associated with the variant.
    taxCode: String

    # The weight of the variant.
    weight: Float

    # The unit of weight that's used to measure the variant.
    weightUnit: WeightUnit
}

# Represents a product variant position.
input ProductVariantPositionInput {
    # Specifies the ID of the product variant to update.
    id: ID!

    # The order of the product variant in the list of product variants. The first position in the list is 1.
    position: Int!
}

# Return type for productCreate mutation.
type ProductCreatePayload {
    # The product object.
    product: Product

    # The shop associated with the product.
    shop: Shop!

    # The list of errors that occurred from executing the mutation.
    userErrors: [UserError!]!
}

# Return type for productCreateMedia mutation.
type ProductCreateMediaPayload {
    # The newly created media.
    media: [Media!]

    # The list of errors that occurred from executing the mutation.
    mediaUserErrors: [MediaUserError!]!

    # The product associated with the media.
    product: Product
}

# Return type for productDelete mutation.
type ProductDeletePayload {
    # The ID of the deleted product.
    deletedProductId: ID

    # The shop associated with the product.
    shop: Shop!

    # The list of errors that occurred from executing the mutation.
    userErrors: [UserError!]!
}

# Return type for productImageUpdate mutation.
type ProductImageUpdatePayload {
    # The image that has been updated.
    image: Image

    # The list of errors that occurred from executing the mutation.
    userErrors: [UserError!]!
}

# Return type for productDeleteImages mutation.
type ProductDeleteImagesPayload {
    # The array of image IDs to delete.
    deletedImageIds: [ID!]!

    # The product object.
    product: Product

    # The list of errors that occurred from executing the mutation.
    userErrors: [UserError!]!
}

# Return type for productDeleteMedia mutation.
type ProductDeleteMediaPayload {
    # List of media IDs which were deleted.
    deletedMediaIds: [ID!]

    # List of product image IDs which were deleted.
    deletedProductImageIds: [ID!]

    # The list of errors that occurred from executing the mutation.
    mediaUserErrors: [MediaUserError!]!

    # The product associated with the deleted media.
    product: Product
}

# Return type for productDuplicate mutation.
type ProductDuplicatePayload {
    # The asynchronous job that duplicates the product images.
    imageJob: Job

    # The duplicated product.
    newProduct: Product

    # The user's shop.
    shop: Shop!

    # The list of errors that occurred from executing the mutation.
    userErrors: [UserError!]!
}

# Return type for productJoinSellingPlanGroups mutation.
type ProductJoinSellingPlanGroupsPayload {
    # The product object.
    product: Product

    # The list of errors that occurred from executing the mutation.
    userErrors: [SellingPlanGroupUserError!]!
}

# Return type for productLeaveSellingPlanGroups mutation.
type ProductLeaveSellingPlanGroupsPayload {
    # The product object.
    product: Product

    # The list of errors that occurred from executing the mutation.
    userErrors: [SellingPlanGroupUserError!]!
}

# Return type for productReorderImages mutation.
type ProductReorderImagesPayload {
    # The asynchronous job which reorders the images.
    job: Job

    # The list of errors that occurred from executing the mutation.
    userErrors: [UserError!]!
}

# Return type for productReorderMedia mutation.
type ProductReorderMediaPayload {
    # The asynchronous job which reorders the media.
    job: Job

    # The list of errors that occurred from executing the mutation.
    mediaUserErrors: [MediaUserError!]!
}

# Return type for productUpdate mutation.
type ProductUpdatePayload {
    # The updated product object.
    product: Product

    # The list of errors that occurred from executing the mutation.
    userErrors: [UserError!]!
}

# Return type for productUpdateMedia mutation.
type ProductUpdateMediaPayload {
    # The updated media object.
    media: [Media!]

    # The list of errors that occurred from executing the mutation.
    mediaUserErrors: [MediaUserError!]!

    # The product on which media was updated.
    product: Product
}

# Return type for productVariantAppendMedia mutation.
type ProductVariantAppendMediaPayload {
    # The product associated with the variants and media.
    product: Product

    # The product variants that were updated.
    productVariants: [ProductVariant!]

    # The list of errors that occurred from executing the mutation.
    userErrors: [MediaUserError!]!
}

# Return type for productVariantCreate mutation.
type ProductVariantCreatePayload {
    # The product associated with the variant.
    product: Product

    # The successfully created variant.
    productVariant: ProductVariant

    # The list of errors that occurred from executing the mutation.
    userErrors: [UserError!]!
}

# Return type for productVariantDelete mutation.
type ProductVariantDeletePayload {
    # The ID of the deleted product variant.
    deletedProductVariantId: ID

    # The product associated with the deleted product variant.
    product: Product

    # The list of errors that occurred from executing the mutation.
    userErrors: [UserError!]!
}

# Return type for productVariantDetachMedia mutation.
type ProductVariantDetachMediaPayload {
    # The product associated with the variants and media.
    product: Product

    # The product variants that were updated.
    productVariants: [ProductVariant!]

    # The list of errors that occurred from executing the mutation.
    userErrors: [MediaUserError!]!
}

# Return type for productVariantJoinSellingPlanGroups mutation.
type ProductVariantJoinSellingPlanGroupsPayload {
    # The product variant object.
    productVariant: ProductVariant

    # The list of errors that occurred from executing the mutation.
    userErrors: [SellingPlanGroupUserError!]!
}

# Return type for productVariantLeaveSellingPlanGroups mutation.
type ProductVariantLeaveSellingPlanGroupsPayload {
    # The product variant object.
    productVariant: ProductVariant

    # The list of errors that occurred from executing the mutation.
    userErrors: [SellingPlanGroupUserError!]!
}

# Return type for productVariantUpdate mutation.
type ProductVariantUpdatePayload {
    # The product associated with the variant.
    product: Product

    # The updated variant.
    productVariant: ProductVariant

    # The list of errors that occurred from executing the mutation.
    userErrors: [UserError!]!
}

# Return type for productVariantsBulkCreate mutation.
type ProductVariantsBulkCreatePayload {
    # The updated product object.
    product: Product

    # The newly created variants.
    productVariants: [ProductVariant!]

    # The list of errors that occurred from executing the mutation.
    userErrors: [ProductVariantsBulkCreateUserError!]!
}

# Return type for productVariantsBulkDelete mutation.
type ProductVariantsBulkDeletePayload {
    # The updated product object.
    product: Product

    # The list of errors that occurred from executing the mutation.
    userErrors: [ProductVariantsBulkDeleteUserError!]!
}

# Return type for productVariantsBulkReorder mutation.
type ProductVariantsBulkReorderPayload {
    # The updated product.
    product: Product

    # The list of errors that occurred from executing the mutation.
    userErrors: [ProductVariantsBulkReorderUserError!]!
}

# Return type for productVariantsBulkUpdate mutation.
type ProductVariantsBulkUpdatePayload {
    # The updated product object.
    product: Product

    # The updated variants.
    productVariants: [ProductVariant!]

    # The list of errors that occurred from executing the mutation.
    userErrors: [ProductVariantsBulkUpdateUserError!]!
}

# Reports the status of product for a Sales Channel or Storefront API.
# This might include why a product is not available in a Sales Channel
# and how a merchant might fix this.
type ProductResourceFeedback {
    # The time when the feedback was generated. Used to help determine whether
    # incoming feedback is outdated compared to existing feedback.
    feedbackGeneratedAt: DateTime!

    # The feedback messages presented to the merchant.
    messages: [String!]!

    # The ID of the product associated with the feedback.
    productId: ID!

    # The timestamp of the product associated with the feedback.
    productUpdatedAt: DateTime!

    # Conveys the state of the feedback and whether it requires merchant action or not.
    state: ResourceFeedbackState!
}

extend type App @key(fields: "id") {
    id: ID! @external
}

extend type Shop @key(fields: "id") {
    id: ID! @external
}

extend type Market @key(fields: "id") {
    id: ID! @external
}

extend type Job @key(fields: "id") {
    id: ID! @external
}

extend type Customer @key(fields: "id") {
    id: ID! @external
}

extend type Order @key(fields: "id") {
    id: ID! @external
}

extend type DraftOrder @key(fields: "id") {
    id: ID! @external
}

extend type MarketWebPresence @key(fields: "id") {
    id: ID! @external
}
