type Query {
    # Returns a Customer resource by ID.
    customer(id: ID!): Customer
}

type Mutation {
    customerCreate(input: CustomerInput!): CustomerCreatePayload
}

input CustomerInput {
    # The addresses for a customer.
    addresses: [MailingAddressInput!]

    # The unique email address of the customer.
    email: String

    # The customer's first name.
    firstName: String

    # The ID of the customer to update.
    id: ID

    # The customer's last name.
    lastName: String

    # The customer's locale.
    locale: String

    # Additional metafields to associate to the customer.
    metafields: [MetafieldInput!]

    # A note about the customer.
    note: String

    # The unique phone number for the customer.
    phone: String

    # The private metafields to associate with the customer.
    privateMetafields: [PrivateMetafieldInput!]

    # A list of tags to associate with the customer. Can be an array or a comma-separated list. Example values: ["tag1", "tag2", "tag3"], "tag1, tag2, tag3"
    #
    # Updating tags overwrites any existing tags that were previously added to the customer. To add new tags without overwriting
    # existing tags, use the tagsAdd mutation.
    tags: [String!]
}

# Return type for customerCreate mutation.
type CustomerCreatePayload {
    # The created customer.
    customer: Customer

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

# Represents information about a customer of the shop, such as the customer's contact details, their order
# history, and whether they've agreed to receive marketing material by email.
#
# Caution: Only use this data if it's required for your app's functionality.
# Shopify will restrict access to scopes for apps that don't have a legitimate use for the associated data.
type Customer
    implements CommentEventSubject&HasEvents&HasMetafieldDefinitions&HasMetafields&LegacyInteroperability&Node
    @key(fields: "id") {
    # A list of addresses associated with the customer.
    addresses(first: Int): [MailingAddress!]!

    # The total amount that the customer has spent on orders in their lifetime.
    amountSpent: MoneyV2!

    # The average amount that the customer spent per order.
    averageOrderAmountV2: MoneyV2

    # Whether the merchant can delete the customer from their store.
    #
    # A customer can be deleted from a store only if they have not yet made an order. After a customer makes an
    # order, they can't be deleted from a store.
    canDelete: Boolean!

    # A list of the customer's company contact profiles.
    companyContactProfiles: [CompanyContact!]!

    # The date and time when the customer was added to the store.
    createdAt: DateTime!

    # The default address associated with the customer.
    defaultAddress: MailingAddress

    # The full name of the customer, based on the values for first_name and last_name. If the first_name and
    # last_name are not available, then this falls back to the customer's email address, and if that is not available, the customer's phone number.
    displayName: String!

    # The customer's email address.
    email: String

    # The current email marketing state for the customer.
    # If the customer doesn't have an email address, then this property is `null`.
    emailMarketingConsent: CustomerEmailMarketingConsentState

    # A list of events associated with the customer.
    events(
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
        sortKey: EventSortKeys = ID
        query: String
    ): EventConnection!

    # The customer's first name.
    firstName: String

    # Whether the timeline subject has a timeline comment. If true, then a timeline comment exists.
    hasTimelineComment: Boolean!

    # A globally-unique identifier.
    id: ID!

    # The image associated with the customer.
    image: Image!

    # The customer's last name.
    lastName: String

    # The customer's last order.
    lastOrder: Order

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

    # The amount of time since the customer was first added to the store.
    #
    # Example: 'about 12 years'.
    lifetimeDuration: String!

    # The customer's locale.
    locale: String!

    # The market that includes the customer’s default address.
    market: Market

    # 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!

    # A unique identifier for the customer that's used with Multipass login.
    multipassIdentifier: String

    # A note about the customer.
    note: String

    # The number of orders that the customer has made at the store in their lifetime.
    numberOfOrders: UnsignedInt64!

    # A list of the customer's orders.
    orders(
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
        sortKey: OrderSortKeys = ID
        query: String
    ): OrderConnection!

    # A list of the customer's payment methods.
    paymentMethods(
        showRevoked: Boolean = false
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): CustomerPaymentMethodConnection!

    # The customer's phone number.
    phone: String

    # 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!

    # Possible subscriber states of a customer defined by their subscription contracts.
    productSubscriberStatus: CustomerProductSubscriberStatus!

    # The current SMS marketing state for the customer's phone number.
    #
    # If the customer does not have a phone number, then this property is null.
    smsMarketingConsent: CustomerSmsMarketingConsentState

    # The state of the customer's account with the shop.
    state: CustomerState!

    # The statistics for a given customer.
    statistics: CustomerStatistics!

    # A list of the customer's subscription contracts.
    subscriptionContracts(
        first: Int
        after: String
        last: Int
        before: String
        reverse: Boolean = false
    ): SubscriptionContractConnection!

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

    # Whether the customer is exempt from being charged taxes on their orders.
    taxExempt: Boolean!

    # The list of tax exemptions applied to the customer.
    taxExemptions: [TaxExemption!]!

    # The URL to unsubscribe the customer from the mailing list.
    unsubscribeUrl: URL!

    # The date and time when the customer was last updated.
    updatedAt: DateTime!

    # Whether the email address is formatted correctly.
    # Returns true when the email is formatted correctly and
    # belongs to an existing domain. This doesn't guarantee that
    # the email address actually exists.
    validEmailAddress: Boolean!

    # Whether the customer has verified their email address. Defaults to true if the customer is created through the Shopify admin or API.
    verifiedEmail: Boolean!
}

extend type App @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 ProductVariant @key(fields: "id") {
   id: ID! @external
}

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

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

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

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

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

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