diff --git a/rust/domains-client/openapi/domains.oas3.json b/rust/domains-client/openapi/domains.oas3.json index e8624058..6a258d77 100644 --- a/rust/domains-client/openapi/domains.oas3.json +++ b/rust/domains-client/openapi/domains.oas3.json @@ -140,6 +140,15 @@ "type": "string" } }, + "registrationBatchId": { + "description": "Server-assigned registration batch identifier.", + "in": "path", + "name": "registrationBatchId", + "required": true, + "schema": { + "$ref": "#/components/schemas/uuid" + } + }, "registrationId": { "description": "Server-assigned registration identifier.", "in": "path", @@ -363,6 +372,30 @@ } }, "schemas": { + "AcknowledgedFee": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/acknowledged-fee.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A fee that the customer explicitly acknowledged before executing a purchase. Used to confirm the customer saw and accepted specific charges (e.g., PREMIUM domain fees) before the irreversible purchase is executed.\n", + "properties": { + "fee": { + "allOf": [ + { + "$ref": "#/components/schemas/simple-money" + }, + { + "description": "The monetary amount of this fee." + } + ] + }, + "type": { + "description": "Fee type identifying the charge category. Common values include ONE_TIME_PREMIUM_DOMAIN_PURCHASE for premium domain acquisition fees.\n", + "example": "ONE_TIME_PREMIUM_DOMAIN_PURCHASE", + "type": "string" + } + }, + "title": "AcknowledgedFee", + "type": "object" + }, "Agreement": { "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/agreement.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -650,6 +683,11 @@ "type": "string", "x-sensitivity": "confidential" }, + "metadata": { + "description": "The contact eligibility data fields as specified by GET /profile-schemas/{tld} (operationId: getProfileSchema)\n", + "type": "object", + "x-sensitivity": "confidential" + }, "organization": { "description": "Organization or company name. Required for contacts acting on behalf of a legal entity. Leave blank for individual registrants.\n", "example": "Example LLC", @@ -1227,6 +1265,88 @@ "title": "Domain Operation Type", "type": "string" }, + "DomainQuoteDetails": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/domain-quote-details.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "Shared quote details for a single domain. Contains the domain name, registration period, locked price, fees, availability status, resolved settings, and required agreements. Used as a base for both single-domain quotes (RegistrationQuote) and per-domain details in batch quotes (RegistrationBatchDomain).\n", + "properties": { + "available": { + "description": "Whether the domain is available for registration. When false, no quoteToken is returned (for single quotes) or the domain is excluded from the bulk quote.\n", + "type": "boolean" + }, + "domain": { + "description": "The domain name in punycode A-label form for IDNs.\n", + "example": "example.com", + "type": "string" + }, + "fees": { + "description": "Fees charged at the time of purchase, in addition to the registration price. For PREMIUM domains, includes ONE_TIME_PREMIUM_DOMAIN_PURCHASE.\n", + "items": { + "$ref": "#/components/schemas/Fee" + }, + "nullable": true, + "type": "array" + }, + "inventory": { + "allOf": [ + { + "$ref": "#/components/schemas/InventoryType" + }, + { + "description": "The inventory source for this domain. REGISTRY for standard domains, PREMIUM for aftermarket/premium domains, UNAVAILABLE when not available for registration.\n" + } + ] + }, + "period": { + "default": 1, + "description": "Registration period in years for which the price is quoted.", + "example": 1, + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "price": { + "allOf": [ + { + "$ref": "#/components/schemas/simple-money" + }, + { + "description": "The locked registration price for the quoted period. Total amount charged on execute is this price plus any fees.\n" + } + ] + }, + "renewalPrice": { + "allOf": [ + { + "$ref": "#/components/schemas/simple-money" + }, + { + "description": "The standard renewal price at the end of the registration period. This is the price that will be charged for subsequent renewals at non-promotional rates.\n" + } + ] + }, + "requiredAgreements": { + "description": "Legal agreements that must be accepted before executing this quote. The agreementType values from this list must be included in the execute request's consent object.\n", + "items": { + "$ref": "#/components/schemas/Agreement" + }, + "nullable": true, + "type": "array" + }, + "resolved": { + "allOf": [ + { + "$ref": "#/components/schemas/ResolvedSettings" + }, + { + "description": "The effective contact and preference settings that will be applied on execute. Review before execute to verify registrant, contacts, and preferences match intent.\n" + } + ] + } + }, + "title": "DomainQuoteDetails", + "type": "object" + }, "DomainStatus": { "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/domain-status.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -1287,47 +1407,6 @@ "title": "Fee Type", "type": "string" }, - "InlineRegistrationProfile": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/inline-registration-profile.v3", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "A one-time, non-persisted set of contacts and purchase preference defaults supplied inline on a quote or execute request. Use to provide registration data for this transaction without creating or updating a saved registration profile.\nShared by the registration quote and execute request bodies. Every field is optional. Omitted fields account identity or other default values. Provided fields override only what is supplied — contact roles replace as a whole block; preference fields replace individually.\nThis is not a saved registration profile and is not JSON Patch. Data here applies only to the current quote or registration request.\n", - "properties": { - "autoRenew": { - "description": "Auto-renew preference for this registration. Omit to inherit from the resolved saved profile or account defaults.\n", - "type": "boolean" - }, - "contacts": { - "allOf": [ - { - "$ref": "#/components/schemas/Contacts" - }, - { - "description": "Contact records for this request. Each role provided replaces that role from the resolved saved profile or account identity. Omitted roles continue to resolve from the saved profile or cascade from registrant.\n" - } - ] - }, - "nameServers": { - "allOf": [ - { - "$ref": "#/components/schemas/NameServers" - }, - { - "description": "Authoritative nameservers for this registration. Omit to inherit from the resolved saved profile or platform defaults.\n", - "example": [ - "ns1.example.com", - "ns2.example.com" - ] - } - ] - }, - "privacy": { - "description": "WHOIS privacy preference for this registration. Omit to inherit from the resolved saved profile or account defaults.\n", - "type": "boolean" - } - }, - "title": "Inline Registration Profile", - "type": "object" - }, "InventoryType": { "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/inventory-type.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -1370,6 +1449,54 @@ "title": "Optimization Target", "type": "string" }, + "Profile": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/profile.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A set of contacts and purchase preference defaults supplied on a quote or registration request. Use to provide registration data for a transaction, either inline or via a saved registration profile.\nEvery field is optional at the base level. Each usage site layers its own required constraints. Omitted fields account identity or other default values. Provided fields override only what is supplied — contact roles replace as a whole block; preference fields replace individually.\n", + "properties": { + "autoRenew": { + "description": "Auto-renew preference for this registration. Omit to inherit from the resolved saved profile or account defaults.\n", + "type": "boolean" + }, + "contacts": { + "allOf": [ + { + "$ref": "#/components/schemas/Contacts" + }, + { + "description": "Contact records for this request. Each role provided replaces that role from the resolved saved profile or account identity. Omitted roles continue to resolve from the saved profile or cascade from registrant.\n" + } + ] + }, + "nameServers": { + "allOf": [ + { + "$ref": "#/components/schemas/NameServers" + }, + { + "description": "Authoritative nameservers for this registration. Omit to inherit from the resolved saved profile or platform defaults.\n", + "example": [ + "ns1.example.com", + "ns2.example.com" + ] + } + ] + }, + "privacy": { + "description": "WHOIS privacy preference for this registration. Omit to inherit from the resolved saved profile or account defaults.\n", + "type": "boolean" + } + }, + "title": "Profile", + "type": "object" + }, + "ProfileSchema": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/profile-schema.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "TLD-specific JSON Schema describing the fields required to build a profile for a domain under this TLD. The structure varies per TLD and is not further constrained at the API layer. Use the contents to guide construction of POST /registration-quotes and POST /registrations request bodies.\n", + "title": "Profile Schema", + "type": "object" + }, "Registration": { "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -1467,10 +1594,10 @@ "profile": { "allOf": [ { - "$ref": "#/components/schemas/InlineRegistrationProfile" + "$ref": "#/components/schemas/Profile" }, { - "description": "One-time inline contacts and purchase preference defaults for this registration. Not persisted. Must match the profile supplied on the quote when a profile was included at quote time.\n" + "description": "One-time contacts and purchase preference defaults for this registration. Not persisted. Must match the profile supplied on the quote when a profile was included at quote time.\n" } ] }, @@ -1537,30 +1664,18 @@ "title": "Registration", "type": "object" }, - "RegistrationPreference": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-preference.v3", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "A purchase preference enabled on a saved registration profile.\nAUTO_RENEW — renew the domain automatically before it expires. PRIVACY — withhold registrant details from public WHOIS. TRUSTEE — local-presence service required by some TLDs. Derived from the contacts supplied rather than set directly, and returned on read when it applies.\nNot a closed set. These are the preferences this version names; a profile may carry a preference that is not among them, and new ones may be named in a later version.\n", - "examples": [ - "AUTO_RENEW", - "PRIVACY", - "TRUSTEE" - ], - "title": "Registration Preference", - "type": "string" - }, - "RegistrationProfile": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-profile.v3", + "RegistrationBatch": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-batch.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "A saved, reusable set of contacts and purchase preference defaults, referenced by profileId on a registration quote or a registration.\nA profile is a registration-time template. Its values are copied into the registration when a quote is executed, and nothing links the profile to the resulting domain afterwards. A profile cannot be edited, and no change to a profile can affect a domain already registered from it. To change saved details, create the replacement first, then delete the profile it supersedes.\nA profile is scoped to the TLDs named on create, because contact requirements are set by the TLD rather than by the contacts supplied. TLDs sharing one set of requirements share a profile; a TLD demanding additional registrant detail needs its own. See GET /registration-schemas/{tld} for what contacts a TLD requires.\nSee profileId on the registration quote for how a saved profile, an inline profile and account identity combine.\n", + "description": "A batch domain registration entity created when a POST /registration-batch request is accepted. Registration batches are a top-level resource with their own stable registrationBatchId; the domain relationships are captured in the domains array.\nOn POST /registration-batch, supply the writable fields (domains array, registrationQuoteBatchToken, consent). The server returns the full RegistrationBatch with readOnly fields populated. Poll links[rel=self] until status reaches COMPLETED or FAILED.\nAll domains are registered atomically (all succeed or all fail). On COMPLETED, each domain in the array includes expiresAt and orderId. On FAILED, no domains were registered and the error field contains the failure reason.\n", "properties": { - "contacts": { + "consent": { "allOf": [ { - "$ref": "#/components/schemas/Contacts" + "$ref": "#/components/schemas/Consent" }, { - "description": "Contacts saved on this profile. Every role given here applies to all the TLDs the profile covers, since those TLDs share one set of contact requirements.\n" + "description": "The customer's consent for the legal agreements returned in the quote. On execute, supply agreementTypes and agreedAt; agreedBy is server-derived and returned on the persisted record.\nNOTE: For batch registrations, do NOT include acknowledgedFees in this top-level consent object. Premium domain fees must be acknowledged per-domain in the domains array using the acknowledgedFees field on each RegistrationBatchDomainItem that has fees.\n" } ] }, @@ -1570,194 +1685,543 @@ "$ref": "#/components/schemas/date-time" }, { - "description": "When the profile was created. Absent for profiles created before this timestamp was recorded.\n", + "description": "Timestamp when this registration batch was initiated.", "readOnly": true } ] }, - "links": { - "description": "HATEOAS link relations. rel=self — the canonical URL for this profile. Profiles are replace-only, so no relation is offered for modifying one.\n", - "items": { - "$ref": "#/components/schemas/link-description" - }, - "readOnly": true, - "type": "array" + "defaultProfile": { + "allOf": [ + { + "$ref": "#/components/schemas/Profile" + }, + { + "description": "The default inline profile supplied on the registration request, if any. Applied to all domains unless overridden at the per-domain level. Echoed from the request.\n" + } + ] }, - "name": { - "description": "Optional human-readable label. Recommended, since it is the only human-readable field that tells one profile from another on read. Not required to be unique.\n", - "example": "Acme Corp standard contacts", - "type": "string" + "defaultProfileId": { + "allOf": [ + { + "$ref": "#/components/schemas/uuid" + }, + { + "description": "The default profileId supplied on the registration request, if any. Applied to all domains unless overridden at the per-domain level. Echoed from the request.\n" + } + ] }, - "nameServers": { - "description": "Authoritative nameservers applied when this profile is used. Omit to inherit platform defaults at registration time. No minimum count applies to a stored profile, which may carry a partial set or none.\n", - "example": [ - "ns1.example.com", - "ns2.example.com" - ], + "domains": { + "description": "List of domains to register. On execute (POST), supply domain and period for each. On poll (GET), includes per-domain outcomes (expiresAt, status) when COMPLETED.\n", "items": { - "$ref": "#/components/schemas/NameserverHostname" + "$ref": "#/components/schemas/RegistrationBatchDomainItem" }, - "maxItems": 13, + "maxItems": 50, + "minItems": 1, + "nullable": true, "type": "array" }, - "preferences": { - "description": "Purchase preferences to enable when this profile is used. A profile can only enable a preference, never disable one, so leaving a value out of the list means the registration takes the platform default for it: auto-renew on, privacy off. To register without auto-renew, supply the preference inline on that registration instead.\nOn read the list is what the profile will apply, which is not always what was sent: a preference the supplied contacts require is added when the profile is created. Treat it as open — it may name a preference this version does not document.\n", - "example": [ - "AUTO_RENEW", - "PRIVACY" - ], - "items": { - "$ref": "#/components/schemas/RegistrationPreference" - }, - "type": "array", - "uniqueItems": true - }, - "profileId": { + "error": { "allOf": [ { - "$ref": "#/components/schemas/uuid" + "$ref": "#/components/schemas/error" }, { - "description": "Server-assigned identifier. Opaque: store it and echo it back on quote and registration requests. Do not parse it or infer meaning from its value.\n", - "example": "14514a29-5fce-4624-8d8a-d8abd56015e2", + "description": "Failure reason when status is FAILED. Absent otherwise.\n", "readOnly": true } ] }, - "tlds": { - "description": "The TLDs this profile is for. Supplied on create and not returned on read, so a caller that needs the mapping should keep its own. All TLDs listed must share one set of contact requirements; if they do not, the request is rejected and the caller should create one profile per requirement set.\n", - "example": [ - "com", - "net" - ], + "links": { + "description": "HATEOAS link relations for this registration batch. rel=self — the canonical URL for this registration batch record. rel=domains — links to each registered domain-name resource once the batch registration is complete.\n", "items": { - "type": "string" + "$ref": "#/components/schemas/link-description" }, - "minItems": 1, - "type": "array", + "nullable": true, + "readOnly": true, + "type": "array" + }, + "operationId": { + "allOf": [ + { + "$ref": "#/components/schemas/uuid" + }, + { + "description": "Identifier of the DomainOperation tracking this registration batch. Same value returned by GET /operations/{operationId} for abstract operation tracking.\n", + "example": "9f1c2e7a-4b3d-4e8f-a1c2-3d4e5f6a7b8c", + "readOnly": true + } + ] + }, + "orderId": { + "description": "The orderId for the batch registration order. All domains in this registration batch are part of a single order. Present only when status is COMPLETED.\n", + "readOnly": true, + "type": "string" + }, + "registrationBatchId": { + "allOf": [ + { + "$ref": "#/components/schemas/uuid" + }, + { + "description": "Server-assigned stable identifier for this registration batch record.\n", + "readOnly": true + } + ] + }, + "registrationQuoteBatchToken": { + "description": "The single-use opaque token from the preceding quoteRegistrationBatch call. Required. Consumed on first successful execution; idempotent retries with the same Idempotency-Key replay the original operation without re-consuming.\nThe token has a bqt_ prefix followed by a UUID to distinguish it from single-domain quote tokens. Treat as a capability; do not parse.\n", + "example": "bqt_7f3a2b1c-9d8e-4012-a5b6-c1d2e3f4a5b6", + "type": "string", "writeOnly": true + }, + "status": { + "allOf": [ + { + "$ref": "#/components/schemas/DomainOperationStatus" + }, + { + "description": "Current execution status of this registration batch.", + "readOnly": true + } + ] } }, - "required": [ - "contacts" + "title": "RegistrationBatch", + "type": "object" + }, + "RegistrationBatchDomain": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-batch-domain.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "allOf": [ + { + "$ref": "#/components/schemas/DomainQuoteDetails" + }, + { + "properties": { + "error": { + "allOf": [ + { + "$ref": "#/components/schemas/error" + }, + { + "description": "Error details for this domain if it could not be quoted or registered. Present only when a per-domain failure occurred.\n", + "readOnly": true + } + ] + } + }, + "type": "object" + } ], - "title": "Registration Profile", - "type": "object", - "x-sensitivity": "confidential" + "description": "A single domain within a batch registration quote response. Extends DomainQuoteDetails with additional fields for per-domain profile overrides and error details. This model is used only for quote responses (RegistrationQuoteBatch); the execute/poll path uses RegistrationBatchDomainItem instead.\n", + "title": "RegistrationBatchDomain" }, - "RegistrationQuote": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-quote.v3", + "RegistrationBatchDomainItem": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-batch-domain-item.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "A price quote for registering a single domain. Contains a locked price, resolved contact and preference settings, required legal agreements, and a short-lived single-use quoteToken that must be presented on the subsequent registration execute call. Execution without a valid quoteToken is structurally impossible.\nWhen available is false, no quoteToken is returned — this is not an error; it means the domain cannot be registered as requested.\n", + "description": "A single domain within a batch registration execution request or poll response. Contains core registration fields (domain, period, price, fees) plus fields for execute requests (acknowledgedFees, profile overrides) and poll responses (status, expiresAt, updatedAt).\n", "properties": { - "available": { - "description": "Whether the domain is available for registration. When false, no quoteToken is returned. The availability check at quote time is authoritative; a name sniped between suggest/availability and quote fails cleanly here.\n", - "type": "boolean" + "acknowledgedFees": { + "description": "Fees acknowledged by the customer for this domain. Required on execute when the quote's fees array is non-empty (PREMIUM domains). Must match the quote's fees verbatim. Present only on execute requests.\n", + "items": { + "$ref": "#/components/schemas/AcknowledgedFee" + }, + "nullable": true, + "type": "array", + "writeOnly": true }, "domain": { - "description": "The domain name being quoted, in punycode A-label form for IDNs.\n", + "description": "The domain name in punycode A-label form for IDNs.\n", "example": "example.com", "type": "string" }, + "error": { + "allOf": [ + { + "$ref": "#/components/schemas/error" + }, + { + "description": "Per-domain failure detail when this domain's status is FAILED. Absent otherwise.\n", + "readOnly": true + } + ] + }, "expiresAt": { "allOf": [ { "$ref": "#/components/schemas/date-time" }, { - "description": "The expiry timestamp of the quoteToken. After this time, presenting the token on execute returns quote_expired and a new quote must be obtained.\n" + "description": "The domain's expiry date once the registration completes. Present only on poll responses when this domain's status is COMPLETED.\n", + "readOnly": true + } + ] + }, + "fees": { + "description": "Fees charged at the time of purchase, in addition to the registration price. For PREMIUM domains, includes ONE_TIME_PREMIUM_DOMAIN_PURCHASE.\n", + "items": { + "$ref": "#/components/schemas/Fee" + }, + "nullable": true, + "readOnly": true, + "type": "array" + }, + "period": { + "default": 1, + "description": "Registration period in years.", + "example": 1, + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "price": { + "allOf": [ + { + "$ref": "#/components/schemas/simple-money" + }, + { + "description": "The locked registration price for the quoted period. Total amount charged on execute is this price plus any fees.\n", + "readOnly": true + } + ] + }, + "profile": { + "allOf": [ + { + "$ref": "#/components/schemas/Profile" + }, + { + "description": "Optional inline profile override for this specific domain. When present, this inline profile is used instead of the batch operation's defaultProfile. Echoed from the request.\n" + } + ] + }, + "profileId": { + "allOf": [ + { + "$ref": "#/components/schemas/uuid" + }, + { + "description": "Optional profileId override for this specific domain. When present, this profile is used instead of the batch operation's defaultProfileId. Echoed from the request.\n" + } + ] + }, + "status": { + "allOf": [ + { + "$ref": "#/components/schemas/DomainOperationStatus" + }, + { + "description": "Current status of this individual domain within the batch registration. Possible values: PENDING, EXECUTING, COMPLETED, FAILED. Each domain progresses independently.\n", + "readOnly": true + } + ] + }, + "updatedAt": { + "allOf": [ + { + "$ref": "#/components/schemas/date-time" + }, + { + "description": "Timestamp of the most recent status update for this domain.\n", + "readOnly": true + } + ] + } + }, + "title": "RegistrationBatchDomainItem", + "type": "object" + }, + "RegistrationPreference": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-preference.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A purchase preference enabled on a saved registration profile.\nAUTO_RENEW — renew the domain automatically before it expires. PRIVACY — withhold registrant details from public WHOIS. TRUSTEE — local-presence service required by some TLDs. Derived from the contacts supplied rather than set directly, and returned on read when it applies.\nNot a closed set. These are the preferences this version names; a profile may carry a preference that is not among them, and new ones may be named in a later version.\n", + "examples": [ + "AUTO_RENEW", + "PRIVACY", + "TRUSTEE" + ], + "title": "Registration Preference", + "type": "string" + }, + "RegistrationProfile": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-profile.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A saved, reusable set of contacts and purchase preference defaults, referenced by profileId on a registration quote or a registration.\nA profile is a registration-time template. Its values are copied into the registration when a quote is executed, and nothing links the profile to the resulting domain afterwards. A profile cannot be edited, and no change to a profile can affect a domain already registered from it. To change saved details, create the replacement first, then delete the profile it supersedes.\nA profile is scoped to the TLDs named on create, because contact requirements are set by the TLD rather than by the contacts supplied. TLDs sharing one set of requirements share a profile; a TLD demanding additional registrant detail needs its own. See GET /profile-schemas/{tld} for what contacts a TLD requires.\nSee profileId on the registration quote for how a saved profile, an inline profile and account identity combine.\n", + "properties": { + "contacts": { + "allOf": [ + { + "$ref": "#/components/schemas/Contacts" + }, + { + "description": "Contacts saved on this profile. Every role given here applies to all the TLDs the profile covers, since those TLDs share one set of contact requirements.\n" + } + ] + }, + "createdAt": { + "allOf": [ + { + "$ref": "#/components/schemas/date-time" + }, + { + "description": "When the profile was created. Absent for profiles created before this timestamp was recorded.\n", + "readOnly": true + } + ] + }, + "links": { + "description": "HATEOAS link relations. rel=self — the canonical URL for this profile. Profiles are replace-only, so no relation is offered for modifying one.\n", + "items": { + "$ref": "#/components/schemas/link-description" + }, + "readOnly": true, + "type": "array" + }, + "name": { + "description": "Optional human-readable label. Recommended, since it is the only human-readable field that tells one profile from another on read. Not required to be unique.\n", + "example": "Acme Corp standard contacts", + "type": "string" + }, + "nameServers": { + "description": "Authoritative nameservers applied when this profile is used. Omit to inherit platform defaults at registration time. No minimum count applies to a stored profile, which may carry a partial set or none.\n", + "example": [ + "ns1.example.com", + "ns2.example.com" + ], + "items": { + "$ref": "#/components/schemas/NameserverHostname" + }, + "maxItems": 13, + "type": "array" + }, + "preferences": { + "description": "Purchase preferences to enable when this profile is used. A profile can only enable a preference, never disable one, so leaving a value out of the list means the registration takes the platform default for it: auto-renew on, privacy off. To register without auto-renew, supply the preference inline on that registration instead.\nOn read the list is what the profile will apply, which is not always what was sent: a preference the supplied contacts require is added when the profile is created. Treat it as open — it may name a preference this version does not document.\n", + "example": [ + "AUTO_RENEW", + "PRIVACY" + ], + "items": { + "$ref": "#/components/schemas/RegistrationPreference" + }, + "type": "array", + "uniqueItems": true + }, + "profileId": { + "allOf": [ + { + "$ref": "#/components/schemas/uuid" + }, + { + "description": "Server-assigned identifier. Opaque: store it and echo it back on quote and registration requests. Do not parse it or infer meaning from its value.\n", + "example": "14514a29-5fce-4624-8d8a-d8abd56015e2", + "readOnly": true + } + ] + }, + "tlds": { + "description": "The TLDs this profile is for. Supplied on create and not returned on read, so a caller that needs the mapping should keep its own. All TLDs listed must share one set of contact requirements; if they do not, the request is rejected and the caller should create one profile per requirement set.\n", + "example": [ + "com", + "net" + ], + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array", + "writeOnly": true + } + }, + "required": [ + "contacts" + ], + "title": "Registration Profile", + "type": "object", + "x-sensitivity": "confidential" + }, + "RegistrationQuote": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-quote.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "allOf": [ + { + "$ref": "#/components/schemas/DomainQuoteDetails" + }, + { + "properties": { + "expiresAt": { + "allOf": [ + { + "$ref": "#/components/schemas/date-time" + }, + { + "description": "The expiry timestamp of the quoteToken. After this time, presenting the token on execute returns quote_expired and a new quote must be obtained.\n", + "readOnly": true + } + ] + }, + "inventory": { + "allOf": [ + { + "$ref": "#/components/schemas/InventoryType" + }, + { + "description": "The inventory type of the quoted domain. Present when available is true.\n", + "readOnly": true + } + ] + }, + "irreversible": { + "description": "Whether executing this quote is irreversible once accepted. Use to calibrate the explicitness of any confirmation step presented before execute.\n", + "example": false, + "type": "boolean" + }, + "quoteToken": { + "allOf": [ + { + "$ref": "#/components/schemas/uuid" + }, + { + "description": "Opaque, single-use token with a 10-minute TTL. References the locked price, a hash of this request body, and a hash of the resolved profile values. Absent when available is false. Treat as a capability; do not parse.\n", + "example": "7f3a2b1c-9d8e-4012-a5b6-c1d2e3f4a5b6", + "readOnly": true + } + ] + }, + "renewalPrice": { + "allOf": [ + { + "$ref": "#/components/schemas/simple-money" + }, + { + "description": "Indicative renewal cost at current rates. Not a price guarantee; renewal pricing is locked at time of renewal quote.\n" + } + ] } - ] - }, - "fees": { - "description": "Fees charged at the time of purchase, in addition to the registration price. Present when the domain incurs purchase fees beyond the base registration cost.\nThese are the same fees as TermPrice.fees for the selected term (this quote's period) — not a separate term-independent fee list and not additional to term-level fees. Execute cost is price plus this array. Mirrored on Registration.fees after execute.\n", + }, + "type": "object" + } + ], + "description": "A price quote for registering a single domain. Contains a locked price, resolved contact and preference settings, required legal agreements, and a short-lived single-use quoteToken that must be presented on the subsequent registration execute call. Execution without a valid quoteToken is structurally impossible.\nWhen available is false, no quoteToken is returned — this is not an error; it means the domain cannot be registered as requested.\n", + "title": "Registration Quote" + }, + "RegistrationQuoteBatch": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-quote-batch.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A batch registration quote returned by POST /registration-quote-batch. Contains locked prices and settings for 1-50 domains, along with a single-use registrationQuoteBatchToken valid for 10 minutes. Free and read-only; safe to call speculatively.\n", + "properties": { + "domains": { + "description": "Per-domain quote results. Each domain includes locked price, resolved settings, and required agreements. Premium domains include fees that must be acknowledged on execute.\n", "items": { - "$ref": "#/components/schemas/Fee" + "$ref": "#/components/schemas/RegistrationBatchDomain" }, + "maxItems": 50, + "minItems": 1, "nullable": true, "type": "array" }, - "inventory": { + "expiresAt": { "allOf": [ { - "$ref": "#/components/schemas/InventoryType" + "$ref": "#/components/schemas/date-time" }, { - "description": "The inventory type of the quoted domain. Present when available is true.\n", - "readOnly": true + "description": "Timestamp when the registrationQuoteBatchToken expires. After this time, the token cannot be used to execute the registration. Obtain a fresh quote if needed.\n" } ] }, "irreversible": { - "description": "Whether executing this quote is irreversible once accepted. Use to calibrate the explicitness of any confirmation step presented before execute.\n", + "description": "Whether executing this batch quote is irreversible once accepted. Use to calibrate the explicitness of any confirmation step presented before execute.\n", "example": false, "type": "boolean" }, - "period": { - "description": "Registration period in years for which the price is quoted.", - "example": 1, - "maximum": 10, - "minimum": 1, - "type": "integer" - }, - "price": { + "registrationQuoteBatchToken": { + "description": "Single-use opaque token that locks prices and settings for all domains. Valid for 10 minutes. Required when executing the batch registration via POST /registration-batch. Present only when all domains are quotable.\nThe token has a bqt_ prefix followed by a UUID to distinguish it from single-domain quote tokens. Treat as a capability; do not parse.\n", + "example": "bqt_7f3a2b1c-9d8e-4012-a5b6-c1d2e3f4a5b6", + "readOnly": true, + "type": "string" + } + }, + "title": "RegistrationQuoteBatch", + "type": "object" + }, + "RegistrationQuoteBatchInput": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-quote-batch-input.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "Request body for quoting a batch registration of multiple domains. Contains the list of domains to quote (1-50) and optional default/per-domain profile settings for contact resolution.\n", + "properties": { + "defaultProfile": { "allOf": [ { - "$ref": "#/components/schemas/simple-money" + "$ref": "#/components/schemas/Profile" }, { - "description": "The locked registration price for the quoted period. Held for the duration of the quoteToken's TTL. Total amount charged on execute is this price plus any fees on this quote.\n" + "description": "One-time inline contacts and purchase preference defaults for all domains unless overridden at the per-domain level. Not persisted.\n" } ] }, - "quoteToken": { + "defaultProfileId": { "allOf": [ { "$ref": "#/components/schemas/uuid" }, { - "description": "Opaque, single-use token with a 10-minute TTL. References the locked price, a hash of this request body, and a hash of the resolved profile values. Absent when available is false. Treat as a capability; do not parse.\n", - "example": "7f3a2b1c-9d8e-4012-a5b6-c1d2e3f4a5b6" + "description": "ID of a saved registration profile. Applied to all domains unless overridden at the per-domain level.\n" } ] }, - "renewalPrice": { + "domains": { + "description": "List of domains to quote for registration. Minimum 1, maximum 50 domains.\n", + "items": { + "$ref": "#/components/schemas/RegistrationQuoteDomainInput" + }, + "maxItems": 50, + "minItems": 1, + "nullable": true, + "type": "array" + } + }, + "title": "RegistrationQuoteBatchInput", + "type": "object" + }, + "RegistrationQuoteDomainInput": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-quote-domain-input.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A single domain within a batch registration quote request. Contains the domain name, optional registration period, and optional profile overrides for contact resolution.\n", + "properties": { + "domain": { + "description": "The domain name to quote, in punycode A-label form.\n", + "example": "example.com", + "type": "string" + }, + "period": { + "default": 1, + "description": "Registration period in years.", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "profile": { "allOf": [ { - "$ref": "#/components/schemas/simple-money" + "$ref": "#/components/schemas/Profile" }, { - "description": "Indicative renewal cost at current rates. Not a price guarantee; renewal pricing is locked at time of renewal quote.\n" + "description": "Optional inline profile override for this specific domain. Uses defaultProfile if not provided.\n" } ] }, - "requiredAgreements": { - "description": "Legal agreements that must be accepted before executing this quote. The agreementType values from this list must be included in the execute request's consent object.\n", - "items": { - "$ref": "#/components/schemas/Agreement" - }, - "nullable": true, - "type": "array" - }, - "resolved": { + "profileId": { "allOf": [ { - "$ref": "#/components/schemas/ResolvedSettings" + "$ref": "#/components/schemas/uuid" }, { - "description": "The effective contact and preference settings that will be applied on execute. Review before execute to verify registrant, contacts, and preferences match intent.\n" + "description": "Optional profileId override for this specific domain. Uses defaultProfileId if not provided.\n" } ] } }, - "title": "Registration Quote", - "type": "object" - }, - "RegistrationSchema": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-schema.v3", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "TLD-specific JSON Schema describing the fields required to register a domain under this TLD. The structure varies per TLD and is not further constrained at the API layer. Use the contents to guide construction of the POST /registration-quotes and POST /registrations request bodies.\n", - "title": "Registration Schema", + "title": "RegistrationQuoteDomainInput", "type": "object" }, "Renewal": { @@ -2528,7 +2992,7 @@ }, "description": "The GoDaddy Domain Lifecycle Management API provides comprehensive capabilities\nfor discovering, registering, managing, renewing, transferring, and reselling\ndomain names. This is major version 3, designed for agent-first interactions\nwhile remaining fully usable by direct API clients and resellers.\n\n## Namespace\n\nAll paths are under `/v3/domains/`. The namespace is `domains` (the business capability);\nthe core entity collection is `/domain-names`.\n\n## Key Conventions\n\n**Quote/execute for commercial operations.** Every commercial mutation (register,\nrenew, transfer) requires a `quoteToken` minted by the corresponding quote\ncollection endpoint. Execution without a prior quote is structurally impossible.\nThe token locks the price, resolved settings, and required legal agreements for a\n10-minute TTL. Quote calls are free, read-only, and safe to call speculatively.\n\n**Async commercial operations.** `POST /registrations`, `POST /renewals`, and\n`POST /transfers` each return `202 Accepted` with the concrete entity body\n(`Registration`, `Renewal`, or `Transfer`) and a `Location` header. Poll\n`links[rel=self]` on the returned entity until status is `COMPLETED` or `FAILED`.\nEach concrete resource is also reachable via `GET /operations/{operationId}`;\nthe `operationId` is included in the entity for clients that prefer the abstract\nview. Non-commercial mutations return a `DomainOperation` body.\n\n**Entity-oriented resource model.** Domains are the core entity of this API\n(exposed as `/domain-names` in the path to distinguish the resource collection\nfrom the `domains` namespace prefix). Register, renew, and transfer are\ncommercial actions executed by `POST` to their corresponding top-level\nresource collections (`/registrations`, `/renewals`, `/transfers`); each\naccepts a prior quote and returns an async entity to poll until completion.\nFor commercial execute calls, the target domain is\nexpressed in the request body, not the path. Sub-resources (`contacts`,\n`nameservers`, `privacy`, `auto-renew`, `transfer-lock`, `records`) only exist\nin the context of a specific domain-name instance. The `/check-availability`\ncontroller accepts GET (single domain) or POST (1–25 domains) and carries no\npersistent identity.\n\n**Flat, two-level maximum.** No resource path goes deeper than\n`/{collection}/{id}/{sub-resource}` or `/{collection}/{id}/{sub-collection}/{id}`.\n\n**Reseller on-behalf-of.** Resellers pass `X-Shopper-Id`; all operations are\nthen scoped to that shopper. Absent the header, the authenticated entity's own\naccount is used.\n\n## Launch Scope (v3.0)\nStandard TLDs only. TLDs with eligibility requirements (.us, .ca, .eu) return\n`UNSUPPORTED_TLD` until Phase 2.\n", "title": "Domain Lifecycle Management API", - "version": "3.3.0", + "version": "3.4.0", "x-visibility": { "extent": "public" } @@ -2599,7 +3063,7 @@ "description": "Request was successful" } }, - "summary": "Retrieve the legal agreement(s) required to purchase the specified TLD and add-ons", + "summary": "Get required legal agreements for a TLD", "tags": [ "Register and Renew Domains" ] @@ -3164,16 +3628,239 @@ } ], "responses": { - "200": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Domain" + } + } + }, + "description": "Domain found.", + "headers": { + "X-Request-Id": { + "description": "Request correlation identifier echoed from the request or server-generated.", + "schema": { + "$ref": "#/components/schemas/uuid" + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "domains.domain:read" + ] + } + ], + "summary": "Get a registered domain", + "tags": [ + "Domains" + ] + } + }, + "/v3/domains/domain-names/{domain-name}/auto-renew": { + "post": { + "description": "Sets the auto-renewal preference for the domain. When enabled, the domain will be automatically renewed before expiration using the payment method on file. Returns a DomainOperation; propagation to the registry is asynchronous.\n", + "operationId": "setAutoRenew", + "parameters": [ + { + "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", + "in": "header", + "name": "X-Request-Id", + "required": false, + "schema": { + "$ref": "#/components/schemas/uuid" + } + }, + { + "description": "Reseller acting on behalf of a shopper account. When present, all domain operations are scoped to the specified shopper. Absent, the authenticated entity's own account is used. Only valid for reseller OAuth tokens.\n", + "example": "shopper_123", + "in": "header", + "name": "X-Shopper-Id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "The domain name in punycode A-label form (e.g., example.com). For IDNs, use the punycode representation.\n", + "example": "example.com", + "in": "path", + "name": "domain-name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Client-generated unique key (UUID recommended). Retrying a mutating request with the same Idempotency-Key returns the original response without creating a duplicate side effect. Required on all mutation endpoints to ensure safe retries.\n", + "example": "9f1c2e7a-4b3d-4e8f-a1c2-3d4e5f6a7b8c", + "in": "header", + "name": "Idempotency-Key", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "disableAutoRenew": { + "summary": "Disable auto-renewal", + "value": false + }, + "enableAutoRenew": { + "summary": "Enable auto-renewal", + "value": true + } + }, + "schema": { + "description": "Whether auto-renewal should be enabled for this domain. When true, the domain will be automatically renewed before expiration using the payment method on file.\n", + "type": "boolean" + } + } + }, + "required": true + }, + "responses": { + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DomainOperation" + } + } + }, + "description": "Auto-renew update accepted; poll the operation for completion.", + "headers": { + "Location": { + "description": "URL of the created or async resource.", + "schema": { + "format": "uri", + "type": "string" + } + }, + "Retry-After": { + "description": "Suggested number of seconds before the client should poll again. Present on 202 responses and non-terminal operation poll responses.\n", + "schema": { + "example": 5, + "type": "integer" + } + }, + "X-Request-Id": { + "description": "Request correlation identifier echoed from the request or server-generated.", + "schema": { + "$ref": "#/components/schemas/uuid" + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "domains.domain:update" + ] + } + ], + "summary": "Set auto-renew setting for a domain", + "tags": [ + "Domain Management" + ] + } + }, + "/v3/domains/domain-names/{domain-name}/nameservers": { + "put": { + "description": "Replaces the authoritative nameservers for the domain with the provided list. Minimum 2, maximum 13. Returns a DomainOperation; propagation to the registry is asynchronous.\n", + "operationId": "updateNameservers", + "parameters": [ + { + "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", + "in": "header", + "name": "X-Request-Id", + "required": false, + "schema": { + "$ref": "#/components/schemas/uuid" + } + }, + { + "description": "Reseller acting on behalf of a shopper account. When present, all domain operations are scoped to the specified shopper. Absent, the authenticated entity's own account is used. Only valid for reseller OAuth tokens.\n", + "example": "shopper_123", + "in": "header", + "name": "X-Shopper-Id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "The domain name in punycode A-label form (e.g., example.com). For IDNs, use the punycode representation.\n", + "example": "example.com", + "in": "path", + "name": "domain-name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Client-generated unique key (UUID recommended). Retrying a mutating request with the same Idempotency-Key returns the original response without creating a duplicate side effect. Required on all mutation endpoints to ensure safe retries.\n", + "example": "9f1c2e7a-4b3d-4e8f-a1c2-3d4e5f6a7b8c", + "in": "header", + "name": "Idempotency-Key", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "nameservers": { + "value": [ + "ns1.example.com", + "ns2.example.com" + ] + } + }, + "schema": { + "$ref": "#/components/schemas/NameServers" + } + } + }, + "required": true + }, + "responses": { + "202": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Domain" + "$ref": "#/components/schemas/DomainOperation" } } }, - "description": "Domain found.", + "description": "Nameserver update accepted; poll the operation for completion.", "headers": { + "Location": { + "description": "URL of the created or async resource.", + "schema": { + "format": "uri", + "type": "string" + } + }, + "Retry-After": { + "description": "Suggested number of seconds before the client should poll again. Present on 202 responses and non-terminal operation poll responses.\n", + "schema": { + "example": 5, + "type": "integer" + } + }, "X-Request-Id": { "description": "Request correlation identifier echoed from the request or server-generated.", "schema": { @@ -3186,20 +3873,20 @@ "security": [ { "oauth2": [ - "domains.domain:read" + "domains.nameserver:update" ] } ], - "summary": "Get a registered domain", + "summary": "Replace the nameservers for a domain", "tags": [ - "Domains" + "Domain Management" ] } }, - "/v3/domains/domain-names/{domain-name}/auto-renew": { + "/v3/domains/domain-names/{domain-name}/transfer-lock": { "post": { - "description": "Sets the auto-renewal preference for the domain. When enabled, the domain will be automatically renewed before expiration using the payment method on file. Returns a DomainOperation; propagation to the registry is asynchronous.\n", - "operationId": "setAutoRenew", + "description": "Sets the transfer-lock (registrar lock / EPP lock) for the domain. When enabled, outbound transfers to another registrar are blocked. Returns a DomainOperation; propagation to the registry is asynchronous.\n", + "operationId": "setTransferLock", "parameters": [ { "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", @@ -3245,17 +3932,17 @@ "content": { "application/json": { "examples": { - "disableAutoRenew": { - "summary": "Disable auto-renewal", + "disableTransferLock": { + "summary": "Disable transfer-lock", "value": false }, - "enableAutoRenew": { - "summary": "Enable auto-renewal", + "enableTransferLock": { + "summary": "Enable transfer-lock", "value": true } }, "schema": { - "description": "Whether auto-renewal should be enabled for this domain. When true, the domain will be automatically renewed before expiration using the payment method on file.\n", + "description": "Whether transfer-lock should be enabled for this domain. When true, outbound transfers to another registrar are blocked. When false, transfers are allowed.\n", "type": "boolean" } } @@ -3271,7 +3958,7 @@ } } }, - "description": "Auto-renew update accepted; poll the operation for completion.", + "description": "Transfer-lock update accepted; poll the operation for completion.", "headers": { "Location": { "description": "URL of the created or async resource.", @@ -3303,19 +3990,16 @@ ] } ], - "summary": "Set auto-renew setting for a domain", + "summary": "Set transfer-lock setting for a domain", "tags": [ "Domain Management" - ], - "x-visibility": { - "extent": "private" - } + ] } }, - "/v3/domains/domain-names/{domain-name}/nameservers": { - "put": { - "description": "Replaces the authoritative nameservers for the domain with the provided list. Minimum 2, maximum 13. Returns a DomainOperation; propagation to the registry is asynchronous.\n", - "operationId": "updateNameservers", + "/v3/domains/operations/{operationId}": { + "get": { + "description": "Universal poll endpoint for all asynchronous domain mutations. Returns\nthe current state of the operation. Non-terminal responses include a\n`Retry-After` header.\n\nTerminal statuses:\n- `COMPLETED` — operation succeeded; `result` contains the final outcome.\n- `FAILED` — operation terminated with an error; `error` contains detail.\n\nWhile status is non-terminal (`CONFIRMED`, `EXECUTING`), neither\n`result` nor `error` is present. Poll until a terminal status is reached.\n\nThe poll URL is provided in the `Location` header of the initiating 202\nresponse and in `links[rel=self]`. Clients must not construct this URL\nindependently.\n", + "operationId": "getOperation", "parameters": [ { "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", @@ -3337,62 +4021,71 @@ } }, { - "description": "The domain name in punycode A-label form (e.g., example.com). For IDNs, use the punycode representation.\n", - "example": "example.com", - "in": "path", - "name": "domain-name", - "required": true, - "schema": { - "type": "string" - } - }, - { - "description": "Client-generated unique key (UUID recommended). Retrying a mutating request with the same Idempotency-Key returns the original response without creating a duplicate side effect. Required on all mutation endpoints to ensure safe retries.\n", + "description": "The server-assigned operation identifier returned in the 202 response of any async domain mutation.\n", "example": "9f1c2e7a-4b3d-4e8f-a1c2-3d4e5f6a7b8c", - "in": "header", - "name": "Idempotency-Key", + "in": "path", + "name": "operationId", "required": true, "schema": { - "type": "string" + "$ref": "#/components/schemas/uuid" } } ], - "requestBody": { - "content": { - "application/json": { - "examples": { - "nameservers": { - "value": [ - "ns1.example.com", - "ns2.example.com" - ] - } - }, - "schema": { - "$ref": "#/components/schemas/NameServers" - } - } - }, - "required": true - }, "responses": { - "202": { + "200": { "content": { "application/json": { + "examples": { + "completed": { + "summary": "Registration completed", + "value": { + "createdAt": "2026-06-12T10:02:05Z", + "domain": "example.com", + "links": [ + { + "href": "/v3/domains/operations/9f1c2e7a-4b3d-4e8f-a1c2-3d4e5f6a7b8c", + "rel": "self" + }, + { + "href": "/v3/domains/domain-names/example.com", + "rel": "domain" + } + ], + "operationId": "9f1c2e7a-4b3d-4e8f-a1c2-3d4e5f6a7b8c", + "result": { + "expiresAt": "2027-06-12T10:02:10Z", + "orderId": "ord_xyz789" + }, + "status": "COMPLETED", + "type": "REGISTER", + "updatedAt": "2026-06-12T10:02:10Z" + } + }, + "executing": { + "summary": "Operation in progress", + "value": { + "createdAt": "2026-06-12T10:02:05Z", + "domain": "example.com", + "links": [ + { + "href": "/v3/domains/operations/9f1c2e7a-4b3d-4e8f-a1c2-3d4e5f6a7b8c", + "rel": "self" + } + ], + "operationId": "9f1c2e7a-4b3d-4e8f-a1c2-3d4e5f6a7b8c", + "status": "EXECUTING", + "type": "REGISTER", + "updatedAt": "2026-06-12T10:02:07Z" + } + } + }, "schema": { "$ref": "#/components/schemas/DomainOperation" } } }, - "description": "Nameserver update accepted; poll the operation for completion.", + "description": "Current operation state.", "headers": { - "Location": { - "description": "URL of the created or async resource.", - "schema": { - "format": "uri", - "type": "string" - } - }, "Retry-After": { "description": "Suggested number of seconds before the client should poll again. Present on 202 responses and non-terminal operation poll responses.\n", "schema": { @@ -3412,20 +4105,20 @@ "security": [ { "oauth2": [ - "domains.nameserver:update" + "domains.domain:read" ] } ], - "summary": "Replace the nameservers for a domain", + "summary": "Poll an async domain operation", "tags": [ - "Domain Management" + "Operations" ] } }, - "/v3/domains/domain-names/{domain-name}/transfer-lock": { - "post": { - "description": "Sets the transfer-lock (registrar lock / EPP lock) for the domain. When enabled, outbound transfers to another registrar are blocked. Returns a DomainOperation; propagation to the registry is asynchronous.\n", - "operationId": "setTransferLock", + "/v3/domains/profile-schemas/{tld}": { + "get": { + "description": "Returns the TLD-specific JSON Schema describing the fields required\nwhen calling POST /registration-quotes or POST /registrations for\nthe given TLD. The schema shape varies by TLD; clients should call\nthis endpoint before quoting or registering to discover required\ncontact and eligibility fields.\n", + "operationId": "getProfileSchema", "parameters": [ { "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", @@ -3447,14 +4140,75 @@ } }, { - "description": "The domain name in punycode A-label form (e.g., example.com). For IDNs, use the punycode representation.\n", - "example": "example.com", + "description": "The Top-Level Domain (e.g. com, net, io) whose registration schema should be retrieved.\n", + "example": "com", "in": "path", - "name": "domain-name", + "name": "tld", "required": true, "schema": { "type": "string" } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProfileSchema" + } + } + }, + "description": "TLD-specific profile schema.", + "headers": { + "X-Request-Id": { + "description": "Request correlation identifier echoed from the request or server-generated.", + "schema": { + "$ref": "#/components/schemas/uuid" + } + } + } + } + }, + "security": [ + { + "oauth2": [ + "domains.domain:read" + ] + } + ], + "summary": "Retrieve the profile schema for a TLD", + "tags": [ + "Discovery" + ], + "x-visibility": { + "extent": "private" + } + } + }, + "/v3/domains/registration-batches": { + "post": { + "description": "Executes a previously quoted batch domain registration. **Irreversible once\naccepted; creates charges for all domains.** Requires a valid unexpired\nregistrationQuoteBatchToken from `quoteRegistrationBatch`, an `Idempotency-Key` header,\nand a consent record.\n\nAll domains are registered atomically (all succeed or all fail). If any\ndomain fails during execution (registry error, payment failure), the entire\nbatch registration is rolled back and no domains are registered.\n\nIdempotency takes precedence over the single-use check: retrying with the\nsame `Idempotency-Key` replays the original operation even after the token\nis consumed.\n\nReturns a `RegistrationBatch` entity. Poll `links[rel=self]`\n(`GET /registration-batches/{registrationBatchId}`) until status is `COMPLETED`\nor `FAILED`. The `operationId` field is also provided for clients that\nprefer `GET /operations/{operationId}`; both resolve the same resource.\n\n**PREMIUM domains:** when the quote's per-domain `fees` array is non-empty\n(inventory `PREMIUM`), the execute request must include that domain's\n`acknowledgedFees` containing the same fees verbatim — same types, amounts,\nand currencies. This confirms the customer explicitly saw and accepted the\nspecific charge before the irreversible purchase is executed.\n\n- `acknowledgedFees` absent when fees exist → `422` with error name\n `consent_fees_required`.\n- `acknowledgedFees` present but type or amount does not match the locked\n quote → `422` with error name `quote_mismatch`.\n", + "operationId": "registerDomainBatches", + "parameters": [ + { + "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", + "in": "header", + "name": "X-Request-Id", + "required": false, + "schema": { + "$ref": "#/components/schemas/uuid" + } + }, + { + "description": "Reseller acting on behalf of a shopper account. When present, all domain operations are scoped to the specified shopper. Absent, the authenticated entity's own account is used. Only valid for reseller OAuth tokens.\n", + "example": "shopper_123", + "in": "header", + "name": "X-Shopper-Id", + "required": false, + "schema": { + "type": "string" + } }, { "description": "Client-generated unique key (UUID recommended). Retrying a mutating request with the same Idempotency-Key returns the original response without creating a duplicate side effect. Required on all mutation endpoints to ensure safe retries.\n", @@ -3465,24 +4219,78 @@ "schema": { "type": "string" } + }, + { + "description": "ISC (International Shopper Code) for pricing context. When provided, prices reflect the applicable rates for this ISC.\n", + "example": "ISC_PARTNER_001", + "in": "query", + "name": "iscCode", + "required": false, + "schema": { + "type": "string" + } } ], "requestBody": { "content": { "application/json": { "examples": { - "disableTransferLock": { - "summary": "Disable transfer-lock", - "value": false + "withPremiumToken": { + "summary": "PREMIUM domain in batch with fee acknowledgment", + "value": { + "consent": { + "agreedAt": "2026-06-12T10:02:00Z", + "agreementTypes": [ + "API_DPA" + ] + }, + "domains": [ + { + "domain": "example.com", + "period": 1 + }, + { + "acknowledgedFees": [ + { + "fee": { + "currencyCode": "USD", + "value": 390000 + }, + "type": "ONE_TIME_PREMIUM_DOMAIN_PURCHASE" + } + ], + "domain": "examplepremium.net", + "period": 1 + } + ], + "registrationQuoteBatchToken": "bqt_9a1b2c3d-4e5f-6789-abcd-ef0123456789" + } }, - "enableTransferLock": { - "summary": "Enable transfer-lock", - "value": true + "withToken": { + "summary": "Batch REGISTRY registration with registrationQuoteBatchToken", + "value": { + "consent": { + "agreedAt": "2026-06-12T10:02:00Z", + "agreementTypes": [ + "API_DPA" + ] + }, + "domains": [ + { + "domain": "example.com", + "period": 1 + }, + { + "domain": "example.net", + "period": 2 + } + ], + "registrationQuoteBatchToken": "bqt_7f3a2b1c-9d8e-4012-a5b6-c1d2e3f4a5b6" + } } }, "schema": { - "description": "Whether transfer-lock should be enabled for this domain. When true, outbound transfers to another registrar are blocked. When false, transfers are allowed.\n", - "type": "boolean" + "$ref": "#/components/schemas/RegistrationBatch" } } }, @@ -3493,11 +4301,11 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DomainOperation" + "$ref": "#/components/schemas/RegistrationBatch" } } }, - "description": "Transfer-lock update accepted; poll the operation for completion.", + "description": "Registration batch accepted. Poll the self link for status. All domains will be registered atomically.\n", "headers": { "Location": { "description": "URL of the created or async resource.", @@ -3525,23 +4333,23 @@ "security": [ { "oauth2": [ - "domains.domain:update" + "domains.domain:create" ] } ], - "summary": "Set transfer-lock setting for a domain", + "summary": "Register multiple domains atomically (requires registrationQuoteBatchToken)", "tags": [ - "Domain Management" + "Registrations" ], "x-visibility": { "extent": "private" } } }, - "/v3/domains/operations/{operationId}": { + "/v3/domains/registration-batches/{registrationBatchId}": { "get": { - "description": "Universal poll endpoint for all asynchronous domain mutations. Returns\nthe current state of the operation. Non-terminal responses include a\n`Retry-After` header.\n\nTerminal statuses:\n- `COMPLETED` — operation succeeded; `result` contains the final outcome.\n- `FAILED` — operation terminated with an error; `error` contains detail.\n\nWhile status is non-terminal (`CONFIRMED`, `EXECUTING`), neither\n`result` nor `error` is present. Poll until a terminal status is reached.\n\nThe poll URL is provided in the `Location` header of the initiating 202\nresponse and in `links[rel=self]`. Clients must not construct this URL\nindependently.\n", - "operationId": "getOperation", + "description": "Returns a single registration batch record by its server-assigned registrationBatchId, including the current execution status and per-domain outcomes once the batch registration completes. This is the concrete poll endpoint for batch registration operations; the abstract equivalent is GET /operations/{operationId}.\nPoll until status is COMPLETED or FAILED. When COMPLETED, the batch-level orderId is populated and each domain in the `domains` array includes expiresAt. When FAILED, the `error` field contains the failure reason and no domains were registered.\n", + "operationId": "getRegistrationBatch", "parameters": [ { "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", @@ -3563,10 +4371,9 @@ } }, { - "description": "The server-assigned operation identifier returned in the 202 response of any async domain mutation.\n", - "example": "9f1c2e7a-4b3d-4e8f-a1c2-3d4e5f6a7b8c", + "description": "Server-assigned registration batch identifier.", "in": "path", - "name": "operationId", + "name": "registrationBatchId", "required": true, "schema": { "$ref": "#/components/schemas/uuid" @@ -3577,56 +4384,12 @@ "200": { "content": { "application/json": { - "examples": { - "completed": { - "summary": "Registration completed", - "value": { - "createdAt": "2026-06-12T10:02:05Z", - "domain": "example.com", - "links": [ - { - "href": "/v3/domains/operations/9f1c2e7a-4b3d-4e8f-a1c2-3d4e5f6a7b8c", - "rel": "self" - }, - { - "href": "/v3/domains/domain-names/example.com", - "rel": "domain" - } - ], - "operationId": "9f1c2e7a-4b3d-4e8f-a1c2-3d4e5f6a7b8c", - "result": { - "expiresAt": "2027-06-12T10:02:10Z", - "orderId": "ord_xyz789" - }, - "status": "COMPLETED", - "type": "REGISTER", - "updatedAt": "2026-06-12T10:02:10Z" - } - }, - "executing": { - "summary": "Operation in progress", - "value": { - "createdAt": "2026-06-12T10:02:05Z", - "domain": "example.com", - "links": [ - { - "href": "/v3/domains/operations/9f1c2e7a-4b3d-4e8f-a1c2-3d4e5f6a7b8c", - "rel": "self" - } - ], - "operationId": "9f1c2e7a-4b3d-4e8f-a1c2-3d4e5f6a7b8c", - "status": "EXECUTING", - "type": "REGISTER", - "updatedAt": "2026-06-12T10:02:07Z" - } - } - }, "schema": { - "$ref": "#/components/schemas/DomainOperation" + "$ref": "#/components/schemas/RegistrationBatch" } } }, - "description": "Current operation state.", + "description": "Registration batch record returned.", "headers": { "Retry-After": { "description": "Suggested number of seconds before the client should poll again. Present on 202 responses and non-terminal operation poll responses.\n", @@ -3651,10 +4414,13 @@ ] } ], - "summary": "Poll an async domain operation", + "summary": "Get a registration batch record", "tags": [ - "Operations" - ] + "Registrations" + ], + "x-visibility": { + "extent": "private" + } } }, "/v3/domains/registration-profiles": { @@ -3922,10 +4688,10 @@ } } }, - "/v3/domains/registration-quotes": { + "/v3/domains/registration-quote-batches": { "post": { - "description": "Prices the registration, resolves contact and preference settings,\nreturns required legal agreements, and mints a single-use quoteToken\nwith a 10-minute TTL. Free and read-only; safe to call speculatively.\n\nWhen the domain is unavailable, `available: false` is returned with\nno quoteToken — this is a valid non-error response.\n\nWhen required contact fields are missing, a `422` is returned with\nfield-level details so the agent can collect the missing data and re-quote.\n\nMay pass `iscCode` to lock pricing at applicable rates;\nthe same value must be supplied on /registrations if provided here.\n\n**PREMIUM domains:** when the quoted domain has inventory `PREMIUM`,\nthe response includes a `fees` array containing a\n`ONE_TIME_PREMIUM_DOMAIN_PURCHASE` entry. The execute request must\necho this array verbatim in `consent.acknowledgedFees` to confirm\nthe customer accepted the specific charge before the irreversible\npurchase proceeds.\n", - "operationId": "quoteDomainRegistration", + "description": "Prices the registration of 1-50 domains, resolves contact and preference\nsettings for each, returns required legal agreements, and mints a single-use\nregistrationQuoteBatchToken with a 10-minute TTL. Free and read-only; safe to call\nspeculatively.\n\nAll domains are quoted atomically. If any domain cannot be quoted (unavailable,\ninvalid, unsupported TLD), the entire quote fails with per-domain error details.\n\nWhen all domains are quotable, returns a registrationQuoteBatchToken that locks prices and\nsettings for all domains. Executing the quote consumes all domains atomically\n(all succeed or all fail).\n\n**PREMIUM domains:** when any quoted domain has inventory `PREMIUM`, that\ndomain's result includes a `fees` array containing a\n`ONE_TIME_PREMIUM_DOMAIN_PURCHASE` entry. The execute request must echo all\nfees verbatim in the per-domain `acknowledgedFees` to confirm the customer\naccepted the specific charges before the irreversible purchase proceeds.\n\n**Contact resolution:** Contacts can be supplied via `defaultProfileId` (saved\nprofile) or inline `defaultProfile` (one-time contacts), or derived from account\nidentity. Individual domains can override with their own `profileId` or `profile`.\nDomains without overrides use the default contact source.\n", + "operationId": "quoteRegistrationBatches", "parameters": [ { "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", @@ -3964,57 +4730,39 @@ "minimal": { "summary": "Minimal — derive registrant from account identity", "value": { - "domain": "example.com" + "domains": [ + { + "domain": "example.com" + }, + { + "domain": "example.net", + "period": 2 + } + ] } }, "withProfile": { - "summary": "With saved profile ID", + "summary": "With default profile and per-domain override", "value": { - "domain": "example.com", - "period": 2, - "profileId": "14514a29-5fce-4624-8d8a-d8abd56015e2" - } - } - }, - "schema": { - "properties": { - "domain": { - "description": "The domain name to quote, in punycode A-label form.", - "example": "example.com", - "type": "string" - }, - "period": { - "default": 1, - "description": "Registration period in years.", - "maximum": 10, - "minimum": 1, - "type": "integer" - }, - "profile": { - "allOf": [ + "defaultProfileId": "14514a29-5fce-4624-8d8a-d8abd56015e2", + "domains": [ { - "$ref": "#/components/schemas/InlineRegistrationProfile" + "domain": "example.com" }, { - "description": "One-time inline contacts and purchase preference defaults for this quote. Not persisted.\n" - } - ] - }, - "profileId": { - "allOf": [ - { - "$ref": "#/components/schemas/uuid" + "domain": "test.com", + "profileId": "99999999-aaaa-bbbb-cccc-dddddddddddd" }, { - "description": "ID of a saved registration profile. Any inline profile overrides it role by role; when neither supplies a registrant, account identity applies. An id that names no profile the caller owns is rejected, never ignored, so a quote never silently applies contacts other than the ones asked for.\n" + "domain": "mysite.io", + "period": 3 } ] } - }, - "required": [ - "domain" - ], - "type": "object" + } + }, + "schema": { + "$ref": "#/components/schemas/RegistrationQuoteBatchInput" } } }, @@ -4025,11 +4773,11 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RegistrationQuote" + "$ref": "#/components/schemas/RegistrationQuoteBatch" } } }, - "description": "Registration quote. When available is false, no quoteToken is returned; this is not an error.\n", + "description": "Registration batch quote. When all domains are quotable, includes a registrationQuoteBatchToken.\n", "headers": { "X-Request-Id": { "description": "Request correlation identifier echoed from the request or server-generated.", @@ -4047,16 +4795,19 @@ ] } ], - "summary": "Quote a single-domain registration (no commitment)", + "summary": "Quote a batch registration of multiple domains (no commitment)", "tags": [ "Registration Quotes" - ] + ], + "x-visibility": { + "extent": "private" + } } }, - "/v3/domains/registration-schemas/{tld}": { - "get": { - "description": "Returns the TLD-specific JSON Schema describing the fields required\nwhen calling POST /registration-quotes or POST /registrations for\nthe given TLD. The schema shape varies by TLD; clients should call\nthis endpoint before quoting or registering to discover required\ncontact and eligibility fields.\n", - "operationId": "getRegistrationSchema", + "/v3/domains/registration-quotes": { + "post": { + "description": "Prices the registration, resolves contact and preference settings,\nreturns required legal agreements, and mints a single-use quoteToken\nwith a 10-minute TTL. Free and read-only; safe to call speculatively.\n\nWhen the domain is unavailable, `available: false` is returned with\nno quoteToken — this is a valid non-error response.\n\nWhen required contact fields are missing, a `422` is returned with\nfield-level details so the agent can collect the missing data and re-quote.\n\nMay pass `iscCode` to lock pricing at applicable rates;\nthe same value must be supplied on /registrations if provided here.\n\n**PREMIUM domains:** when the quoted domain has inventory `PREMIUM`,\nthe response includes a `fees` array containing a\n`ONE_TIME_PREMIUM_DOMAIN_PURCHASE` entry. The execute request must\necho this array verbatim in `consent.acknowledgedFees` to confirm\nthe customer accepted the specific charge before the irreversible\npurchase proceeds.\n", + "operationId": "quoteDomainRegistration", "parameters": [ { "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", @@ -4078,26 +4829,89 @@ } }, { - "description": "The Top-Level Domain (e.g. com, net, io) whose registration schema should be retrieved.\n", - "example": "com", - "in": "path", - "name": "tld", - "required": true, + "description": "ISC (International Shopper Code) for pricing context. When provided, prices reflect the applicable rates for this ISC.\n", + "example": "ISC_PARTNER_001", + "in": "query", + "name": "iscCode", + "required": false, "schema": { "type": "string" } } ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "minimal": { + "summary": "Minimal — derive registrant from account identity", + "value": { + "domain": "example.com" + } + }, + "withProfile": { + "summary": "With saved profile ID", + "value": { + "domain": "example.com", + "period": 2, + "profileId": "14514a29-5fce-4624-8d8a-d8abd56015e2" + } + } + }, + "schema": { + "properties": { + "domain": { + "description": "The domain name to quote, in punycode A-label form.", + "example": "example.com", + "type": "string" + }, + "period": { + "default": 1, + "description": "Registration period in years.", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "profile": { + "allOf": [ + { + "$ref": "#/components/schemas/Profile" + }, + { + "description": "One-time inline contacts and purchase preference defaults for this quote. Not persisted.\n" + } + ] + }, + "profileId": { + "allOf": [ + { + "$ref": "#/components/schemas/uuid" + }, + { + "description": "ID of a saved registration profile. Any inline profile overrides it role by role; when neither supplies a registrant, account identity applies. An id that names no profile the caller owns is rejected, never ignored, so a quote never silently applies contacts other than the ones asked for.\n" + } + ] + } + }, + "required": [ + "domain" + ], + "type": "object" + } + } + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RegistrationSchema" + "$ref": "#/components/schemas/RegistrationQuote" } } }, - "description": "TLD-specific registration schema.", + "description": "Registration quote. When available is false, no quoteToken is returned; this is not an error.\n", "headers": { "X-Request-Id": { "description": "Request correlation identifier echoed from the request or server-generated.", @@ -4115,9 +4929,9 @@ ] } ], - "summary": "Retrieve the registration schema for a TLD", + "summary": "Quote a single-domain registration (no commitment)", "tags": [ - "Registrations" + "Registration Quotes" ] } }, diff --git a/rust/hosting-client/openapi/hosting.oas3.json b/rust/hosting-client/openapi/hosting.oas3.json index 2bec364d..2b9d0f0a 100644 --- a/rust/hosting-client/openapi/hosting.oas3.json +++ b/rust/hosting-client/openapi/hosting.oas3.json @@ -1314,7 +1314,7 @@ "name": "Proprietary", "url": "https://www.godaddy.com/legal/agreements/software-license-agreement" }, - "title": "Hosting API", + "title": "Hosted Application Lifecycle Management API", "version": "1.0.0" }, "openapi": "3.0.3", diff --git a/rust/schemas/api/bulk-operations.json b/rust/schemas/api/bulk-operations.json index 685c0055..ce37010b 100644 --- a/rust/schemas/api/bulk-operations.json +++ b/rust/schemas/api/bulk-operations.json @@ -625,6 +625,70 @@ "title": "Bulk Operation Error", "type": "object" }, + "BulkOperationErrorList": { + "$id": "https://godaddy.com/schemas/commerce/bulk-operations/bulk-operation-error-list.v1", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A list of bulk operation errors", + "properties": { + "errors": { + "description": "The bulk operation errors", + "items": { + "$ref": "#/$defs/BulkOperationError" + }, + "type": "array" + }, + "links": { + "description": "The links", + "items": { + "$ref": "#/$defs/link-description" + }, + "type": "array" + }, + "pageToken": { + "deprecated": true, + "description": "Deprecated. Use links[rel=next].href to advance pages instead. Will be\nremoved in a future release.\n", + "type": "string" + } + }, + "required": [ + "errors", + "links" + ], + "title": "Bulk Operation Errors", + "type": "object" + }, + "BulkOperationList": { + "$id": "https://godaddy.com/schemas/commerce/bulk-operations/bulk-operation-list.v1", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A list of bulk operations", + "properties": { + "bulkOperations": { + "description": "The bulk operations", + "items": { + "$ref": "#/$defs/BulkOperation" + }, + "type": "array" + }, + "links": { + "description": "The links", + "items": { + "$ref": "#/$defs/link-description" + }, + "type": "array" + }, + "pageToken": { + "deprecated": true, + "description": "Deprecated. Use links[rel=next].href to advance pages instead. Will be\nremoved in a future release.\n", + "type": "string" + } + }, + "required": [ + "bulkOperations", + "links" + ], + "title": "Bulk Operations", + "type": "object" + }, "BulkOperationOperation": { "$id": "https://godaddy.com/schemas/commerce/bulk-operations/bulk-operation-operation.v1", "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -765,6 +829,21 @@ "title": "Bulk Operation GraphQL Operation", "type": "object" }, + "BulkOperationResponse": { + "$id": "https://godaddy.com/schemas/commerce/bulk-operations/bulk-operation-response.v1", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A response containing a single bulk operation", + "properties": { + "bulkOperation": { + "$ref": "#/$defs/BulkOperation" + } + }, + "required": [ + "bulkOperation" + ], + "title": "Bulk Operation Response", + "type": "object" + }, "BulkOperationRoundingMode": { "$id": "https://godaddy.com/schemas/commerce/bulk-operations/bulk-operation-rounding-mode.v1", "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -2482,29 +2561,7 @@ "200": { "description": "Successfully retrieved bulk operations", "schema": { - "description": "A list of bulk operations", - "properties": { - "bulkOperations": { - "description": "The bulk operations", - "items": { - "$ref": "#/$defs/BulkOperation" - }, - "type": "array" - }, - "links": { - "description": "The links", - "items": { - "$ref": "#/$defs/link-description" - }, - "type": "array" - }, - "pageToken": { - "description": "The page token", - "type": "string" - } - }, - "title": "Bulk Operations", - "type": "object" + "$ref": "#/$defs/BulkOperationList" } }, "400": { @@ -2552,12 +2609,7 @@ "201": { "description": "Bulk operation created", "schema": { - "properties": { - "bulkOperation": { - "$ref": "#/$defs/BulkOperation" - } - }, - "type": "object" + "$ref": "#/$defs/BulkOperationResponse" } }, "400": { @@ -2613,12 +2665,7 @@ "200": { "description": "Successfully retrieved bulk operation", "schema": { - "properties": { - "bulkOperation": { - "$ref": "#/$defs/BulkOperation" - } - }, - "type": "object" + "$ref": "#/$defs/BulkOperationResponse" } }, "400": { @@ -2640,9 +2687,9 @@ "summary": "Get a bulk operation" }, { - "description": "Cancel an ongoing bulk operation. This is a state transition; the\noperation remains retrievable via GET with status CANCELED.\nA dedicated POST .../cancellations controller resource is a follow-up\nalignment with bulk-ingestions/bulk-exports.\n", + "description": "Deprecated. Cancel an ongoing bulk operation. This is a state\ntransition; the operation remains retrievable via GET with status\nCANCELED. `DELETE` is semantically incorrect for a state transition\nand is deprecated in favor of\n`POST .../bulk-operations/{bulkOperationId}/cancelations`, aligning\nwith bulk-ingestions/bulk-exports. This operation will be removed in\na future release.\n", "method": "DELETE", - "operationId": "cancelBulkOperation", + "operationId": "cancelBulkOperationLegacy", "parameters": [ { "description": "The Store ID", @@ -2668,12 +2715,51 @@ "200": { "description": "Bulk operation cancelled", "schema": { - "properties": { - "bulkOperation": { - "$ref": "#/$defs/BulkOperation" - } - }, - "type": "object" + "$ref": "#/$defs/BulkOperationResponse" + } + }, + "400": { + "description": "Error", + "schema": { + "$ref": "#/$defs/error" + } + } + }, + "scopes": [ + "commerce.bulk-operation:write" + ], + "summary": "Cancel a bulk operation (deprecated)" + }, + { + "description": "Cancel an ongoing bulk operation. This is a state transition; the\noperation remains retrievable via GET with status CANCELED. Replaces\nthe deprecated `DELETE .../bulk-operations/{bulkOperationId}` route,\naligning with bulk-ingestions/bulk-exports.\n", + "method": "POST", + "operationId": "cancelBulkOperation", + "parameters": [ + { + "description": "The Store ID", + "in": "path", + "name": "storeId", + "required": true, + "schema": { + "$ref": "#/$defs/uuid" + } + }, + { + "description": "The Bulk Operation ID", + "in": "path", + "name": "bulkOperationId", + "required": true, + "schema": { + "$ref": "#/$defs/uuid" + } + } + ], + "path": "/stores/{storeId}/bulk-operations/{bulkOperationId}/cancelations", + "responses": { + "200": { + "description": "Bulk operation cancelled", + "schema": { + "$ref": "#/$defs/BulkOperationResponse" } }, "400": { @@ -2681,6 +2767,12 @@ "schema": { "$ref": "#/$defs/error" } + }, + "404": { + "description": "Error", + "schema": { + "$ref": "#/$defs/error" + } } }, "scopes": [ @@ -2735,26 +2827,7 @@ "200": { "description": "Successfully retrieved bulk operation errors", "schema": { - "properties": { - "errors": { - "items": { - "$ref": "#/$defs/BulkOperationError" - }, - "type": "array" - }, - "links": { - "description": "The links", - "items": { - "$ref": "#/$defs/link-description" - }, - "type": "array" - }, - "pageToken": { - "description": "The page token", - "type": "string" - } - }, - "type": "object" + "$ref": "#/$defs/BulkOperationErrorList" } }, "400": { @@ -2772,5 +2845,5 @@ ], "name": "bulk-operations", "title": "Bulk Operations API", - "version": "1.1.0" + "version": "1.2.0" } \ No newline at end of file diff --git a/rust/schemas/api/catalog-products.json b/rust/schemas/api/catalog-products.json index b149d9cc..5b06ed62 100644 --- a/rust/schemas/api/catalog-products.json +++ b/rust/schemas/api/catalog-products.json @@ -81,6 +81,7 @@ "type": "Int" }, { + "description": "Filters SKU groups by list membership: eq is in this list, in is in any of these lists, isNull is in no list, and ne is not in this list.", "name": "listId", "required": false, "type": "ListIdFilter" @@ -781,6 +782,7 @@ "type": "Int" }, { + "description": "Filters nodes by their associated list via eq, in, and ne. isNull never matches, since every node belongs to a list.", "name": "listId", "required": false, "type": "ListIdFilter" @@ -1087,6 +1089,12 @@ "required": false, "type": "Int" }, + { + "description": "Filter prices by whether compareAtValue exists (true) or not (false).", + "name": "hasCompareAtValue", + "required": false, + "type": "Boolean" + }, { "name": "id", "required": false, @@ -1148,6 +1156,12 @@ "required": false, "type": "Int" }, + { + "description": "Filter prices by whether compareAtValue exists (true) or not (false).", + "name": "hasCompareAtValue", + "required": false, + "type": "Boolean" + }, { "name": "id", "required": false, @@ -1278,12 +1292,6 @@ "required": false, "type": "OptionIdsFilter" }, - { - "description": "Filter options by their shareable status. When true, returns only shareable options; when false, returns only non-shareable options.", - "name": "shareable", - "required": false, - "type": "Boolean" - }, { "name": "label", "required": false, @@ -1310,6 +1318,12 @@ "required": false, "type": "PaginationType" }, + { + "description": "Filter options by their shareable status. When true, returns only shareable options; when false, returns only non-shareable options.", + "name": "shareable", + "required": false, + "type": "Boolean" + }, { "name": "skuGroupId", "required": false, @@ -1384,6 +1398,17 @@ "required": false, "type": "Int" }, + { + "name": "hasCompareAt", + "required": false, + "type": "HasCompareAtFilter" + }, + { + "description": "When true, returns only SKU groups with at least one SKU. When false, returns only SKU groups with zero SKUs.", + "name": "hasSKUs", + "required": false, + "type": "Boolean" + }, { "name": "id", "required": false, @@ -1400,6 +1425,7 @@ "type": "Int" }, { + "description": "Filters SKU groups by list membership: eq is in this list, in is in any of these lists, isNull is in no list, and ne is not in this list.", "name": "listId", "required": false, "type": "ListIdFilter" @@ -1420,6 +1446,11 @@ "required": false, "type": "PaginationType" }, + { + "name": "priceRange", + "required": false, + "type": "PriceRangeFilter" + }, { "name": "referenceValue", "required": false, @@ -1469,6 +1500,12 @@ "required": false, "type": "Int" }, + { + "description": "Filter prices by whether compareAtValue exists (true) or not (false).", + "name": "hasCompareAtValue", + "required": false, + "type": "Boolean" + }, { "name": "id", "required": false, @@ -1495,6 +1532,12 @@ "required": false, "type": "SKUIdFilter" }, + { + "description": "Filter prices by the status of the parent SKU (ACTIVE, DRAFT, ARCHIVED).", + "name": "skuStatus", + "required": false, + "type": "SKUStatusFilter" + }, { "name": "updatedAt", "required": false, @@ -2777,7 +2820,7 @@ } ], "deprecated": false, - "description": "Release inventory from committed. If there are not enough committed inventory, this mutation will error. Documentation: https://godaddy-corp.atlassian.net/wiki/spaces/COMCORE/pages/3758600912/Inventory+Helper+Mutations#3.-releaseInventory", + "description": "Release inventory from committed and/or backordered. Releases from committed first, then backordered. Errors if the requested quantity exceeds committed + backordered. Documentation: https://godaddy-corp.atlassian.net/wiki/spaces/COMCORE/pages/3758600912/Inventory+Helper+Mutations#3.-releaseInventory", "kind": "mutation", "name": "releaseInventory", "returnType": "[InventoryAdjustment!]" @@ -4220,7 +4263,7 @@ } ], "schemaRef": "./graphql/schema.graphql", - "sdl": "extend schema\n @link(url: \"https://specs.apollo.dev/federation/v2.6\", import: [])\n\ninput AddListTreeNodeInput {\n listId: String!\n parentNodeId: String\n position: Int\n references: [CreateReferenceInput!]\n}\n\ntype Address {\n \"\"\"The details of the address.\"\"\"\n addressDetails: AddressDetails\n\n \"\"\"The first line of the address.\"\"\"\n addressLine1: String!\n\n \"\"\"The second line of the address.\"\"\"\n addressLine2: String\n\n \"\"\"The third line of the address.\"\"\"\n addressLine3: String\n\n \"\"\"The first administrative area of the address.\"\"\"\n adminArea1: String\n\n \"\"\"The second administrative area of the address.\"\"\"\n adminArea2: String\n\n \"\"\"The third administrative area of the address.\"\"\"\n adminArea3: String\n\n \"\"\"The fourth administrative area of the address.\"\"\"\n adminArea4: String\n\n \"\"\"The country code of the address.\"\"\"\n countryCode: String!\n\n \"\"\"The postal code of the address.\"\"\"\n postalCode: String\n}\n\ntype AddressDetails {\n \"\"\"\n The type of address. Single character representation of a type. For example: 'B' for building, 'F' for organization, 'G' for general delivery, 'H' for high-rise, 'L' for large-volume organization, 'P' for Post Office box or delivery service, 'R' for rural route, 'S' for street, 'U' for unidentified address.\n \"\"\"\n addressType: String\n\n \"\"\"\n A named locations that represents the premise. Usually a building name or number or collection of buildings with a common name or number.\n \"\"\"\n buildingName: String\n\n \"\"\"The delivery service. Post office box, bag number, or post office name\"\"\"\n deliveryService: String\n\n \"\"\"The latitude and longitude of the address.\"\"\"\n geoCoordinates: GeoCoordinates\n\n \"\"\"The street name. Just `Drury` in `Drury Lane`.\"\"\"\n streetName: String\n\n \"\"\"The street number.\"\"\"\n streetNumber: String\n\n \"\"\"The street type. For example, avenue, boulevard, road, or expressway.\"\"\"\n streetType: String\n\n \"\"\"\n The first-order entity below a named building or location that represents the sub-premise. Usually a single building within a collection of buildings with a common name. Can be a flat, story, floor, room, or apartment.\n \"\"\"\n subBuilding: String\n}\n\ninput AddressDetailsInput {\n addressType: String\n buildingName: String\n deliveryService: String\n geoCoordinates: GeoCoordinatesInput\n streetName: String\n streetNumber: String\n streetType: String\n subBuilding: String\n}\n\ninput AssociateAttributeValueInput {\n label: String!\n name: String\n position: Int\n}\n\ninput AssociateAttributeValueToSKUInput {\n attributeName: String!\n valueName: String!\n}\n\n\"\"\"A SKU is comprised of a combination of multiple attributes\"\"\"\ntype Attribute {\n \"\"\"\n HTML description for the Attribute. Will be used to display rich text content to customers.\n \"\"\"\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"\n A SKU group is a grouping of related SKUs. It provides information about all the SKUs that are sold together on storefronts or devices.\n \"\"\"\n SKUGroup: SKUGroup @deprecated(reason: \"Use skuGroup instead.\")\n\n \"\"\"The creation date of the Attribute.\"\"\"\n createdAt: DateTime!\n\n \"\"\"A description of the Attribute.\"\"\"\n description: String\n\n \"\"\"\n HTML description for the Attribute. Will be used to display rich text content to customers.\n \"\"\"\n htmlDescription: String\n\n \"\"\"The UUID of the Attribute.\"\"\"\n id: ID!\n\n \"\"\"The display label of the Attribute. E.g. 'Color', 'Size', etc.\"\"\"\n label: String!\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): AttributeMetafieldsConnection\n\n \"\"\"A unique name of the Attribute. E.g. 'color', 'size', etc.\"\"\"\n name: String!\n\n \"\"\"The position of the attribute.\"\"\"\n position: Int\n\n \"\"\"\n A SKU group is a grouping of related SKUs. It provides information about all the SKUs that are sold together on storefronts or devices.\n \"\"\"\n skuGroup: SKUGroup\n\n \"\"\"The update date of the Attribute.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"Attribute values of Attribute.\"\"\"\n values(after: String, before: String, first: Int, id: AttributeValueIdsFilter, last: Int, orderBy: AttributeValueOrderBy, paginationType: PaginationType = CURSOR, skuId: SKUIdFilter): AttributeValuesConnection\n}\n\ninput AttributeIdFilter {\n eq: String\n in: [String!]\n}\n\ninput AttributeIdsFilter {\n in: [String!]\n}\n\ntype AttributeMetafieldsConnection {\n edges: [AttributeMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype AttributeMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ninput AttributeOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n label: OrderByDirectionEnum\n name: OrderByDirectionEnum\n position: OrderByDirectionEnum\n skuGroupId: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\n\"\"\"Value for an Attribute.\"\"\"\ntype AttributeValue {\n \"\"\"The attribute that this value belongs to.\"\"\"\n attribute: Attribute\n\n \"\"\"The creation date of the Attribute Value.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The UUID of the Attribute Value.\"\"\"\n id: ID!\n\n \"\"\"The display label of the Attribute Value. E.g. 'Red', 'Blue', etc.\"\"\"\n label: String!\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): AttributeValueMetafieldsConnection\n\n \"\"\"A unique name of the Attribute Value. E.g. 'red', 'blue', etc.\"\"\"\n name: String!\n\n \"\"\"The position of the attribute value.\"\"\"\n position: Int\n\n \"\"\"The last update date of the Attribute Value.\"\"\"\n updatedAt: DateTime!\n}\n\ninput AttributeValueIdsFilter {\n in: [String!]\n}\n\ntype AttributeValueMetafieldsConnection {\n edges: [AttributeValueMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype AttributeValueMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ninput AttributeValueOrderBy {\n attributeId: OrderByDirectionEnum\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n name: OrderByDirectionEnum\n position: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\ntype AttributeValuesConnection {\n edges: [AttributeValuesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype AttributeValuesConnectionEdge {\n cursor: String!\n node: AttributeValue\n}\n\n\"\"\"Configuration for cascade archiving related entities.\"\"\"\ninput CascadeArchiveInput {\n \"\"\"Whether to cascade archive SKUs when archiving the SKU Group.\"\"\"\n skus: Boolean\n}\n\ninput CreateAddressInput {\n addressDetails: AddressDetailsInput\n addressLine1: String!\n addressLine2: String\n addressLine3: String\n adminArea1: String\n adminArea2: String\n adminArea3: String\n adminArea4: String\n countryCode: String!\n postalCode: String\n}\n\ninput CreateAttributeValueInput {\n attributeId: String!\n label: String!\n metafields: [CreateMetafieldInput!]\n name: String\n position: Int\n}\n\n\"\"\"Input for creating a new file.\"\"\"\ninput CreateFileInput {\n contentType: String!\n description: String\n filename: String!\n sizeBytes: Float!\n storageUrl: String!\n}\n\ninput CreateInventoryAdjustmentInput {\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n\n \"\"\"\n The change in inventory quantity. Positive for additions, negative for removals.\n \"\"\"\n delta: Int!\n locationId: String!\n metafields: [CreateMetafieldInput!]\n\n \"\"\"The date and time when the inventory adjustment occurred.\"\"\"\n occurredAt: DateTime\n\n \"\"\"\n The name of an inventory adjustment reason to associate with this adjustment. Use the exact reason name (e.g. \"g-damage\" for global presets, or a store-scoped name).\n \"\"\"\n reasonName: String\n references: [CreateReferenceInput!]\n skuId: String!\n\n \"\"\"\n The type of inventory adjustment, one of `AVAILABLE`, `COMMITTED`, `BACKORDERED`.\n \"\"\"\n type: String!\n}\n\ninput CreateListTreeNodeInput {\n listId: String!\n position: Int\n references: [CreateReferenceInput!]\n}\n\ninput CreateMediaObjectInput {\n label: String\n metafields: [CreateMetafieldInput!]\n name: String\n position: Int\n\n \"\"\"The type of the media, one of `PHOTO`, `VIDEO`, `IMAGE`, `AUDIO`.\"\"\"\n type: String!\n url: String!\n}\n\ninput CreateMetafieldInput {\n key: String!\n namespace: String!\n type: String!\n value: String!\n}\n\ninput CreateOptionInput {\n description: String\n label: String!\n metafields: [CreateMetafieldInput!]\n name: String\n position: Int\n prices: [CreateOptionPriceInput!]\n\n \"\"\"\n The type of the Option, one of `TEXT`, `NUMBER`, `LIST`. Option Values are only available on the 'LIST' type.\n \"\"\"\n type: String!\n validation: CreateOptionValidationInput\n values: [CreateOptionValueInput!]\n}\n\ninput CreateOptionPriceInput {\n compareAtValue: SimpleMoneyInput\n value: SimpleMoneyInput!\n}\n\ninput CreateOptionValidationInput {\n max: Int\n min: Int\n}\n\ninput CreateOptionValueInput {\n label: String!\n metafields: [CreateMetafieldInput!]\n name: String\n position: Int\n prices: [CreateOptionValuePriceInput!]\n}\n\ninput CreateOptionValuePriceInput {\n compareAtValue: SimpleMoneyInput\n value: SimpleMoneyInput!\n}\n\ninput CreateReferenceInput {\n origin: String!\n value: String!\n}\n\ninput CreateSKUGroupAttributeInput {\n description: String\n label: String!\n metafields: [CreateMetafieldInput!]\n name: String\n position: Int\n values: [AssociateAttributeValueInput!]\n}\n\ninput CreateSKUGroupSKUInput {\n backorderLimit: Int\n code: String\n\n \"\"\"DEPRECATED. Use unitCost instead.\"\"\"\n cost: Int @deprecated(reason: \"This cost field cannot specify currency code. Use `unitCost` instead.\")\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n disableInventoryTracking: Boolean\n disablePriceOverrides: Boolean\n disableShipping: Boolean\n eanCode: String\n gtinCode: String\n htmlDescription: String\n inventoryQuantities: [CreateSKUInventoryInput!]\n isbnCode: String\n label: String!\n mediaObjects: [CreateMediaObjectInput!]\n metafields: [CreateMetafieldInput!]\n name: String\n prices: [CreateSKUPriceInput!]\n references: [CreateReferenceInput!]\n shortLabel: String\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n unitCost: SimpleMoneyInput\n\n \"\"\"The unit of the weight, one of `KG`, `GR`, `LB`, `OZ`.\"\"\"\n unitOfWeight: String\n upcCode: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n weight: Float\n}\n\ninput CreateSKUInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n attributeValueIds: [String!]\n attributeValues: [AssociateAttributeValueToSKUInput!]\n backorderLimit: Int\n code: String\n\n \"\"\"DEPRECATED. Use unitCost instead.\"\"\"\n cost: Int @deprecated(reason: \"This cost field cannot specify currency code. Use `unitCost` instead.\")\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n disableInventoryTracking: Boolean\n disablePriceOverrides: Boolean\n disableShipping: Boolean\n eanCode: String\n gtinCode: String\n htmlDescription: String\n inventoryQuantities: [CreateSKUInventoryInput!]\n isbnCode: String\n label: String!\n mediaObjects: [CreateMediaObjectInput!]\n metafields: [CreateMetafieldInput!]\n name: String\n prices: [CreateSKUPriceInput!]\n references: [CreateReferenceInput!]\n shortLabel: String\n skuGroupId: String\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n unitCost: SimpleMoneyInput\n\n \"\"\"The status of the SKU, one of `KG`, `GR`, `LB`, `OZ`.\"\"\"\n unitOfWeight: String\n upcCode: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n weight: Float\n}\n\ninput CreateSKUInventoryInput {\n locationId: String!\n quantity: Int!\n}\n\ninput CreateSKUPriceInput {\n compareAtValue: SimpleMoneyInput\n value: SimpleMoneyInput!\n}\n\n\"\"\"Filters items based on the date they were created.\"\"\"\ninput CreatedAtFilter {\n gt: String\n lt: String\n}\n\n\"\"\"\nFilters items by currency code. Can be used to filter for an exact match or for multiple values.\n\"\"\"\ninput CurrencyCodeFilter {\n \"\"\"\n Filters items where the currency code equals the specified 3-letter ISO currency code.\n \"\"\"\n eq: String\n\n \"\"\"\n Filters items where the currency code matches any of the specified 3-letter ISO currency codes.\n \"\"\"\n in: [String!]\n}\n\n\"\"\"\nA date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.\n\"\"\"\nscalar DateTime\n\n\"\"\"\nA file represents a stored digital asset such as an image, document, or downloadable content.\n\"\"\"\ntype File {\n \"\"\"The MIME type of the file.\"\"\"\n contentType: String!\n\n \"\"\"The timestamp when the file was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"An optional description of the file.\"\"\"\n description: String\n\n \"\"\"The name of the file including extension.\"\"\"\n filename: String!\n\n \"\"\"The globally unique identifier of the file.\"\"\"\n id: ID!\n\n \"\"\"\n The size of the file in bytes. Typed as Float to support files larger than 2GB.\n \"\"\"\n sizeBytes: Float!\n\n \"\"\"The current status of the file.\"\"\"\n status: FileStatus!\n\n \"\"\"The URL where the file is stored.\"\"\"\n storageUrl: String!\n\n \"\"\"The timestamp when the file was last updated.\"\"\"\n updatedAt: DateTime!\n}\n\ninput FileIdsFilter {\n in: [String!]\n}\n\ninput FileOrderBy {\n createdAt: OrderByDirectionEnum\n filename: OrderByDirectionEnum\n id: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\n\"\"\"The status of a file.\"\"\"\nenum FileStatus {\n ACTIVE\n ARCHIVED\n}\n\n\"\"\"Filter for the status of the File, one of `ACTIVE`, `ARCHIVED`.\"\"\"\ninput FileStatusFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"Filter for the storage URL of the File.\"\"\"\ninput FileStorageUrlFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"The geographic latitude and longitude coordinates.\"\"\"\ntype GeoCoordinates {\n \"\"\"The latitude of the geo coordinates.\"\"\"\n latitude: Float!\n\n \"\"\"The longitude of the geo coordinates.\"\"\"\n longitude: Float!\n}\n\ninput GeoCoordinatesInput {\n latitude: Float\n longitude: Float\n}\n\n\"\"\"\nAn immutable entity that represents a change in state of a quantity of SKU at a particular time and location.\n\"\"\"\ntype InventoryAdjustment {\n \"\"\"The SKU associated with the Inventory Adjustment.\"\"\"\n SKU: SKU @deprecated(reason: \"Use sku instead.\")\n\n \"\"\"The creation date of the inventory adjustment.\"\"\"\n createdAt: DateTime\n\n \"\"\"The change in quantity of a SKU at a location.\"\"\"\n delta: Int\n\n \"\"\"The globally-unique ID of the inventory adjustment object.\"\"\"\n id: ID\n\n \"\"\"The Location associated with the Inventory Adjustment.\"\"\"\n location: Location\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): InventoryAdjustmentMetafieldsConnection\n\n \"\"\"The date when the inventory adjustment occurred.\"\"\"\n occurredAt: DateTime\n\n \"\"\"The reason associated with this inventory adjustment.\"\"\"\n reason: InventoryAdjustmentReason\n\n \"\"\"\n A reference to the resource in an external service. This can be useful for integrating the resource to any external service.\n \"\"\"\n references(after: String, before: String, first: Int, last: Int, origin: ReferenceOriginFilter, paginationType: PaginationType = CURSOR): InventoryAdjustmentReferencesConnection\n\n \"\"\"The SKU associated with the Inventory Adjustment.\"\"\"\n sku: SKU\n\n \"\"\"\n The adjustment type of the inventory being adjusted, one of `AVAILABLE`, `COMMITTED`, `BACKORDERED`.\n \"\"\"\n type: String!\n}\n\ninput InventoryAdjustmentIdsFilter {\n in: [String!]\n}\n\ntype InventoryAdjustmentMetafieldsConnection {\n edges: [InventoryAdjustmentMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype InventoryAdjustmentMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ninput InventoryAdjustmentOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n}\n\n\"\"\"\nA reason that can be associated with an inventory adjustment to explain why it occurred. Global preset reasons are prefixed with \"g-\" (e.g. g-damage, g-shrinkage). Store-scoped reasons use plain kebab-case names.\n\"\"\"\ntype InventoryAdjustmentReason {\n \"\"\"The date the reason was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the inventory adjustment reason.\"\"\"\n id: ID!\n\n \"\"\"\n Whether this is a global preset reason. Global reasons are shared across all stores and cannot be modified or archived.\n \"\"\"\n isGlobal: Boolean!\n\n \"\"\"The human-readable display label of the reason.\"\"\"\n label: String!\n\n \"\"\"\n The unique kebab-case name of the reason. Global preset names are prefixed with \"g-\" (e.g. g-damage). Store-scoped names must not use the \"g-\" prefix.\n \"\"\"\n name: String!\n\n \"\"\"The status of the reason, one of ACTIVE, ARCHIVED.\"\"\"\n status: String!\n\n \"\"\"The date the reason was last updated.\"\"\"\n updatedAt: DateTime!\n}\n\n\"\"\"Filters inventory adjustment reasons by name.\"\"\"\ninput InventoryAdjustmentReasonNameFilter {\n eq: String\n in: [String!]\n}\n\ninput InventoryAdjustmentReasonOrderBy {\n id: OrderByDirectionEnum\n}\n\n\"\"\"\nFilter for the status of the Inventory Adjustment Reason, one of `ACTIVE`, `ARCHIVED`.\n\"\"\"\ninput InventoryAdjustmentReasonStatusFilter {\n eq: String\n in: [String!]\n}\n\ntype InventoryAdjustmentReferencesConnection {\n edges: [InventoryAdjustmentReferencesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype InventoryAdjustmentReferencesConnectionEdge {\n cursor: String!\n node: Reference\n}\n\n\"\"\"\nFilter for the type of inventory adjustment, one of `AVAILABLE`, `COMMITTED`, `BACKORDERED`.\n\"\"\"\ninput InventoryAdjustmentTypeFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"\nRepresents the quantity of a SKU in a specific state at a particular time and location.\n\"\"\"\ntype InventoryCount {\n \"\"\"The SKU associated with the Inventory Count.\"\"\"\n SKU: SKU @deprecated(reason: \"Use sku instead.\")\n\n \"\"\"The timestamp of when the inventory count was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the inventory count object.\"\"\"\n id: ID!\n\n \"\"\"The Location associated with the Inventory Count.\"\"\"\n location: Location\n\n \"\"\"\n The on-hand inventory count (available + committed) for this SKU and location.\n \"\"\"\n onHand: Int\n\n \"\"\"The count of the inventory.\"\"\"\n quantity: Int\n\n \"\"\"The SKU associated with the Inventory Count.\"\"\"\n sku: SKU\n\n \"\"\"\n The type of inventory count, one of `AVAILABLE`, `COMMITTED`, `BACKORDERED`.\n \"\"\"\n type: String!\n\n \"\"\"The timestamp of when the inventory count was updated.\"\"\"\n updatedAt: DateTime!\n}\n\ninput InventoryCountIdsFilter {\n in: [String!]\n}\n\ninput InventoryCountOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\n\"\"\"\nFilter inventory counts by the status of the associated SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\n\"\"\"\ninput InventoryCountSKUStatusFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"\nFilter for the type of inventory count, one of `AVAILABLE`, `COMMITTED`, `BACKORDERED`.\n\"\"\"\ninput InventoryCountTypeFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"\nFilters items by label. Can be used to either filter for an exact match or for a partial match.\n\"\"\"\ninput LabelFilter {\n \"\"\"\n Filters items where the label contains the specified string, case-insensitive.\n \"\"\"\n contains: String\n eq: String\n}\n\n\"\"\"\nA list is a group of SKU groups that are generally organized by similar characteristics.\n\"\"\"\ntype List {\n \"\"\"\n HTML description for the List. Will be used to display rich text content to customers.\n \"\"\"\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"\n A SKU Group is a grouping of related SKUs. It provides information about all of the SKUs that are sold together on storefronts or devices.\n \"\"\"\n SKUGroups(after: String, before: String, first: Int, last: Int, paginationType: PaginationType = CURSOR): ListSKUGroupsConnection @deprecated(reason: \"Use skuGroups instead.\")\n\n \"\"\"The date and time of when the List was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"A single-line textual description of the List.\"\"\"\n description: String\n\n \"\"\"\n HTML description for the List. Will be used to display rich text content to customers.\n \"\"\"\n htmlDescription: String\n\n \"\"\"The globally-unique ID of the List.\"\"\"\n id: ID!\n\n \"\"\"The display label of the List.\"\"\"\n label: String!\n\n \"\"\"Media can be images, videos, or files\"\"\"\n mediaObjects(after: String, before: String, first: Int, last: Int, paginationType: PaginationType = CURSOR): ListMediaObjectsConnection\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): ListMetafieldsConnection\n\n \"\"\"A unique name for the List.\"\"\"\n name: String!\n\n \"\"\"\n A reference to the resource in an external service. This can be useful for integrating the resource to any external service.\n \"\"\"\n references(after: String, before: String, first: Int, last: Int, origin: ReferenceOriginFilter, paginationType: PaginationType = CURSOR): ListReferencesConnection\n\n \"\"\"\n A SKU Group is a grouping of related SKUs. It provides information about all of the SKUs that are sold together on storefronts or devices.\n \"\"\"\n skuGroups(after: String, before: String, first: Int, last: Int, orderBy: SKUGroupOrderBy, paginationType: PaginationType = CURSOR, status: SKUGroupStatusFilter): ListSkuGroupsConnection\n\n \"\"\"The status of the list, one of `ACTIVE`, `DRAFT`, `ARCHIVED`.\"\"\"\n status: String\n\n \"\"\"The date and time of when the List was updated.\"\"\"\n updatedAt: DateTime!\n}\n\ninput ListIdFilter {\n eq: String\n in: [String!]\n isNull: Boolean\n}\n\ninput ListIdsFilter {\n in: [String!]\n}\n\ntype ListMediaObjectsConnection {\n edges: [ListMediaObjectsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListMediaObjectsConnectionEdge {\n cursor: String!\n node: Media\n}\n\ntype ListMetafieldsConnection {\n edges: [ListMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ntype ListOption {\n \"\"\"\n The `compareAt` price range of the option, tracks the min and max `compareAt` price of all the option values under this option.\n \"\"\"\n compareAtPriceRange: PriceRange\n\n \"\"\"The timestamp of when the Option was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"A description of the Option.\"\"\"\n description: String\n\n \"\"\"The UUID of the Option\"\"\"\n id: ID!\n\n \"\"\"\n Whether the option is shareable across multiple SKU Groups (a global modifier).\n \"\"\"\n shareable: Boolean!\n\n \"\"\"The display lable of the Option\"\"\"\n label: String!\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): OptionMetafieldsConnection\n\n \"\"\"A unique name of the Option.\"\"\"\n name: String!\n\n \"\"\"The position of the option.\"\"\"\n position: Int\n\n \"\"\"\n The price range of the option, tracks the min and max price of all the option values under this option.\n \"\"\"\n priceRange: PriceRange\n\n \"\"\"\n Represents the additional cost of a List Option. When empty, it indicates this option allows for flexible pricing.\n \"\"\"\n prices(\n after: String\n before: String\n\n \"\"\"Filter prices by currency code.\"\"\"\n currencyCode: CurrencyCodeFilter\n first: Int\n last: Int\n paginationType: PaginationType = CURSOR\n ): ListOptionPricesConnection\n\n \"\"\"The UUID of the SKU Group that the Option belongs to.\"\"\"\n skuGroupId: ID! @deprecated(reason: \"Use skuGroupIds or the SKUGroup.options connection instead. An option may belong to multiple SKU groups.\")\n\n \"\"\"The IDs of all SKU groups this option is associated with.\"\"\"\n skuGroupIds: [String!]!\n\n \"\"\"\n The type of the option, one of `TEXT`, `NUMBER`, `LIST`, Option Values are available for the 'LIST' type.\n \"\"\"\n type: String\n\n \"\"\"The timestamp of when the Option was updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"\n Provide validations on how the option can be applied to a SKU. If `TEXT` option then `min` and `max` apply to the number of characters. If `NUMBER` then `min` and `max` apply to the actual number value. If `LIST` then `min` and `max` apply to the number of values that can be selected.\n \"\"\"\n validation: OptionValidation\n\n \"\"\"\n Represents the additional cost of a List Option. Each value can have one or more prices.\n \"\"\"\n values(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: OptionValueIdsFilter, last: Int, orderBy: OptionValueOrderBy, paginationType: PaginationType = CURSOR, updatedAt: UpdatedAtFilter): ListOptionValuesConnection\n}\n\ntype ListOptionPricesConnection {\n edges: [ListOptionPricesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListOptionPricesConnectionEdge {\n cursor: String!\n node: OptionPrice\n}\n\ntype ListOptionValuesConnection {\n edges: [ListOptionValuesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListOptionValuesConnectionEdge {\n cursor: String!\n node: OptionValue\n}\n\ninput ListOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n label: OrderByDirectionEnum\n name: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\ntype ListReferencesConnection {\n edges: [ListReferencesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListReferencesConnectionEdge {\n cursor: String!\n node: Reference\n}\n\ntype ListSKUGroupsConnection {\n edges: [ListSKUGroupsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListSKUGroupsConnectionEdge {\n cursor: String!\n node: SKUGroup\n}\n\ntype ListSkuGroupsConnection {\n edges: [ListSkuGroupsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListSkuGroupsConnectionEdge {\n cursor: String!\n node: SKUGroup\n}\n\n\"\"\"\nFilter for the status of the List, one of `ACTIVE`, `DRAFT`, `ARCHIVED`.\n\"\"\"\ninput ListStatusFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"A List tree holds the hierarchical information of a group of lists.\"\"\"\ntype ListTree {\n \"\"\"\n HTML description for the List Tree. Will be used to display rich text content to customers.\n \"\"\"\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"The timestamp of when the list tree was activated.\"\"\"\n activatedAt: DateTime\n\n \"\"\"The timestamp of when the list tree was archived.\"\"\"\n archivedAt: DateTime\n\n \"\"\"The creation date of the list tree.\"\"\"\n createdAt: DateTime\n\n \"\"\"The description of the list tree.\"\"\"\n description: String\n\n \"\"\"\n HTML description for the List Tree. Will be used to display rich text content to customers.\n \"\"\"\n htmlDescription: String\n\n \"\"\"The globally-unique ID of the list tree.\"\"\"\n id: ID\n\n \"\"\"The display label of the list tree.\"\"\"\n label: String!\n\n \"\"\"\n List tree node is associated to a single List and a node can be a parent node to provide the hierarchy of list trees.\n \"\"\"\n listTreeNodes(after: String, before: String, first: Int, hasParent: Boolean, last: Int, listId: ListIdFilter, listStatus: ListTreeNodeListStatusFilter = {in: [\"ACTIVE\", \"DRAFT\"]}, orderBy: ListTreeNodeOrderBy, paginationType: PaginationType = CURSOR, parentNodeId: ListTreeNodeParentNodeIdFilter): ListTreeListTreeNodesConnection\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): ListTreeMetafieldsConnection\n\n \"\"\"A unique name of the list tree.\"\"\"\n name: String\n\n \"\"\"\n A reference to the resource in an external service. This can be useful for integrating the resource to any external service.\n \"\"\"\n references(after: String, before: String, first: Int, last: Int, origin: ReferenceOriginFilter, paginationType: PaginationType = CURSOR): ListTreeReferencesConnection\n\n \"\"\"The status of the list tree, one of `ACTIVE`, `ARCHIVED`, `DRAFT`.\"\"\"\n status: String\n\n \"\"\"The last update date of the list tree.\"\"\"\n updatedAt: DateTime\n}\n\ninput ListTreeIdFilter {\n eq: String\n}\n\ninput ListTreeIdsFilter {\n in: [String!]\n}\n\ntype ListTreeListTreeNodesConnection {\n edges: [ListTreeListTreeNodesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListTreeListTreeNodesConnectionEdge {\n cursor: String!\n node: ListTreeNode\n}\n\ntype ListTreeMetafieldsConnection {\n edges: [ListTreeMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListTreeMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\n\"\"\"\nList tree node is associated to a single List and a node can be a parent node to provide the hierarchy of list trees.\n\"\"\"\ntype ListTreeNode {\n \"\"\"The creation date of the list node.\"\"\"\n createdAt: DateTime\n\n \"\"\"The globally-unique ID of the list node.\"\"\"\n id: ID\n\n \"\"\"The list associated with the node.\"\"\"\n list: List\n\n \"\"\"The List Tree associated with the node.\"\"\"\n listTree: ListTree\n\n \"\"\"The children nodes of the list node.\"\"\"\n listTreeNodes(after: String, before: String, first: Int, last: Int, listStatus: ListTreeNodeListStatusFilter = {in: [\"ACTIVE\", \"DRAFT\"]}, orderBy: ListTreeNodeOrderBy, paginationType: PaginationType = CURSOR): ListTreeNodeListTreeNodesConnection\n\n \"\"\"The parent node of the list node.\"\"\"\n parentListTreeNode: ListTreeNode\n\n \"\"\"The position of the node in the list.\"\"\"\n position: Int\n\n \"\"\"\n A reference to the resource in an external service. This can be useful for integrating the resource to any external service.\n \"\"\"\n references(after: String, before: String, first: Int, last: Int, origin: ReferenceOriginFilter, paginationType: PaginationType = CURSOR): ListTreeNodeReferencesConnection\n\n \"\"\"The last update date of the list node.\"\"\"\n updatedAt: DateTime\n}\n\ninput ListTreeNodeIdsFilter {\n in: [String!]\n}\n\n\"\"\"\nFilter for the status of the List, one of `ACTIVE`, `DRAFT`, `ARCHIVED`.\n\"\"\"\ninput ListTreeNodeListStatusFilter {\n eq: String\n in: [String!]\n}\n\ntype ListTreeNodeListTreeNodesConnection {\n edges: [ListTreeNodeListTreeNodesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListTreeNodeListTreeNodesConnectionEdge {\n cursor: String!\n node: ListTreeNode\n}\n\n\"\"\"\nFilter for the status of the List Tree, one of `ACTIVE`, `ARCHIVED`, `DRAFT`.\n\"\"\"\ninput ListTreeNodeListTreeStatusFilter {\n eq: String\n in: [String!]\n}\n\ninput ListTreeNodeOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n position: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\ninput ListTreeNodeParentNodeIdFilter {\n eq: String\n}\n\ntype ListTreeNodeReferencesConnection {\n edges: [ListTreeNodeReferencesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListTreeNodeReferencesConnectionEdge {\n cursor: String!\n node: Reference\n}\n\ninput ListTreeOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n name: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\ntype ListTreeReferencesConnection {\n edges: [ListTreeReferencesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListTreeReferencesConnectionEdge {\n cursor: String!\n node: Reference\n}\n\n\"\"\"\nFilter for the status of the List Tree, one of `ACTIVE`, `ARCHIVED`, `DRAFT`.\n\"\"\"\ninput ListTreeStatusFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"A location represents the physical location of an inventory.\"\"\"\ntype Location {\n \"\"\"The SKUs are purchasable items in the catalog.\"\"\"\n SKUs(\n after: String\n attributeValues: SKUAttributeValueFilter\n before: String\n createdAt: CreatedAtFilter\n first: Int\n label: LabelFilter\n last: Int\n name: NameFilter\n paginationType: PaginationType = CURSOR\n\n \"\"\"\n A string filter in the ODATA format. ex: \"label eq 'shirt' and contains(code, '123')\".\n\n\n Supported columns: `label`, `code`\n\n Supported operators: `eq`, `ne`, `lt`, `gt`, `and`, `or`\n\n Supported functions: `contains`\n \"\"\"\n queryFilter: String\n referenceValue: ReferenceValueFilter\n skuGroupId: SKUGroupIdFilter\n status: SKUStatusFilter\n updatedAt: UpdatedAtFilter\n ): LocationSKUsConnection @deprecated(reason: \"Use skus instead.\")\n\n \"\"\"The address of the Location.\"\"\"\n address: Address\n\n \"\"\"The timestamp of when the Location was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the Location.\"\"\"\n id: ID!\n\n \"\"\"\n An immutable entity that represents a change in state of a quantity of SKU at a particular time and location. Each adjustment will either have a positive, negative, or neutral impact on the count of available SKUs in a location.\n \"\"\"\n inventoryAdjustments(after: String, before: String, first: Int, last: Int, orderBy: InventoryAdjustmentOrderBy, paginationType: PaginationType = CURSOR): LocationInventoryAdjustmentsConnection\n\n \"\"\"\n The quantity of a SKU in a specific state at a particular time and location.\n \"\"\"\n inventoryCounts(after: String, before: String, first: Int, last: Int, locationStatus: LocationStatusFilter, orderBy: InventoryCountOrderBy, paginationType: PaginationType = CURSOR, skuId: SKUIdFilter, skuStatus: InventoryCountSKUStatusFilter, type: InventoryCountTypeFilter): LocationInventoryCountsConnection\n\n \"\"\"The display name of the Location.\"\"\"\n label: String!\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): LocationMetafieldsConnection\n\n \"\"\"A unique and human-friendly name of the Location.\"\"\"\n name: String!\n\n \"\"\"\n A reference to the resource in an external service. This can be useful for integrating the resource to any external service.\n \"\"\"\n references(after: String, before: String, first: Int, last: Int, origin: ReferenceOriginFilter, paginationType: PaginationType = CURSOR): LocationReferencesConnection\n\n \"\"\"The SKUs are purchasable items in the catalog.\"\"\"\n skus(\n after: String\n attributeValues: SKUAttributeValueFilter\n before: String\n code: SKUCodeFilter\n createdAt: CreatedAtFilter\n eanCode: SKUEanCodeFilter\n first: Int\n gtinCode: SKUGtinCodeFilter\n isbnCode: SKUIsbnCodeFilter\n label: LabelFilter\n last: Int\n name: NameFilter\n orderBy: SKUOrderBy\n paginationType: PaginationType = CURSOR\n\n \"\"\"\n A string filter in the ODATA format. ex: \"label eq 'shirt' and contains(code, '123')\".\n\n\n Supported columns: `label`, `code`\n\n Supported operators: `eq`, `ne`, `lt`, `gt`, `and`, `or`\n\n Supported functions: `contains`\n \"\"\"\n queryFilter: String\n referenceValue: ReferenceValueFilter\n skuGroupId: SKUGroupIdFilter\n status: SKUStatusFilter\n upcCode: SKUUpcCodeFilter\n updatedAt: UpdatedAtFilter\n ): LocationSkusConnection\n\n \"\"\"The status of the location, one of `ACTIVE`, `INACTIVE`, `ARCHIVED`.\"\"\"\n status: String!\n\n \"\"\"The timestamp of when the Location was updated.\"\"\"\n updatedAt: DateTime!\n}\n\ninput LocationIdFilter {\n eq: String\n}\n\ninput LocationIdsFilter {\n in: [String!]\n}\n\ntype LocationInventoryAdjustmentsConnection {\n edges: [LocationInventoryAdjustmentsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype LocationInventoryAdjustmentsConnectionEdge {\n cursor: String!\n node: InventoryAdjustment\n}\n\ntype LocationInventoryCountsConnection {\n edges: [LocationInventoryCountsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype LocationInventoryCountsConnectionEdge {\n cursor: String!\n node: InventoryCount\n}\n\ntype LocationMetafieldsConnection {\n edges: [LocationMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype LocationMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ninput LocationOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n name: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\ntype LocationReferencesConnection {\n edges: [LocationReferencesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype LocationReferencesConnectionEdge {\n cursor: String!\n node: Reference\n}\n\ntype LocationSKUsConnection {\n edges: [LocationSKUsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype LocationSKUsConnectionEdge {\n cursor: String!\n node: SKU\n}\n\ntype LocationSkusConnection {\n edges: [LocationSkusConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype LocationSkusConnectionEdge {\n cursor: String!\n node: SKU\n}\n\n\"\"\"\nFilter for the status of the Location, one of `ACTIVE`, `INACTIVE`, `ARCHIVED`.\n\"\"\"\ninput LocationStatusFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"Represents a media object, including photos and videos.\"\"\"\ntype Media {\n \"\"\"The globally-unique ID of the media.\"\"\"\n id: ID!\n\n \"\"\"An optional label for the media.\"\"\"\n label: String\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): MediaMetafieldsConnection\n\n \"\"\"A unique name of the media.\"\"\"\n name: String\n\n \"\"\"The position of the media.\"\"\"\n position: Int\n\n \"\"\"The type of the media, one of `PHOTO`, `VIDEO`, `IMAGE`, `AUDIO`.\"\"\"\n type: String\n\n \"\"\"The URL of the media.\"\"\"\n url: String!\n}\n\ntype MediaMetafieldsConnection {\n edges: [MediaMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype MediaMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\n\"\"\"Custom data\"\"\"\ntype Metafield {\n createdAt: String\n id: ID\n key: String\n namespace: String\n resourceId: ID\n type: String\n updatedAt: String\n value: String\n}\n\ntype Mutation {\n \"\"\"Add Attribute Value(s) to an existing SKU.\"\"\"\n addAttributeValuesToSKU(id: String!, input: MutationAddAttributeValuesToSKUInput!): SKU @deprecated(reason: \"Use `addAttributeValuesToSku` instead.\")\n\n \"\"\"Add Attribute Value(s) to an existing SKU.\"\"\"\n addAttributeValuesToSku(id: String!, input: MutationAddAttributeValuesToSkuInput!): SKU\n\n \"\"\"Add Attributes to an existing SKU group.\"\"\"\n addAttributesToSKUGroup(id: String!, input: MutationAddAttributesToSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `addAttributesToSkuGroup` instead.\")\n\n \"\"\"Add Attributes to an existing SKU group.\"\"\"\n addAttributesToSkuGroup(id: String!, input: MutationAddAttributesToSkuGroupInput!): SKUGroup\n\n \"\"\"Add channels to an existing SKU group.\"\"\"\n addChannelsToSKUGroup(id: String!, input: MutationAddChannelsToSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `addChannelsToSkuGroup` instead.\")\n\n \"\"\"Add channels to an existing SKU group.\"\"\"\n addChannelsToSkuGroup(id: String!, input: MutationAddChannelsToSkuGroupInput!): SKUGroup\n\n \"\"\"Add a new node to a list tree.\"\"\"\n addListTreeNodesToListTree(id: String!, input: MutationAddListTreeNodesToListTreeInput!): ListTree\n\n \"\"\"Add a new node to a list tree node.\"\"\"\n addListTreeNodesToParentListTreeNode(id: String!, input: MutationAddListTreeNodesToParentListTreeNodeInput!): ListTreeNode\n\n \"\"\"Add media objects to an existing List.\"\"\"\n addMediaObjectsToList(id: String!, input: MutationAddMediaObjectsToListInput!): List\n\n \"\"\"Add media objects to an existing SKU\"\"\"\n addMediaObjectsToSKU(id: String!, input: MutationAddMediaObjectsToSKUInput!): SKU @deprecated(reason: \"Use `addMediaObjectsToSku` instead.\")\n\n \"\"\"Add media objects to an existing SKU group.\"\"\"\n addMediaObjectsToSKUGroup(id: String!, input: MutationAddMediaObjectsToSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `addMediaObjectsToSkuGroup` instead.\")\n\n \"\"\"Add media objects to an existing SKU\"\"\"\n addMediaObjectsToSku(id: String!, input: MutationAddMediaObjectsToSkuInput!): SKU\n\n \"\"\"Add media objects to an existing SKU group.\"\"\"\n addMediaObjectsToSkuGroup(id: String!, input: MutationAddMediaObjectsToSkuGroupInput!): SKUGroup\n\n \"\"\"Add options to an existing SKU group.\"\"\"\n addOptionsToSKUGroup(id: String!, input: MutationAddOptionsToSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `addOptionsToSkuGroup` instead.\")\n\n \"\"\"Add options to an existing SKU group.\"\"\"\n addOptionsToSkuGroup(id: String!, input: MutationAddOptionsToSkuGroupInput!): SKUGroup\n\n \"\"\"Add references to an existing List.\"\"\"\n addReferencesToList(id: String!, input: MutationAddReferencesToListInput!): List\n\n \"\"\"Add references to an existing List Tree.\"\"\"\n addReferencesToListTree(id: String!, input: MutationAddReferencesToListTreeInput!): ListTree\n\n \"\"\"Add references to an existing List Tree Node\"\"\"\n addReferencesToListTreeNode(id: String!, input: MutationAddReferencesToListTreeNodeInput!): ListTreeNode\n\n \"\"\"Add references to an existing location.\"\"\"\n addReferencesToLocation(id: String!, input: MutationAddReferencesToLocationInput!): Location\n\n \"\"\"Add references to an existing SKU.\"\"\"\n addReferencesToSKU(id: String!, input: MutationAddReferencesToSKUInput!): SKU @deprecated(reason: \"Use `addReferencesToSku` instead.\")\n\n \"\"\"Add references to an existing SKU group.\"\"\"\n addReferencesToSKUGroup(id: String!, input: MutationAddReferencesToSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `addReferencesToSkuGroup` instead.\")\n\n \"\"\"Add references to an existing SKU.\"\"\"\n addReferencesToSku(id: String!, input: MutationAddReferencesToSkuInput!): SKU\n\n \"\"\"Add references to an existing SKU group.\"\"\"\n addReferencesToSkuGroup(id: String!, input: MutationAddReferencesToSkuGroupInput!): SKUGroup\n\n \"\"\"Add a single SKU Group to multiple lists\"\"\"\n addSKUGroupToLists(id: String!, input: MutationAddSKUGroupToListsInput!): SKUGroup @deprecated(reason: \"Use `addSkuGroupToLists` instead.\")\n\n \"\"\"Add SKU Groups to an existing list.\"\"\"\n addSKUGroupsToList(id: String!, input: MutationAddSKUGroupsToListInput!): List @deprecated(reason: \"Use `addSkuGroupsToList` instead.\")\n\n \"\"\"Add SKUs to an existing location.\"\"\"\n addSKUsToLocation(id: String!, input: MutationAddSKUsToLocationInput!): Location @deprecated(reason: \"Use `addSkusToLocation` instead.\")\n\n \"\"\"Add SKUs to an existing SKU group.\"\"\"\n addSKUsToSKUGroup(id: String!, input: MutationAddSKUsToSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `addSkusToSkuGroup` instead.\")\n\n \"\"\"Add a single SKU Group to multiple lists\"\"\"\n addSkuGroupToLists(id: String!, input: MutationAddSkuGroupToListsInput!): SKUGroup\n\n \"\"\"Add SKU Groups to an existing list.\"\"\"\n addSkuGroupsToList(id: String!, input: MutationAddSkuGroupsToListInput!): List\n\n \"\"\"Add SKUs to an existing location.\"\"\"\n addSkusToLocation(id: String!, input: MutationAddSkusToLocationInput!): Location\n\n \"\"\"Add SKUs to an existing SKU group.\"\"\"\n addSkusToSkuGroup(id: String!, input: MutationAddSkusToSkuGroupInput!): SKUGroup\n\n \"\"\"\n Adjust inventory by a positive or negative delta. Positive deltas stock inventory, negative deltas reduce inventory.\n \"\"\"\n adjustInventory(input: MutationAdjustInventoryInput!): [InventoryAdjustment!]\n\n \"\"\"Archive a file.\"\"\"\n archiveFile(id: String!): File\n\n \"\"\"\n Archive a store-scoped inventory adjustment reason. Global reasons cannot be archived.\n \"\"\"\n archiveInventoryAdjustmentReason(input: MutationArchiveInventoryAdjustmentReasonInput!): InventoryAdjustmentReason\n\n \"\"\"Archive a list.\"\"\"\n archiveList(id: String!): List\n\n \"\"\"Archive a list tree.\"\"\"\n archiveListTree(id: String!): ListTree\n\n \"\"\"Archive a location.\"\"\"\n archiveLocation(id: String!): Location\n\n \"\"\"Archive an existing SKU.\"\"\"\n archiveSKU(id: String!): SKU @deprecated(reason: \"Use `archiveSku` instead.\")\n\n \"\"\"Archive an existing SKU Group.\"\"\"\n archiveSKUGroup(cascadeArchive: CascadeArchiveInput, id: String!): SKUGroup @deprecated(reason: \"Use `archiveSkuGroup` instead.\")\n\n \"\"\"Archive an existing SKU.\"\"\"\n archiveSku(id: String!): SKU\n\n \"\"\"Archive an existing SKU Group.\"\"\"\n archiveSkuGroup(cascadeArchive: CascadeArchiveInput, id: String!): SKUGroup\n\n \"\"\"Archive multiple existing SKUs. Limit 25 SKUs.\"\"\"\n archiveSkus(ids: [String!]!): [SKU!]\n\n \"\"\"\n Commit new inventory. If there are not enough available inventory, they will be moved to backordered if allowed. Documentation: https://godaddy-corp.atlassian.net/wiki/spaces/COMCORE/pages/3758600912/Inventory+Helper+Mutations#2.-commitInventory\n \"\"\"\n commitInventory(input: MutationCommitInventoryInput!): [InventoryAdjustment!]\n\n \"\"\"Create a new attribute.\"\"\"\n createAttribute(input: MutationCreateAttributeInput!): Attribute\n\n \"\"\"Create a new attribute value.\"\"\"\n createAttributeValue(input: CreateAttributeValueInput!): AttributeValue\n\n \"\"\"Create new attribute values.\"\"\"\n createAttributeValues(input: [CreateAttributeValueInput!]!): [AttributeValue!]\n\n \"\"\"Create a new file.\"\"\"\n createFile(input: CreateFileInput!): File\n\n \"\"\"Create a new inventory adjustment.\"\"\"\n createInventoryAdjustment(input: CreateInventoryAdjustmentInput!): InventoryAdjustment\n\n \"\"\"\n Create a new store-scoped inventory adjustment reason. Name must be kebab-case and must not start with \"g-\" (reserved for global presets). Once created, the name is immutable.\n \"\"\"\n createInventoryAdjustmentReason(input: MutationCreateInventoryAdjustmentReasonInput!): InventoryAdjustmentReason\n\n \"\"\"Create multiple inventory adjustments in a single operation.\"\"\"\n createInventoryAdjustments(input: [CreateInventoryAdjustmentInput!]!): [InventoryAdjustment!]\n\n \"\"\"Create a new list.\"\"\"\n createList(input: MutationCreateListInput!): List\n\n \"\"\"Create a new list tree.\"\"\"\n createListTree(input: MutationCreateListTreeInput!): ListTree\n\n \"\"\"Create a new location.\"\"\"\n createLocation(input: MutationCreateLocationInput!): Location\n\n \"\"\"Create a new option.\"\"\"\n createOption(input: MutationCreateOptionInput!): Option\n\n \"\"\"\n Create a flat price for the option. This will be ignore if a price is present on the option values.\n \"\"\"\n createOptionPrice(input: MutationCreateOptionPriceInput!): OptionPrice\n\n \"\"\"Create a new option value.\"\"\"\n createOptionValue(input: MutationCreateOptionValueInput!): OptionValue\n\n \"\"\"Create a price.\"\"\"\n createOptionValuePrice(input: MutationCreateOptionValuePriceInput!): OptionValuePrice\n\n \"\"\"Create multiple new Option Values in a single transaction.\"\"\"\n createOptionValues(input: [MutationCreateOptionValueInput!]!): [OptionValue!]\n\n \"\"\"Create a new SKU.\"\"\"\n createSKU(input: CreateSKUInput!): SKU @deprecated(reason: \"Use `createSku` instead.\")\n\n \"\"\"Create a new SKU Group.\"\"\"\n createSKUGroup(input: MutationCreateSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `createSkuGroup` instead.\")\n\n \"\"\"Create a price.\"\"\"\n createSKUPrice(input: MutationCreateSKUPriceInput!): SKUPrice @deprecated(reason: \"Use `createSkuPrice` instead.\")\n\n \"\"\"Create multiple new SKUs in a single transaction. Limit 25 SKUs.\"\"\"\n createSKUs(input: [CreateSKUInput!]!): [SKU!] @deprecated(reason: \"Use `createSkus` instead.\")\n\n \"\"\"Create a new SKU.\"\"\"\n createSku(input: CreateSKUInput!): SKU\n\n \"\"\"Create a new SKU Group.\"\"\"\n createSkuGroup(input: MutationCreateSkuGroupInput!): SKUGroup\n\n \"\"\"Create a price.\"\"\"\n createSkuPrice(input: MutationCreateSkuPriceInput!): SKUPrice\n\n \"\"\"Create multiple new SKUs in a single transaction. Limit 25 SKUs.\"\"\"\n createSkus(input: [CreateSKUInput!]!): [SKU!]\n\n \"\"\"\n WARNING: This mutation hard deletes an existing SKU Group and all its associated records.\n \"\"\"\n deleteSkuGroupById(id: String!): SKUGroup\n\n \"\"\"\n Reduce inventory by first reducing available, then moving committed to backordered. If insufficient inventory exists, additional available inventory is automatically added to fulfill the reduction. This mutation does not respect backorder limits.\n \"\"\"\n reduceInventory(input: MutationReduceInventoryInput!): [InventoryAdjustment!]\n\n \"\"\"\n Release inventory from committed. If there are not enough committed inventory, this mutation will error. Documentation: https://godaddy-corp.atlassian.net/wiki/spaces/COMCORE/pages/3758600912/Inventory+Helper+Mutations#3.-releaseInventory\n \"\"\"\n releaseInventory(input: MutationReleaseInventoryInput!): [InventoryAdjustment!]\n\n \"\"\"Remove Attribute Value(s) from an existing Attribute.\"\"\"\n removeAttributeValuesFromAttribute(id: String!, input: MutationRemoveAttributeValuesFromAttributeInput!): Attribute\n\n \"\"\"Remove Attribute Value(s) from an existing SKU.\"\"\"\n removeAttributeValuesFromSKU(id: String!, input: MutationRemoveAttributeValuesFromSKUInput!): SKU @deprecated(reason: \"Use `removeAttributeValuesFromSku` instead.\")\n\n \"\"\"Remove Attribute Value(s) from an existing SKU.\"\"\"\n removeAttributeValuesFromSku(id: String!, input: MutationRemoveAttributeValuesFromSkuInput!): SKU\n\n \"\"\"Remove Attributes from an existing SKU group.\"\"\"\n removeAttributesFromSKUGroup(id: String!, input: MutationRemoveAttributesFromSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `removeAttributesFromSkuGroup` instead.\")\n\n \"\"\"Remove Attributes from an existing SKU group.\"\"\"\n removeAttributesFromSkuGroup(id: String!, input: MutationRemoveAttributesFromSkuGroupInput!): SKUGroup\n\n \"\"\"Remove channel associations from an existing SKU group.\"\"\"\n removeChannelsFromSKUGroup(id: String!, input: MutationRemoveChannelsFromSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `removeChannelsFromSkuGroup` instead.\")\n\n \"\"\"Remove channel associations from an existing SKU group.\"\"\"\n removeChannelsFromSkuGroup(id: String!, input: MutationRemoveChannelsFromSkuGroupInput!): SKUGroup\n\n \"\"\"Remove nodes from a list tree.\"\"\"\n removeListTreeNodesFromListTree(id: String!, input: MutationRemoveListTreeNodesFromListTreeInput!): ListTree\n\n \"\"\"Remove nodes from a list tree node.\"\"\"\n removeListTreeNodesFromParentListTreeNode(id: String!, input: MutationRemoveListTreeNodesFromParentListTreeNodeInput!): ListTreeNode\n\n \"\"\"Remove media objects from an existing List.\"\"\"\n removeMediaObjectsFromList(id: String!, input: MutationRemoveMediaObjectsFromListInput!): List\n\n \"\"\"Remove media objects from an existing SKU\"\"\"\n removeMediaObjectsFromSKU(id: String!, input: MutationRemoveMediaObjectsFromSKUInput!): SKU @deprecated(reason: \"Use `removeMediaObjectsFromSku` instead.\")\n\n \"\"\"Remove media objects from an existing SKU group.\"\"\"\n removeMediaObjectsFromSKUGroup(id: String!, input: MutationRemoveMediaObjectsFromSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `removeMediaObjectsFromSkuGroup` instead.\")\n\n \"\"\"Remove media objects from an existing SKU\"\"\"\n removeMediaObjectsFromSku(id: String!, input: MutationRemoveMediaObjectsFromSkuInput!): SKU\n\n \"\"\"Remove media objects from an existing SKU group.\"\"\"\n removeMediaObjectsFromSkuGroup(id: String!, input: MutationRemoveMediaObjectsFromSkuGroupInput!): SKUGroup\n\n \"\"\"Remove metafields from an existing Attribute.\"\"\"\n removeMetafieldsFromAttribute(id: String!, input: MutationRemoveMetafieldsFromAttributeInput!): Attribute\n\n \"\"\"Remove metafields from an existing Attribute Value.\"\"\"\n removeMetafieldsFromAttributeValue(id: String!, input: MutationRemoveMetafieldsFromAttributeValueInput!): AttributeValue\n\n \"\"\"Remove metafields from an existing List.\"\"\"\n removeMetafieldsFromList(id: String!, input: MutationRemoveMetafieldsFromListInput!): List\n\n \"\"\"Remove metafields from an existing List Tree.\"\"\"\n removeMetafieldsFromListTree(id: String!, input: MutationRemoveMetafieldsFromListTreeInput!): ListTree\n\n \"\"\"Remove metafields from an existing Location.\"\"\"\n removeMetafieldsFromLocation(id: String!, input: MutationRemoveMetafieldsFromLocationInput!): Location\n\n \"\"\"Remove metafields from an existing Option.\"\"\"\n removeMetafieldsFromOption(id: String!, input: MutationRemoveMetafieldsFromOptionInput!): Option\n\n \"\"\"Remove metafields from an existing Option Value.\"\"\"\n removeMetafieldsFromOptionValue(id: String!, input: MutationRemoveMetafieldsFromOptionValueInput!): OptionValue\n\n \"\"\"Remove metafields from an existing SKU.\"\"\"\n removeMetafieldsFromSku(id: String!, input: MutationRemoveMetafieldsFromSkuInput!): SKU\n\n \"\"\"Remove metafields from an existing SKU Group.\"\"\"\n removeMetafieldsFromSkuGroup(id: String!, input: MutationRemoveMetafieldsFromSkuGroupInput!): SKUGroup\n\n \"\"\"Remove an existing option.\"\"\"\n removeOption(id: String!): Null\n\n \"\"\"Remove an existing option value.\"\"\"\n removeOptionValue(id: String!): Null\n\n \"\"\"Remove values from an existing Option.\"\"\"\n removeOptionValuesFromListOption(id: String!, input: MutationRemoveOptionValuesFromListOptionInput!): ListOption\n\n \"\"\"Remove Options from an existing SKU group.\"\"\"\n removeOptionsFromSKUGroup(id: String!, input: MutationRemoveOptionsFromSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `removeOptionsFromSkuGroup` instead.\")\n\n \"\"\"Remove Options from an existing SKU group.\"\"\"\n removeOptionsFromSkuGroup(id: String!, input: MutationRemoveOptionsFromSkuGroupInput!): SKUGroup\n\n \"\"\"Remove prices from an existing Option.\"\"\"\n removePricesFromOption(id: String!, input: MutationRemovePricesFromOptionInput!): Option\n\n \"\"\"Remove prices from an existing OptionValue.\"\"\"\n removePricesFromOptionValue(id: String!, input: MutationRemovePricesFromOptionValueInput!): OptionValue\n\n \"\"\"Remove prices from an existing SKU.\"\"\"\n removePricesFromSKU(id: String!, input: MutationRemovePricesFromSKUInput!): SKU @deprecated(reason: \"Use `removePricesFromSku` instead.\")\n\n \"\"\"Remove prices from an existing SKU.\"\"\"\n removePricesFromSku(id: String!, input: MutationRemovePricesFromSkuInput!): SKU\n\n \"\"\"Remove references from an existing List.\"\"\"\n removeReferencesFromList(id: String!, input: MutationRemoveReferencesFromListInput!): List\n\n \"\"\"Remove references from an existing List Tree\"\"\"\n removeReferencesFromListTree(id: String!, input: MutationRemoveReferencesFromListTreeInput!): ListTree\n\n \"\"\"Remove references from an existing List Tree Node\"\"\"\n removeReferencesFromListTreeNode(id: String!, input: MutationRemoveReferencesFromListTreeNodeInput!): ListTreeNode\n\n \"\"\"Remove references from an existing location.\"\"\"\n removeReferencesFromLocation(id: String!, input: MutationRemoveReferencesFromLocationInput!): Location\n\n \"\"\"Remove references from an existing SKU.\"\"\"\n removeReferencesFromSKU(id: String!, input: MutationRemoveReferencesFromSKUInput!): SKU @deprecated(reason: \"Use `removeReferencesFromSku` instead.\")\n\n \"\"\"Remove references from an existing SKU group.\"\"\"\n removeReferencesFromSKUGroup(id: String!, input: MutationRemoveReferencesFromSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `removeReferencesFromSkuGroup` instead.\")\n\n \"\"\"Remove references from an existing SKU.\"\"\"\n removeReferencesFromSku(id: String!, input: MutationRemoveReferencesFromSkuInput!): SKU\n\n \"\"\"Remove references from an existing SKU group.\"\"\"\n removeReferencesFromSkuGroup(id: String!, input: MutationRemoveReferencesFromSkuGroupInput!): SKUGroup\n\n \"\"\"Remove a single SKU Group from multiple lists\"\"\"\n removeSKUGroupFromLists(id: String!, input: MutationRemoveSKUGroupFromListsInput!): SKUGroup @deprecated(reason: \"Use `removeSkuGroupFromLists` instead.\")\n\n \"\"\"Remove SKU Groups from an existing list.\"\"\"\n removeSKUGroupsFromList(id: String!, input: MutationRemoveSKUGroupsFromListInput!): List @deprecated(reason: \"Use `removeSkuGroupsFromList` instead.\")\n\n \"\"\"Remove SKU from an existing location.\"\"\"\n removeSKUsFromLocation(id: String!, input: MutationRemoveSKUsFromLocationInput!): Location @deprecated(reason: \"Use `removeSkusFromLocation` instead.\")\n\n \"\"\"Remove SKUs from an existing SKU group.\"\"\"\n removeSKUsFromSKUGroup(id: String!, input: MutationRemoveSKUsFromSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `removeSkusFromSkuGroup` instead.\")\n\n \"\"\"Remove a single SKU Group from multiple lists\"\"\"\n removeSkuGroupFromLists(id: String!, input: MutationRemoveSkuGroupFromListsInput!): SKUGroup\n\n \"\"\"Remove SKU Groups from an existing list.\"\"\"\n removeSkuGroupsFromList(id: String!, input: MutationRemoveSkuGroupsFromListInput!): List\n\n \"\"\"Remove SKU from an existing location.\"\"\"\n removeSkusFromLocation(id: String!, input: MutationRemoveSkusFromLocationInput!): Location\n\n \"\"\"Remove SKUs from an existing SKU group.\"\"\"\n removeSkusFromSkuGroup(id: String!, input: MutationRemoveSkusFromSkuGroupInput!): SKUGroup\n\n \"\"\"\n Restock inventory from committed. If there are not enough committed inventory, this mutation will error.\n \"\"\"\n restockFromCommittedInventory(input: MutationRestockFromCommittedInventoryInput!): [InventoryAdjustment!]\n\n \"\"\"Set the channel association mode for a SKU Group.\"\"\"\n setSkuGroupChannelAssociationMode(\n \"\"\"SKU Group ID\"\"\"\n id: String!\n input: MutationSetSkuGroupChannelAssociationModeInput!\n ): SKUGroup\n\n \"\"\"\n Stock new inventory. If there are backordered inventory, they will be moved to committed. It does not validate aganist backorder limit. Any extra inventory will be added to available. Documentation: https://godaddy-corp.atlassian.net/wiki/spaces/COMCORE/pages/3758600912/Inventory+Helper+Mutations#1.-stockInventory\n \"\"\"\n stockInventory(input: MutationStockInventoryInput!): [InventoryAdjustment!]\n\n \"\"\"Update an existing attribute.\"\"\"\n updateAttribute(id: String!, input: MutationUpdateAttributeInput!): Attribute\n\n \"\"\"Update an existing attribute value.\"\"\"\n updateAttributeValue(id: String!, input: MutationUpdateAttributeValueInput!): AttributeValue\n\n \"\"\"Update an existing file.\"\"\"\n updateFile(id: String!, input: UpdateFileInput!): File\n\n \"\"\"\n Update the label of a store-scoped inventory adjustment reason. Global preset reasons cannot be updated.\n \"\"\"\n updateInventoryAdjustmentReason(input: MutationUpdateInventoryAdjustmentReasonInput!): InventoryAdjustmentReason\n\n \"\"\"Update an existing list.\"\"\"\n updateList(id: String!, input: MutationUpdateListInput!): List\n\n \"\"\"Add media objects or update existing media objects to existing List.\"\"\"\n updateListMediaObjects(id: String!, input: MutationUpdateListMediaObjectsInput!): List\n\n \"\"\"Update an existing list tree.\"\"\"\n updateListTree(id: String!, input: MutationUpdateListTreeInput!): ListTree\n\n \"\"\"Update an existing list tree node.\"\"\"\n updateListTreeNode(id: String!, input: MutationUpdateListTreeNodeInput!): ListTreeNode\n\n \"\"\"Update an existing location.\"\"\"\n updateLocation(id: String!, input: MutationUpdateLocationInput!): Location\n\n \"\"\"Update an existing option.\"\"\"\n updateOption(id: String!, input: MutationUpdateOptionInput!): Option\n\n \"\"\"Update an existing price object for an option.\"\"\"\n updateOptionPrice(id: String!, input: MutationUpdateOptionPriceInput!): OptionPrice\n\n \"\"\"\n Update the currency code for an existing option price. This updates the currency code for both value and compareAtValue.\n \"\"\"\n updateOptionPriceCurrencyCode(id: String!, input: MutationUpdateOptionPriceCurrencyCodeInput!): OptionPrice\n\n \"\"\"Update an existing option value.\"\"\"\n updateOptionValue(id: String!, input: MutationUpdateOptionValueInput!): OptionValue\n\n \"\"\"Update an existing price object.\"\"\"\n updateOptionValuePrice(id: String!, input: MutationUpdateOptionValuePriceInput!): OptionValuePrice\n\n \"\"\"\n Update the currency code for an existing option value price. This updates the currency code for both value and compareAtValue.\n \"\"\"\n updateOptionValuePriceCurrencyCode(id: String!, input: MutationUpdateOptionValuePriceCurrencyCodeInput!): OptionValuePrice\n\n \"\"\"Update an existing SKU.\"\"\"\n updateSKU(id: String!, input: MutationUpdateSKUInput!): SKU @deprecated(reason: \"Use `updateSku` instead.\")\n\n \"\"\"Update an existing SKU Group.\"\"\"\n updateSKUGroup(id: String!, input: MutationUpdateSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `updateSkuGroup` instead.\")\n\n \"\"\"Update an existing price object.\"\"\"\n updateSKUPrice(id: String!, input: MutationUpdateSKUPriceInput!): SKUPrice @deprecated(reason: \"Use `updateSkuPrice` instead.\")\n\n \"\"\"Update an existing SKU.\"\"\"\n updateSku(id: String!, input: MutationUpdateSkuInput!): SKU\n\n \"\"\"Update an existing SKU Group.\"\"\"\n updateSkuGroup(id: String!, input: MutationUpdateSkuGroupInput!): SKUGroup\n\n \"\"\"\n Add media objects or update existing media objects to existing SKU Group.\n \"\"\"\n updateSkuGroupMediaObjects(id: String!, input: MutationUpdateSkuGroupMediaObjectsInput!): SKUGroup\n\n \"\"\"\n Reorder options within a SKU group by updating the position of each option's association.\n \"\"\"\n updateSkuGroupOptionPositions(id: String!, input: MutationUpdateSkuGroupOptionPositionsInput!): SKUGroup\n\n \"\"\"Add media objects or update existing media objects to existing SKU.\"\"\"\n updateSkuMediaObjects(id: String!, input: MutationUpdateSkuMediaObjectsInput!): SKU\n\n \"\"\"Update an existing price object.\"\"\"\n updateSkuPrice(id: String!, input: MutationUpdateSkuPriceInput!): SKUPrice\n\n \"\"\"\n Update the currency code for an existing price. This updates the currency code for both value and compareAtValue.\n \"\"\"\n updateSkuPriceCurrencyCode(id: String!, input: MutationUpdateSkuPriceCurrencyCodeInput!): SKUPrice\n}\n\ninput MutationAddAttributeValuesToSKUInput {\n attributeValueIds: [String!]!\n}\n\ninput MutationAddAttributeValuesToSkuInput {\n attributeValueIds: [String!]!\n}\n\ninput MutationAddAttributesToSKUGroupInput {\n attributes: [CreateSKUGroupAttributeInput!]!\n}\n\ninput MutationAddAttributesToSkuGroupInput {\n attributes: [CreateSKUGroupAttributeInput!]!\n}\n\ninput MutationAddChannelsToSKUGroupInput {\n \"\"\"\n The channels to add to the SKU group.\n \t\t\t\tThese are pointers to the Channels API, Catalog API\n \t\t\t\tdoes not create the channel resources.\n \"\"\"\n channels: [SKUGroupChannelAddInput!]!\n}\n\ninput MutationAddChannelsToSkuGroupInput {\n \"\"\"\n The channels to add to the SKU group.\n \t\t\t\tThese are pointers to the Channels API, Catalog API\n \t\t\t\tdoes not create the channel resources.\n \"\"\"\n channels: [SKUGroupChannelAddInput!]!\n}\n\ninput MutationAddListTreeNodesToListTreeInput {\n listTreeNodes: [AddListTreeNodeInput!]!\n}\n\ninput MutationAddListTreeNodesToParentListTreeNodeInput {\n listTreeNodes: [AddListTreeNodeInput!]!\n}\n\ninput MutationAddMediaObjectsToListInput {\n mediaObjects: [CreateMediaObjectInput!]!\n}\n\ninput MutationAddMediaObjectsToSKUGroupInput {\n mediaObjects: [CreateMediaObjectInput!]!\n}\n\ninput MutationAddMediaObjectsToSKUInput {\n mediaObjects: [CreateMediaObjectInput!]!\n}\n\ninput MutationAddMediaObjectsToSkuGroupInput {\n mediaObjects: [CreateMediaObjectInput!]!\n}\n\ninput MutationAddMediaObjectsToSkuInput {\n mediaObjects: [CreateMediaObjectInput!]!\n}\n\ninput MutationAddOptionsToSKUGroupInput {\n \"\"\"UUIDs of existing options to associate with this SKU group.\"\"\"\n optionIds: [String!]\n options: [CreateOptionInput!]\n}\n\ninput MutationAddOptionsToSkuGroupInput {\n \"\"\"UUIDs of existing options to associate with this SKU group.\"\"\"\n optionIds: [String!]\n options: [CreateOptionInput!]\n}\n\ninput MutationAddReferencesToListInput {\n references: [CreateReferenceInput!]!\n}\n\ninput MutationAddReferencesToListTreeInput {\n references: [CreateReferenceInput!]!\n}\n\ninput MutationAddReferencesToListTreeNodeInput {\n references: [CreateReferenceInput!]!\n}\n\ninput MutationAddReferencesToLocationInput {\n references: [CreateReferenceInput!]!\n}\n\ninput MutationAddReferencesToSKUGroupInput {\n references: [CreateReferenceInput!]!\n}\n\ninput MutationAddReferencesToSKUInput {\n references: [CreateReferenceInput!]!\n}\n\ninput MutationAddReferencesToSkuGroupInput {\n references: [CreateReferenceInput!]!\n}\n\ninput MutationAddReferencesToSkuInput {\n references: [CreateReferenceInput!]!\n}\n\ninput MutationAddSKUGroupToListsInput {\n listIds: [String!]!\n}\n\ninput MutationAddSKUGroupsToListInput {\n skuGroupIds: [String!]!\n}\n\ninput MutationAddSKUsToLocationInput {\n skuIds: [String!]!\n}\n\ninput MutationAddSKUsToSKUGroupInput {\n skuIds: [String!]!\n}\n\ninput MutationAddSkuGroupToListsInput {\n listIds: [String!]!\n}\n\ninput MutationAddSkuGroupsToListInput {\n skuGroupIds: [String!]!\n}\n\ninput MutationAddSkusToLocationInput {\n skuIds: [String!]!\n}\n\ninput MutationAddSkusToSkuGroupInput {\n skuIds: [String!]!\n}\n\ninput MutationAdjustInventoryInput {\n delta: Int!\n locationId: ID!\n reasonName: String\n references: [CreateReferenceInput!]\n skuId: ID!\n}\n\ninput MutationArchiveInventoryAdjustmentReasonInput {\n id: ID!\n}\n\ninput MutationCommitInventoryInput {\n allowBackorders: Boolean\n locationId: ID!\n quantity: Int!\n reasonName: String\n references: [CreateReferenceInput!]\n skuId: ID!\n}\n\ninput MutationCreateAttributeInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n description: String\n htmlDescription: String\n label: String!\n metafields: [CreateMetafieldInput!]\n name: String\n position: Int\n skuGroupId: ID!\n values: [AssociateAttributeValueInput!]\n}\n\ninput MutationCreateInventoryAdjustmentReasonInput {\n label: String!\n name: String!\n}\n\ninput MutationCreateListInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n htmlDescription: String\n label: String!\n mediaObjects: [CreateMediaObjectInput!]\n metafields: [CreateMetafieldInput!]\n name: String\n references: [CreateReferenceInput!]\n\n \"\"\"The status of the list, one of `ACTIVE`, `DRAFT`, `ARCHIVED`.\"\"\"\n status: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationCreateListTreeInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n htmlDescription: String\n label: String!\n listTreeNodes: [CreateListTreeNodeInput!]\n metafields: [CreateMetafieldInput!]\n name: String\n references: [CreateReferenceInput!]\n\n \"\"\"The status of the list tree, one of `ACTIVE`, `ARCHIVED`, `DRAFT`.\"\"\"\n status: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationCreateLocationInput {\n address: CreateAddressInput!\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n label: String!\n metafields: [CreateMetafieldInput!]\n name: String\n references: [CreateReferenceInput!]\n\n \"\"\"The status of the location, one of `ACTIVE`, `INACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationCreateOptionInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n description: String\n htmlDescription: String\n\n \"\"\"Whether this option is shareable across multiple SKU Groups.\"\"\"\n shareable: Boolean\n label: String!\n metafields: [CreateMetafieldInput!]\n name: String\n position: Int\n prices: [CreateOptionPriceInput!]\n skuGroupId: String @deprecated(reason: \"Use skuGroupIds instead.\")\n\n \"\"\"The UUIDs of the SKU Groups to associate the Option with.\"\"\"\n skuGroupIds: [String!]\n\n \"\"\"\n The type of the Option, one of `TEXT`, `NUMBER`, `LIST`. Option Values are only available on the 'LIST' type.\n \"\"\"\n type: String!\n validation: CreateOptionValidationInput\n values: [CreateOptionValueInput!]\n}\n\ninput MutationCreateOptionPriceInput {\n compareAtValue: SimpleMoneyInput\n optionId: String!\n value: SimpleMoneyInput!\n}\n\ninput MutationCreateOptionValueInput {\n label: String!\n metafields: [CreateMetafieldInput!]\n name: String\n optionId: String!\n position: Int\n prices: [CreateOptionValuePriceInput!]\n}\n\ninput MutationCreateOptionValuePriceInput {\n compareAtValue: SimpleMoneyInput\n optionValueId: String!\n value: SimpleMoneyInput!\n}\n\ninput MutationCreateSKUGroupInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n attributes: [CreateSKUGroupAttributeInput!]\n channels: [SKUGroupChannelAddInput!]\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n htmlDescription: String\n label: String!\n mediaObjects: [CreateMediaObjectInput!]\n metafields: [CreateMetafieldInput!]\n name: String\n options: [CreateOptionInput!]\n references: [CreateReferenceInput!]\n shortLabel: String @deprecated(reason: \"Use channel-specific overrides for short labels.\")\n skus: [CreateSKUGroupSKUInput!]\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n type: String!\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationCreateSKUPriceInput {\n compareAtValue: SimpleMoneyInput\n skuId: ID!\n value: SimpleMoneyInput!\n}\n\ninput MutationCreateSkuGroupInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n attributes: [CreateSKUGroupAttributeInput!]\n channels: [SKUGroupChannelAddInput!]\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n htmlDescription: String\n label: String!\n mediaObjects: [CreateMediaObjectInput!]\n metafields: [CreateMetafieldInput!]\n name: String\n options: [CreateOptionInput!]\n references: [CreateReferenceInput!]\n shortLabel: String @deprecated(reason: \"Use channel-specific overrides for short labels.\")\n skus: [CreateSKUGroupSKUInput!]\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n type: String!\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationCreateSkuPriceInput {\n compareAtValue: SimpleMoneyInput\n skuId: ID!\n value: SimpleMoneyInput!\n}\n\ninput MutationReduceInventoryInput {\n locationId: ID!\n quantity: Int!\n reasonName: String\n references: [CreateReferenceInput!]\n skuId: ID!\n}\n\ninput MutationReleaseInventoryInput {\n locationId: ID!\n quantity: Int!\n reasonName: String\n references: [CreateReferenceInput!]\n skuId: ID!\n}\n\ninput MutationRemoveAttributeValuesFromAttributeInput {\n attributeValueIds: [String!]!\n}\n\ninput MutationRemoveAttributeValuesFromSKUInput {\n attributeValueIds: [String!]!\n}\n\ninput MutationRemoveAttributeValuesFromSkuInput {\n attributeValueIds: [String!]!\n}\n\ninput MutationRemoveAttributesFromSKUGroupInput {\n attributeIds: [String!]!\n}\n\ninput MutationRemoveAttributesFromSkuGroupInput {\n attributeIds: [String!]!\n}\n\ninput MutationRemoveChannelsFromSKUGroupInput {\n channelIds: [String!]!\n}\n\ninput MutationRemoveChannelsFromSkuGroupInput {\n channelIds: [String!]!\n}\n\ninput MutationRemoveListTreeNodesFromListTreeInput {\n listTreeNodeIds: [String!]!\n}\n\ninput MutationRemoveListTreeNodesFromParentListTreeNodeInput {\n listTreeNodeIds: [String!]!\n}\n\ninput MutationRemoveMediaObjectsFromListInput {\n mediaObjectIds: [String!]!\n}\n\ninput MutationRemoveMediaObjectsFromSKUGroupInput {\n mediaObjectIds: [String!]!\n}\n\ninput MutationRemoveMediaObjectsFromSKUInput {\n mediaObjectIds: [String!]!\n}\n\ninput MutationRemoveMediaObjectsFromSkuGroupInput {\n mediaObjectIds: [String!]!\n}\n\ninput MutationRemoveMediaObjectsFromSkuInput {\n mediaObjectIds: [String!]!\n}\n\ninput MutationRemoveMetafieldsFromAttributeInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveMetafieldsFromAttributeValueInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveMetafieldsFromListInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveMetafieldsFromListTreeInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveMetafieldsFromLocationInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveMetafieldsFromOptionInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveMetafieldsFromOptionValueInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveMetafieldsFromSkuGroupInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveMetafieldsFromSkuInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveOptionValuesFromListOptionInput {\n valueIds: [String!]!\n}\n\ninput MutationRemoveOptionsFromSKUGroupInput {\n optionIds: [String!]!\n}\n\ninput MutationRemoveOptionsFromSkuGroupInput {\n optionIds: [String!]!\n}\n\ninput MutationRemovePricesFromOptionInput {\n priceIds: [String!]!\n}\n\ninput MutationRemovePricesFromOptionValueInput {\n priceIds: [String!]!\n}\n\ninput MutationRemovePricesFromSKUInput {\n priceIds: [String!]!\n}\n\ninput MutationRemovePricesFromSkuInput {\n priceIds: [String!]!\n}\n\ninput MutationRemoveReferencesFromListInput {\n referenceIds: [String!]!\n}\n\ninput MutationRemoveReferencesFromListTreeInput {\n referenceIds: [String!]!\n}\n\ninput MutationRemoveReferencesFromListTreeNodeInput {\n referenceIds: [String!]!\n}\n\ninput MutationRemoveReferencesFromLocationInput {\n referenceIds: [String!]!\n}\n\ninput MutationRemoveReferencesFromSKUGroupInput {\n referenceIds: [String!]!\n}\n\ninput MutationRemoveReferencesFromSKUInput {\n referenceIds: [String!]!\n}\n\ninput MutationRemoveReferencesFromSkuGroupInput {\n referenceIds: [String!]!\n}\n\ninput MutationRemoveReferencesFromSkuInput {\n referenceIds: [String!]!\n}\n\ninput MutationRemoveSKUGroupFromListsInput {\n listIds: [String!]!\n}\n\ninput MutationRemoveSKUGroupsFromListInput {\n skuGroupIds: [String!]!\n}\n\ninput MutationRemoveSKUsFromLocationInput {\n skuIds: [String!]!\n}\n\ninput MutationRemoveSKUsFromSKUGroupInput {\n skuIds: [String!]!\n}\n\ninput MutationRemoveSkuGroupFromListsInput {\n listIds: [String!]!\n}\n\ninput MutationRemoveSkuGroupsFromListInput {\n skuGroupIds: [String!]!\n}\n\ninput MutationRemoveSkusFromLocationInput {\n skuIds: [String!]!\n}\n\ninput MutationRemoveSkusFromSkuGroupInput {\n skuIds: [String!]!\n}\n\ninput MutationRestockFromCommittedInventoryInput {\n locationId: ID!\n quantity: Int!\n reasonName: String\n references: [CreateReferenceInput!]\n skuId: ID!\n}\n\ninput MutationSetSkuGroupChannelAssociationModeInput {\n \"\"\"\n The channel association mode for this SKU Group. Can be ALL (uses active channels registered to the store) or\n \t\t\t\t\tSELECTIVE (uses custom channel associations).\n \"\"\"\n mode: String!\n}\n\ninput MutationStockInventoryInput {\n locationId: ID!\n quantity: Int!\n reasonName: String\n references: [CreateReferenceInput!]\n skuId: ID!\n}\n\ninput MutationUpdateAttributeInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n description: String\n htmlDescription: String\n label: String\n metafields: [UpsertMetafieldInput!]\n name: String\n position: Int\n}\n\ninput MutationUpdateAttributeValueInput {\n label: String\n metafields: [UpsertMetafieldInput!]\n name: String\n position: Int\n}\n\ninput MutationUpdateInventoryAdjustmentReasonInput {\n id: ID!\n label: String\n}\n\ninput MutationUpdateListInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n htmlDescription: String\n label: String\n metafields: [UpsertMetafieldInput!]\n name: String\n\n \"\"\"The status of the list, one of `ACTIVE`, `DRAFT`, `ARCHIVED`.\"\"\"\n status: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationUpdateListMediaObjectsInput {\n mediaObjects: [UpdateMediaObjectInput!]!\n}\n\ninput MutationUpdateListTreeInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n htmlDescription: String\n label: String\n metafields: [UpsertMetafieldInput!]\n name: String\n\n \"\"\"The status of the list tree, one of `ACTIVE`, `ARCHIVED`, `DRAFT`.\"\"\"\n status: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationUpdateListTreeNodeInput {\n listId: String\n listTreeId: String\n parentNodeId: String\n position: Int\n}\n\ninput MutationUpdateLocationInput {\n address: UpdateAddressInput\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n label: String\n metafields: [UpsertMetafieldInput!]\n name: String\n\n \"\"\"The status of the location, one of `ACTIVE`, `INACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationUpdateOptionInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n description: String\n htmlDescription: String\n shareable: Boolean\n label: String\n metafields: [UpsertMetafieldInput!]\n name: String\n position: Int\n\n \"\"\"\n The type of the Option, one of `TEXT`, `NUMBER`, `LIST`. Option Values are only available on the 'LIST' type.\n \"\"\"\n type: String\n validation: CreateOptionValidationInput\n}\n\ninput MutationUpdateOptionPriceCurrencyCodeInput {\n currencyCode: String!\n}\n\ninput MutationUpdateOptionPriceInput {\n compareAtValue: SimpleMoneyInput\n value: SimpleMoneyInput\n}\n\ninput MutationUpdateOptionValueInput {\n label: String\n metafields: [UpsertMetafieldInput!]\n name: String\n position: Int\n}\n\ninput MutationUpdateOptionValuePriceCurrencyCodeInput {\n currencyCode: String!\n}\n\ninput MutationUpdateOptionValuePriceInput {\n compareAtValue: SimpleMoneyInput\n value: SimpleMoneyInput\n}\n\ninput MutationUpdateSKUGroupInput {\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n label: String\n name: String\n shortLabel: String @deprecated(reason: \"Use channel-specific overrides for short labels.\")\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationUpdateSKUInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n backorderLimit: Int\n code: String\n\n \"\"\"DEPRECATED. Use unitCost instead.\"\"\"\n cost: Int @deprecated(reason: \"This cost field cannot specify currency code. Use `unitCost` instead.\")\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n disableInventoryTracking: Boolean\n disablePriceOverrides: Boolean\n disableShipping: Boolean\n eanCode: String\n gtinCode: String\n htmlDescription: String\n isbnCode: String\n label: String\n name: String\n shortLabel: String @deprecated(reason: \"Use channel-specific overrides for short labels.\")\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n unitCost: SimpleMoneyInput\n\n \"\"\"The unit of weight, one of `KG`, `GR`, `LB`, `OZ`.\"\"\"\n unitOfWeight: String\n upcCode: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n weight: Float\n}\n\ninput MutationUpdateSKUPriceInput {\n compareAtValue: SimpleMoneyInput\n\n \"\"\"\n Update the currency code for this price. When provided, updates the currency code while keeping the numeric value unchanged.\n \"\"\"\n currencyCode: String\n value: SimpleMoneyInput\n}\n\ninput MutationUpdateSkuGroupInput {\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n htmlDescription: String\n label: String\n metafields: [UpsertMetafieldInput!]\n name: String\n shortLabel: String @deprecated(reason: \"Use channel-specific overrides for short labels.\")\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationUpdateSkuGroupMediaObjectsInput {\n mediaObjects: [UpdateMediaObjectInput!]!\n}\n\ninput MutationUpdateSkuGroupOptionPositionsInput {\n positions: [UpdateSKUGroupOptionPositionInput!]!\n}\n\ninput MutationUpdateSkuInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n backorderLimit: Int\n code: String\n\n \"\"\"DEPRECATED. Use unitCost instead.\"\"\"\n cost: Int @deprecated(reason: \"This cost field cannot specify currency code. Use `unitCost` instead.\")\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n disableInventoryTracking: Boolean\n disablePriceOverrides: Boolean\n disableShipping: Boolean\n eanCode: String\n gtinCode: String\n htmlDescription: String\n isbnCode: String\n label: String\n metafields: [UpsertMetafieldInput!]\n name: String\n shortLabel: String @deprecated(reason: \"Use channel-specific overrides for short labels.\")\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n unitCost: SimpleMoneyInput\n\n \"\"\"The unit of weight, one of `KG`, `GR`, `LB`, `OZ`.\"\"\"\n unitOfWeight: String\n upcCode: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n weight: Float\n}\n\ninput MutationUpdateSkuMediaObjectsInput {\n mediaObjects: [UpdateMediaObjectInput!]!\n}\n\ninput MutationUpdateSkuPriceCurrencyCodeInput {\n currencyCode: String!\n}\n\ninput MutationUpdateSkuPriceInput {\n compareAtValue: SimpleMoneyInput\n value: SimpleMoneyInput\n}\n\n\"\"\"\nFilters items where the name is equal to the specified string or in an array of strings.\n\"\"\"\ninput NameFilter {\n \"\"\"\n Filters items where the name contains the specified string, case-insensitive.\n \"\"\"\n contains: String\n eq: String\n\n \"\"\"Filters items where the name matches any of the specified names.\"\"\"\n in: [String!]\n}\n\nscalar Null\n\ntype NumericOption {\n \"\"\"The timestamp of when the Option was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"A description of the Option.\"\"\"\n description: String\n\n \"\"\"The UUID of the Option\"\"\"\n id: ID!\n\n \"\"\"\n Whether the option is shareable across multiple SKU Groups (a global modifier).\n \"\"\"\n shareable: Boolean!\n\n \"\"\"The display lable of the Option\"\"\"\n label: String!\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): OptionMetafieldsConnection\n\n \"\"\"A unique name of the Option.\"\"\"\n name: String!\n\n \"\"\"The position of the option.\"\"\"\n position: Int\n\n \"\"\"\n Represents the additional cost of a Numeric Option. When empty, it indicates this option allows for flexible pricing.\n \"\"\"\n prices(\n after: String\n before: String\n\n \"\"\"Filter prices by currency code.\"\"\"\n currencyCode: CurrencyCodeFilter\n first: Int\n last: Int\n paginationType: PaginationType = CURSOR\n ): NumericOptionPricesConnection\n\n \"\"\"The UUID of the SKU Group that the Option belongs to.\"\"\"\n skuGroupId: ID! @deprecated(reason: \"Use skuGroupIds or the SKUGroup.options connection instead. An option may belong to multiple SKU groups.\")\n\n \"\"\"The IDs of all SKU groups this option is associated with.\"\"\"\n skuGroupIds: [String!]!\n\n \"\"\"\n The type of the option, one of `TEXT`, `NUMBER`, `LIST`, Option Values are available for the 'LIST' type.\n \"\"\"\n type: String\n\n \"\"\"The timestamp of when the Option was updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"\n Provide validations on how the option can be applied to a SKU. If `TEXT` option then `min` and `max` apply to the number of characters. If `NUMBER` then `min` and `max` apply to the actual number value. If `LIST` then `min` and `max` apply to the number of values that can be selected.\n \"\"\"\n validation: OptionValidation\n}\n\ntype NumericOptionPricesConnection {\n edges: [NumericOptionPricesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype NumericOptionPricesConnectionEdge {\n cursor: String!\n node: OptionPrice\n}\n\nunion Option = ListOption | NumericOption | TextOption\n\ninput OptionIdFilter {\n eq: String\n in: [String!]\n}\n\ninput OptionIdsFilter {\n in: [String!]\n}\n\ntype OptionMetafieldsConnection {\n edges: [OptionMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype OptionMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ninput OptionOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n label: OrderByDirectionEnum\n name: OrderByDirectionEnum\n position: OrderByDirectionEnum\n price: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\n\"\"\"\nRepresents the additional cost of an option added to a SKU group (e.g 'Toppings' option for a coffee drink).\n\"\"\"\ntype OptionPrice {\n \"\"\"The compare-at value of the price.\"\"\"\n compareAtValue: SimpleMoney\n\n \"\"\"The timestamp of when the price was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the price.\"\"\"\n id: ID!\n\n \"\"\"The option that this price belongs to.\"\"\"\n option: Option\n\n \"\"\"The last update timestamp of the price.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The value of the price.\"\"\"\n value: SimpleMoney!\n}\n\ninput OptionPriceIdsFilter {\n in: [String!]\n}\n\ninput OptionPriceOrderBy {\n id: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\n\"\"\"\nProvide validations on how the option can be applied to a SKU. If `TEXT` option then `min` and `max` apply to the number of characters. If `NUMBER` then `min` and `max` apply to the actual number value. If `LIST` then `min` and `max` apply to the number of values that can be selected.\n\"\"\"\ntype OptionValidation {\n \"\"\"The maximum number that can be applied to the option.\"\"\"\n max: Int\n\n \"\"\"The minimum number that can be applied to the option.\"\"\"\n min: Int\n}\n\ntype OptionValue {\n \"\"\"The timestamp of when the Option Value was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The UUID of the Option Value.\"\"\"\n id: ID!\n\n \"\"\"The display label of the Option Value.\"\"\"\n label: String!\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): OptionValueMetafieldsConnection\n\n \"\"\"A unique name of the Option Value.\"\"\"\n name: String!\n\n \"\"\"The option that this value belongs to.\"\"\"\n option: ListOption\n\n \"\"\"The position of the option value.\"\"\"\n position: Int\n\n \"\"\"\n These are all the prices the Option Value can be sold at. The price can be different based the channel where it is listed or if there is a promotion running.\n \"\"\"\n prices(\n after: String\n before: String\n\n \"\"\"Filter prices by currency code.\"\"\"\n currencyCode: CurrencyCodeFilter\n first: Int\n last: Int\n paginationType: PaginationType = CURSOR\n ): OptionValuePricesConnection\n\n \"\"\"The timestamp of when the Option Value was updated.\"\"\"\n updatedAt: DateTime!\n}\n\ninput OptionValueIdFilter {\n eq: String\n}\n\ninput OptionValueIdsFilter {\n in: [String!]\n}\n\ntype OptionValueMetafieldsConnection {\n edges: [OptionValueMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype OptionValueMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ninput OptionValueOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n name: OrderByDirectionEnum\n position: OrderByDirectionEnum\n price: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\n\"\"\"\nRepresents the additional cost of the option value added to a SKU (e.g the option value 'Caramel Drizzle' could have a different cost to other 'Topping' options).\n\"\"\"\ntype OptionValuePrice {\n \"\"\"The compare-at value of the price.\"\"\"\n compareAtValue: SimpleMoney\n\n \"\"\"The timestamp of when the price was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the price.\"\"\"\n id: ID!\n\n \"\"\"The option value that this price belongs to.\"\"\"\n optionValue: OptionValue\n\n \"\"\"The last update timestamp of the price.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The value of the price.\"\"\"\n value: SimpleMoney!\n}\n\ninput OptionValuePriceIdsFilter {\n in: [String!]\n}\n\ninput OptionValuePriceOrderBy {\n id: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\ntype OptionValuePricesConnection {\n edges: [OptionValuePricesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype OptionValuePricesConnectionEdge {\n cursor: String!\n node: OptionValuePrice\n}\n\n\"\"\"The direction in which to order items.\"\"\"\nenum OrderByDirectionEnum {\n ASC\n DESC\n}\n\ntype PageInfo {\n endCursor: String\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n startCursor: String\n}\n\nenum PaginationType {\n CURSOR\n OFFSET\n}\n\n\"\"\"Defines a range of prices.\"\"\"\ntype PriceRange {\n \"\"\"Maximum price.\"\"\"\n max: Float\n\n \"\"\"Minimum price.\"\"\"\n min: Float\n}\n\ntype Query {\n SKU(id: String!): SKU @deprecated(reason: \"Use sku instead.\")\n SKUGroup(id: String!): SKUGroup @deprecated(reason: \"Use skuGroup instead.\")\n SKUGroups(after: String, before: String, channelId: SKUGroupChannelIdFilter, createdAt: CreatedAtFilter, first: Int, id: SKUGroupIdsFilter, last: Int, listId: ListIdFilter, name: NameFilter, orderBy: SKUGroupOrderBy, paginationType: PaginationType = CURSOR, referenceValue: ReferenceValueFilter, status: SKUGroupStatusFilter, updatedAt: UpdatedAtFilter): QuerySKUGroupsConnection @deprecated(reason: \"Use skuGroups instead.\")\n SKUs(after: String, attributeValues: SKUAttributeValueFilter, before: String, createdAt: CreatedAtFilter, first: Int, id: SKUIdsFilter, last: Int, locationId: LocationIdFilter, name: NameFilter, orderBy: SKUOrderBy, paginationType: PaginationType = CURSOR, referenceValue: ReferenceValueFilter, skuGroupId: SKUGroupIdFilter, status: SKUStatusFilter, updatedAt: UpdatedAtFilter): QuerySKUsConnection @deprecated(reason: \"Use skus instead.\")\n _service: _Service!\n attribute(id: String!): Attribute\n attributeValue(id: String!): AttributeValue\n attributeValues(after: String, attributeId: AttributeIdFilter, before: String, createdAt: CreatedAtFilter, first: Int, id: AttributeValueIdsFilter, last: Int, name: NameFilter, orderBy: AttributeValueOrderBy, paginationType: PaginationType = CURSOR, skuId: SKUIdFilter, updatedAt: UpdatedAtFilter): QueryAttributeValuesConnection\n attributes(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: AttributeIdsFilter, last: Int, name: NameFilter, orderBy: AttributeOrderBy, paginationType: PaginationType = CURSOR, skuGroupId: SKUGroupIdFilter, skuGroupStatus: SKUGroupStatusFilter, updatedAt: UpdatedAtFilter): QueryAttributesConnection\n\n \"\"\"\n Special list tree to hold the main categories of the store. It cannot be updated or archived.\n \"\"\"\n categoriesListTree: ListTree\n\n \"\"\"Retrieve a file by its ID.\"\"\"\n file(id: String!): File\n files(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: FileIdsFilter, last: Int, orderBy: FileOrderBy, paginationType: PaginationType = CURSOR, status: FileStatusFilter, storageUrl: FileStorageUrlFilter, updatedAt: UpdatedAtFilter): QueryFilesConnection\n inventoryAdjustment(id: String!): InventoryAdjustment\n\n \"\"\"\n List inventory adjustment reasons available to the current store. Includes both store-scoped and global preset reasons.\n \"\"\"\n inventoryAdjustmentReasons(after: String, before: String, first: Int, last: Int, name: NameFilter, orderBy: InventoryAdjustmentReasonOrderBy, paginationType: PaginationType = CURSOR, status: InventoryAdjustmentReasonStatusFilter): QueryInventoryAdjustmentReasonsConnection\n inventoryAdjustments(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: InventoryAdjustmentIdsFilter, last: Int, locationId: LocationIdFilter, orderBy: InventoryAdjustmentOrderBy, paginationType: PaginationType = CURSOR, reasonName: InventoryAdjustmentReasonNameFilter, referenceValue: ReferenceValueFilter, skuId: SKUIdFilter, type: InventoryAdjustmentTypeFilter): QueryInventoryAdjustmentsConnection\n inventoryCount(locationId: String!, skuId: String!, type: String): [InventoryCount!]\n inventoryCounts(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: InventoryCountIdsFilter, last: Int, locationId: LocationIdFilter, locationStatus: LocationStatusFilter, orderBy: InventoryCountOrderBy, paginationType: PaginationType = CURSOR, skuId: SKUIdFilter, skuStatus: InventoryCountSKUStatusFilter, type: InventoryCountTypeFilter, updatedAt: UpdatedAtFilter): QueryInventoryCountsConnection\n list(id: String!): List\n listTree(id: String!): ListTree\n listTreeNode(id: String!): ListTreeNode\n listTreeNodes(after: String, before: String, createdAt: CreatedAtFilter, first: Int, hasParent: Boolean, id: ListTreeNodeIdsFilter, last: Int, listId: ListIdFilter, listStatus: ListTreeNodeListStatusFilter = {in: [\"ACTIVE\", \"DRAFT\"]}, listTreeId: ListTreeIdFilter, listTreeStatus: ListTreeNodeListTreeStatusFilter, orderBy: ListTreeNodeOrderBy, paginationType: PaginationType = CURSOR, parentNodeId: ListTreeNodeParentNodeIdFilter, referenceValue: ReferenceValueFilter, updatedAt: UpdatedAtFilter): QueryListTreeNodesConnection\n\n \"\"\"List trees. Excludes the special categories list tree.\"\"\"\n listTrees(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: ListTreeIdsFilter, last: Int, name: NameFilter, orderBy: ListTreeOrderBy, paginationType: PaginationType = CURSOR, referenceValue: ReferenceValueFilter, status: ListTreeStatusFilter, updatedAt: UpdatedAtFilter): QueryListTreesConnection\n lists(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: ListIdsFilter, last: Int, name: NameFilter, orderBy: ListOrderBy, paginationType: PaginationType = CURSOR, referenceValue: ReferenceValueFilter, skuGroupId: SKUGroupIdFilter, status: ListStatusFilter, updatedAt: UpdatedAtFilter): QueryListsConnection\n location(id: String!): Location\n locations(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: LocationIdsFilter, last: Int, name: NameFilter, orderBy: LocationOrderBy, paginationType: PaginationType = CURSOR, referenceValue: ReferenceValueFilter, skuId: SKUIdFilter, status: LocationStatusFilter, updatedAt: UpdatedAtFilter): QueryLocationsConnection\n\n \"\"\"Query all option prices.\"\"\"\n optionPrices(\n after: String\n before: String\n\n \"\"\"Filter prices by currency code.\"\"\"\n currencyCode: CurrencyCodeFilter\n first: Int\n id: OptionPriceIdsFilter\n last: Int\n optionId: OptionIdFilter\n orderBy: OptionPriceOrderBy\n paginationType: PaginationType = CURSOR\n updatedAt: UpdatedAtFilter\n ): QueryOptionPricesConnection\n\n \"\"\"Query all option value prices.\"\"\"\n optionValuePrices(\n after: String\n before: String\n\n \"\"\"Filter prices by currency code.\"\"\"\n currencyCode: CurrencyCodeFilter\n first: Int\n id: OptionValuePriceIdsFilter\n last: Int\n optionValueId: OptionValueIdFilter\n orderBy: OptionValuePriceOrderBy\n paginationType: PaginationType = CURSOR\n updatedAt: UpdatedAtFilter\n ): QueryOptionValuePricesConnection\n optionValues(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: OptionValueIdsFilter, last: Int, optionId: OptionIdFilter, orderBy: OptionValueOrderBy, paginationType: PaginationType = CURSOR, updatedAt: UpdatedAtFilter): QueryOptionValuesConnection\n options(\n after: String\n\n \"\"\"\n Returns shareable options that are not already associated with the specified SKU group. Use this to find options that can be added to a SKU group. Cannot be combined with skuGroupId or skuGroupStatus filters.\n \"\"\"\n assignableToSkuGroupId: String\n before: String\n createdAt: CreatedAtFilter\n first: Int\n id: OptionIdsFilter\n\n \"\"\"\n Filter options by their shareable status. When true, returns only shareable options; when false, returns only non-shareable options.\n \"\"\"\n shareable: Boolean\n label: LabelFilter\n last: Int\n name: NameFilter\n orderBy: OptionOrderBy\n paginationType: PaginationType = CURSOR\n skuGroupId: SKUGroupIdFilter\n skuGroupStatus: SKUGroupStatusFilter\n updatedAt: UpdatedAtFilter\n ): QueryOptionsConnection\n sku(id: String!): SKU\n skuGroup(id: String!): SKUGroup\n skuGroups(after: String, before: String, channelId: SKUGroupChannelIdFilter, createdAt: CreatedAtFilter, first: Int, id: SKUGroupIdsFilter, label: LabelFilter, last: Int, listId: ListIdFilter, name: NameFilter, orderBy: SKUGroupOrderBy, paginationType: PaginationType = CURSOR, referenceValue: ReferenceValueFilter, status: SKUGroupStatusFilter, type: SKUGroupTypeFilter, updatedAt: UpdatedAtFilter): QuerySkuGroupsConnection\n\n \"\"\"Query all SKU prices.\"\"\"\n skuPrices(\n after: String\n before: String\n\n \"\"\"Filter prices by currency code.\"\"\"\n currencyCode: CurrencyCodeFilter\n first: Int\n id: SKUPriceIdsFilter\n last: Int\n orderBy: SKUPriceOrderBy\n paginationType: PaginationType = CURSOR\n skuId: SKUIdFilter\n updatedAt: UpdatedAtFilter\n ): QuerySkuPricesConnection\n skus(\n after: String\n attributeValues: SKUAttributeValueFilter\n before: String\n code: SKUCodeFilter\n createdAt: CreatedAtFilter\n eanCode: SKUEanCodeFilter\n first: Int\n gtinCode: SKUGtinCodeFilter\n id: SKUIdsFilter\n isbnCode: SKUIsbnCodeFilter\n label: LabelFilter\n last: Int\n locationId: LocationIdFilter\n name: NameFilter\n orderBy: SKUOrderBy\n paginationType: PaginationType = CURSOR\n\n \"\"\"\n A string filter in the ODATA format. ex: \"label eq 'shirt' and contains(code, '123')\".\n\n\n Supported columns: `label`, `code`\n\n Supported operators: `eq`, `ne`, `lt`, `gt`, `and`, `or`\n\n Supported functions: `contains`\n \"\"\"\n queryFilter: String\n referenceValue: ReferenceValueFilter\n skuGroupId: SKUGroupIdFilter\n\n \"\"\"\n Filter SKUs by their SKU group's status. SKUs without a SKU group will be excluded when this filter is present.\n \"\"\"\n skuGroupStatus: SKUGroupStatusFilter\n status: SKUStatusFilter\n upcCode: SKUUpcCodeFilter\n updatedAt: UpdatedAtFilter\n ): QuerySkusConnection\n}\n\ntype QueryAttributeValuesConnection {\n edges: [QueryAttributeValuesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryAttributeValuesConnectionEdge {\n cursor: String!\n node: AttributeValue\n}\n\ntype QueryAttributesConnection {\n edges: [QueryAttributesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryAttributesConnectionEdge {\n cursor: String!\n node: Attribute\n}\n\ntype QueryFilesConnection {\n edges: [QueryFilesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryFilesConnectionEdge {\n cursor: String!\n node: File\n}\n\ntype QueryInventoryAdjustmentReasonsConnection {\n edges: [QueryInventoryAdjustmentReasonsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryInventoryAdjustmentReasonsConnectionEdge {\n cursor: String!\n node: InventoryAdjustmentReason\n}\n\ntype QueryInventoryAdjustmentsConnection {\n edges: [QueryInventoryAdjustmentsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryInventoryAdjustmentsConnectionEdge {\n cursor: String!\n node: InventoryAdjustment\n}\n\ntype QueryInventoryCountsConnection {\n edges: [QueryInventoryCountsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryInventoryCountsConnectionEdge {\n cursor: String!\n node: InventoryCount\n}\n\ntype QueryListTreeNodesConnection {\n edges: [QueryListTreeNodesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryListTreeNodesConnectionEdge {\n cursor: String!\n node: ListTreeNode\n}\n\ntype QueryListTreesConnection {\n edges: [QueryListTreesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryListTreesConnectionEdge {\n cursor: String!\n node: ListTree\n}\n\ntype QueryListsConnection {\n edges: [QueryListsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryListsConnectionEdge {\n cursor: String!\n node: List\n}\n\ntype QueryLocationsConnection {\n edges: [QueryLocationsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryLocationsConnectionEdge {\n cursor: String!\n node: Location\n}\n\ntype QueryOptionPricesConnection {\n edges: [QueryOptionPricesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryOptionPricesConnectionEdge {\n cursor: String!\n node: OptionPrice\n}\n\ntype QueryOptionValuePricesConnection {\n edges: [QueryOptionValuePricesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryOptionValuePricesConnectionEdge {\n cursor: String!\n node: OptionValuePrice\n}\n\ntype QueryOptionValuesConnection {\n edges: [QueryOptionValuesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryOptionValuesConnectionEdge {\n cursor: String!\n node: OptionValue\n}\n\ntype QueryOptionsConnection {\n edges: [QueryOptionsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryOptionsConnectionEdge {\n cursor: String!\n node: Option\n}\n\ntype QuerySKUGroupsConnection {\n edges: [QuerySKUGroupsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QuerySKUGroupsConnectionEdge {\n cursor: String!\n node: SKUGroup\n}\n\ntype QuerySKUsConnection {\n edges: [QuerySKUsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QuerySKUsConnectionEdge {\n cursor: String!\n node: SKU\n}\n\ntype QuerySkuGroupsConnection {\n edges: [QuerySkuGroupsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QuerySkuGroupsConnectionEdge {\n cursor: String!\n node: SKUGroup\n}\n\ntype QuerySkuPricesConnection {\n edges: [QuerySkuPricesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QuerySkuPricesConnectionEdge {\n cursor: String!\n node: SKUPrice\n}\n\ntype QuerySkusConnection {\n edges: [QuerySkusConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QuerySkusConnectionEdge {\n cursor: String!\n node: SKU\n}\n\n\"\"\"A reference to the resource in an external service.\"\"\"\ntype Reference {\n \"\"\"The globally-unique ID of the reference.\"\"\"\n id: ID\n\n \"\"\"The origin or location of the reference. Ex. OLS or POYNT\"\"\"\n origin: String\n\n \"\"\"The identifier of the resource in an external service\"\"\"\n value: String\n}\n\ninput ReferenceOriginFilter {\n eq: String\n in: [String!]\n}\n\ninput ReferenceValueFilter {\n eq: String\n in: [String!]\n}\n\ninput RemoveMetafieldInput {\n key: String!\n namespace: String!\n}\n\n\"\"\"A SKU represents a stock keeping unit (SKU) in the catalog.\"\"\"\ntype SKU {\n \"\"\"\n HTML description for the SKU. Will be used to display rich text content to customers.\n \"\"\"\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"\n A SKU group is a grouping of related SKUs. It provides information about all the SKUs that are sold together on storefronts or devices.\n \"\"\"\n SKUGroup: SKUGroup @deprecated(reason: \"Use skuGroup instead.\")\n\n \"\"\"The timestamp of when the SKU was archived.\"\"\"\n archivedAt: DateTime\n\n \"\"\"Attribute values of SKU.\"\"\"\n attributeValues(after: String, before: String, first: Int, last: Int, orderBy: AttributeValueOrderBy, paginationType: PaginationType = CURSOR): SKUAttributeValuesConnection\n\n \"\"\"\n Attributes are properties or characteristics of the SKU. For example, color or size.\n \"\"\"\n attributes(after: String, before: String, first: Int, id: AttributeIdsFilter, last: Int, orderBy: AttributeOrderBy, paginationType: PaginationType = CURSOR): SKUAttributesConnection\n\n \"\"\"\n The number of backorders allowed for the SKU. If set to 0, backorders are not allowed. If set to null, backorders are allowed without limit.\n \"\"\"\n backorderLimit: Int\n\n \"\"\"The unique code for the SKU.\"\"\"\n code: String!\n\n \"\"\"DEPRECATED. Use unitCost instead.\"\"\"\n cost: Int @deprecated(reason: \"This cost field cannot specify currency code. Use `unitCost` instead.\")\n\n \"\"\"The timestamp of when the SKU was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The description of the SKU.\"\"\"\n description: String\n\n \"\"\"Flag to mark whether stock should be tracked for the SKU.\"\"\"\n disableInventoryTracking: Boolean\n\n \"\"\"Flag to mark whether or not a custom price can be provided.\"\"\"\n disablePriceOverrides: Boolean\n\n \"\"\"Flag to mark whether the SKU should be shipped or not.\"\"\"\n disableShipping: Boolean\n\n \"\"\"The EAN code for the SKU.\"\"\"\n eanCode: String\n\n \"\"\"The GTIN code for the SKU.\"\"\"\n gtinCode: String\n\n \"\"\"\n HTML description for the SKU. Will be used to display rich text content to customers.\n \"\"\"\n htmlDescription: String\n\n \"\"\"The globally-unique ID of the SKU.\"\"\"\n id: ID!\n\n \"\"\"\n An immutable entity that represents a change in state of a quantity of SKU at a particular time and location. Each adjustment will either have a positive, negative, or neutral impact on the count of available SKUs in a location.\n \"\"\"\n inventoryAdjustments(after: String, before: String, first: Int, last: Int, orderBy: InventoryAdjustmentOrderBy, paginationType: PaginationType = CURSOR): SKUInventoryAdjustmentsConnection\n\n \"\"\"\n The quantity of a SKU in a specific state at a particular time and location.\n \"\"\"\n inventoryCounts(after: String, before: String, first: Int, last: Int, locationId: LocationIdFilter, locationStatus: LocationStatusFilter, orderBy: InventoryCountOrderBy, paginationType: PaginationType = CURSOR, skuStatus: InventoryCountSKUStatusFilter, type: InventoryCountTypeFilter): SKUInventoryCountsConnection\n\n \"\"\"The ISBN code for the SKU.\"\"\"\n isbnCode: String\n\n \"\"\"The display label of the SKU.\"\"\"\n label: String!\n\n \"\"\"The locations where the SKU is available.\"\"\"\n locations(after: String, before: String, first: Int, last: Int, orderBy: LocationOrderBy, paginationType: PaginationType = CURSOR, status: LocationStatusFilter): SKULocationsConnection\n\n \"\"\"Media stored under this SKU.\"\"\"\n mediaObjects(after: String, before: String, first: Int, last: Int, paginationType: PaginationType = CURSOR): SKUMediaObjectsConnection\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): SKUMetafieldsConnection\n\n \"\"\"A unique name for the SKU.\"\"\"\n name: String!\n\n \"\"\"\n These are all the prices the SKU can be sold at. The price can be different based the channel where it is listed or if there is a promotion running.\n \"\"\"\n prices(\n after: String\n before: String\n\n \"\"\"Filter prices by currency code.\"\"\"\n currencyCode: CurrencyCodeFilter\n first: Int\n last: Int\n ): SKUPricesConnection\n\n \"\"\"\n A reference to the resource in an external service. This can be useful for integrating the resource to any external service.\n \"\"\"\n references(after: String, before: String, first: Int, last: Int, origin: ReferenceOriginFilter, paginationType: PaginationType = CURSOR): SKUReferencesConnection\n\n \"\"\"A short label for the SKU, useful for UI with limited space.\"\"\"\n shortLabel: String @deprecated(reason: \"Use channel-specific overrides for short labels.\")\n\n \"\"\"\n A SKU group is a grouping of related SKUs. It provides information about all the SKUs that are sold together on storefronts or devices.\n \"\"\"\n skuGroup: SKUGroup\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n\n \"\"\"\n The cost of the SKU per unit. This is a money object that includes the value and currency code.\n \"\"\"\n unitCost: SimpleMoney\n\n \"\"\"The unit of weight, one of `KG`, `GR`, `LB`, `OZ`.\"\"\"\n unitOfWeight: String\n\n \"\"\"The UPC code for the SKU.\"\"\"\n upcCode: String\n\n \"\"\"The timestamp of when the SKU was updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The weight of the SKU.\"\"\"\n weight: Float\n}\n\ninput SKUAttributeValueFilter {\n has: [String!]\n}\n\ntype SKUAttributeValuesConnection {\n edges: [SKUAttributeValuesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUAttributeValuesConnectionEdge {\n cursor: String!\n node: AttributeValue\n}\n\ntype SKUAttributesConnection {\n edges: [SKUAttributesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUAttributesConnectionEdge {\n cursor: String!\n node: Attribute\n}\n\ninput SKUCodeFilter {\n \"\"\"\n Filters SKUs where the code contains the specified string, case-insensitive.\n \"\"\"\n contains: String\n eq: String\n\n \"\"\"Filters SKUs where the code matches any of the specified codes.\"\"\"\n in: [String!]\n}\n\ninput SKUEanCodeFilter {\n eq: String\n in: [String!]\n}\n\ntype SKUGroup {\n \"\"\"\n HTML description for the SKU group. Will be used to display rich text content to customers.\n \"\"\"\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"A SKU represents a stock keeping unit (SKU) in the catalog.\"\"\"\n SKUs(\n after: String\n attributeValues: SKUAttributeValueFilter\n before: String\n createdAt: CreatedAtFilter\n first: Int\n label: LabelFilter\n last: Int\n locationId: LocationIdFilter\n name: NameFilter\n paginationType: PaginationType = CURSOR\n\n \"\"\"\n A string filter in the ODATA format. ex: \"label eq 'shirt' and contains(code, '123')\".\n\n\n Supported columns: `label`, `code`\n\n Supported operators: `eq`, `ne`, `lt`, `gt`, `and`, `or`\n\n Supported functions: `contains`\n \"\"\"\n queryFilter: String\n referenceValue: ReferenceValueFilter\n status: SKUStatusFilter\n updatedAt: UpdatedAtFilter\n ): SKUGroupSKUsConnection @deprecated(reason: \"Use skus instead.\")\n\n \"\"\"The timestamp of when the SKU was activated.\"\"\"\n activatedAt: DateTime\n\n \"\"\"The timestamp of when the SKU was archived.\"\"\"\n archivedAt: DateTime\n\n \"\"\"Attributes of SKU Group.\"\"\"\n attributes(after: String, before: String, first: Int, id: AttributeIdsFilter, last: Int, orderBy: AttributeOrderBy, paginationType: PaginationType = CURSOR): SKUGroupAttributesConnection\n\n \"\"\"\n The channel association mode for this SKU Group. Can be ALL (uses active channels registered to the store) or\n \t\t\t\tSELECTIVE (uses custom channel associations).\n \"\"\"\n channelAssociationMode: String\n\n \"\"\"An association to a channel that exists in the Channel API.\"\"\"\n channels(after: String, before: String, first: Int, last: Int): SKUGroupChannelsConnection\n\n \"\"\"\n The compare-at price range of the SKU group, showing min and max compare-at prices of SKUs in the group.\n \"\"\"\n compareAtPriceRange(\n \"\"\"\n Filter SKUs by status. Defaults to ACTIVE and DRAFT, excluding ARCHIVED SKUs.\n \"\"\"\n status: SKUStatusFilter = {in: [\"ACTIVE\", \"DRAFT\"]}\n ): PriceRange\n\n \"\"\"The timestamp of when the SKU was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The merchant defined description of the group.\"\"\"\n description: String\n\n \"\"\"\n HTML description for the SKU group. Will be used to display rich text content to customers.\n \"\"\"\n htmlDescription: String\n\n \"\"\"The globally-unique ID of the group.\"\"\"\n id: ID!\n\n \"\"\"The display label of the group.\"\"\"\n label: String!\n\n \"\"\"\n A list is a group of SKU groups that are generally organized by similar characteristics.\n \"\"\"\n lists(after: String, before: String, first: Int, id: ListIdFilter, last: Int, orderBy: ListOrderBy, paginationType: PaginationType = CURSOR, status: ListStatusFilter): SKUGroupListsConnection\n\n \"\"\"Media objects stored under the SKU Group.\"\"\"\n mediaObjects(after: String, before: String, first: Int, last: Int, paginationType: PaginationType = CURSOR): SKUGroupMediaObjectsConnection\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): SKUGroupMetafieldsConnection\n\n \"\"\"A unique human-friendly identifier for the group.\"\"\"\n name: String!\n\n \"\"\"An option is a add-on that can be added on to a SKU group.\"\"\"\n options(after: String, before: String, first: Int, last: Int, orderBy: OptionOrderBy, paginationType: PaginationType = CURSOR): SKUGroupOptionsConnection\n\n \"\"\"\n The price range of the SKU group, showing min and max prices of SKUs in the group.\n \"\"\"\n priceRange(\n \"\"\"\n Filter SKUs by status. Defaults to ACTIVE and DRAFT, excluding ARCHIVED SKUs.\n \"\"\"\n status: SKUStatusFilter = {in: [\"ACTIVE\", \"DRAFT\"]}\n ): PriceRange\n\n \"\"\"\n A reference to the resource in an external service. This can be useful for integrating the resource to any external service.\n \"\"\"\n references(after: String, before: String, first: Int, last: Int, origin: ReferenceOriginFilter, paginationType: PaginationType = CURSOR): SKUGroupReferencesConnection\n\n \"\"\"\n A short label for the group. Can be used instead of the label on smaller screens.\n \"\"\"\n shortLabel: String @deprecated(reason: \"Use channel-specific overrides for short labels.\")\n\n \"\"\"\n The count of all SKUs associated with the SKU Group. Can be filtered by status. The default statuses are ACTIVE and DRAFT.\n \"\"\"\n skuCount(status: SKUStatusFilter = {in: [\"ACTIVE\", \"DRAFT\"]}): Int\n\n \"\"\"A SKU represents a stock keeping unit (SKU) in the catalog.\"\"\"\n skus(\n after: String\n attributeValues: SKUAttributeValueFilter\n before: String\n code: SKUCodeFilter\n createdAt: CreatedAtFilter\n eanCode: SKUEanCodeFilter\n first: Int\n gtinCode: SKUGtinCodeFilter\n isbnCode: SKUIsbnCodeFilter\n label: LabelFilter\n last: Int\n locationId: LocationIdFilter\n name: NameFilter\n orderBy: SKUOrderBy\n paginationType: PaginationType = CURSOR\n\n \"\"\"\n A string filter in the ODATA format. ex: \"label eq 'shirt' and contains(code, '123')\".\n\n\n Supported columns: `label`, `code`\n\n Supported operators: `eq`, `ne`, `lt`, `gt`, `and`, `or`\n\n Supported functions: `contains`\n \"\"\"\n queryFilter: String\n referenceValue: ReferenceValueFilter\n status: SKUStatusFilter\n upcCode: SKUUpcCodeFilter\n updatedAt: UpdatedAtFilter\n ): SKUGroupSkusConnection\n\n \"\"\"The status of the SKU Group, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String!\n\n \"\"\"\n The type of the SKU Group, typically PHYSICAL or DIGITAL, but can also be a custom type.\n \"\"\"\n type: String!\n\n \"\"\"The timestamp of when the SKU was updated.\"\"\"\n updatedAt: DateTime!\n}\n\ntype SKUGroupAttributesConnection {\n edges: [SKUGroupAttributesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupAttributesConnectionEdge {\n cursor: String!\n node: Attribute\n}\n\n\"\"\"\nA SKU Group Channel represents an association with the application by which your SKUs are sold. Can be a platform, marketplace, POS, and more.\n\"\"\"\ntype SKUGroupChannel {\n \"\"\"The globally-unique ID of the channel.\"\"\"\n channelId: ID!\n\n \"\"\"The timestamp of when the channel association was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the channel association.\"\"\"\n id: ID!\n\n \"\"\"The status of the channel association. One of `ACTIVE`, `INACTIVE`\"\"\"\n status: String!\n\n \"\"\"The timestamp of when the channel association was updated.\"\"\"\n updatedAt: DateTime!\n}\n\ninput SKUGroupChannelAddInput {\n channelId: String!\n}\n\ninput SKUGroupChannelIdFilter {\n eq: String\n in: [String!]\n}\n\ntype SKUGroupChannelsConnection {\n edges: [SKUGroupChannelsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupChannelsConnectionEdge {\n cursor: String!\n node: SKUGroupChannel\n}\n\ninput SKUGroupIdFilter {\n eq: String\n in: [String!]\n}\n\ninput SKUGroupIdsFilter {\n eq: String\n in: [String!]\n}\n\ntype SKUGroupListsConnection {\n edges: [SKUGroupListsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupListsConnectionEdge {\n cursor: String!\n node: List\n}\n\ntype SKUGroupMediaObjectsConnection {\n edges: [SKUGroupMediaObjectsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupMediaObjectsConnectionEdge {\n cursor: String!\n node: Media\n}\n\ntype SKUGroupMetafieldsConnection {\n edges: [SKUGroupMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ntype SKUGroupOptionsConnection {\n edges: [SKUGroupOptionsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupOptionsConnectionEdge {\n cursor: String!\n node: Option\n}\n\ninput SKUGroupOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n label: OrderByDirectionEnum\n lowestPrice: OrderByDirectionEnum\n name: OrderByDirectionEnum\n saleCount: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\ntype SKUGroupReferencesConnection {\n edges: [SKUGroupReferencesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupReferencesConnectionEdge {\n cursor: String!\n node: Reference\n}\n\ntype SKUGroupSKUsConnection {\n edges: [SKUGroupSKUsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupSKUsConnectionEdge {\n cursor: String!\n node: SKU\n}\n\ntype SKUGroupSkusConnection {\n edges: [SKUGroupSkusConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupSkusConnectionEdge {\n cursor: String!\n node: SKU\n}\n\n\"\"\"\nFilter for the status of the SKU Group, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\n\"\"\"\ninput SKUGroupStatusFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"\nFilter for the type of the SKU Group, typically PHYSICAL or DIGITAL, but can also be a custom type.\n\"\"\"\ninput SKUGroupTypeFilter {\n eq: String\n in: [String!]\n}\n\ninput SKUGtinCodeFilter {\n eq: String\n in: [String!]\n}\n\ninput SKUIdFilter {\n eq: String\n in: [String!]\n}\n\ninput SKUIdsFilter {\n in: [String!]\n}\n\ntype SKUInventoryAdjustmentsConnection {\n edges: [SKUInventoryAdjustmentsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUInventoryAdjustmentsConnectionEdge {\n cursor: String!\n node: InventoryAdjustment\n}\n\ntype SKUInventoryCountsConnection {\n edges: [SKUInventoryCountsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUInventoryCountsConnectionEdge {\n cursor: String!\n node: InventoryCount\n}\n\ninput SKUIsbnCodeFilter {\n eq: String\n in: [String!]\n}\n\ntype SKULocationsConnection {\n edges: [SKULocationsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKULocationsConnectionEdge {\n cursor: String!\n node: Location\n}\n\ntype SKUMediaObjectsConnection {\n edges: [SKUMediaObjectsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUMediaObjectsConnectionEdge {\n cursor: String!\n node: Media\n}\n\ntype SKUMetafieldsConnection {\n edges: [SKUMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ninput SKUOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n label: OrderByDirectionEnum\n name: OrderByDirectionEnum\n price: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\n\"\"\"Represents the cost of a SKU\"\"\"\ntype SKUPrice {\n \"\"\"A SKU represents a stock keeping unit (SKU) in the catalog.\"\"\"\n SKU: SKU @deprecated(reason: \"Use sku instead.\")\n\n \"\"\"The compare-at value of the price.\"\"\"\n compareAtValue: SimpleMoney\n\n \"\"\"The timestamp of when the price was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the price.\"\"\"\n id: ID!\n\n \"\"\"A SKU represents a stock keeping unit (SKU) in the catalog.\"\"\"\n sku: SKU\n\n \"\"\"The last update timestamp of the price.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The value of the price.\"\"\"\n value: SimpleMoney!\n}\n\ninput SKUPriceIdsFilter {\n in: [String!]\n}\n\ninput SKUPriceOrderBy {\n id: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\ntype SKUPricesConnection {\n edges: [SKUPricesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUPricesConnectionEdge {\n cursor: String!\n node: SKUPrice\n}\n\ntype SKUReferencesConnection {\n edges: [SKUReferencesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUReferencesConnectionEdge {\n cursor: String!\n node: Reference\n}\n\n\"\"\"\nFilter for the status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\n\"\"\"\ninput SKUStatusFilter {\n eq: String\n in: [String!]\n}\n\ninput SKUUpcCodeFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"\nThe currency and amount for a financial transaction, such as a balance or payment due. Use for value representations with default transactable-value precision.\n\"\"\"\ntype SimpleMoney {\n \"\"\"A three-character ISO-4217 currency code.\"\"\"\n currencyCode: String!\n\n \"\"\"\n The integer value, which might be: An integer for currencies like JPY that are not typically fractional; or, a decimal fraction for currencies that are subdivided into hundredths, like USD; or, subdivided into thousandths, like TND. For the required number of decimal places for a currency code, see ISO-4217 Currency Codes. This field is typed as Float to be able to support values larger than GraphQL's 32-bit Integer.\n \"\"\"\n value: Float!\n}\n\n\"\"\"\nThe currency and amount for a financial transaction, such as a balance or payment due. Use for value representations with default transactable-value precision.\n\"\"\"\ninput SimpleMoneyInput {\n currencyCode: String!\n\n \"\"\"\n The integer value, which might represent intergrals for currencies like `JPY` that are not typically fractional; or, with an implied decimal fraction for currencies that are subdivided into hundredths, like USD; or, subdivided into thousandths, like TND. Only accepts integer value. Decimals are not accepted. This input is typed as Float to be able to support values larger than GraphQL's 32-bit Integer.\n \"\"\"\n value: Float!\n}\n\ntype TextOption {\n \"\"\"\n HTML description for the Option. Will be used to display rich text content to customers.\n \"\"\"\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"The timestamp of when the Option was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"A description of the Option.\"\"\"\n description: String\n\n \"\"\"\n HTML description for the Option. Will be used to display rich text content to customers.\n \"\"\"\n htmlDescription: String\n\n \"\"\"The UUID of the Option\"\"\"\n id: ID!\n\n \"\"\"\n Whether the option is shareable across multiple SKU Groups (a global modifier).\n \"\"\"\n shareable: Boolean!\n\n \"\"\"The display lable of the Option\"\"\"\n label: String!\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): OptionMetafieldsConnection\n\n \"\"\"A unique name of the Option.\"\"\"\n name: String!\n\n \"\"\"The position of the option.\"\"\"\n position: Int\n\n \"\"\"\n Represents the additional cost of a Text Option. When empty, it indicates this option allows for flexible pricing.\n \"\"\"\n prices(\n after: String\n before: String\n\n \"\"\"Filter prices by currency code.\"\"\"\n currencyCode: CurrencyCodeFilter\n first: Int\n last: Int\n paginationType: PaginationType = CURSOR\n ): TextOptionPricesConnection\n\n \"\"\"The UUID of the SKU Group that the Option belongs to.\"\"\"\n skuGroupId: ID! @deprecated(reason: \"Use skuGroupIds or the SKUGroup.options connection instead. An option may belong to multiple SKU groups.\")\n\n \"\"\"The IDs of all SKU groups this option is associated with.\"\"\"\n skuGroupIds: [String!]!\n\n \"\"\"\n The type of the option, one of `TEXT`, `NUMBER`, `LIST`, Option Values are available for the 'LIST' type.\n \"\"\"\n type: String\n\n \"\"\"The timestamp of when the Option was updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"\n Provide validations on how the option can be applied to a SKU. If `TEXT` option then `min` and `max` apply to the number of characters. If `NUMBER` then `min` and `max` apply to the actual number value. If `LIST` then `min` and `max` apply to the number of values that can be selected.\n \"\"\"\n validation: OptionValidation\n}\n\ntype TextOptionPricesConnection {\n edges: [TextOptionPricesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype TextOptionPricesConnectionEdge {\n cursor: String!\n node: OptionPrice\n}\n\ninput UpdateAddressInput {\n addressDetails: AddressDetailsInput\n addressLine1: String\n addressLine2: String\n addressLine3: String\n adminArea1: String\n adminArea2: String\n adminArea3: String\n adminArea4: String\n countryCode: String\n postalCode: String\n}\n\n\"\"\"Input for updating an existing file.\"\"\"\ninput UpdateFileInput {\n contentType: String\n description: String\n filename: String\n}\n\ninput UpdateMediaObjectInput {\n id: String!\n label: String\n metafields: [UpsertMetafieldInput!]\n name: String\n position: Int\n\n \"\"\"The type of the media, one of `PHOTO`, `VIDEO`, `IMAGE`, `AUDIO`.\"\"\"\n type: String\n url: String\n}\n\n\"\"\"A single option and its new position within a SKU group.\"\"\"\ninput UpdateSKUGroupOptionPositionInput {\n optionId: String!\n position: Int!\n}\n\n\"\"\"Filters items based on the date they were last updated.\"\"\"\ninput UpdatedAtFilter {\n gt: String\n lt: String\n}\n\ninput UpsertMetafieldInput {\n key: String!\n namespace: String!\n type: String!\n value: String!\n}\n\ntype _Service {\n \"\"\"\n The sdl representing the federated service capabilities. Includes federation directives, removes federation types, and includes rest of full schema after schema directives have been applied\n \"\"\"\n sdl: String\n}", + "sdl": "extend schema\n @link(url: \"https://specs.apollo.dev/federation/v2.6\", import: [])\n\ninput AddListTreeNodeInput {\n listId: String!\n parentNodeId: String\n position: Int\n references: [CreateReferenceInput!]\n}\n\ntype Address {\n \"\"\"The details of the address.\"\"\"\n addressDetails: AddressDetails\n\n \"\"\"The first line of the address.\"\"\"\n addressLine1: String!\n\n \"\"\"The second line of the address.\"\"\"\n addressLine2: String\n\n \"\"\"The third line of the address.\"\"\"\n addressLine3: String\n\n \"\"\"The first administrative area of the address.\"\"\"\n adminArea1: String\n\n \"\"\"The second administrative area of the address.\"\"\"\n adminArea2: String\n\n \"\"\"The third administrative area of the address.\"\"\"\n adminArea3: String\n\n \"\"\"The fourth administrative area of the address.\"\"\"\n adminArea4: String\n\n \"\"\"The country code of the address.\"\"\"\n countryCode: String!\n\n \"\"\"The postal code of the address.\"\"\"\n postalCode: String\n}\n\ntype AddressDetails {\n \"\"\"\n The type of address. Single character representation of a type. For example: 'B' for building, 'F' for organization, 'G' for general delivery, 'H' for high-rise, 'L' for large-volume organization, 'P' for Post Office box or delivery service, 'R' for rural route, 'S' for street, 'U' for unidentified address.\n \"\"\"\n addressType: String\n\n \"\"\"\n A named locations that represents the premise. Usually a building name or number or collection of buildings with a common name or number.\n \"\"\"\n buildingName: String\n\n \"\"\"The delivery service. Post office box, bag number, or post office name\"\"\"\n deliveryService: String\n\n \"\"\"The latitude and longitude of the address.\"\"\"\n geoCoordinates: GeoCoordinates\n\n \"\"\"The street name. Just `Drury` in `Drury Lane`.\"\"\"\n streetName: String\n\n \"\"\"The street number.\"\"\"\n streetNumber: String\n\n \"\"\"The street type. For example, avenue, boulevard, road, or expressway.\"\"\"\n streetType: String\n\n \"\"\"\n The first-order entity below a named building or location that represents the sub-premise. Usually a single building within a collection of buildings with a common name. Can be a flat, story, floor, room, or apartment.\n \"\"\"\n subBuilding: String\n}\n\ninput AddressDetailsInput {\n addressType: String\n buildingName: String\n deliveryService: String\n geoCoordinates: GeoCoordinatesInput\n streetName: String\n streetNumber: String\n streetType: String\n subBuilding: String\n}\n\ninput AssociateAttributeValueInput {\n label: String!\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n position: Int\n}\n\ninput AssociateAttributeValueToSKUInput {\n attributeName: String!\n valueName: String!\n}\n\n\"\"\"A SKU is comprised of a combination of multiple attributes\"\"\"\ntype Attribute {\n \"\"\"\n HTML description for the Attribute. Will be used to display rich text content to customers.\n \"\"\"\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"\n A SKU group is a grouping of related SKUs. It provides information about all the SKUs that are sold together on storefronts or devices.\n \"\"\"\n SKUGroup: SKUGroup @deprecated(reason: \"Use skuGroup instead.\")\n\n \"\"\"The creation date of the Attribute.\"\"\"\n createdAt: DateTime!\n\n \"\"\"A description of the Attribute.\"\"\"\n description: String\n\n \"\"\"\n HTML description for the Attribute. Will be used to display rich text content to customers.\n \"\"\"\n htmlDescription: String\n\n \"\"\"The UUID of the Attribute.\"\"\"\n id: ID!\n\n \"\"\"The display label of the Attribute. E.g. 'Color', 'Size', etc.\"\"\"\n label: String!\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): AttributeMetafieldsConnection\n\n \"\"\"A unique name of the Attribute. E.g. 'color', 'size', etc.\"\"\"\n name: String!\n\n \"\"\"The position of the attribute.\"\"\"\n position: Int\n\n \"\"\"\n A SKU group is a grouping of related SKUs. It provides information about all the SKUs that are sold together on storefronts or devices.\n \"\"\"\n skuGroup: SKUGroup\n\n \"\"\"The update date of the Attribute.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"Attribute values of Attribute.\"\"\"\n values(after: String, before: String, first: Int, id: AttributeValueIdsFilter, last: Int, orderBy: AttributeValueOrderBy, paginationType: PaginationType = CURSOR, skuId: SKUIdFilter): AttributeValuesConnection\n}\n\ninput AttributeIdFilter {\n eq: String\n in: [String!]\n}\n\ninput AttributeIdsFilter {\n in: [String!]\n}\n\ntype AttributeMetafieldsConnection {\n edges: [AttributeMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype AttributeMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ninput AttributeOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n label: OrderByDirectionEnum\n name: OrderByDirectionEnum\n position: OrderByDirectionEnum\n skuGroupId: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\n\"\"\"Value for an Attribute.\"\"\"\ntype AttributeValue {\n \"\"\"The attribute that this value belongs to.\"\"\"\n attribute: Attribute\n\n \"\"\"The creation date of the Attribute Value.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The UUID of the Attribute Value.\"\"\"\n id: ID!\n\n \"\"\"The display label of the Attribute Value. E.g. 'Red', 'Blue', etc.\"\"\"\n label: String!\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): AttributeValueMetafieldsConnection\n\n \"\"\"A unique name of the Attribute Value. E.g. 'red', 'blue', etc.\"\"\"\n name: String!\n\n \"\"\"The position of the attribute value.\"\"\"\n position: Int\n\n \"\"\"The last update date of the Attribute Value.\"\"\"\n updatedAt: DateTime!\n}\n\ninput AttributeValueIdsFilter {\n in: [String!]\n}\n\ntype AttributeValueMetafieldsConnection {\n edges: [AttributeValueMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype AttributeValueMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ninput AttributeValueOrderBy {\n attributeId: OrderByDirectionEnum\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n name: OrderByDirectionEnum\n position: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\ntype AttributeValuesConnection {\n edges: [AttributeValuesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype AttributeValuesConnectionEdge {\n cursor: String!\n node: AttributeValue\n}\n\n\"\"\"Configuration for cascade archiving related entities.\"\"\"\ninput CascadeArchiveInput {\n \"\"\"Whether to cascade archive SKUs when archiving the SKU Group.\"\"\"\n skus: Boolean\n}\n\ninput CreateAddressInput {\n addressDetails: AddressDetailsInput\n addressLine1: String!\n addressLine2: String\n addressLine3: String\n adminArea1: String\n adminArea2: String\n adminArea3: String\n adminArea4: String\n countryCode: String!\n postalCode: String\n}\n\ninput CreateAttributeValueInput {\n attributeId: String!\n label: String!\n metafields: [CreateMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n position: Int\n}\n\n\"\"\"Input for creating a new file.\"\"\"\ninput CreateFileInput {\n contentType: String!\n description: String\n filename: String!\n sizeBytes: Float!\n storageUrl: String!\n}\n\ninput CreateInventoryAdjustmentInput {\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n\n \"\"\"\n The change in inventory quantity. Positive for additions, negative for removals.\n \"\"\"\n delta: Int!\n locationId: String!\n metafields: [CreateMetafieldInput!]\n\n \"\"\"The date and time when the inventory adjustment occurred.\"\"\"\n occurredAt: DateTime\n\n \"\"\"\n The name of an inventory adjustment reason to associate with this adjustment. Use the exact reason name (e.g. \"g-damage\" for global presets, or a store-scoped name).\n \"\"\"\n reasonName: String\n references: [CreateReferenceInput!]\n skuId: String!\n\n \"\"\"\n The type of inventory adjustment, one of `AVAILABLE`, `COMMITTED`, `BACKORDERED`.\n \"\"\"\n type: String!\n}\n\ninput CreateListTreeNodeInput {\n listId: String!\n position: Int\n references: [CreateReferenceInput!]\n}\n\ninput CreateMediaObjectInput {\n label: String\n metafields: [CreateMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n position: Int\n\n \"\"\"\n The type of the media. Currently accepted values on write: `VIDEO`, `IMAGE`, `AUDIO`. `PHOTO` is not accepted on create or update.\n \"\"\"\n type: String!\n url: String!\n}\n\ninput CreateMetafieldInput {\n key: String!\n namespace: String!\n\n \"\"\"\n Metafield type. Currently accepted values (lowercase): `boolean`, `string`, `stringMultiLine`, `number`, `numberDecimal`, `date`, `dateTime`, `json`, `measurement`, `url`, `reference`, `money`, `list.string`, `list.number`, `list.numberDecimal`, `list.measurement`, `list.date`, `list.url`.\n \"\"\"\n type: String!\n value: String!\n}\n\ninput CreateOptionInput {\n description: String\n label: String!\n metafields: [CreateMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n position: Int\n prices: [CreateOptionPriceInput!]\n\n \"\"\"\n The type of the Option, one of `TEXT`, `NUMBER`, `LIST`. Option Values are only available on the 'LIST' type.\n \"\"\"\n type: String!\n validation: CreateOptionValidationInput\n values: [CreateOptionValueInput!]\n}\n\ninput CreateOptionPriceInput {\n compareAtValue: SimpleMoneyInput\n value: SimpleMoneyInput!\n}\n\ninput CreateOptionValidationInput {\n max: Int\n min: Int\n}\n\ninput CreateOptionValueInput {\n label: String!\n metafields: [CreateMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n position: Int\n prices: [CreateOptionValuePriceInput!]\n}\n\ninput CreateOptionValuePriceInput {\n compareAtValue: SimpleMoneyInput\n value: SimpleMoneyInput!\n}\n\ninput CreateReferenceInput {\n origin: String!\n value: String!\n}\n\ninput CreateSKUGroupAttributeInput {\n description: String\n label: String!\n metafields: [CreateMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n position: Int\n values: [AssociateAttributeValueInput!]\n}\n\ninput CreateSKUGroupSKUInput {\n backorderLimit: Int\n code: String\n\n \"\"\"DEPRECATED. Use unitCost instead.\"\"\"\n cost: Int @deprecated(reason: \"This cost field cannot specify currency code. Use `unitCost` instead.\")\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n disableInventoryTracking: Boolean\n disablePriceOverrides: Boolean\n disableShipping: Boolean\n eanCode: String\n gtinCode: String\n htmlDescription: String\n inventoryQuantities: [CreateSKUInventoryInput!]\n isbnCode: String\n label: String!\n mediaObjects: [CreateMediaObjectInput!]\n metafields: [CreateMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n prices: [CreateSKUPriceInput!]\n references: [CreateReferenceInput!]\n shortLabel: String\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n unitCost: SimpleMoneyInput\n\n \"\"\"The unit of the weight, one of `KG`, `GR`, `LB`, `OZ`.\"\"\"\n unitOfWeight: String\n upcCode: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n weight: Float\n}\n\ninput CreateSKUInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n attributeValueIds: [String!]\n attributeValues: [AssociateAttributeValueToSKUInput!]\n backorderLimit: Int\n code: String\n\n \"\"\"DEPRECATED. Use unitCost instead.\"\"\"\n cost: Int @deprecated(reason: \"This cost field cannot specify currency code. Use `unitCost` instead.\")\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n disableInventoryTracking: Boolean\n disablePriceOverrides: Boolean\n disableShipping: Boolean\n eanCode: String\n gtinCode: String\n htmlDescription: String\n inventoryQuantities: [CreateSKUInventoryInput!]\n isbnCode: String\n label: String!\n mediaObjects: [CreateMediaObjectInput!]\n metafields: [CreateMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n prices: [CreateSKUPriceInput!]\n references: [CreateReferenceInput!]\n shortLabel: String\n skuGroupId: String\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n unitCost: SimpleMoneyInput\n\n \"\"\"The status of the SKU, one of `KG`, `GR`, `LB`, `OZ`.\"\"\"\n unitOfWeight: String\n upcCode: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n weight: Float\n}\n\ninput CreateSKUInventoryInput {\n locationId: String!\n quantity: Int!\n}\n\ninput CreateSKUPriceInput {\n compareAtValue: SimpleMoneyInput\n value: SimpleMoneyInput!\n}\n\n\"\"\"Filters items based on the date they were created.\"\"\"\ninput CreatedAtFilter {\n gt: String\n lt: String\n}\n\n\"\"\"\nFilters items by currency code. Can be used to filter for an exact match or for multiple values.\n\"\"\"\ninput CurrencyCodeFilter {\n \"\"\"\n Filters items where the currency code equals the specified 3-letter ISO currency code.\n \"\"\"\n eq: String\n\n \"\"\"\n Filters items where the currency code matches any of the specified 3-letter ISO currency codes.\n \"\"\"\n in: [String!]\n}\n\n\"\"\"\nA date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.\n\"\"\"\nscalar DateTime\n\n\"\"\"\nA file represents a stored digital asset such as an image, document, or downloadable content.\n\"\"\"\ntype File {\n \"\"\"The MIME type of the file.\"\"\"\n contentType: String!\n\n \"\"\"The timestamp when the file was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"An optional description of the file.\"\"\"\n description: String\n\n \"\"\"The name of the file including extension.\"\"\"\n filename: String!\n\n \"\"\"The globally unique identifier of the file.\"\"\"\n id: ID!\n\n \"\"\"\n The size of the file in bytes. Typed as Float to support files larger than 2GB.\n \"\"\"\n sizeBytes: Float!\n\n \"\"\"The current status of the file.\"\"\"\n status: FileStatus!\n\n \"\"\"The URL where the file is stored.\"\"\"\n storageUrl: String!\n\n \"\"\"The timestamp when the file was last updated.\"\"\"\n updatedAt: DateTime!\n}\n\ninput FileIdsFilter {\n in: [String!]\n}\n\ninput FileOrderBy {\n createdAt: OrderByDirectionEnum\n filename: OrderByDirectionEnum\n id: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\n\"\"\"The status of a file.\"\"\"\nenum FileStatus {\n ACTIVE\n ARCHIVED\n}\n\n\"\"\"Filter for the status of the File, one of `ACTIVE`, `ARCHIVED`.\"\"\"\ninput FileStatusFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"Filter for the storage URL of the File.\"\"\"\ninput FileStorageUrlFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"The geographic latitude and longitude coordinates.\"\"\"\ntype GeoCoordinates {\n \"\"\"The latitude of the geo coordinates.\"\"\"\n latitude: Float!\n\n \"\"\"The longitude of the geo coordinates.\"\"\"\n longitude: Float!\n}\n\ninput GeoCoordinatesInput {\n latitude: Float\n longitude: Float\n}\n\n\"\"\"\nFilters items based on whether they have a compareAtValue (on sale) in the requested currency. A compareAtValue > 0 is considered a valid sale price; zero or negative values are treated as not on sale.\n\"\"\"\ninput HasCompareAtFilter {\n \"\"\"The three-letter currency code of prices to match.\"\"\"\n currencyCode: String!\n\n \"\"\"\n When true, returns items with at least one price that has a compareAtValue > 0 (on sale) in the requested currency. When false, returns items that have at least one price in the requested currency but none with a compareAtValue > 0 (available at regular price in that currency).\n \"\"\"\n exists: Boolean!\n}\n\n\"\"\"\nAn immutable entity that represents a change in state of a quantity of SKU at a particular time and location.\n\"\"\"\ntype InventoryAdjustment {\n \"\"\"The SKU associated with the Inventory Adjustment.\"\"\"\n SKU: SKU @deprecated(reason: \"Use sku instead.\")\n\n \"\"\"The creation date of the inventory adjustment.\"\"\"\n createdAt: DateTime\n\n \"\"\"The change in quantity of a SKU at a location.\"\"\"\n delta: Int\n\n \"\"\"The globally-unique ID of the inventory adjustment object.\"\"\"\n id: ID\n\n \"\"\"The Location associated with the Inventory Adjustment.\"\"\"\n location: Location\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): InventoryAdjustmentMetafieldsConnection\n\n \"\"\"The date when the inventory adjustment occurred.\"\"\"\n occurredAt: DateTime\n\n \"\"\"The reason associated with this inventory adjustment.\"\"\"\n reason: InventoryAdjustmentReason\n\n \"\"\"\n A reference to the resource in an external service. This can be useful for integrating the resource to any external service.\n \"\"\"\n references(after: String, before: String, first: Int, last: Int, origin: ReferenceOriginFilter, paginationType: PaginationType = CURSOR): InventoryAdjustmentReferencesConnection\n\n \"\"\"The SKU associated with the Inventory Adjustment.\"\"\"\n sku: SKU\n\n \"\"\"\n The adjustment type of the inventory being adjusted, one of `AVAILABLE`, `COMMITTED`, `BACKORDERED`.\n \"\"\"\n type: String!\n}\n\ninput InventoryAdjustmentIdsFilter {\n in: [String!]\n}\n\ntype InventoryAdjustmentMetafieldsConnection {\n edges: [InventoryAdjustmentMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype InventoryAdjustmentMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ninput InventoryAdjustmentOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n}\n\n\"\"\"\nA reason that can be associated with an inventory adjustment to explain why it occurred. Global preset reasons are prefixed with \"g-\" (e.g. g-damage, g-shrinkage). Store-scoped reasons use plain kebab-case names.\n\"\"\"\ntype InventoryAdjustmentReason {\n \"\"\"The date the reason was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the inventory adjustment reason.\"\"\"\n id: ID!\n\n \"\"\"\n Whether this is a global preset reason. Global reasons are shared across all stores and cannot be modified or archived.\n \"\"\"\n isGlobal: Boolean!\n\n \"\"\"The human-readable display label of the reason.\"\"\"\n label: String!\n\n \"\"\"\n The unique kebab-case name of the reason. Global preset names are prefixed with \"g-\" (e.g. g-damage). Store-scoped names must not use the \"g-\" prefix.\n \"\"\"\n name: String!\n\n \"\"\"The status of the reason, one of ACTIVE, ARCHIVED.\"\"\"\n status: String!\n\n \"\"\"The date the reason was last updated.\"\"\"\n updatedAt: DateTime!\n}\n\n\"\"\"Filters inventory adjustment reasons by name.\"\"\"\ninput InventoryAdjustmentReasonNameFilter {\n eq: String\n in: [String!]\n}\n\ninput InventoryAdjustmentReasonOrderBy {\n id: OrderByDirectionEnum\n}\n\n\"\"\"\nFilter for the status of the Inventory Adjustment Reason, one of `ACTIVE`, `ARCHIVED`.\n\"\"\"\ninput InventoryAdjustmentReasonStatusFilter {\n eq: String\n in: [String!]\n}\n\ntype InventoryAdjustmentReferencesConnection {\n edges: [InventoryAdjustmentReferencesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype InventoryAdjustmentReferencesConnectionEdge {\n cursor: String!\n node: Reference\n}\n\n\"\"\"\nFilter for the type of inventory adjustment, one of `AVAILABLE`, `COMMITTED`, `BACKORDERED`.\n\"\"\"\ninput InventoryAdjustmentTypeFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"\nRepresents the quantity of a SKU in a specific state at a particular time and location.\n\"\"\"\ntype InventoryCount {\n \"\"\"The SKU associated with the Inventory Count.\"\"\"\n SKU: SKU @deprecated(reason: \"Use sku instead.\")\n\n \"\"\"The timestamp of when the inventory count was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the inventory count object.\"\"\"\n id: ID!\n\n \"\"\"The Location associated with the Inventory Count.\"\"\"\n location: Location\n\n \"\"\"\n The on-hand inventory count (available + committed) for this SKU and location.\n \"\"\"\n onHand: Int\n\n \"\"\"The count of the inventory.\"\"\"\n quantity: Int\n\n \"\"\"The SKU associated with the Inventory Count.\"\"\"\n sku: SKU\n\n \"\"\"\n The type of inventory count, one of `AVAILABLE`, `COMMITTED`, `BACKORDERED`.\n \"\"\"\n type: String!\n\n \"\"\"The timestamp of when the inventory count was updated.\"\"\"\n updatedAt: DateTime!\n}\n\ninput InventoryCountIdsFilter {\n in: [String!]\n}\n\ninput InventoryCountOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\n\"\"\"\nFilter inventory counts by the status of the associated SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\n\"\"\"\ninput InventoryCountSKUStatusFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"\nFilter for the type of inventory count, one of `AVAILABLE`, `COMMITTED`, `BACKORDERED`.\n\"\"\"\ninput InventoryCountTypeFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"\nFilters items by label. Can be used to either filter for an exact match or for a partial match.\n\"\"\"\ninput LabelFilter {\n \"\"\"\n Filters items where the label contains the specified string, case-insensitive.\n \"\"\"\n contains: String\n eq: String\n}\n\n\"\"\"\nA list is a group of SKU groups that are generally organized by similar characteristics.\n\"\"\"\ntype List {\n \"\"\"\n HTML description for the List. Will be used to display rich text content to customers.\n \"\"\"\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"\n A SKU Group is a grouping of related SKUs. It provides information about all of the SKUs that are sold together on storefronts or devices.\n \"\"\"\n SKUGroups(after: String, before: String, first: Int, last: Int, paginationType: PaginationType = CURSOR): ListSKUGroupsConnection @deprecated(reason: \"Use skuGroups instead.\")\n\n \"\"\"The date and time of when the List was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"A single-line textual description of the List.\"\"\"\n description: String\n\n \"\"\"\n HTML description for the List. Will be used to display rich text content to customers.\n \"\"\"\n htmlDescription: String\n\n \"\"\"The globally-unique ID of the List.\"\"\"\n id: ID!\n\n \"\"\"The display label of the List.\"\"\"\n label: String!\n\n \"\"\"Media can be images, videos, or files\"\"\"\n mediaObjects(after: String, before: String, first: Int, last: Int, paginationType: PaginationType = CURSOR): ListMediaObjectsConnection\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): ListMetafieldsConnection\n\n \"\"\"A unique name for the List.\"\"\"\n name: String!\n\n \"\"\"\n A reference to the resource in an external service. This can be useful for integrating the resource to any external service.\n \"\"\"\n references(after: String, before: String, first: Int, last: Int, origin: ReferenceOriginFilter, paginationType: PaginationType = CURSOR): ListReferencesConnection\n\n \"\"\"\n A SKU Group is a grouping of related SKUs. It provides information about all of the SKUs that are sold together on storefronts or devices.\n \"\"\"\n skuGroups(after: String, before: String, first: Int, hasCompareAt: HasCompareAtFilter, last: Int, orderBy: SKUGroupOrderBy, paginationType: PaginationType = CURSOR, priceRange: PriceRangeFilter, status: SKUGroupStatusFilter): ListSkuGroupsConnection\n\n \"\"\"The status of the list, one of `ACTIVE`, `DRAFT`, `ARCHIVED`.\"\"\"\n status: String\n\n \"\"\"The date and time of when the List was updated.\"\"\"\n updatedAt: DateTime!\n}\n\ninput ListIdFilter {\n eq: String\n in: [String!]\n isNull: Boolean\n ne: String\n}\n\ninput ListIdsFilter {\n in: [String!]\n}\n\ntype ListMediaObjectsConnection {\n edges: [ListMediaObjectsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListMediaObjectsConnectionEdge {\n cursor: String!\n node: Media\n}\n\ntype ListMetafieldsConnection {\n edges: [ListMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ntype ListOption {\n \"\"\"\n The `compareAt` price range of the option, tracks the min and max `compareAt` price of all the option values under this option.\n \"\"\"\n compareAtPriceRange: PriceRange\n\n \"\"\"The timestamp of when the Option was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"A description of the Option.\"\"\"\n description: String\n\n \"\"\"The UUID of the Option\"\"\"\n id: ID!\n\n \"\"\"The display label of the Option\"\"\"\n label: String!\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): OptionMetafieldsConnection\n\n \"\"\"A unique name of the Option.\"\"\"\n name: String!\n\n \"\"\"The position of the option within its SKU group.\"\"\"\n position: Int @deprecated(reason: \"Use the position from the SKUGroup.options connection instead. Position is per-SKU-group relationship.\")\n\n \"\"\"\n The price range of the option, tracks the min and max price of all the option values under this option.\n \"\"\"\n priceRange: PriceRange\n\n \"\"\"\n Represents the additional cost of a List Option. When empty, it indicates this option allows for flexible pricing.\n \"\"\"\n prices(\n after: String\n before: String\n\n \"\"\"Filter prices by currency code.\"\"\"\n currencyCode: CurrencyCodeFilter\n first: Int\n last: Int\n paginationType: PaginationType = CURSOR\n ): ListOptionPricesConnection\n\n \"\"\"\n Whether the option is shareable across multiple SKU Groups (a global modifier).\n \"\"\"\n shareable: Boolean!\n\n \"\"\"The UUID of the SKU Group that the Option belongs to.\"\"\"\n skuGroupId: ID! @deprecated(reason: \"Use skuGroupIds or the SKUGroup.options connection instead. An option may belong to multiple SKU groups.\")\n\n \"\"\"The IDs of all SKU groups this option is associated with.\"\"\"\n skuGroupIds: [String!]!\n\n \"\"\"\n The type of the option, one of `TEXT`, `NUMBER`, `LIST`, Option Values are available for the 'LIST' type.\n \"\"\"\n type: String\n\n \"\"\"The timestamp of when the Option was updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"\n Provide validations on how the option can be applied to a SKU. If `TEXT` option then `min` and `max` apply to the number of characters. If `NUMBER` then `min` and `max` apply to the actual number value. If `LIST` then `min` and `max` apply to the number of values that can be selected.\n \"\"\"\n validation: OptionValidation\n\n \"\"\"\n Represents the additional cost of a List Option. Each value can have one or more prices.\n \"\"\"\n values(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: OptionValueIdsFilter, last: Int, orderBy: OptionValueOrderBy, paginationType: PaginationType = CURSOR, updatedAt: UpdatedAtFilter): ListOptionValuesConnection\n}\n\ntype ListOptionPricesConnection {\n edges: [ListOptionPricesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListOptionPricesConnectionEdge {\n cursor: String!\n node: OptionPrice\n}\n\ntype ListOptionValuesConnection {\n edges: [ListOptionValuesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListOptionValuesConnectionEdge {\n cursor: String!\n node: OptionValue\n}\n\ninput ListOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n label: OrderByDirectionEnum\n name: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\ntype ListReferencesConnection {\n edges: [ListReferencesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListReferencesConnectionEdge {\n cursor: String!\n node: Reference\n}\n\ntype ListSKUGroupsConnection {\n edges: [ListSKUGroupsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListSKUGroupsConnectionEdge {\n cursor: String!\n node: SKUGroup\n}\n\ntype ListSkuGroupsConnection {\n edges: [ListSkuGroupsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListSkuGroupsConnectionEdge {\n cursor: String!\n node: SKUGroup\n}\n\n\"\"\"\nFilter for the status of the List, one of `ACTIVE`, `DRAFT`, `ARCHIVED`.\n\"\"\"\ninput ListStatusFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"A List tree holds the hierarchical information of a group of lists.\"\"\"\ntype ListTree {\n \"\"\"\n HTML description for the List Tree. Will be used to display rich text content to customers.\n \"\"\"\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"The timestamp of when the list tree was activated.\"\"\"\n activatedAt: DateTime\n\n \"\"\"The timestamp of when the list tree was archived.\"\"\"\n archivedAt: DateTime\n\n \"\"\"The creation date of the list tree.\"\"\"\n createdAt: DateTime\n\n \"\"\"The description of the list tree.\"\"\"\n description: String\n\n \"\"\"\n HTML description for the List Tree. Will be used to display rich text content to customers.\n \"\"\"\n htmlDescription: String\n\n \"\"\"The globally-unique ID of the list tree.\"\"\"\n id: ID\n\n \"\"\"The display label of the list tree.\"\"\"\n label: String!\n\n \"\"\"\n List tree node is associated to a single List and a node can be a parent node to provide the hierarchy of list trees.\n \"\"\"\n listTreeNodes(\n after: String\n before: String\n first: Int\n hasParent: Boolean\n last: Int\n\n \"\"\"\n Filters nodes by their associated list via eq, in, and ne. isNull never matches, since every node belongs to a list.\n \"\"\"\n listId: ListIdFilter\n listStatus: ListTreeNodeListStatusFilter = {in: [\"ACTIVE\", \"DRAFT\"]}\n orderBy: ListTreeNodeOrderBy\n paginationType: PaginationType = CURSOR\n parentNodeId: ListTreeNodeParentNodeIdFilter\n ): ListTreeListTreeNodesConnection\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): ListTreeMetafieldsConnection\n\n \"\"\"A unique name of the list tree.\"\"\"\n name: String\n\n \"\"\"\n A reference to the resource in an external service. This can be useful for integrating the resource to any external service.\n \"\"\"\n references(after: String, before: String, first: Int, last: Int, origin: ReferenceOriginFilter, paginationType: PaginationType = CURSOR): ListTreeReferencesConnection\n\n \"\"\"The status of the list tree, one of `ACTIVE`, `ARCHIVED`, `DRAFT`.\"\"\"\n status: String\n\n \"\"\"The last update date of the list tree.\"\"\"\n updatedAt: DateTime\n}\n\ninput ListTreeIdFilter {\n eq: String\n}\n\ninput ListTreeIdsFilter {\n in: [String!]\n}\n\ntype ListTreeListTreeNodesConnection {\n edges: [ListTreeListTreeNodesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListTreeListTreeNodesConnectionEdge {\n cursor: String!\n node: ListTreeNode\n}\n\ntype ListTreeMetafieldsConnection {\n edges: [ListTreeMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListTreeMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\n\"\"\"\nList tree node is associated to a single List and a node can be a parent node to provide the hierarchy of list trees.\n\"\"\"\ntype ListTreeNode {\n \"\"\"The creation date of the list node.\"\"\"\n createdAt: DateTime\n\n \"\"\"The globally-unique ID of the list node.\"\"\"\n id: ID\n\n \"\"\"The list associated with the node.\"\"\"\n list: List\n\n \"\"\"The List Tree associated with the node.\"\"\"\n listTree: ListTree\n\n \"\"\"The children nodes of the list node.\"\"\"\n listTreeNodes(after: String, before: String, first: Int, last: Int, listStatus: ListTreeNodeListStatusFilter = {in: [\"ACTIVE\", \"DRAFT\"]}, orderBy: ListTreeNodeOrderBy, paginationType: PaginationType = CURSOR): ListTreeNodeListTreeNodesConnection\n\n \"\"\"The parent node of the list node.\"\"\"\n parentListTreeNode: ListTreeNode\n\n \"\"\"The position of the node in the list.\"\"\"\n position: Int\n\n \"\"\"\n A reference to the resource in an external service. This can be useful for integrating the resource to any external service.\n \"\"\"\n references(after: String, before: String, first: Int, last: Int, origin: ReferenceOriginFilter, paginationType: PaginationType = CURSOR): ListTreeNodeReferencesConnection\n\n \"\"\"The last update date of the list node.\"\"\"\n updatedAt: DateTime\n}\n\ninput ListTreeNodeIdsFilter {\n in: [String!]\n}\n\n\"\"\"\nFilter for the status of the List, one of `ACTIVE`, `DRAFT`, `ARCHIVED`.\n\"\"\"\ninput ListTreeNodeListStatusFilter {\n eq: String\n in: [String!]\n}\n\ntype ListTreeNodeListTreeNodesConnection {\n edges: [ListTreeNodeListTreeNodesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListTreeNodeListTreeNodesConnectionEdge {\n cursor: String!\n node: ListTreeNode\n}\n\n\"\"\"\nFilter for the status of the List Tree, one of `ACTIVE`, `ARCHIVED`, `DRAFT`.\n\"\"\"\ninput ListTreeNodeListTreeStatusFilter {\n eq: String\n in: [String!]\n}\n\ninput ListTreeNodeOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n position: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\ninput ListTreeNodeParentNodeIdFilter {\n eq: String\n}\n\ntype ListTreeNodeReferencesConnection {\n edges: [ListTreeNodeReferencesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListTreeNodeReferencesConnectionEdge {\n cursor: String!\n node: Reference\n}\n\ninput ListTreeOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n name: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\ntype ListTreeReferencesConnection {\n edges: [ListTreeReferencesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype ListTreeReferencesConnectionEdge {\n cursor: String!\n node: Reference\n}\n\n\"\"\"\nFilter for the status of the List Tree, one of `ACTIVE`, `ARCHIVED`, `DRAFT`.\n\"\"\"\ninput ListTreeStatusFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"A location represents the physical location of an inventory.\"\"\"\ntype Location {\n \"\"\"The SKUs are purchasable items in the catalog.\"\"\"\n SKUs(\n after: String\n attributeValues: SKUAttributeValueFilter\n before: String\n createdAt: CreatedAtFilter\n first: Int\n label: LabelFilter\n last: Int\n name: NameFilter\n paginationType: PaginationType = CURSOR\n\n \"\"\"\n A string filter in the ODATA format. ex: \"label eq 'shirt' and contains(code, '123')\".\n\n\n Supported columns: `label`, `code`\n\n Supported operators: `eq`, `ne`, `lt`, `gt`, `and`, `or`\n\n Supported functions: `contains`\n \"\"\"\n queryFilter: String\n referenceValue: ReferenceValueFilter\n skuGroupId: SKUGroupIdFilter\n status: SKUStatusFilter\n updatedAt: UpdatedAtFilter\n ): LocationSKUsConnection @deprecated(reason: \"Use skus instead.\")\n\n \"\"\"The address of the Location.\"\"\"\n address: Address\n\n \"\"\"The timestamp of when the Location was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the Location.\"\"\"\n id: ID!\n\n \"\"\"\n An immutable entity that represents a change in state of a quantity of SKU at a particular time and location. Each adjustment will either have a positive, negative, or neutral impact on the count of available SKUs in a location.\n \"\"\"\n inventoryAdjustments(after: String, before: String, first: Int, last: Int, orderBy: InventoryAdjustmentOrderBy, paginationType: PaginationType = CURSOR): LocationInventoryAdjustmentsConnection\n\n \"\"\"\n The quantity of a SKU in a specific state at a particular time and location.\n \"\"\"\n inventoryCounts(after: String, before: String, first: Int, last: Int, locationStatus: LocationStatusFilter, orderBy: InventoryCountOrderBy, paginationType: PaginationType = CURSOR, skuId: SKUIdFilter, skuStatus: InventoryCountSKUStatusFilter, type: InventoryCountTypeFilter): LocationInventoryCountsConnection\n\n \"\"\"The display name of the Location.\"\"\"\n label: String!\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): LocationMetafieldsConnection\n\n \"\"\"A unique and human-friendly name of the Location.\"\"\"\n name: String!\n\n \"\"\"\n A reference to the resource in an external service. This can be useful for integrating the resource to any external service.\n \"\"\"\n references(after: String, before: String, first: Int, last: Int, origin: ReferenceOriginFilter, paginationType: PaginationType = CURSOR): LocationReferencesConnection\n\n \"\"\"The SKUs are purchasable items in the catalog.\"\"\"\n skus(\n after: String\n attributeValues: SKUAttributeValueFilter\n before: String\n code: SKUCodeFilter\n createdAt: CreatedAtFilter\n eanCode: SKUEanCodeFilter\n first: Int\n gtinCode: SKUGtinCodeFilter\n isbnCode: SKUIsbnCodeFilter\n label: LabelFilter\n last: Int\n name: NameFilter\n orderBy: SKUOrderBy\n paginationType: PaginationType = CURSOR\n\n \"\"\"\n A string filter in the ODATA format. ex: \"label eq 'shirt' and contains(code, '123')\".\n\n\n Supported columns: `label`, `code`\n\n Supported operators: `eq`, `ne`, `lt`, `gt`, `and`, `or`\n\n Supported functions: `contains`\n \"\"\"\n queryFilter: String\n referenceValue: ReferenceValueFilter\n skuGroupId: SKUGroupIdFilter\n status: SKUStatusFilter\n upcCode: SKUUpcCodeFilter\n updatedAt: UpdatedAtFilter\n ): LocationSkusConnection\n\n \"\"\"The status of the location, one of `ACTIVE`, `INACTIVE`, `ARCHIVED`.\"\"\"\n status: String!\n\n \"\"\"The timestamp of when the Location was updated.\"\"\"\n updatedAt: DateTime!\n}\n\ninput LocationIdFilter {\n eq: String\n}\n\ninput LocationIdsFilter {\n in: [String!]\n}\n\ntype LocationInventoryAdjustmentsConnection {\n edges: [LocationInventoryAdjustmentsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype LocationInventoryAdjustmentsConnectionEdge {\n cursor: String!\n node: InventoryAdjustment\n}\n\ntype LocationInventoryCountsConnection {\n edges: [LocationInventoryCountsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype LocationInventoryCountsConnectionEdge {\n cursor: String!\n node: InventoryCount\n}\n\ntype LocationMetafieldsConnection {\n edges: [LocationMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype LocationMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ninput LocationOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n name: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\ntype LocationReferencesConnection {\n edges: [LocationReferencesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype LocationReferencesConnectionEdge {\n cursor: String!\n node: Reference\n}\n\ntype LocationSKUsConnection {\n edges: [LocationSKUsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype LocationSKUsConnectionEdge {\n cursor: String!\n node: SKU\n}\n\ntype LocationSkusConnection {\n edges: [LocationSkusConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype LocationSkusConnectionEdge {\n cursor: String!\n node: SKU\n}\n\n\"\"\"\nFilter for the status of the Location, one of `ACTIVE`, `INACTIVE`, `ARCHIVED`.\n\"\"\"\ninput LocationStatusFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"Represents a media object, including photos and videos.\"\"\"\ntype Media {\n \"\"\"The globally-unique ID of the media.\"\"\"\n id: ID!\n\n \"\"\"An optional label for the media.\"\"\"\n label: String\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): MediaMetafieldsConnection\n\n \"\"\"A unique name of the media.\"\"\"\n name: String\n\n \"\"\"The position of the media.\"\"\"\n position: Int\n\n \"\"\"\n The type of the media. Currently: `VIDEO`, `IMAGE`, `AUDIO`. Legacy objects may still have `PHOTO`.\n \"\"\"\n type: String\n\n \"\"\"The URL of the media.\"\"\"\n url: String!\n}\n\ntype MediaMetafieldsConnection {\n edges: [MediaMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype MediaMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\n\"\"\"Custom data\"\"\"\ntype Metafield {\n createdAt: String\n id: ID\n key: String\n namespace: String\n resourceId: ID\n\n \"\"\"\n Metafield type. Currently accepted values (lowercase): `boolean`, `string`, `stringMultiLine`, `number`, `numberDecimal`, `date`, `dateTime`, `json`, `measurement`, `url`, `reference`, `money`, `list.string`, `list.number`, `list.numberDecimal`, `list.measurement`, `list.date`, `list.url`.\n \"\"\"\n type: String\n updatedAt: String\n value: String\n}\n\ntype Mutation {\n \"\"\"Add Attribute Value(s) to an existing SKU.\"\"\"\n addAttributeValuesToSKU(id: String!, input: MutationAddAttributeValuesToSKUInput!): SKU @deprecated(reason: \"Use `addAttributeValuesToSku` instead.\")\n\n \"\"\"Add Attribute Value(s) to an existing SKU.\"\"\"\n addAttributeValuesToSku(id: String!, input: MutationAddAttributeValuesToSkuInput!): SKU\n\n \"\"\"Add Attributes to an existing SKU group.\"\"\"\n addAttributesToSKUGroup(id: String!, input: MutationAddAttributesToSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `addAttributesToSkuGroup` instead.\")\n\n \"\"\"Add Attributes to an existing SKU group.\"\"\"\n addAttributesToSkuGroup(id: String!, input: MutationAddAttributesToSkuGroupInput!): SKUGroup\n\n \"\"\"Add channels to an existing SKU group.\"\"\"\n addChannelsToSKUGroup(id: String!, input: MutationAddChannelsToSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `addChannelsToSkuGroup` instead.\")\n\n \"\"\"Add channels to an existing SKU group.\"\"\"\n addChannelsToSkuGroup(id: String!, input: MutationAddChannelsToSkuGroupInput!): SKUGroup\n\n \"\"\"Add a new node to a list tree.\"\"\"\n addListTreeNodesToListTree(id: String!, input: MutationAddListTreeNodesToListTreeInput!): ListTree\n\n \"\"\"Add a new node to a list tree node.\"\"\"\n addListTreeNodesToParentListTreeNode(id: String!, input: MutationAddListTreeNodesToParentListTreeNodeInput!): ListTreeNode\n\n \"\"\"Add media objects to an existing List.\"\"\"\n addMediaObjectsToList(id: String!, input: MutationAddMediaObjectsToListInput!): List\n\n \"\"\"Add media objects to an existing SKU\"\"\"\n addMediaObjectsToSKU(id: String!, input: MutationAddMediaObjectsToSKUInput!): SKU @deprecated(reason: \"Use `addMediaObjectsToSku` instead.\")\n\n \"\"\"Add media objects to an existing SKU group.\"\"\"\n addMediaObjectsToSKUGroup(id: String!, input: MutationAddMediaObjectsToSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `addMediaObjectsToSkuGroup` instead.\")\n\n \"\"\"Add media objects to an existing SKU\"\"\"\n addMediaObjectsToSku(id: String!, input: MutationAddMediaObjectsToSkuInput!): SKU\n\n \"\"\"Add media objects to an existing SKU group.\"\"\"\n addMediaObjectsToSkuGroup(id: String!, input: MutationAddMediaObjectsToSkuGroupInput!): SKUGroup\n\n \"\"\"Add options to an existing SKU group.\"\"\"\n addOptionsToSKUGroup(id: String!, input: MutationAddOptionsToSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `addOptionsToSkuGroup` instead.\")\n\n \"\"\"Add options to an existing SKU group.\"\"\"\n addOptionsToSkuGroup(id: String!, input: MutationAddOptionsToSkuGroupInput!): SKUGroup\n\n \"\"\"Add references to an existing List.\"\"\"\n addReferencesToList(id: String!, input: MutationAddReferencesToListInput!): List\n\n \"\"\"Add references to an existing List Tree.\"\"\"\n addReferencesToListTree(id: String!, input: MutationAddReferencesToListTreeInput!): ListTree\n\n \"\"\"Add references to an existing List Tree Node\"\"\"\n addReferencesToListTreeNode(id: String!, input: MutationAddReferencesToListTreeNodeInput!): ListTreeNode\n\n \"\"\"Add references to an existing location.\"\"\"\n addReferencesToLocation(id: String!, input: MutationAddReferencesToLocationInput!): Location\n\n \"\"\"Add references to an existing SKU.\"\"\"\n addReferencesToSKU(id: String!, input: MutationAddReferencesToSKUInput!): SKU @deprecated(reason: \"Use `addReferencesToSku` instead.\")\n\n \"\"\"Add references to an existing SKU group.\"\"\"\n addReferencesToSKUGroup(id: String!, input: MutationAddReferencesToSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `addReferencesToSkuGroup` instead.\")\n\n \"\"\"Add references to an existing SKU.\"\"\"\n addReferencesToSku(id: String!, input: MutationAddReferencesToSkuInput!): SKU\n\n \"\"\"Add references to an existing SKU group.\"\"\"\n addReferencesToSkuGroup(id: String!, input: MutationAddReferencesToSkuGroupInput!): SKUGroup\n\n \"\"\"Add a single SKU Group to multiple lists\"\"\"\n addSKUGroupToLists(id: String!, input: MutationAddSKUGroupToListsInput!): SKUGroup @deprecated(reason: \"Use `addSkuGroupToLists` instead.\")\n\n \"\"\"Add SKU Groups to an existing list.\"\"\"\n addSKUGroupsToList(id: String!, input: MutationAddSKUGroupsToListInput!): List @deprecated(reason: \"Use `addSkuGroupsToList` instead.\")\n\n \"\"\"Add SKUs to an existing location.\"\"\"\n addSKUsToLocation(id: String!, input: MutationAddSKUsToLocationInput!): Location @deprecated(reason: \"Use `addSkusToLocation` instead.\")\n\n \"\"\"Add SKUs to an existing SKU group.\"\"\"\n addSKUsToSKUGroup(id: String!, input: MutationAddSKUsToSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `addSkusToSkuGroup` instead.\")\n\n \"\"\"Add a single SKU Group to multiple lists\"\"\"\n addSkuGroupToLists(id: String!, input: MutationAddSkuGroupToListsInput!): SKUGroup\n\n \"\"\"Add SKU Groups to an existing list.\"\"\"\n addSkuGroupsToList(id: String!, input: MutationAddSkuGroupsToListInput!): List\n\n \"\"\"Add SKUs to an existing location.\"\"\"\n addSkusToLocation(id: String!, input: MutationAddSkusToLocationInput!): Location\n\n \"\"\"Add SKUs to an existing SKU group.\"\"\"\n addSkusToSkuGroup(id: String!, input: MutationAddSkusToSkuGroupInput!): SKUGroup\n\n \"\"\"\n Adjust inventory by a positive or negative delta. Positive deltas stock inventory, negative deltas reduce inventory.\n \"\"\"\n adjustInventory(input: MutationAdjustInventoryInput!): [InventoryAdjustment!]\n\n \"\"\"Archive a file.\"\"\"\n archiveFile(id: String!): File\n\n \"\"\"\n Archive a store-scoped inventory adjustment reason. Global reasons cannot be archived.\n \"\"\"\n archiveInventoryAdjustmentReason(input: MutationArchiveInventoryAdjustmentReasonInput!): InventoryAdjustmentReason\n\n \"\"\"Archive a list.\"\"\"\n archiveList(id: String!): List\n\n \"\"\"Archive a list tree.\"\"\"\n archiveListTree(id: String!): ListTree\n\n \"\"\"Archive a location.\"\"\"\n archiveLocation(id: String!): Location\n\n \"\"\"Archive an existing SKU.\"\"\"\n archiveSKU(id: String!): SKU @deprecated(reason: \"Use `archiveSku` instead.\")\n\n \"\"\"Archive an existing SKU Group.\"\"\"\n archiveSKUGroup(cascadeArchive: CascadeArchiveInput, id: String!): SKUGroup @deprecated(reason: \"Use `archiveSkuGroup` instead.\")\n\n \"\"\"Archive an existing SKU.\"\"\"\n archiveSku(id: String!): SKU\n\n \"\"\"Archive an existing SKU Group.\"\"\"\n archiveSkuGroup(cascadeArchive: CascadeArchiveInput, id: String!): SKUGroup\n\n \"\"\"Archive multiple existing SKUs. Limit 25 SKUs.\"\"\"\n archiveSkus(ids: [String!]!): [SKU!]\n\n \"\"\"\n Commit new inventory. If there are not enough available inventory, they will be moved to backordered if allowed. Documentation: https://godaddy-corp.atlassian.net/wiki/spaces/COMCORE/pages/3758600912/Inventory+Helper+Mutations#2.-commitInventory\n \"\"\"\n commitInventory(input: MutationCommitInventoryInput!): [InventoryAdjustment!]\n\n \"\"\"Create a new attribute.\"\"\"\n createAttribute(input: MutationCreateAttributeInput!): Attribute\n\n \"\"\"Create a new attribute value.\"\"\"\n createAttributeValue(input: CreateAttributeValueInput!): AttributeValue\n\n \"\"\"Create new attribute values.\"\"\"\n createAttributeValues(input: [CreateAttributeValueInput!]!): [AttributeValue!]\n\n \"\"\"Create a new file.\"\"\"\n createFile(input: CreateFileInput!): File\n\n \"\"\"Create a new inventory adjustment.\"\"\"\n createInventoryAdjustment(input: CreateInventoryAdjustmentInput!): InventoryAdjustment\n\n \"\"\"\n Create a new store-scoped inventory adjustment reason. Name must be kebab-case and must not start with \"g-\" (reserved for global presets). Once created, the name is immutable.\n \"\"\"\n createInventoryAdjustmentReason(input: MutationCreateInventoryAdjustmentReasonInput!): InventoryAdjustmentReason\n\n \"\"\"Create multiple inventory adjustments in a single operation.\"\"\"\n createInventoryAdjustments(input: [CreateInventoryAdjustmentInput!]!): [InventoryAdjustment!]\n\n \"\"\"Create a new list.\"\"\"\n createList(input: MutationCreateListInput!): List\n\n \"\"\"Create a new list tree.\"\"\"\n createListTree(input: MutationCreateListTreeInput!): ListTree\n\n \"\"\"Create a new location.\"\"\"\n createLocation(input: MutationCreateLocationInput!): Location\n\n \"\"\"Create a new option.\"\"\"\n createOption(input: MutationCreateOptionInput!): Option\n\n \"\"\"\n Create a flat price for the option. This will be ignore if a price is present on the option values.\n \"\"\"\n createOptionPrice(input: MutationCreateOptionPriceInput!): OptionPrice\n\n \"\"\"Create a new option value.\"\"\"\n createOptionValue(input: MutationCreateOptionValueInput!): OptionValue\n\n \"\"\"Create a price.\"\"\"\n createOptionValuePrice(input: MutationCreateOptionValuePriceInput!): OptionValuePrice\n\n \"\"\"Create multiple new Option Values in a single transaction.\"\"\"\n createOptionValues(input: [MutationCreateOptionValueInput!]!): [OptionValue!]\n\n \"\"\"Create a new SKU.\"\"\"\n createSKU(input: CreateSKUInput!): SKU @deprecated(reason: \"Use `createSku` instead.\")\n\n \"\"\"Create a new SKU Group.\"\"\"\n createSKUGroup(input: MutationCreateSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `createSkuGroup` instead.\")\n\n \"\"\"Create a price.\"\"\"\n createSKUPrice(input: MutationCreateSKUPriceInput!): SKUPrice @deprecated(reason: \"Use `createSkuPrice` instead.\")\n\n \"\"\"Create multiple new SKUs in a single transaction. Limit 25 SKUs.\"\"\"\n createSKUs(input: [CreateSKUInput!]!): [SKU!] @deprecated(reason: \"Use `createSkus` instead.\")\n\n \"\"\"Create a new SKU.\"\"\"\n createSku(input: CreateSKUInput!): SKU\n\n \"\"\"Create a new SKU Group.\"\"\"\n createSkuGroup(input: MutationCreateSkuGroupInput!): SKUGroup\n\n \"\"\"Create a price.\"\"\"\n createSkuPrice(input: MutationCreateSkuPriceInput!): SKUPrice\n\n \"\"\"Create multiple new SKUs in a single transaction. Limit 25 SKUs.\"\"\"\n createSkus(input: [CreateSKUInput!]!): [SKU!]\n\n \"\"\"\n WARNING: This mutation hard deletes an existing SKU Group and all its associated records.\n \"\"\"\n deleteSkuGroupById(id: String!): SKUGroup\n\n \"\"\"\n Reduce inventory by first reducing available, then moving committed to backordered. If insufficient inventory exists, additional available inventory is automatically added to fulfill the reduction. This mutation does not respect backorder limits.\n \"\"\"\n reduceInventory(input: MutationReduceInventoryInput!): [InventoryAdjustment!]\n\n \"\"\"\n Release inventory from committed and/or backordered. Releases from committed first, then backordered. Errors if the requested quantity exceeds committed + backordered. Documentation: https://godaddy-corp.atlassian.net/wiki/spaces/COMCORE/pages/3758600912/Inventory+Helper+Mutations#3.-releaseInventory\n \"\"\"\n releaseInventory(input: MutationReleaseInventoryInput!): [InventoryAdjustment!]\n\n \"\"\"Remove Attribute Value(s) from an existing Attribute.\"\"\"\n removeAttributeValuesFromAttribute(id: String!, input: MutationRemoveAttributeValuesFromAttributeInput!): Attribute\n\n \"\"\"Remove Attribute Value(s) from an existing SKU.\"\"\"\n removeAttributeValuesFromSKU(id: String!, input: MutationRemoveAttributeValuesFromSKUInput!): SKU @deprecated(reason: \"Use `removeAttributeValuesFromSku` instead.\")\n\n \"\"\"Remove Attribute Value(s) from an existing SKU.\"\"\"\n removeAttributeValuesFromSku(id: String!, input: MutationRemoveAttributeValuesFromSkuInput!): SKU\n\n \"\"\"Remove Attributes from an existing SKU group.\"\"\"\n removeAttributesFromSKUGroup(id: String!, input: MutationRemoveAttributesFromSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `removeAttributesFromSkuGroup` instead.\")\n\n \"\"\"Remove Attributes from an existing SKU group.\"\"\"\n removeAttributesFromSkuGroup(id: String!, input: MutationRemoveAttributesFromSkuGroupInput!): SKUGroup\n\n \"\"\"Remove channel associations from an existing SKU group.\"\"\"\n removeChannelsFromSKUGroup(id: String!, input: MutationRemoveChannelsFromSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `removeChannelsFromSkuGroup` instead.\")\n\n \"\"\"Remove channel associations from an existing SKU group.\"\"\"\n removeChannelsFromSkuGroup(id: String!, input: MutationRemoveChannelsFromSkuGroupInput!): SKUGroup\n\n \"\"\"Remove nodes from a list tree.\"\"\"\n removeListTreeNodesFromListTree(id: String!, input: MutationRemoveListTreeNodesFromListTreeInput!): ListTree\n\n \"\"\"Remove nodes from a list tree node.\"\"\"\n removeListTreeNodesFromParentListTreeNode(id: String!, input: MutationRemoveListTreeNodesFromParentListTreeNodeInput!): ListTreeNode\n\n \"\"\"Remove media objects from an existing List.\"\"\"\n removeMediaObjectsFromList(id: String!, input: MutationRemoveMediaObjectsFromListInput!): List\n\n \"\"\"Remove media objects from an existing SKU\"\"\"\n removeMediaObjectsFromSKU(id: String!, input: MutationRemoveMediaObjectsFromSKUInput!): SKU @deprecated(reason: \"Use `removeMediaObjectsFromSku` instead.\")\n\n \"\"\"Remove media objects from an existing SKU group.\"\"\"\n removeMediaObjectsFromSKUGroup(id: String!, input: MutationRemoveMediaObjectsFromSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `removeMediaObjectsFromSkuGroup` instead.\")\n\n \"\"\"Remove media objects from an existing SKU\"\"\"\n removeMediaObjectsFromSku(id: String!, input: MutationRemoveMediaObjectsFromSkuInput!): SKU\n\n \"\"\"Remove media objects from an existing SKU group.\"\"\"\n removeMediaObjectsFromSkuGroup(id: String!, input: MutationRemoveMediaObjectsFromSkuGroupInput!): SKUGroup\n\n \"\"\"Remove metafields from an existing Attribute.\"\"\"\n removeMetafieldsFromAttribute(id: String!, input: MutationRemoveMetafieldsFromAttributeInput!): Attribute\n\n \"\"\"Remove metafields from an existing Attribute Value.\"\"\"\n removeMetafieldsFromAttributeValue(id: String!, input: MutationRemoveMetafieldsFromAttributeValueInput!): AttributeValue\n\n \"\"\"Remove metafields from an existing List.\"\"\"\n removeMetafieldsFromList(id: String!, input: MutationRemoveMetafieldsFromListInput!): List\n\n \"\"\"Remove metafields from an existing List Tree.\"\"\"\n removeMetafieldsFromListTree(id: String!, input: MutationRemoveMetafieldsFromListTreeInput!): ListTree\n\n \"\"\"Remove metafields from an existing Location.\"\"\"\n removeMetafieldsFromLocation(id: String!, input: MutationRemoveMetafieldsFromLocationInput!): Location\n\n \"\"\"Remove metafields from an existing Option.\"\"\"\n removeMetafieldsFromOption(id: String!, input: MutationRemoveMetafieldsFromOptionInput!): Option\n\n \"\"\"Remove metafields from an existing Option Value.\"\"\"\n removeMetafieldsFromOptionValue(id: String!, input: MutationRemoveMetafieldsFromOptionValueInput!): OptionValue\n\n \"\"\"Remove metafields from an existing SKU.\"\"\"\n removeMetafieldsFromSku(id: String!, input: MutationRemoveMetafieldsFromSkuInput!): SKU\n\n \"\"\"Remove metafields from an existing SKU Group.\"\"\"\n removeMetafieldsFromSkuGroup(id: String!, input: MutationRemoveMetafieldsFromSkuGroupInput!): SKUGroup\n\n \"\"\"Remove an existing option.\"\"\"\n removeOption(id: String!): Null\n\n \"\"\"Remove an existing option value.\"\"\"\n removeOptionValue(id: String!): Null\n\n \"\"\"Remove values from an existing Option.\"\"\"\n removeOptionValuesFromListOption(id: String!, input: MutationRemoveOptionValuesFromListOptionInput!): ListOption\n\n \"\"\"Remove Options from an existing SKU group.\"\"\"\n removeOptionsFromSKUGroup(id: String!, input: MutationRemoveOptionsFromSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `removeOptionsFromSkuGroup` instead.\")\n\n \"\"\"Remove Options from an existing SKU group.\"\"\"\n removeOptionsFromSkuGroup(id: String!, input: MutationRemoveOptionsFromSkuGroupInput!): SKUGroup\n\n \"\"\"Remove prices from an existing Option.\"\"\"\n removePricesFromOption(id: String!, input: MutationRemovePricesFromOptionInput!): Option\n\n \"\"\"Remove prices from an existing OptionValue.\"\"\"\n removePricesFromOptionValue(id: String!, input: MutationRemovePricesFromOptionValueInput!): OptionValue\n\n \"\"\"Remove prices from an existing SKU.\"\"\"\n removePricesFromSKU(id: String!, input: MutationRemovePricesFromSKUInput!): SKU @deprecated(reason: \"Use `removePricesFromSku` instead.\")\n\n \"\"\"Remove prices from an existing SKU.\"\"\"\n removePricesFromSku(id: String!, input: MutationRemovePricesFromSkuInput!): SKU\n\n \"\"\"Remove references from an existing List.\"\"\"\n removeReferencesFromList(id: String!, input: MutationRemoveReferencesFromListInput!): List\n\n \"\"\"Remove references from an existing List Tree\"\"\"\n removeReferencesFromListTree(id: String!, input: MutationRemoveReferencesFromListTreeInput!): ListTree\n\n \"\"\"Remove references from an existing List Tree Node\"\"\"\n removeReferencesFromListTreeNode(id: String!, input: MutationRemoveReferencesFromListTreeNodeInput!): ListTreeNode\n\n \"\"\"Remove references from an existing location.\"\"\"\n removeReferencesFromLocation(id: String!, input: MutationRemoveReferencesFromLocationInput!): Location\n\n \"\"\"Remove references from an existing SKU.\"\"\"\n removeReferencesFromSKU(id: String!, input: MutationRemoveReferencesFromSKUInput!): SKU @deprecated(reason: \"Use `removeReferencesFromSku` instead.\")\n\n \"\"\"Remove references from an existing SKU group.\"\"\"\n removeReferencesFromSKUGroup(id: String!, input: MutationRemoveReferencesFromSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `removeReferencesFromSkuGroup` instead.\")\n\n \"\"\"Remove references from an existing SKU.\"\"\"\n removeReferencesFromSku(id: String!, input: MutationRemoveReferencesFromSkuInput!): SKU\n\n \"\"\"Remove references from an existing SKU group.\"\"\"\n removeReferencesFromSkuGroup(id: String!, input: MutationRemoveReferencesFromSkuGroupInput!): SKUGroup\n\n \"\"\"Remove a single SKU Group from multiple lists\"\"\"\n removeSKUGroupFromLists(id: String!, input: MutationRemoveSKUGroupFromListsInput!): SKUGroup @deprecated(reason: \"Use `removeSkuGroupFromLists` instead.\")\n\n \"\"\"Remove SKU Groups from an existing list.\"\"\"\n removeSKUGroupsFromList(id: String!, input: MutationRemoveSKUGroupsFromListInput!): List @deprecated(reason: \"Use `removeSkuGroupsFromList` instead.\")\n\n \"\"\"Remove SKU from an existing location.\"\"\"\n removeSKUsFromLocation(id: String!, input: MutationRemoveSKUsFromLocationInput!): Location @deprecated(reason: \"Use `removeSkusFromLocation` instead.\")\n\n \"\"\"Remove SKUs from an existing SKU group.\"\"\"\n removeSKUsFromSKUGroup(id: String!, input: MutationRemoveSKUsFromSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `removeSkusFromSkuGroup` instead.\")\n\n \"\"\"Remove a single SKU Group from multiple lists\"\"\"\n removeSkuGroupFromLists(id: String!, input: MutationRemoveSkuGroupFromListsInput!): SKUGroup\n\n \"\"\"Remove SKU Groups from an existing list.\"\"\"\n removeSkuGroupsFromList(id: String!, input: MutationRemoveSkuGroupsFromListInput!): List\n\n \"\"\"Remove SKU from an existing location.\"\"\"\n removeSkusFromLocation(id: String!, input: MutationRemoveSkusFromLocationInput!): Location\n\n \"\"\"Remove SKUs from an existing SKU group.\"\"\"\n removeSkusFromSkuGroup(id: String!, input: MutationRemoveSkusFromSkuGroupInput!): SKUGroup\n\n \"\"\"\n Restock inventory from committed. If there are not enough committed inventory, this mutation will error.\n \"\"\"\n restockFromCommittedInventory(input: MutationRestockFromCommittedInventoryInput!): [InventoryAdjustment!]\n\n \"\"\"Set the channel association mode for a SKU Group.\"\"\"\n setSkuGroupChannelAssociationMode(\n \"\"\"SKU Group ID\"\"\"\n id: String!\n input: MutationSetSkuGroupChannelAssociationModeInput!\n ): SKUGroup\n\n \"\"\"\n Stock new inventory. If there are backordered inventory, they will be moved to committed. It does not validate aganist backorder limit. Any extra inventory will be added to available. Documentation: https://godaddy-corp.atlassian.net/wiki/spaces/COMCORE/pages/3758600912/Inventory+Helper+Mutations#1.-stockInventory\n \"\"\"\n stockInventory(input: MutationStockInventoryInput!): [InventoryAdjustment!]\n\n \"\"\"Update an existing attribute.\"\"\"\n updateAttribute(id: String!, input: MutationUpdateAttributeInput!): Attribute\n\n \"\"\"Update an existing attribute value.\"\"\"\n updateAttributeValue(id: String!, input: MutationUpdateAttributeValueInput!): AttributeValue\n\n \"\"\"Update an existing file.\"\"\"\n updateFile(id: String!, input: UpdateFileInput!): File\n\n \"\"\"\n Update the label of a store-scoped inventory adjustment reason. Global preset reasons cannot be updated.\n \"\"\"\n updateInventoryAdjustmentReason(input: MutationUpdateInventoryAdjustmentReasonInput!): InventoryAdjustmentReason\n\n \"\"\"Update an existing list.\"\"\"\n updateList(id: String!, input: MutationUpdateListInput!): List\n\n \"\"\"Add media objects or update existing media objects to existing List.\"\"\"\n updateListMediaObjects(id: String!, input: MutationUpdateListMediaObjectsInput!): List\n\n \"\"\"Update an existing list tree.\"\"\"\n updateListTree(id: String!, input: MutationUpdateListTreeInput!): ListTree\n\n \"\"\"Update an existing list tree node.\"\"\"\n updateListTreeNode(id: String!, input: MutationUpdateListTreeNodeInput!): ListTreeNode\n\n \"\"\"Update an existing location.\"\"\"\n updateLocation(id: String!, input: MutationUpdateLocationInput!): Location\n\n \"\"\"Update an existing option.\"\"\"\n updateOption(id: String!, input: MutationUpdateOptionInput!): Option\n\n \"\"\"Update an existing price object for an option.\"\"\"\n updateOptionPrice(id: String!, input: MutationUpdateOptionPriceInput!): OptionPrice\n\n \"\"\"\n Update the currency code for an existing option price. This updates the currency code for both value and compareAtValue.\n \"\"\"\n updateOptionPriceCurrencyCode(id: String!, input: MutationUpdateOptionPriceCurrencyCodeInput!): OptionPrice\n\n \"\"\"Update an existing option value.\"\"\"\n updateOptionValue(id: String!, input: MutationUpdateOptionValueInput!): OptionValue\n\n \"\"\"Update an existing price object.\"\"\"\n updateOptionValuePrice(id: String!, input: MutationUpdateOptionValuePriceInput!): OptionValuePrice\n\n \"\"\"\n Update the currency code for an existing option value price. This updates the currency code for both value and compareAtValue.\n \"\"\"\n updateOptionValuePriceCurrencyCode(id: String!, input: MutationUpdateOptionValuePriceCurrencyCodeInput!): OptionValuePrice\n\n \"\"\"Update an existing SKU.\"\"\"\n updateSKU(id: String!, input: MutationUpdateSKUInput!): SKU @deprecated(reason: \"Use `updateSku` instead.\")\n\n \"\"\"Update an existing SKU Group.\"\"\"\n updateSKUGroup(id: String!, input: MutationUpdateSKUGroupInput!): SKUGroup @deprecated(reason: \"Use `updateSkuGroup` instead.\")\n\n \"\"\"Update an existing price object.\"\"\"\n updateSKUPrice(id: String!, input: MutationUpdateSKUPriceInput!): SKUPrice @deprecated(reason: \"Use `updateSkuPrice` instead.\")\n\n \"\"\"Update an existing SKU.\"\"\"\n updateSku(id: String!, input: MutationUpdateSkuInput!): SKU\n\n \"\"\"Update an existing SKU Group.\"\"\"\n updateSkuGroup(id: String!, input: MutationUpdateSkuGroupInput!): SKUGroup\n\n \"\"\"\n Add media objects or update existing media objects to existing SKU Group.\n \"\"\"\n updateSkuGroupMediaObjects(id: String!, input: MutationUpdateSkuGroupMediaObjectsInput!): SKUGroup\n\n \"\"\"\n Reorder options within a SKU group by updating the position of each option's association.\n \"\"\"\n updateSkuGroupOptionPositions(id: String!, input: MutationUpdateSkuGroupOptionPositionsInput!): SKUGroup\n\n \"\"\"Add media objects or update existing media objects to existing SKU.\"\"\"\n updateSkuMediaObjects(id: String!, input: MutationUpdateSkuMediaObjectsInput!): SKU\n\n \"\"\"Update an existing price object.\"\"\"\n updateSkuPrice(id: String!, input: MutationUpdateSkuPriceInput!): SKUPrice\n\n \"\"\"\n Update the currency code for an existing price. This updates the currency code for both value and compareAtValue.\n \"\"\"\n updateSkuPriceCurrencyCode(id: String!, input: MutationUpdateSkuPriceCurrencyCodeInput!): SKUPrice\n}\n\ninput MutationAddAttributeValuesToSKUInput {\n attributeValueIds: [String!]!\n}\n\ninput MutationAddAttributeValuesToSkuInput {\n attributeValueIds: [String!]!\n}\n\ninput MutationAddAttributesToSKUGroupInput {\n attributes: [CreateSKUGroupAttributeInput!]!\n}\n\ninput MutationAddAttributesToSkuGroupInput {\n attributes: [CreateSKUGroupAttributeInput!]!\n}\n\ninput MutationAddChannelsToSKUGroupInput {\n \"\"\"\n The channels to add to the SKU group.\n \t\t\t\tThese are pointers to the Channels API, Catalog API\n \t\t\t\tdoes not create the channel resources.\n \"\"\"\n channels: [SKUGroupChannelAddInput!]!\n}\n\ninput MutationAddChannelsToSkuGroupInput {\n \"\"\"\n The channels to add to the SKU group.\n \t\t\t\tThese are pointers to the Channels API, Catalog API\n \t\t\t\tdoes not create the channel resources.\n \"\"\"\n channels: [SKUGroupChannelAddInput!]!\n}\n\ninput MutationAddListTreeNodesToListTreeInput {\n listTreeNodes: [AddListTreeNodeInput!]!\n}\n\ninput MutationAddListTreeNodesToParentListTreeNodeInput {\n listTreeNodes: [AddListTreeNodeInput!]!\n}\n\ninput MutationAddMediaObjectsToListInput {\n mediaObjects: [CreateMediaObjectInput!]!\n}\n\ninput MutationAddMediaObjectsToSKUGroupInput {\n mediaObjects: [CreateMediaObjectInput!]!\n}\n\ninput MutationAddMediaObjectsToSKUInput {\n mediaObjects: [CreateMediaObjectInput!]!\n}\n\ninput MutationAddMediaObjectsToSkuGroupInput {\n mediaObjects: [CreateMediaObjectInput!]!\n}\n\ninput MutationAddMediaObjectsToSkuInput {\n mediaObjects: [CreateMediaObjectInput!]!\n}\n\ninput MutationAddOptionsToSKUGroupInput {\n \"\"\"UUIDs of existing options to associate with this SKU group.\"\"\"\n optionIds: [String!]\n options: [CreateOptionInput!]\n}\n\ninput MutationAddOptionsToSkuGroupInput {\n \"\"\"UUIDs of existing options to associate with this SKU group.\"\"\"\n optionIds: [String!]\n options: [CreateOptionInput!]\n}\n\ninput MutationAddReferencesToListInput {\n references: [CreateReferenceInput!]!\n}\n\ninput MutationAddReferencesToListTreeInput {\n references: [CreateReferenceInput!]!\n}\n\ninput MutationAddReferencesToListTreeNodeInput {\n references: [CreateReferenceInput!]!\n}\n\ninput MutationAddReferencesToLocationInput {\n references: [CreateReferenceInput!]!\n}\n\ninput MutationAddReferencesToSKUGroupInput {\n references: [CreateReferenceInput!]!\n}\n\ninput MutationAddReferencesToSKUInput {\n references: [CreateReferenceInput!]!\n}\n\ninput MutationAddReferencesToSkuGroupInput {\n references: [CreateReferenceInput!]!\n}\n\ninput MutationAddReferencesToSkuInput {\n references: [CreateReferenceInput!]!\n}\n\ninput MutationAddSKUGroupToListsInput {\n listIds: [String!]!\n}\n\ninput MutationAddSKUGroupsToListInput {\n skuGroupIds: [String!]!\n}\n\ninput MutationAddSKUsToLocationInput {\n skuIds: [String!]!\n}\n\ninput MutationAddSKUsToSKUGroupInput {\n skuIds: [String!]!\n}\n\ninput MutationAddSkuGroupToListsInput {\n listIds: [String!]!\n}\n\ninput MutationAddSkuGroupsToListInput {\n skuGroupIds: [String!]!\n}\n\ninput MutationAddSkusToLocationInput {\n skuIds: [String!]!\n}\n\ninput MutationAddSkusToSkuGroupInput {\n skuIds: [String!]!\n}\n\ninput MutationAdjustInventoryInput {\n delta: Int!\n locationId: ID!\n reasonName: String\n references: [CreateReferenceInput!]\n skuId: ID!\n}\n\ninput MutationArchiveInventoryAdjustmentReasonInput {\n id: ID!\n}\n\ninput MutationCommitInventoryInput {\n allowBackorders: Boolean\n locationId: ID!\n quantity: Int!\n reasonName: String\n references: [CreateReferenceInput!]\n skuId: ID!\n}\n\ninput MutationCreateAttributeInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n description: String\n htmlDescription: String\n label: String!\n metafields: [CreateMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n position: Int\n skuGroupId: ID!\n values: [AssociateAttributeValueInput!]\n}\n\ninput MutationCreateInventoryAdjustmentReasonInput {\n label: String!\n\n \"\"\"\n Must be kebab-case: lowercase alphanumeric segments separated by single dashes. Must not start with \"g-\" (reserved for global presets).\n \"\"\"\n name: String!\n}\n\ninput MutationCreateListInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n htmlDescription: String\n label: String!\n mediaObjects: [CreateMediaObjectInput!]\n metafields: [CreateMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n references: [CreateReferenceInput!]\n\n \"\"\"The status of the list, one of `ACTIVE`, `DRAFT`, `ARCHIVED`.\"\"\"\n status: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationCreateListTreeInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n htmlDescription: String\n label: String!\n listTreeNodes: [CreateListTreeNodeInput!]\n metafields: [CreateMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n references: [CreateReferenceInput!]\n\n \"\"\"The status of the list tree, one of `ACTIVE`, `ARCHIVED`, `DRAFT`.\"\"\"\n status: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationCreateLocationInput {\n address: CreateAddressInput!\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n label: String!\n metafields: [CreateMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n references: [CreateReferenceInput!]\n\n \"\"\"The status of the location, one of `ACTIVE`, `INACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationCreateOptionInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n description: String\n htmlDescription: String\n label: String!\n metafields: [CreateMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n position: Int\n prices: [CreateOptionPriceInput!]\n\n \"\"\"Whether this option is shareable across multiple SKU Groups.\"\"\"\n shareable: Boolean\n skuGroupId: String @deprecated(reason: \"Use skuGroupIds instead.\")\n\n \"\"\"The UUIDs of the SKU Groups to associate the Option with.\"\"\"\n skuGroupIds: [String!]\n\n \"\"\"\n The type of the Option, one of `TEXT`, `NUMBER`, `LIST`. Option Values are only available on the 'LIST' type.\n \"\"\"\n type: String!\n validation: CreateOptionValidationInput\n values: [CreateOptionValueInput!]\n}\n\ninput MutationCreateOptionPriceInput {\n compareAtValue: SimpleMoneyInput\n optionId: String!\n value: SimpleMoneyInput!\n}\n\ninput MutationCreateOptionValueInput {\n label: String!\n metafields: [CreateMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n optionId: String!\n position: Int\n prices: [CreateOptionValuePriceInput!]\n}\n\ninput MutationCreateOptionValuePriceInput {\n compareAtValue: SimpleMoneyInput\n optionValueId: String!\n value: SimpleMoneyInput!\n}\n\ninput MutationCreateSKUGroupInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n attributes: [CreateSKUGroupAttributeInput!]\n channels: [SKUGroupChannelAddInput!]\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n htmlDescription: String\n label: String!\n mediaObjects: [CreateMediaObjectInput!]\n metafields: [CreateMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n options: [CreateOptionInput!]\n references: [CreateReferenceInput!]\n shortLabel: String @deprecated(reason: \"Use channel-specific overrides for short labels.\")\n skus: [CreateSKUGroupSKUInput!]\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n type: String!\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationCreateSKUPriceInput {\n compareAtValue: SimpleMoneyInput\n skuId: ID!\n value: SimpleMoneyInput!\n}\n\ninput MutationCreateSkuGroupInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n attributes: [CreateSKUGroupAttributeInput!]\n channels: [SKUGroupChannelAddInput!]\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n htmlDescription: String\n label: String!\n mediaObjects: [CreateMediaObjectInput!]\n metafields: [CreateMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n options: [CreateOptionInput!]\n references: [CreateReferenceInput!]\n shortLabel: String @deprecated(reason: \"Use channel-specific overrides for short labels.\")\n skus: [CreateSKUGroupSKUInput!]\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n type: String!\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationCreateSkuPriceInput {\n compareAtValue: SimpleMoneyInput\n skuId: ID!\n value: SimpleMoneyInput!\n}\n\ninput MutationReduceInventoryInput {\n locationId: ID!\n quantity: Int!\n reasonName: String\n references: [CreateReferenceInput!]\n skuId: ID!\n}\n\ninput MutationReleaseInventoryInput {\n locationId: ID!\n quantity: Int!\n reasonName: String\n references: [CreateReferenceInput!]\n skuId: ID!\n}\n\ninput MutationRemoveAttributeValuesFromAttributeInput {\n attributeValueIds: [String!]!\n}\n\ninput MutationRemoveAttributeValuesFromSKUInput {\n attributeValueIds: [String!]!\n}\n\ninput MutationRemoveAttributeValuesFromSkuInput {\n attributeValueIds: [String!]!\n}\n\ninput MutationRemoveAttributesFromSKUGroupInput {\n attributeIds: [String!]!\n}\n\ninput MutationRemoveAttributesFromSkuGroupInput {\n attributeIds: [String!]!\n}\n\ninput MutationRemoveChannelsFromSKUGroupInput {\n channelIds: [String!]!\n}\n\ninput MutationRemoveChannelsFromSkuGroupInput {\n channelIds: [String!]!\n}\n\ninput MutationRemoveListTreeNodesFromListTreeInput {\n listTreeNodeIds: [String!]!\n}\n\ninput MutationRemoveListTreeNodesFromParentListTreeNodeInput {\n listTreeNodeIds: [String!]!\n}\n\ninput MutationRemoveMediaObjectsFromListInput {\n mediaObjectIds: [String!]!\n}\n\ninput MutationRemoveMediaObjectsFromSKUGroupInput {\n mediaObjectIds: [String!]!\n}\n\ninput MutationRemoveMediaObjectsFromSKUInput {\n mediaObjectIds: [String!]!\n}\n\ninput MutationRemoveMediaObjectsFromSkuGroupInput {\n mediaObjectIds: [String!]!\n}\n\ninput MutationRemoveMediaObjectsFromSkuInput {\n mediaObjectIds: [String!]!\n}\n\ninput MutationRemoveMetafieldsFromAttributeInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveMetafieldsFromAttributeValueInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveMetafieldsFromListInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveMetafieldsFromListTreeInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveMetafieldsFromLocationInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveMetafieldsFromOptionInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveMetafieldsFromOptionValueInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveMetafieldsFromSkuGroupInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveMetafieldsFromSkuInput {\n metafields: [RemoveMetafieldInput!]!\n}\n\ninput MutationRemoveOptionValuesFromListOptionInput {\n valueIds: [String!]!\n}\n\ninput MutationRemoveOptionsFromSKUGroupInput {\n optionIds: [String!]!\n}\n\ninput MutationRemoveOptionsFromSkuGroupInput {\n optionIds: [String!]!\n}\n\ninput MutationRemovePricesFromOptionInput {\n priceIds: [String!]!\n}\n\ninput MutationRemovePricesFromOptionValueInput {\n priceIds: [String!]!\n}\n\ninput MutationRemovePricesFromSKUInput {\n priceIds: [String!]!\n}\n\ninput MutationRemovePricesFromSkuInput {\n priceIds: [String!]!\n}\n\ninput MutationRemoveReferencesFromListInput {\n referenceIds: [String!]!\n}\n\ninput MutationRemoveReferencesFromListTreeInput {\n referenceIds: [String!]!\n}\n\ninput MutationRemoveReferencesFromListTreeNodeInput {\n referenceIds: [String!]!\n}\n\ninput MutationRemoveReferencesFromLocationInput {\n referenceIds: [String!]!\n}\n\ninput MutationRemoveReferencesFromSKUGroupInput {\n referenceIds: [String!]!\n}\n\ninput MutationRemoveReferencesFromSKUInput {\n referenceIds: [String!]!\n}\n\ninput MutationRemoveReferencesFromSkuGroupInput {\n referenceIds: [String!]!\n}\n\ninput MutationRemoveReferencesFromSkuInput {\n referenceIds: [String!]!\n}\n\ninput MutationRemoveSKUGroupFromListsInput {\n listIds: [String!]!\n}\n\ninput MutationRemoveSKUGroupsFromListInput {\n skuGroupIds: [String!]!\n}\n\ninput MutationRemoveSKUsFromLocationInput {\n skuIds: [String!]!\n}\n\ninput MutationRemoveSKUsFromSKUGroupInput {\n skuIds: [String!]!\n}\n\ninput MutationRemoveSkuGroupFromListsInput {\n listIds: [String!]!\n}\n\ninput MutationRemoveSkuGroupsFromListInput {\n skuGroupIds: [String!]!\n}\n\ninput MutationRemoveSkusFromLocationInput {\n skuIds: [String!]!\n}\n\ninput MutationRemoveSkusFromSkuGroupInput {\n skuIds: [String!]!\n}\n\ninput MutationRestockFromCommittedInventoryInput {\n locationId: ID!\n quantity: Int!\n reasonName: String\n references: [CreateReferenceInput!]\n skuId: ID!\n}\n\ninput MutationSetSkuGroupChannelAssociationModeInput {\n \"\"\"\n The channel association mode for this SKU Group. Can be ALL (uses active channels registered to the store) or\n \t\t\t\t\tSELECTIVE (uses custom channel associations).\n \"\"\"\n mode: String!\n}\n\ninput MutationStockInventoryInput {\n locationId: ID!\n quantity: Int!\n reasonName: String\n references: [CreateReferenceInput!]\n skuId: ID!\n}\n\ninput MutationUpdateAttributeInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n description: String\n htmlDescription: String\n label: String\n metafields: [UpsertMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n position: Int\n}\n\ninput MutationUpdateAttributeValueInput {\n label: String\n metafields: [UpsertMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n position: Int\n}\n\ninput MutationUpdateInventoryAdjustmentReasonInput {\n id: ID!\n label: String\n}\n\ninput MutationUpdateListInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n htmlDescription: String\n label: String\n metafields: [UpsertMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n\n \"\"\"The status of the list, one of `ACTIVE`, `DRAFT`, `ARCHIVED`.\"\"\"\n status: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationUpdateListMediaObjectsInput {\n mediaObjects: [UpdateMediaObjectInput!]!\n}\n\ninput MutationUpdateListTreeInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n htmlDescription: String\n label: String\n metafields: [UpsertMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n\n \"\"\"The status of the list tree, one of `ACTIVE`, `ARCHIVED`, `DRAFT`.\"\"\"\n status: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationUpdateListTreeNodeInput {\n listId: String\n listTreeId: String\n parentNodeId: String\n position: Int\n}\n\ninput MutationUpdateLocationInput {\n address: UpdateAddressInput\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n label: String\n metafields: [UpsertMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n\n \"\"\"The status of the location, one of `ACTIVE`, `INACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationUpdateOptionInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n description: String\n htmlDescription: String\n label: String\n metafields: [UpsertMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n position: Int\n shareable: Boolean\n\n \"\"\"\n The type of the Option, one of `TEXT`, `NUMBER`, `LIST`. Option Values are only available on the 'LIST' type.\n \"\"\"\n type: String\n validation: CreateOptionValidationInput\n}\n\ninput MutationUpdateOptionPriceCurrencyCodeInput {\n currencyCode: String!\n}\n\ninput MutationUpdateOptionPriceInput {\n compareAtValue: SimpleMoneyInput\n value: SimpleMoneyInput\n}\n\ninput MutationUpdateOptionValueInput {\n label: String\n metafields: [UpsertMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n position: Int\n}\n\ninput MutationUpdateOptionValuePriceCurrencyCodeInput {\n currencyCode: String!\n}\n\ninput MutationUpdateOptionValuePriceInput {\n compareAtValue: SimpleMoneyInput\n value: SimpleMoneyInput\n}\n\ninput MutationUpdateSKUGroupInput {\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n label: String\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n shortLabel: String @deprecated(reason: \"Use channel-specific overrides for short labels.\")\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationUpdateSKUInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n backorderLimit: Int\n code: String\n\n \"\"\"DEPRECATED. Use unitCost instead.\"\"\"\n cost: Int @deprecated(reason: \"This cost field cannot specify currency code. Use `unitCost` instead.\")\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n disableInventoryTracking: Boolean\n disablePriceOverrides: Boolean\n disableShipping: Boolean\n eanCode: String\n gtinCode: String\n htmlDescription: String\n isbnCode: String\n label: String\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n shortLabel: String @deprecated(reason: \"Use channel-specific overrides for short labels.\")\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n unitCost: SimpleMoneyInput\n\n \"\"\"The unit of weight, one of `KG`, `GR`, `LB`, `OZ`.\"\"\"\n unitOfWeight: String\n upcCode: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n weight: Float\n}\n\ninput MutationUpdateSKUPriceInput {\n compareAtValue: SimpleMoneyInput\n\n \"\"\"\n Update the currency code for this price. When provided, updates the currency code while keeping the numeric value unchanged.\n \"\"\"\n currencyCode: String\n value: SimpleMoneyInput\n}\n\ninput MutationUpdateSkuGroupInput {\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n htmlDescription: String\n label: String\n metafields: [UpsertMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n shortLabel: String @deprecated(reason: \"Use channel-specific overrides for short labels.\")\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n}\n\ninput MutationUpdateSkuGroupMediaObjectsInput {\n mediaObjects: [UpdateMediaObjectInput!]!\n}\n\ninput MutationUpdateSkuGroupOptionPositionsInput {\n positions: [UpdateSKUGroupOptionPositionInput!]!\n}\n\ninput MutationUpdateSkuInput {\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n backorderLimit: Int\n code: String\n\n \"\"\"DEPRECATED. Use unitCost instead.\"\"\"\n cost: Int @deprecated(reason: \"This cost field cannot specify currency code. Use `unitCost` instead.\")\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n createdAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n description: String\n disableInventoryTracking: Boolean\n disablePriceOverrides: Boolean\n disableShipping: Boolean\n eanCode: String\n gtinCode: String\n htmlDescription: String\n isbnCode: String\n label: String\n metafields: [UpsertMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n shortLabel: String @deprecated(reason: \"Use channel-specific overrides for short labels.\")\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n unitCost: SimpleMoneyInput\n\n \"\"\"The unit of weight, one of `KG`, `GR`, `LB`, `OZ`.\"\"\"\n unitOfWeight: String\n upcCode: String\n\n \"\"\"DEPRECATED: Do not use this field.\"\"\"\n updatedAt: DateTime @deprecated(reason: \"This field is only used for Catalog v1 > v2 sync and will be removed in the future.\")\n weight: Float\n}\n\ninput MutationUpdateSkuMediaObjectsInput {\n mediaObjects: [UpdateMediaObjectInput!]!\n}\n\ninput MutationUpdateSkuPriceCurrencyCodeInput {\n currencyCode: String!\n}\n\ninput MutationUpdateSkuPriceInput {\n compareAtValue: SimpleMoneyInput\n value: SimpleMoneyInput\n}\n\n\"\"\"\nFilters items where the name is equal to the specified string or in an array of strings.\n\"\"\"\ninput NameFilter {\n \"\"\"\n Filters items where the name contains the specified string, case-insensitive.\n \"\"\"\n contains: String\n eq: String\n\n \"\"\"Filters items where the name matches any of the specified names.\"\"\"\n in: [String!]\n}\n\nscalar Null\n\ntype NumericOption {\n \"\"\"The timestamp of when the Option was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"A description of the Option.\"\"\"\n description: String\n\n \"\"\"The UUID of the Option\"\"\"\n id: ID!\n\n \"\"\"The display label of the Option\"\"\"\n label: String!\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): OptionMetafieldsConnection\n\n \"\"\"A unique name of the Option.\"\"\"\n name: String!\n\n \"\"\"The position of the option within its SKU group.\"\"\"\n position: Int @deprecated(reason: \"Use the position from the SKUGroup.options connection instead. Position is per-SKU-group relationship.\")\n\n \"\"\"\n Represents the additional cost of a Numeric Option. When empty, it indicates this option allows for flexible pricing.\n \"\"\"\n prices(\n after: String\n before: String\n\n \"\"\"Filter prices by currency code.\"\"\"\n currencyCode: CurrencyCodeFilter\n first: Int\n last: Int\n paginationType: PaginationType = CURSOR\n ): NumericOptionPricesConnection\n\n \"\"\"\n Whether the option is shareable across multiple SKU Groups (a global modifier).\n \"\"\"\n shareable: Boolean!\n\n \"\"\"The UUID of the SKU Group that the Option belongs to.\"\"\"\n skuGroupId: ID! @deprecated(reason: \"Use skuGroupIds or the SKUGroup.options connection instead. An option may belong to multiple SKU groups.\")\n\n \"\"\"The IDs of all SKU groups this option is associated with.\"\"\"\n skuGroupIds: [String!]!\n\n \"\"\"\n The type of the option, one of `TEXT`, `NUMBER`, `LIST`, Option Values are available for the 'LIST' type.\n \"\"\"\n type: String\n\n \"\"\"The timestamp of when the Option was updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"\n Provide validations on how the option can be applied to a SKU. If `TEXT` option then `min` and `max` apply to the number of characters. If `NUMBER` then `min` and `max` apply to the actual number value. If `LIST` then `min` and `max` apply to the number of values that can be selected.\n \"\"\"\n validation: OptionValidation\n}\n\ntype NumericOptionPricesConnection {\n edges: [NumericOptionPricesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype NumericOptionPricesConnectionEdge {\n cursor: String!\n node: OptionPrice\n}\n\nunion Option = ListOption | NumericOption | TextOption\n\ninput OptionIdFilter {\n eq: String\n in: [String!]\n}\n\ninput OptionIdsFilter {\n in: [String!]\n}\n\ntype OptionMetafieldsConnection {\n edges: [OptionMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype OptionMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ninput OptionOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n label: OrderByDirectionEnum\n name: OrderByDirectionEnum\n position: OrderByDirectionEnum\n price: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\n\"\"\"\nRepresents the additional cost of an option added to a SKU group (e.g 'Toppings' option for a coffee drink).\n\"\"\"\ntype OptionPrice {\n \"\"\"The compare-at value of the price.\"\"\"\n compareAtValue: SimpleMoney\n\n \"\"\"The timestamp of when the price was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the price.\"\"\"\n id: ID!\n\n \"\"\"The option that this price belongs to.\"\"\"\n option: Option\n\n \"\"\"The last update timestamp of the price.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The value of the price.\"\"\"\n value: SimpleMoney!\n}\n\ninput OptionPriceIdsFilter {\n in: [String!]\n}\n\ninput OptionPriceOrderBy {\n id: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\n\"\"\"\nProvide validations on how the option can be applied to a SKU. If `TEXT` option then `min` and `max` apply to the number of characters. If `NUMBER` then `min` and `max` apply to the actual number value. If `LIST` then `min` and `max` apply to the number of values that can be selected.\n\"\"\"\ntype OptionValidation {\n \"\"\"The maximum number that can be applied to the option.\"\"\"\n max: Int\n\n \"\"\"The minimum number that can be applied to the option.\"\"\"\n min: Int\n}\n\ntype OptionValue {\n \"\"\"The timestamp of when the Option Value was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The UUID of the Option Value.\"\"\"\n id: ID!\n\n \"\"\"The display label of the Option Value.\"\"\"\n label: String!\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): OptionValueMetafieldsConnection\n\n \"\"\"A unique name of the Option Value.\"\"\"\n name: String!\n\n \"\"\"The option that this value belongs to.\"\"\"\n option: ListOption\n\n \"\"\"The position of the option value.\"\"\"\n position: Int\n\n \"\"\"\n These are all the prices the Option Value can be sold at. The price can be different based the channel where it is listed or if there is a promotion running.\n \"\"\"\n prices(\n after: String\n before: String\n\n \"\"\"Filter prices by currency code.\"\"\"\n currencyCode: CurrencyCodeFilter\n first: Int\n last: Int\n paginationType: PaginationType = CURSOR\n ): OptionValuePricesConnection\n\n \"\"\"The timestamp of when the Option Value was updated.\"\"\"\n updatedAt: DateTime!\n}\n\ninput OptionValueIdFilter {\n eq: String\n}\n\ninput OptionValueIdsFilter {\n in: [String!]\n}\n\ntype OptionValueMetafieldsConnection {\n edges: [OptionValueMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype OptionValueMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ninput OptionValueOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n name: OrderByDirectionEnum\n position: OrderByDirectionEnum\n price: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\n\"\"\"\nRepresents the additional cost of the option value added to a SKU (e.g the option value 'Caramel Drizzle' could have a different cost to other 'Topping' options).\n\"\"\"\ntype OptionValuePrice {\n \"\"\"The compare-at value of the price.\"\"\"\n compareAtValue: SimpleMoney\n\n \"\"\"The timestamp of when the price was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the price.\"\"\"\n id: ID!\n\n \"\"\"The option value that this price belongs to.\"\"\"\n optionValue: OptionValue\n\n \"\"\"The last update timestamp of the price.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The value of the price.\"\"\"\n value: SimpleMoney!\n}\n\ninput OptionValuePriceIdsFilter {\n in: [String!]\n}\n\ninput OptionValuePriceOrderBy {\n id: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\ntype OptionValuePricesConnection {\n edges: [OptionValuePricesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype OptionValuePricesConnectionEdge {\n cursor: String!\n node: OptionValuePrice\n}\n\n\"\"\"The direction in which to order items.\"\"\"\nenum OrderByDirectionEnum {\n ASC\n DESC\n}\n\ntype PageInfo {\n endCursor: String\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n startCursor: String\n}\n\nenum PaginationType {\n CURSOR\n OFFSET\n}\n\n\"\"\"Defines a range of prices.\"\"\"\ntype PriceRange {\n \"\"\"Maximum price.\"\"\"\n max: Float\n\n \"\"\"Minimum price.\"\"\"\n min: Float\n}\n\n\"\"\"\nFilters items that have at least one price in the requested currency and inclusive price range.\n\"\"\"\ninput PriceRangeFilter {\n \"\"\"The three-letter currency code of prices to match.\"\"\"\n currencyCode: String!\n\n \"\"\"\n The inclusive maximum price in integer minor units, the same convention as `SimpleMoneyInput.value`. At least one of min or max is required; the server returns a validation error if both are omitted.\n \"\"\"\n max: Float\n\n \"\"\"\n The inclusive minimum price in integer minor units, the same convention as `SimpleMoneyInput.value`. At least one of min or max is required; the server returns a validation error if both are omitted.\n \"\"\"\n min: Float\n}\n\ntype Query {\n SKU(id: String!): SKU @deprecated(reason: \"Use sku instead.\")\n SKUGroup(id: String!): SKUGroup @deprecated(reason: \"Use skuGroup instead.\")\n SKUGroups(\n after: String\n before: String\n channelId: SKUGroupChannelIdFilter\n createdAt: CreatedAtFilter\n first: Int\n id: SKUGroupIdsFilter\n last: Int\n\n \"\"\"\n Filters SKU groups by list membership: eq is in this list, in is in any of these lists, isNull is in no list, and ne is not in this list.\n \"\"\"\n listId: ListIdFilter\n name: NameFilter\n orderBy: SKUGroupOrderBy\n paginationType: PaginationType = CURSOR\n referenceValue: ReferenceValueFilter\n status: SKUGroupStatusFilter\n updatedAt: UpdatedAtFilter\n ): QuerySKUGroupsConnection @deprecated(reason: \"Use skuGroups instead.\")\n SKUs(after: String, attributeValues: SKUAttributeValueFilter, before: String, createdAt: CreatedAtFilter, first: Int, id: SKUIdsFilter, last: Int, locationId: LocationIdFilter, name: NameFilter, orderBy: SKUOrderBy, paginationType: PaginationType = CURSOR, referenceValue: ReferenceValueFilter, skuGroupId: SKUGroupIdFilter, status: SKUStatusFilter, updatedAt: UpdatedAtFilter): QuerySKUsConnection @deprecated(reason: \"Use skus instead.\")\n _service: _Service!\n attribute(id: String!): Attribute\n attributeValue(id: String!): AttributeValue\n attributeValues(after: String, attributeId: AttributeIdFilter, before: String, createdAt: CreatedAtFilter, first: Int, id: AttributeValueIdsFilter, last: Int, name: NameFilter, orderBy: AttributeValueOrderBy, paginationType: PaginationType = CURSOR, skuId: SKUIdFilter, updatedAt: UpdatedAtFilter): QueryAttributeValuesConnection\n attributes(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: AttributeIdsFilter, last: Int, name: NameFilter, orderBy: AttributeOrderBy, paginationType: PaginationType = CURSOR, skuGroupId: SKUGroupIdFilter, skuGroupStatus: SKUGroupStatusFilter, updatedAt: UpdatedAtFilter): QueryAttributesConnection\n\n \"\"\"\n Special list tree to hold the main categories of the store. It cannot be updated or archived.\n \"\"\"\n categoriesListTree: ListTree\n\n \"\"\"Retrieve a file by its ID.\"\"\"\n file(id: String!): File\n files(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: FileIdsFilter, last: Int, orderBy: FileOrderBy, paginationType: PaginationType = CURSOR, status: FileStatusFilter, storageUrl: FileStorageUrlFilter, updatedAt: UpdatedAtFilter): QueryFilesConnection\n inventoryAdjustment(id: String!): InventoryAdjustment\n\n \"\"\"\n List inventory adjustment reasons available to the current store. Includes both store-scoped and global preset reasons.\n \"\"\"\n inventoryAdjustmentReasons(after: String, before: String, first: Int, last: Int, name: NameFilter, orderBy: InventoryAdjustmentReasonOrderBy, paginationType: PaginationType = CURSOR, status: InventoryAdjustmentReasonStatusFilter): QueryInventoryAdjustmentReasonsConnection\n inventoryAdjustments(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: InventoryAdjustmentIdsFilter, last: Int, locationId: LocationIdFilter, orderBy: InventoryAdjustmentOrderBy, paginationType: PaginationType = CURSOR, reasonName: InventoryAdjustmentReasonNameFilter, referenceValue: ReferenceValueFilter, skuId: SKUIdFilter, type: InventoryAdjustmentTypeFilter): QueryInventoryAdjustmentsConnection\n inventoryCount(locationId: String!, skuId: String!, type: String): [InventoryCount!]\n inventoryCounts(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: InventoryCountIdsFilter, last: Int, locationId: LocationIdFilter, locationStatus: LocationStatusFilter, orderBy: InventoryCountOrderBy, paginationType: PaginationType = CURSOR, skuId: SKUIdFilter, skuStatus: InventoryCountSKUStatusFilter, type: InventoryCountTypeFilter, updatedAt: UpdatedAtFilter): QueryInventoryCountsConnection\n list(id: String!): List\n listTree(id: String!): ListTree\n listTreeNode(id: String!): ListTreeNode\n listTreeNodes(\n after: String\n before: String\n createdAt: CreatedAtFilter\n first: Int\n hasParent: Boolean\n id: ListTreeNodeIdsFilter\n last: Int\n\n \"\"\"\n Filters nodes by their associated list via eq, in, and ne. isNull never matches, since every node belongs to a list.\n \"\"\"\n listId: ListIdFilter\n listStatus: ListTreeNodeListStatusFilter = {in: [\"ACTIVE\", \"DRAFT\"]}\n listTreeId: ListTreeIdFilter\n listTreeStatus: ListTreeNodeListTreeStatusFilter\n orderBy: ListTreeNodeOrderBy\n paginationType: PaginationType = CURSOR\n parentNodeId: ListTreeNodeParentNodeIdFilter\n referenceValue: ReferenceValueFilter\n updatedAt: UpdatedAtFilter\n ): QueryListTreeNodesConnection\n\n \"\"\"List trees. Excludes the special categories list tree.\"\"\"\n listTrees(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: ListTreeIdsFilter, last: Int, name: NameFilter, orderBy: ListTreeOrderBy, paginationType: PaginationType = CURSOR, referenceValue: ReferenceValueFilter, status: ListTreeStatusFilter, updatedAt: UpdatedAtFilter): QueryListTreesConnection\n lists(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: ListIdsFilter, last: Int, name: NameFilter, orderBy: ListOrderBy, paginationType: PaginationType = CURSOR, referenceValue: ReferenceValueFilter, skuGroupId: SKUGroupIdFilter, status: ListStatusFilter, updatedAt: UpdatedAtFilter): QueryListsConnection\n location(id: String!): Location\n locations(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: LocationIdsFilter, last: Int, name: NameFilter, orderBy: LocationOrderBy, paginationType: PaginationType = CURSOR, referenceValue: ReferenceValueFilter, skuId: SKUIdFilter, status: LocationStatusFilter, updatedAt: UpdatedAtFilter): QueryLocationsConnection\n\n \"\"\"Query all option prices.\"\"\"\n optionPrices(\n after: String\n before: String\n\n \"\"\"Filter prices by currency code.\"\"\"\n currencyCode: CurrencyCodeFilter\n first: Int\n\n \"\"\"Filter prices by whether compareAtValue exists (true) or not (false).\"\"\"\n hasCompareAtValue: Boolean\n id: OptionPriceIdsFilter\n last: Int\n optionId: OptionIdFilter\n orderBy: OptionPriceOrderBy\n paginationType: PaginationType = CURSOR\n updatedAt: UpdatedAtFilter\n ): QueryOptionPricesConnection\n\n \"\"\"Query all option value prices.\"\"\"\n optionValuePrices(\n after: String\n before: String\n\n \"\"\"Filter prices by currency code.\"\"\"\n currencyCode: CurrencyCodeFilter\n first: Int\n\n \"\"\"Filter prices by whether compareAtValue exists (true) or not (false).\"\"\"\n hasCompareAtValue: Boolean\n id: OptionValuePriceIdsFilter\n last: Int\n optionValueId: OptionValueIdFilter\n orderBy: OptionValuePriceOrderBy\n paginationType: PaginationType = CURSOR\n updatedAt: UpdatedAtFilter\n ): QueryOptionValuePricesConnection\n optionValues(after: String, before: String, createdAt: CreatedAtFilter, first: Int, id: OptionValueIdsFilter, last: Int, optionId: OptionIdFilter, orderBy: OptionValueOrderBy, paginationType: PaginationType = CURSOR, updatedAt: UpdatedAtFilter): QueryOptionValuesConnection\n options(\n after: String\n\n \"\"\"\n Returns shareable options that are not already associated with the specified SKU group. Use this to find options that can be added to a SKU group. Cannot be combined with skuGroupId or skuGroupStatus filters.\n \"\"\"\n assignableToSkuGroupId: String\n before: String\n createdAt: CreatedAtFilter\n first: Int\n id: OptionIdsFilter\n label: LabelFilter\n last: Int\n name: NameFilter\n orderBy: OptionOrderBy\n paginationType: PaginationType = CURSOR\n\n \"\"\"\n Filter options by their shareable status. When true, returns only shareable options; when false, returns only non-shareable options.\n \"\"\"\n shareable: Boolean\n skuGroupId: SKUGroupIdFilter\n skuGroupStatus: SKUGroupStatusFilter\n updatedAt: UpdatedAtFilter\n ): QueryOptionsConnection\n sku(id: String!): SKU\n skuGroup(id: String!): SKUGroup\n skuGroups(\n after: String\n before: String\n channelId: SKUGroupChannelIdFilter\n createdAt: CreatedAtFilter\n first: Int\n hasCompareAt: HasCompareAtFilter\n\n \"\"\"\n When true, returns only SKU groups with at least one SKU. When false, returns only SKU groups with zero SKUs.\n \"\"\"\n hasSKUs: Boolean\n id: SKUGroupIdsFilter\n label: LabelFilter\n last: Int\n\n \"\"\"\n Filters SKU groups by list membership: eq is in this list, in is in any of these lists, isNull is in no list, and ne is not in this list.\n \"\"\"\n listId: ListIdFilter\n name: NameFilter\n orderBy: SKUGroupOrderBy\n paginationType: PaginationType = CURSOR\n priceRange: PriceRangeFilter\n referenceValue: ReferenceValueFilter\n status: SKUGroupStatusFilter\n type: SKUGroupTypeFilter\n updatedAt: UpdatedAtFilter\n ): QuerySkuGroupsConnection\n\n \"\"\"Query all SKU prices.\"\"\"\n skuPrices(\n after: String\n before: String\n\n \"\"\"Filter prices by currency code.\"\"\"\n currencyCode: CurrencyCodeFilter\n first: Int\n\n \"\"\"Filter prices by whether compareAtValue exists (true) or not (false).\"\"\"\n hasCompareAtValue: Boolean\n id: SKUPriceIdsFilter\n last: Int\n orderBy: SKUPriceOrderBy\n paginationType: PaginationType = CURSOR\n skuId: SKUIdFilter\n\n \"\"\"\n Filter prices by the status of the parent SKU (ACTIVE, DRAFT, ARCHIVED).\n \"\"\"\n skuStatus: SKUStatusFilter\n updatedAt: UpdatedAtFilter\n ): QuerySkuPricesConnection\n skus(\n after: String\n attributeValues: SKUAttributeValueFilter\n before: String\n code: SKUCodeFilter\n createdAt: CreatedAtFilter\n eanCode: SKUEanCodeFilter\n first: Int\n gtinCode: SKUGtinCodeFilter\n id: SKUIdsFilter\n isbnCode: SKUIsbnCodeFilter\n label: LabelFilter\n last: Int\n locationId: LocationIdFilter\n name: NameFilter\n orderBy: SKUOrderBy\n paginationType: PaginationType = CURSOR\n\n \"\"\"\n A string filter in the ODATA format. ex: \"label eq 'shirt' and contains(code, '123')\".\n\n\n Supported columns: `label`, `code`\n\n Supported operators: `eq`, `ne`, `lt`, `gt`, `and`, `or`\n\n Supported functions: `contains`\n \"\"\"\n queryFilter: String\n referenceValue: ReferenceValueFilter\n skuGroupId: SKUGroupIdFilter\n\n \"\"\"\n Filter SKUs by their SKU group's status. SKUs without a SKU group will be excluded when this filter is present.\n \"\"\"\n skuGroupStatus: SKUGroupStatusFilter\n status: SKUStatusFilter\n upcCode: SKUUpcCodeFilter\n updatedAt: UpdatedAtFilter\n ): QuerySkusConnection\n}\n\ntype QueryAttributeValuesConnection {\n edges: [QueryAttributeValuesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryAttributeValuesConnectionEdge {\n cursor: String!\n node: AttributeValue\n}\n\ntype QueryAttributesConnection {\n edges: [QueryAttributesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryAttributesConnectionEdge {\n cursor: String!\n node: Attribute\n}\n\ntype QueryFilesConnection {\n edges: [QueryFilesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryFilesConnectionEdge {\n cursor: String!\n node: File\n}\n\ntype QueryInventoryAdjustmentReasonsConnection {\n edges: [QueryInventoryAdjustmentReasonsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryInventoryAdjustmentReasonsConnectionEdge {\n cursor: String!\n node: InventoryAdjustmentReason\n}\n\ntype QueryInventoryAdjustmentsConnection {\n edges: [QueryInventoryAdjustmentsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryInventoryAdjustmentsConnectionEdge {\n cursor: String!\n node: InventoryAdjustment\n}\n\ntype QueryInventoryCountsConnection {\n edges: [QueryInventoryCountsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryInventoryCountsConnectionEdge {\n cursor: String!\n node: InventoryCount\n}\n\ntype QueryListTreeNodesConnection {\n edges: [QueryListTreeNodesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryListTreeNodesConnectionEdge {\n cursor: String!\n node: ListTreeNode\n}\n\ntype QueryListTreesConnection {\n edges: [QueryListTreesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryListTreesConnectionEdge {\n cursor: String!\n node: ListTree\n}\n\ntype QueryListsConnection {\n edges: [QueryListsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryListsConnectionEdge {\n cursor: String!\n node: List\n}\n\ntype QueryLocationsConnection {\n edges: [QueryLocationsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryLocationsConnectionEdge {\n cursor: String!\n node: Location\n}\n\ntype QueryOptionPricesConnection {\n edges: [QueryOptionPricesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryOptionPricesConnectionEdge {\n cursor: String!\n node: OptionPrice\n}\n\ntype QueryOptionValuePricesConnection {\n edges: [QueryOptionValuePricesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryOptionValuePricesConnectionEdge {\n cursor: String!\n node: OptionValuePrice\n}\n\ntype QueryOptionValuesConnection {\n edges: [QueryOptionValuesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryOptionValuesConnectionEdge {\n cursor: String!\n node: OptionValue\n}\n\ntype QueryOptionsConnection {\n edges: [QueryOptionsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryOptionsConnectionEdge {\n cursor: String!\n node: Option\n}\n\ntype QuerySKUGroupsConnection {\n edges: [QuerySKUGroupsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QuerySKUGroupsConnectionEdge {\n cursor: String!\n node: SKUGroup\n}\n\ntype QuerySKUsConnection {\n edges: [QuerySKUsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QuerySKUsConnectionEdge {\n cursor: String!\n node: SKU\n}\n\ntype QuerySkuGroupsConnection {\n edges: [QuerySkuGroupsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QuerySkuGroupsConnectionEdge {\n cursor: String!\n node: SKUGroup\n}\n\ntype QuerySkuPricesConnection {\n edges: [QuerySkuPricesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QuerySkuPricesConnectionEdge {\n cursor: String!\n node: SKUPrice\n}\n\ntype QuerySkusConnection {\n edges: [QuerySkusConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QuerySkusConnectionEdge {\n cursor: String!\n node: SKU\n}\n\n\"\"\"A reference to the resource in an external service.\"\"\"\ntype Reference {\n \"\"\"The globally-unique ID of the reference.\"\"\"\n id: ID\n\n \"\"\"The origin or location of the reference. Ex. OLS or POYNT\"\"\"\n origin: String\n\n \"\"\"The identifier of the resource in an external service\"\"\"\n value: String\n}\n\ninput ReferenceOriginFilter {\n eq: String\n in: [String!]\n}\n\ninput ReferenceValueFilter {\n eq: String\n in: [String!]\n}\n\ninput RemoveMetafieldInput {\n key: String!\n namespace: String!\n}\n\n\"\"\"A SKU represents a stock keeping unit (SKU) in the catalog.\"\"\"\ntype SKU {\n \"\"\"\n HTML description for the SKU. Will be used to display rich text content to customers.\n \"\"\"\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"\n A SKU group is a grouping of related SKUs. It provides information about all the SKUs that are sold together on storefronts or devices.\n \"\"\"\n SKUGroup: SKUGroup @deprecated(reason: \"Use skuGroup instead.\")\n\n \"\"\"The timestamp of when the SKU was archived.\"\"\"\n archivedAt: DateTime\n\n \"\"\"Attribute values of SKU.\"\"\"\n attributeValues(after: String, before: String, first: Int, last: Int, orderBy: AttributeValueOrderBy, paginationType: PaginationType = CURSOR): SKUAttributeValuesConnection\n\n \"\"\"\n Attributes are properties or characteristics of the SKU. For example, color or size.\n \"\"\"\n attributes(after: String, before: String, first: Int, id: AttributeIdsFilter, last: Int, orderBy: AttributeOrderBy, paginationType: PaginationType = CURSOR): SKUAttributesConnection\n\n \"\"\"\n The number of backorders allowed for the SKU. If set to 0, backorders are not allowed. If set to null, backorders are allowed without limit.\n \"\"\"\n backorderLimit: Int\n\n \"\"\"The unique code for the SKU.\"\"\"\n code: String!\n\n \"\"\"DEPRECATED. Use unitCost instead.\"\"\"\n cost: Int @deprecated(reason: \"This cost field cannot specify currency code. Use `unitCost` instead.\")\n\n \"\"\"The timestamp of when the SKU was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The description of the SKU.\"\"\"\n description: String\n\n \"\"\"Flag to mark whether stock should be tracked for the SKU.\"\"\"\n disableInventoryTracking: Boolean\n\n \"\"\"Flag to mark whether or not a custom price can be provided.\"\"\"\n disablePriceOverrides: Boolean\n\n \"\"\"Flag to mark whether the SKU should be shipped or not.\"\"\"\n disableShipping: Boolean\n\n \"\"\"The EAN code for the SKU.\"\"\"\n eanCode: String\n\n \"\"\"The GTIN code for the SKU.\"\"\"\n gtinCode: String\n\n \"\"\"\n HTML description for the SKU. Will be used to display rich text content to customers.\n \"\"\"\n htmlDescription: String\n\n \"\"\"The globally-unique ID of the SKU.\"\"\"\n id: ID!\n\n \"\"\"\n An immutable entity that represents a change in state of a quantity of SKU at a particular time and location. Each adjustment will either have a positive, negative, or neutral impact on the count of available SKUs in a location.\n \"\"\"\n inventoryAdjustments(after: String, before: String, first: Int, last: Int, orderBy: InventoryAdjustmentOrderBy, paginationType: PaginationType = CURSOR): SKUInventoryAdjustmentsConnection\n\n \"\"\"\n The quantity of a SKU in a specific state at a particular time and location.\n \"\"\"\n inventoryCounts(after: String, before: String, first: Int, last: Int, locationId: LocationIdFilter, locationStatus: LocationStatusFilter, orderBy: InventoryCountOrderBy, paginationType: PaginationType = CURSOR, skuStatus: InventoryCountSKUStatusFilter, type: InventoryCountTypeFilter): SKUInventoryCountsConnection\n\n \"\"\"The ISBN code for the SKU.\"\"\"\n isbnCode: String\n\n \"\"\"The display label of the SKU.\"\"\"\n label: String!\n\n \"\"\"The locations where the SKU is available.\"\"\"\n locations(after: String, before: String, first: Int, last: Int, orderBy: LocationOrderBy, paginationType: PaginationType = CURSOR, status: LocationStatusFilter): SKULocationsConnection\n\n \"\"\"Media stored under this SKU.\"\"\"\n mediaObjects(after: String, before: String, first: Int, last: Int, paginationType: PaginationType = CURSOR): SKUMediaObjectsConnection\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): SKUMetafieldsConnection\n\n \"\"\"A unique name for the SKU.\"\"\"\n name: String!\n\n \"\"\"\n These are all the prices the SKU can be sold at. The price can be different based the channel where it is listed or if there is a promotion running.\n \"\"\"\n prices(\n after: String\n before: String\n\n \"\"\"Filter prices by currency code.\"\"\"\n currencyCode: CurrencyCodeFilter\n first: Int\n last: Int\n ): SKUPricesConnection\n\n \"\"\"\n A reference to the resource in an external service. This can be useful for integrating the resource to any external service.\n \"\"\"\n references(after: String, before: String, first: Int, last: Int, origin: ReferenceOriginFilter, paginationType: PaginationType = CURSOR): SKUReferencesConnection\n\n \"\"\"A short label for the SKU, useful for UI with limited space.\"\"\"\n shortLabel: String @deprecated(reason: \"Use channel-specific overrides for short labels.\")\n\n \"\"\"\n A SKU group is a grouping of related SKUs. It provides information about all the SKUs that are sold together on storefronts or devices.\n \"\"\"\n skuGroup: SKUGroup\n\n \"\"\"The status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String\n\n \"\"\"\n The cost of the SKU per unit. This is a money object that includes the value and currency code.\n \"\"\"\n unitCost: SimpleMoney\n\n \"\"\"The unit of weight, one of `KG`, `GR`, `LB`, `OZ`.\"\"\"\n unitOfWeight: String\n\n \"\"\"The UPC code for the SKU.\"\"\"\n upcCode: String\n\n \"\"\"The timestamp of when the SKU was updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The weight of the SKU.\"\"\"\n weight: Float\n}\n\ninput SKUAttributeValueFilter {\n \"\"\"\n Filters SKUs that have all of the specified attribute value names, e.g. [\"red\", \"large\"].\n \"\"\"\n has: [String!]\n}\n\ntype SKUAttributeValuesConnection {\n edges: [SKUAttributeValuesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUAttributeValuesConnectionEdge {\n cursor: String!\n node: AttributeValue\n}\n\ntype SKUAttributesConnection {\n edges: [SKUAttributesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUAttributesConnectionEdge {\n cursor: String!\n node: Attribute\n}\n\ninput SKUCodeFilter {\n \"\"\"\n Filters SKUs where the code contains the specified string, case-insensitive.\n \"\"\"\n contains: String\n eq: String\n\n \"\"\"Filters SKUs where the code matches any of the specified codes.\"\"\"\n in: [String!]\n}\n\ninput SKUEanCodeFilter {\n eq: String\n in: [String!]\n}\n\ntype SKUGroup {\n \"\"\"\n HTML description for the SKU group. Will be used to display rich text content to customers.\n \"\"\"\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"A SKU represents a stock keeping unit (SKU) in the catalog.\"\"\"\n SKUs(\n after: String\n attributeValues: SKUAttributeValueFilter\n before: String\n createdAt: CreatedAtFilter\n first: Int\n label: LabelFilter\n last: Int\n locationId: LocationIdFilter\n name: NameFilter\n paginationType: PaginationType = CURSOR\n\n \"\"\"\n A string filter in the ODATA format. ex: \"label eq 'shirt' and contains(code, '123')\".\n\n\n Supported columns: `label`, `code`\n\n Supported operators: `eq`, `ne`, `lt`, `gt`, `and`, `or`\n\n Supported functions: `contains`\n \"\"\"\n queryFilter: String\n referenceValue: ReferenceValueFilter\n status: SKUStatusFilter\n updatedAt: UpdatedAtFilter\n ): SKUGroupSKUsConnection @deprecated(reason: \"Use skus instead.\")\n\n \"\"\"The timestamp of when the SKU was activated.\"\"\"\n activatedAt: DateTime\n\n \"\"\"The timestamp of when the SKU was archived.\"\"\"\n archivedAt: DateTime\n\n \"\"\"Attributes of SKU Group.\"\"\"\n attributes(after: String, before: String, first: Int, id: AttributeIdsFilter, last: Int, orderBy: AttributeOrderBy, paginationType: PaginationType = CURSOR): SKUGroupAttributesConnection\n\n \"\"\"\n The channel association mode for this SKU Group. Can be ALL (uses active channels registered to the store) or\n \t\t\t\tSELECTIVE (uses custom channel associations).\n \"\"\"\n channelAssociationMode: String\n\n \"\"\"An association to a channel that exists in the Channel API.\"\"\"\n channels(after: String, before: String, first: Int, last: Int): SKUGroupChannelsConnection\n\n \"\"\"\n The compare-at price range of the SKU group, showing min and max compare-at prices of SKUs in the group.\n \"\"\"\n compareAtPriceRange(\n \"\"\"\n Filter SKUs by status. Defaults to ACTIVE and DRAFT, excluding ARCHIVED SKUs.\n \"\"\"\n status: SKUStatusFilter = {in: [\"ACTIVE\", \"DRAFT\"]}\n ): PriceRange\n\n \"\"\"The timestamp of when the SKU was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The merchant defined description of the group.\"\"\"\n description: String\n\n \"\"\"\n HTML description for the SKU group. Will be used to display rich text content to customers.\n \"\"\"\n htmlDescription: String\n\n \"\"\"The globally-unique ID of the group.\"\"\"\n id: ID!\n\n \"\"\"The display label of the group.\"\"\"\n label: String!\n\n \"\"\"\n A list is a group of SKU groups that are generally organized by similar characteristics.\n \"\"\"\n lists(\n after: String\n before: String\n first: Int\n\n \"\"\"\n Filters the returned lists by id via eq, in, and ne. isNull is not applicable here and is ignored.\n \"\"\"\n id: ListIdFilter\n last: Int\n orderBy: ListOrderBy\n paginationType: PaginationType = CURSOR\n status: ListStatusFilter\n ): SKUGroupListsConnection\n\n \"\"\"Media objects stored under the SKU Group.\"\"\"\n mediaObjects(after: String, before: String, first: Int, last: Int, paginationType: PaginationType = CURSOR): SKUGroupMediaObjectsConnection\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): SKUGroupMetafieldsConnection\n\n \"\"\"A unique human-friendly identifier for the group.\"\"\"\n name: String!\n\n \"\"\"An option is a add-on that can be added on to a SKU group.\"\"\"\n options(after: String, before: String, first: Int, last: Int, orderBy: OptionOrderBy, paginationType: PaginationType = CURSOR): SKUGroupOptionsConnection\n\n \"\"\"\n The price range of the SKU group, showing min and max prices of SKUs in the group.\n \"\"\"\n priceRange(\n \"\"\"\n Filter SKUs by status. Defaults to ACTIVE and DRAFT, excluding ARCHIVED SKUs.\n \"\"\"\n status: SKUStatusFilter = {in: [\"ACTIVE\", \"DRAFT\"]}\n ): PriceRange\n\n \"\"\"\n A reference to the resource in an external service. This can be useful for integrating the resource to any external service.\n \"\"\"\n references(after: String, before: String, first: Int, last: Int, origin: ReferenceOriginFilter, paginationType: PaginationType = CURSOR): SKUGroupReferencesConnection\n\n \"\"\"\n A short label for the group. Can be used instead of the label on smaller screens.\n \"\"\"\n shortLabel: String @deprecated(reason: \"Use channel-specific overrides for short labels.\")\n\n \"\"\"\n The count of all SKUs associated with the SKU Group. Can be filtered by status. The default statuses are ACTIVE and DRAFT.\n \"\"\"\n skuCount(status: SKUStatusFilter = {in: [\"ACTIVE\", \"DRAFT\"]}): Int\n\n \"\"\"A SKU represents a stock keeping unit (SKU) in the catalog.\"\"\"\n skus(\n after: String\n attributeValues: SKUAttributeValueFilter\n before: String\n code: SKUCodeFilter\n createdAt: CreatedAtFilter\n eanCode: SKUEanCodeFilter\n first: Int\n gtinCode: SKUGtinCodeFilter\n isbnCode: SKUIsbnCodeFilter\n label: LabelFilter\n last: Int\n locationId: LocationIdFilter\n name: NameFilter\n orderBy: SKUOrderBy\n paginationType: PaginationType = CURSOR\n\n \"\"\"\n A string filter in the ODATA format. ex: \"label eq 'shirt' and contains(code, '123')\".\n\n\n Supported columns: `label`, `code`\n\n Supported operators: `eq`, `ne`, `lt`, `gt`, `and`, `or`\n\n Supported functions: `contains`\n \"\"\"\n queryFilter: String\n referenceValue: ReferenceValueFilter\n status: SKUStatusFilter\n upcCode: SKUUpcCodeFilter\n updatedAt: UpdatedAtFilter\n ): SKUGroupSkusConnection\n\n \"\"\"The status of the SKU Group, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\"\"\"\n status: String!\n\n \"\"\"\n The type of the SKU Group, typically PHYSICAL or DIGITAL, but can also be a custom type.\n \"\"\"\n type: String!\n\n \"\"\"The timestamp of when the SKU was updated.\"\"\"\n updatedAt: DateTime!\n}\n\ntype SKUGroupAttributesConnection {\n edges: [SKUGroupAttributesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupAttributesConnectionEdge {\n cursor: String!\n node: Attribute\n}\n\n\"\"\"\nA SKU Group Channel represents an association with the application by which your SKUs are sold. Can be a platform, marketplace, POS, and more.\n\"\"\"\ntype SKUGroupChannel {\n \"\"\"The globally-unique ID of the channel.\"\"\"\n channelId: ID!\n\n \"\"\"The timestamp of when the channel association was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the channel association.\"\"\"\n id: ID!\n\n \"\"\"The status of the channel association. One of `ACTIVE`, `INACTIVE`\"\"\"\n status: String!\n\n \"\"\"The timestamp of when the channel association was updated.\"\"\"\n updatedAt: DateTime!\n}\n\ninput SKUGroupChannelAddInput {\n channelId: String!\n}\n\ninput SKUGroupChannelIdFilter {\n eq: String\n in: [String!]\n}\n\ntype SKUGroupChannelsConnection {\n edges: [SKUGroupChannelsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupChannelsConnectionEdge {\n cursor: String!\n node: SKUGroupChannel\n}\n\ninput SKUGroupIdFilter {\n eq: String\n in: [String!]\n}\n\ninput SKUGroupIdsFilter {\n eq: String\n in: [String!]\n}\n\ntype SKUGroupListsConnection {\n edges: [SKUGroupListsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupListsConnectionEdge {\n cursor: String!\n node: List\n}\n\ntype SKUGroupMediaObjectsConnection {\n edges: [SKUGroupMediaObjectsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupMediaObjectsConnectionEdge {\n cursor: String!\n node: Media\n}\n\ntype SKUGroupMetafieldsConnection {\n edges: [SKUGroupMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ntype SKUGroupOptionsConnection {\n edges: [SKUGroupOptionsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupOptionsConnectionEdge {\n cursor: String!\n node: Option\n}\n\ninput SKUGroupOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n label: OrderByDirectionEnum\n lowestPrice: OrderByDirectionEnum\n name: OrderByDirectionEnum\n saleCount: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\ntype SKUGroupReferencesConnection {\n edges: [SKUGroupReferencesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupReferencesConnectionEdge {\n cursor: String!\n node: Reference\n}\n\ntype SKUGroupSKUsConnection {\n edges: [SKUGroupSKUsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupSKUsConnectionEdge {\n cursor: String!\n node: SKU\n}\n\ntype SKUGroupSkusConnection {\n edges: [SKUGroupSkusConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUGroupSkusConnectionEdge {\n cursor: String!\n node: SKU\n}\n\n\"\"\"\nFilter for the status of the SKU Group, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\n\"\"\"\ninput SKUGroupStatusFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"\nFilter for the type of the SKU Group, typically PHYSICAL or DIGITAL, but can also be a custom type.\n\"\"\"\ninput SKUGroupTypeFilter {\n eq: String\n in: [String!]\n}\n\ninput SKUGtinCodeFilter {\n eq: String\n in: [String!]\n}\n\ninput SKUIdFilter {\n eq: String\n in: [String!]\n}\n\ninput SKUIdsFilter {\n in: [String!]\n}\n\ntype SKUInventoryAdjustmentsConnection {\n edges: [SKUInventoryAdjustmentsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUInventoryAdjustmentsConnectionEdge {\n cursor: String!\n node: InventoryAdjustment\n}\n\ntype SKUInventoryCountsConnection {\n edges: [SKUInventoryCountsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUInventoryCountsConnectionEdge {\n cursor: String!\n node: InventoryCount\n}\n\ninput SKUIsbnCodeFilter {\n eq: String\n in: [String!]\n}\n\ntype SKULocationsConnection {\n edges: [SKULocationsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKULocationsConnectionEdge {\n cursor: String!\n node: Location\n}\n\ntype SKUMediaObjectsConnection {\n edges: [SKUMediaObjectsConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUMediaObjectsConnectionEdge {\n cursor: String!\n node: Media\n}\n\ntype SKUMetafieldsConnection {\n edges: [SKUMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\ninput SKUOrderBy {\n createdAt: OrderByDirectionEnum\n id: OrderByDirectionEnum\n label: OrderByDirectionEnum\n name: OrderByDirectionEnum\n price: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\n\"\"\"Represents the cost of a SKU\"\"\"\ntype SKUPrice {\n \"\"\"A SKU represents a stock keeping unit (SKU) in the catalog.\"\"\"\n SKU: SKU @deprecated(reason: \"Use sku instead.\")\n\n \"\"\"The compare-at value of the price.\"\"\"\n compareAtValue: SimpleMoney\n\n \"\"\"The timestamp of when the price was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the price.\"\"\"\n id: ID!\n\n \"\"\"A SKU represents a stock keeping unit (SKU) in the catalog.\"\"\"\n sku: SKU\n\n \"\"\"The last update timestamp of the price.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The value of the price.\"\"\"\n value: SimpleMoney!\n}\n\ninput SKUPriceIdsFilter {\n in: [String!]\n}\n\ninput SKUPriceOrderBy {\n id: OrderByDirectionEnum\n updatedAt: OrderByDirectionEnum\n}\n\ntype SKUPricesConnection {\n edges: [SKUPricesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUPricesConnectionEdge {\n cursor: String!\n node: SKUPrice\n}\n\ntype SKUReferencesConnection {\n edges: [SKUReferencesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype SKUReferencesConnectionEdge {\n cursor: String!\n node: Reference\n}\n\n\"\"\"\nFilter for the status of the SKU, one of `DRAFT`, `ACTIVE`, `ARCHIVED`.\n\"\"\"\ninput SKUStatusFilter {\n eq: String\n in: [String!]\n}\n\ninput SKUUpcCodeFilter {\n eq: String\n in: [String!]\n}\n\n\"\"\"\nThe currency and amount for a financial transaction, such as a balance or payment due. Use for value representations with default transactable-value precision.\n\"\"\"\ntype SimpleMoney {\n \"\"\"A three-character ISO-4217 currency code.\"\"\"\n currencyCode: String!\n\n \"\"\"\n The integer value, which might be: An integer for currencies like JPY that are not typically fractional; or, a decimal fraction for currencies that are subdivided into hundredths, like USD; or, subdivided into thousandths, like TND. For the required number of decimal places for a currency code, see ISO-4217 Currency Codes. This field is typed as Float to be able to support values larger than GraphQL's 32-bit Integer.\n \"\"\"\n value: Float!\n}\n\n\"\"\"\nThe currency and amount for a financial transaction, such as a balance or payment due. Use for value representations with default transactable-value precision.\n\"\"\"\ninput SimpleMoneyInput {\n currencyCode: String!\n\n \"\"\"\n Integer minor units as a JSON number with no fractional part (for example `1999` for $19.99 USD). Decimals such as `19.99` are rejected. Typed as Float so values can exceed GraphQL's 32-bit Integer. JPY uses the integral amount; USD is hundredths; TND is thousandths.\n \"\"\"\n value: Float!\n}\n\ntype TextOption {\n \"\"\"\n HTML description for the Option. Will be used to display rich text content to customers.\n \"\"\"\n HTMLDescription: String @deprecated(reason: \"Use htmlDescription instead.\")\n\n \"\"\"The timestamp of when the Option was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"A description of the Option.\"\"\"\n description: String\n\n \"\"\"\n HTML description for the Option. Will be used to display rich text content to customers.\n \"\"\"\n htmlDescription: String\n\n \"\"\"The UUID of the Option\"\"\"\n id: ID!\n\n \"\"\"The display label of the Option\"\"\"\n label: String!\n metafields(\n after: String\n before: String\n first: Int\n\n \"\"\"The key of the metafield. Requires namespace to be provided.\"\"\"\n key: String\n last: Int\n\n \"\"\"The namespace of the metafield. Required when key is provided.\"\"\"\n namespace: String\n ): OptionMetafieldsConnection\n\n \"\"\"A unique name of the Option.\"\"\"\n name: String!\n\n \"\"\"The position of the option within its SKU group.\"\"\"\n position: Int @deprecated(reason: \"Use the position from the SKUGroup.options connection instead. Position is per-SKU-group relationship.\")\n\n \"\"\"\n Represents the additional cost of a Text Option. When empty, it indicates this option allows for flexible pricing.\n \"\"\"\n prices(\n after: String\n before: String\n\n \"\"\"Filter prices by currency code.\"\"\"\n currencyCode: CurrencyCodeFilter\n first: Int\n last: Int\n paginationType: PaginationType = CURSOR\n ): TextOptionPricesConnection\n\n \"\"\"\n Whether the option is shareable across multiple SKU Groups (a global modifier).\n \"\"\"\n shareable: Boolean!\n\n \"\"\"The UUID of the SKU Group that the Option belongs to.\"\"\"\n skuGroupId: ID! @deprecated(reason: \"Use skuGroupIds or the SKUGroup.options connection instead. An option may belong to multiple SKU groups.\")\n\n \"\"\"The IDs of all SKU groups this option is associated with.\"\"\"\n skuGroupIds: [String!]!\n\n \"\"\"\n The type of the option, one of `TEXT`, `NUMBER`, `LIST`, Option Values are available for the 'LIST' type.\n \"\"\"\n type: String\n\n \"\"\"The timestamp of when the Option was updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"\n Provide validations on how the option can be applied to a SKU. If `TEXT` option then `min` and `max` apply to the number of characters. If `NUMBER` then `min` and `max` apply to the actual number value. If `LIST` then `min` and `max` apply to the number of values that can be selected.\n \"\"\"\n validation: OptionValidation\n}\n\ntype TextOptionPricesConnection {\n edges: [TextOptionPricesConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype TextOptionPricesConnectionEdge {\n cursor: String!\n node: OptionPrice\n}\n\ninput UpdateAddressInput {\n addressDetails: AddressDetailsInput\n addressLine1: String\n addressLine2: String\n addressLine3: String\n adminArea1: String\n adminArea2: String\n adminArea3: String\n adminArea4: String\n countryCode: String\n postalCode: String\n}\n\n\"\"\"Input for updating an existing file.\"\"\"\ninput UpdateFileInput {\n contentType: String\n description: String\n filename: String\n}\n\ninput UpdateMediaObjectInput {\n id: String!\n label: String\n metafields: [UpsertMetafieldInput!]\n\n \"\"\"\n Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".\n \"\"\"\n name: String\n position: Int\n\n \"\"\"\n The type of the media. Currently accepted values on write: `VIDEO`, `IMAGE`, `AUDIO`. `PHOTO` is not accepted on create or update.\n \"\"\"\n type: String\n url: String\n}\n\n\"\"\"A single option and its new position within a SKU group.\"\"\"\ninput UpdateSKUGroupOptionPositionInput {\n optionId: String!\n position: Int!\n}\n\n\"\"\"Filters items based on the date they were last updated.\"\"\"\ninput UpdatedAtFilter {\n gt: String\n lt: String\n}\n\ninput UpsertMetafieldInput {\n key: String!\n namespace: String!\n\n \"\"\"\n Metafield type. Currently accepted values (lowercase): `boolean`, `string`, `stringMultiLine`, `number`, `numberDecimal`, `date`, `dateTime`, `json`, `measurement`, `url`, `reference`, `money`, `list.string`, `list.number`, `list.numberDecimal`, `list.measurement`, `list.date`, `list.url`.\n \"\"\"\n type: String!\n value: String!\n}\n\ntype _Service {\n \"\"\"\n The sdl representing the federated service capabilities. Includes federation directives, removes federation types, and includes rest of full schema after schema directives have been applied\n \"\"\"\n sdl: String\n}", "types": [ { "fields": [ @@ -4391,6 +4434,7 @@ "type": "String!" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -4797,6 +4841,7 @@ "type": "[CreateMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -4910,6 +4955,7 @@ "type": "[CreateMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -4918,7 +4964,7 @@ "type": "Int" }, { - "description": "The type of the media, one of `PHOTO`, `VIDEO`, `IMAGE`, `AUDIO`.", + "description": "The type of the media. Currently accepted values on write: `VIDEO`, `IMAGE`, `AUDIO`. `PHOTO` is not accepted on create or update.", "name": "type", "type": "String!" }, @@ -4941,6 +4987,7 @@ "type": "String!" }, { + "description": "Metafield type. Currently accepted values (lowercase): `boolean`, `string`, `stringMultiLine`, `number`, `numberDecimal`, `date`, `dateTime`, `json`, `measurement`, `url`, `reference`, `money`, `list.string`, `list.number`, `list.numberDecimal`, `list.measurement`, `list.date`, `list.url`.", "name": "type", "type": "String!" }, @@ -4967,6 +5014,7 @@ "type": "[CreateMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -5034,6 +5082,7 @@ "type": "[CreateMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -5092,6 +5141,7 @@ "type": "[CreateMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -5176,6 +5226,7 @@ "type": "[CreateMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -5303,6 +5354,7 @@ "type": "[CreateMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -5560,6 +5612,22 @@ "kind": "input", "name": "GeoCoordinatesInput" }, + { + "fields": [ + { + "description": "The three-letter currency code of prices to match.", + "name": "currencyCode", + "type": "String!" + }, + { + "description": "When true, returns items with at least one price that has a compareAtValue > 0 (on sale) in the requested currency. When false, returns items that have at least one price in the requested currency but none with a compareAtValue > 0 (available at regular price in that currency).", + "name": "exists", + "type": "Boolean!" + } + ], + "kind": "input", + "name": "HasCompareAtFilter" + }, { "fields": [ { @@ -6011,6 +6079,10 @@ { "name": "isNull", "type": "Boolean" + }, + { + "name": "ne", + "type": "String" } ], "kind": "input", @@ -6113,12 +6185,7 @@ "type": "ID!" }, { - "description": "Whether the option is shareable across multiple SKU Groups (a global modifier).", - "name": "shareable", - "type": "Boolean!" - }, - { - "description": "The display lable of the Option", + "description": "The display label of the Option", "name": "label", "type": "String!" }, @@ -6132,7 +6199,7 @@ "type": "String!" }, { - "description": "The position of the option.", + "description": "The position of the option within its SKU group.", "name": "position", "type": "Int" }, @@ -6146,6 +6213,11 @@ "name": "prices", "type": "ListOptionPricesConnection" }, + { + "description": "Whether the option is shareable across multiple SKU Groups (a global modifier).", + "name": "shareable", + "type": "Boolean!" + }, { "description": "The UUID of the SKU Group that the Option belongs to.", "name": "skuGroupId", @@ -7137,7 +7209,7 @@ "type": "Int" }, { - "description": "The type of the media, one of `PHOTO`, `VIDEO`, `IMAGE`, `AUDIO`.", + "description": "The type of the media. Currently: `VIDEO`, `IMAGE`, `AUDIO`. Legacy objects may still have `PHOTO`.", "name": "type", "type": "String" }, @@ -7205,6 +7277,7 @@ "type": "ID" }, { + "description": "Metafield type. Currently accepted values (lowercase): `boolean`, `string`, `stringMultiLine`, `number`, `numberDecimal`, `date`, `dateTime`, `json`, `measurement`, `url`, `reference`, `money`, `list.string`, `list.number`, `list.numberDecimal`, `list.measurement`, `list.date`, `list.url`.", "name": "type", "type": "String" }, @@ -7631,6 +7704,7 @@ "type": "[CreateMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -7657,6 +7731,7 @@ "type": "String!" }, { + "description": "Must be kebab-case: lowercase alphanumeric segments separated by single dashes. Must not start with \"g-\" (reserved for global presets).", "name": "name", "type": "String!" } @@ -7696,6 +7771,7 @@ "type": "[CreateMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -7749,6 +7825,7 @@ "type": "[CreateMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -7790,6 +7867,7 @@ "type": "[CreateMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -7825,11 +7903,6 @@ "name": "htmlDescription", "type": "String" }, - { - "description": "Whether this option is shareable across multiple SKU Groups.", - "name": "shareable", - "type": "Boolean" - }, { "name": "label", "type": "String!" @@ -7839,6 +7912,7 @@ "type": "[CreateMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -7850,6 +7924,11 @@ "name": "prices", "type": "[CreateOptionPriceInput!]" }, + { + "description": "Whether this option is shareable across multiple SKU Groups.", + "name": "shareable", + "type": "Boolean" + }, { "name": "skuGroupId", "type": "String" @@ -7905,6 +7984,7 @@ "type": "[CreateMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -7982,6 +8062,7 @@ "type": "[CreateMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -8077,6 +8158,7 @@ "type": "[CreateMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -8730,6 +8812,7 @@ "type": "[UpsertMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -8752,6 +8835,7 @@ "type": "[UpsertMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -8805,6 +8889,7 @@ "type": "[UpsertMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -8860,6 +8945,7 @@ "type": "[UpsertMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -8919,6 +9005,7 @@ "type": "[UpsertMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -8950,10 +9037,6 @@ "name": "htmlDescription", "type": "String" }, - { - "name": "shareable", - "type": "Boolean" - }, { "name": "label", "type": "String" @@ -8963,6 +9046,7 @@ "type": "[UpsertMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -8970,6 +9054,10 @@ "name": "position", "type": "Int" }, + { + "name": "shareable", + "type": "Boolean" + }, { "description": "The type of the Option, one of `TEXT`, `NUMBER`, `LIST`. Option Values are only available on the 'LIST' type.", "name": "type", @@ -9018,6 +9106,7 @@ "type": "[UpsertMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -9069,6 +9158,7 @@ "type": "String" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -9151,6 +9241,7 @@ "type": "String" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -9232,6 +9323,7 @@ "type": "[UpsertMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -9338,6 +9430,7 @@ "type": "[UpsertMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -9448,12 +9541,7 @@ "type": "ID!" }, { - "description": "Whether the option is shareable across multiple SKU Groups (a global modifier).", - "name": "shareable", - "type": "Boolean!" - }, - { - "description": "The display lable of the Option", + "description": "The display label of the Option", "name": "label", "type": "String!" }, @@ -9467,7 +9555,7 @@ "type": "String!" }, { - "description": "The position of the option.", + "description": "The position of the option within its SKU group.", "name": "position", "type": "Int" }, @@ -9476,6 +9564,11 @@ "name": "prices", "type": "NumericOptionPricesConnection" }, + { + "description": "Whether the option is shareable across multiple SKU Groups (a global modifier).", + "name": "shareable", + "type": "Boolean!" + }, { "description": "The UUID of the SKU Group that the Option belongs to.", "name": "skuGroupId", @@ -9981,6 +10074,27 @@ "kind": "object", "name": "PriceRange" }, + { + "fields": [ + { + "description": "The three-letter currency code of prices to match.", + "name": "currencyCode", + "type": "String!" + }, + { + "description": "The inclusive maximum price in integer minor units, the same convention as `SimpleMoneyInput.value`. At least one of min or max is required; the server returns a validation error if both are omitted.", + "name": "max", + "type": "Float" + }, + { + "description": "The inclusive minimum price in integer minor units, the same convention as `SimpleMoneyInput.value`. At least one of min or max is required; the server returns a validation error if both are omitted.", + "name": "min", + "type": "Float" + } + ], + "kind": "input", + "name": "PriceRangeFilter" + }, { "fields": [ { @@ -10835,6 +10949,7 @@ { "fields": [ { + "description": "Filters SKUs that have all of the specified attribute value names, e.g. [\"red\", \"large\"].", "name": "has", "type": "[String!]" } @@ -11930,7 +12045,7 @@ "type": "String!" }, { - "description": "The integer value, which might represent intergrals for currencies like `JPY` that are not typically fractional; or, with an implied decimal fraction for currencies that are subdivided into hundredths, like USD; or, subdivided into thousandths, like TND. Only accepts integer value. Decimals are not accepted. This input is typed as Float to be able to support values larger than GraphQL's 32-bit Integer.", + "description": "Integer minor units as a JSON number with no fractional part (for example `1999` for $19.99 USD). Decimals such as `19.99` are rejected. Typed as Float so values can exceed GraphQL's 32-bit Integer. JPY uses the integral amount; USD is hundredths; TND is thousandths.", "name": "value", "type": "Float!" } @@ -11966,12 +12081,7 @@ "type": "ID!" }, { - "description": "Whether the option is shareable across multiple SKU Groups (a global modifier).", - "name": "shareable", - "type": "Boolean!" - }, - { - "description": "The display lable of the Option", + "description": "The display label of the Option", "name": "label", "type": "String!" }, @@ -11985,7 +12095,7 @@ "type": "String!" }, { - "description": "The position of the option.", + "description": "The position of the option within its SKU group.", "name": "position", "type": "Int" }, @@ -11994,6 +12104,11 @@ "name": "prices", "type": "TextOptionPricesConnection" }, + { + "description": "Whether the option is shareable across multiple SKU Groups (a global modifier).", + "name": "shareable", + "type": "Boolean!" + }, { "description": "The UUID of the SKU Group that the Option belongs to.", "name": "skuGroupId", @@ -12134,6 +12249,7 @@ "type": "[UpsertMetafieldInput!]" }, { + "description": "Must be lowercase, alphanumeric, 1–255 characters, and may contain \"-\" or \"_\".", "name": "name", "type": "String" }, @@ -12142,7 +12258,7 @@ "type": "Int" }, { - "description": "The type of the media, one of `PHOTO`, `VIDEO`, `IMAGE`, `AUDIO`.", + "description": "The type of the media. Currently accepted values on write: `VIDEO`, `IMAGE`, `AUDIO`. `PHOTO` is not accepted on create or update.", "name": "type", "type": "String" }, @@ -12193,6 +12309,7 @@ "type": "String!" }, { + "description": "Metafield type. Currently accepted values (lowercase): `boolean`, `string`, `stringMultiLine`, `number`, `numberDecimal`, `date`, `dateTime`, `json`, `measurement`, `url`, `reference`, `money`, `list.string`, `list.number`, `list.numberDecimal`, `list.measurement`, `list.date`, `list.url`.", "name": "type", "type": "String!" }, @@ -12263,7 +12380,7 @@ }, "responses": { "200": { - "description": "GraphQL response", + "description": "GraphQL response. Field validation and business errors are returned as HTTP 200 with an `errors` array and `data` set to null (or the errored field set to null). HTTP 4xx/5xx are transport, auth, or gateway failures — not GraphQL field errors.", "schema": { "properties": { "data": { @@ -12307,5 +12424,5 @@ ], "name": "catalog-products", "title": "Catalog GraphQL API", - "version": "2.1.0" + "version": "2.2.0" } \ No newline at end of file diff --git a/rust/schemas/api/customer-profiles.json b/rust/schemas/api/customer-profiles.json index f4649472..22be415f 100644 --- a/rust/schemas/api/customer-profiles.json +++ b/rust/schemas/api/customer-profiles.json @@ -1,1698 +1,2403 @@ { "$defs": { - "ActionStatuses": { - "description": "The possible statuses an action can be in", - "enum": [ - "FAILED", - "PARTIAL_SUCCESS", - "PENDING", - "SUCCESS" - ], + "uuid": { + "$id": "https://godaddy.com/schemas/common/uuid.v1", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A universally unique identifier (UUID) in [RFC-4122 format](https://tools.ietf.org/html/rfc4122).", + "format": "uuid", "type": "string" - }, - "Address": { - "properties": { - "address1": { - "maxLength": 100, - "pattern": "^[\\u0080-\\uFFFFa-zA-Z0-9\\-.,'#*@/& ]{,100}$", - "type": "string" - }, - "address2": { - "maxLength": 100, - "pattern": "^[\\u0080-\\uFFFFa-zA-Z0-9\\-.,'#*@/& ]{,100}$", - "type": "string" - }, - "city": { - "maxLength": 100, - "pattern": "^[\\u0080-\\uFFFFa-zA-Z0-9\\-.,'#*@/& ]{,100}$", - "type": "string" - }, - "country": { - "description": "Country ISO code", - "maxLength": 100, - "pattern": "^[\\u0080-\\uFFFFa-zA-Z0-9\\-.,'#*@/& ]{,2}$", - "type": "string" - }, - "label": { - "description": "A descriptive name for the address", - "maxLength": 100, - "pattern": "^[\\u0080-\\uFFFFa-zA-Z0-9\\-.,'#*@/& ]{,100}$", - "type": "string" - }, - "postalCode": { - "description": "Postal or zip code", - "maxLength": 100, - "pattern": "^[\\u0080-\\uFFFFa-zA-Z0-9\\-.,'#*@/& ]{,100}$", - "type": "string" - }, - "state": { - "description": "State or province or territory", - "maxLength": 100, - "pattern": "^[\\u0080-\\uFFFFa-zA-Z0-9\\-.,'#*@/& ]{,100}$", - "type": "string" - } - }, - "type": "object" - }, - "Customer": { - "allOf": [ - { - "$ref": "#/$defs/CustomerBase" - }, - { - "$ref": "#/$defs/UpdatedAt" - }, - { - "$ref": "#/$defs/ListKeys" - }, - { - "properties": { - "joined": { - "default": false, - "description": "Whether the customer has been joined with one or more other customers to create a single customer", - "type": "boolean" - }, - "orderCount": { - "description": "Number of orders the customer has made", - "minimum": 0, - "type": "integer" - }, - "paymentCount": { - "description": "Number of payments the customer has completed", - "minimum": 0, - "type": "integer" - }, - "profileImageUrl": { - "description": "Url of the profile images for the customer", - "format": "url", - "type": "string" - }, - "trackingDisabled": { - "default": false, - "description": "Whether the customer has opted out of tracking (eg. email opens and link clicks)", - "type": "boolean" - } + } + }, + "baseUrl": "https://api.godaddy.com/v2/commerce", + "description": "", + "endpoints": [ + { + "graphql": { + "operationCount": 20, + "operations": [ + { + "args": [ + { + "name": "id", + "required": true, + "type": "ID!" + } + ], + "deprecated": false, + "description": "Get a customer by ID.", + "kind": "query", + "name": "customer", + "returnType": "Customer" }, - "required": [ - "customerId" - ], - "type": "object" - } - ] - }, - "CustomerActionResponse": { - "properties": { - "links": { - "items": { - "properties": { - "href": { - "type": "string" + { + "args": [ + { + "name": "after", + "required": false, + "type": "String" + }, + { + "name": "before", + "required": false, + "type": "String" + }, + { + "description": "Filter by created at.", + "name": "createdAt", + "required": false, + "type": "CreatedAtFilter" + }, + { + "description": "Filter by email address.", + "name": "emailAddress", + "required": false, + "type": "CustomerEmailAddressFilterInput" + }, + { + "name": "first", + "required": false, + "type": "Int" + }, + { + "description": "Filter by is guest.", + "name": "isGuest", + "required": false, + "type": "Boolean" + }, + { + "name": "last", + "required": false, + "type": "Int" + }, + { + "description": "Order by a specific field. By default, customers are ordered by ID.", + "name": "orderBy", + "required": false, + "type": "CustomerOrderByInput" }, - "method": { - "type": "string" + { + "description": "Filter by phone number.", + "name": "phoneNumber", + "required": false, + "type": "CustomerPhoneNumberFilterInput" }, - "rel": { - "type": "string" + { + "description": "Filter by updated at.", + "name": "updatedAt", + "required": false, + "type": "UpdatedAtFilter" } - }, - "type": "object" + ], + "deprecated": false, + "description": "Get a collection of customers.", + "kind": "query", + "name": "customers", + "returnType": "QueryCustomersConnection" }, - "type": "array" - } - }, - "required": [ - "links" - ], - "type": "object" - }, - "CustomerAdmin": { - "properties": { - "customer": { - "default": false, - "description": "Whether or not the customer has completed transactions with the user", - "type": "boolean" - }, - "suppressed": { - "default": false, - "description": "Whether the customer is suppressed, due to opting out from email marketing, or their email address being unreachable", - "type": "boolean" - }, - "trackingDisabled": { - "default": false, - "description": "Whether the customer has opted out of tracking (eg. email opens and link clicks)", - "type": "boolean" - } - }, - "type": "object" - }, - "CustomerBase": { - "allOf": [ - { - "$ref": "#/$defs/CustomerId" - }, - { - "properties": { - "addresses": { - "default": [], - "description": "Array of customer addresses. Note that currently only one address is supported", - "items": { - "$ref": "#/$defs/Address" - }, - "maxLength": 10, - "type": "array" - }, - "emails": { - "default": [], - "description": "Array of email addresses", - "items": { - "$ref": "#/$defs/Email" - }, - "maxLength": 10, - "type": "array" - }, - "firstName": { - "example": "Fredrick", - "maxLength": 50, - "pattern": "^[\\u0080-\\uFFFFa-zA-Z0-9\\-.,\\(\\)\\@&' ]*$", - "type": "string" - }, - "instantMessages": { - "default": [], - "description": "Array of instant messaging accounts associated with the customer", - "items": { - "$ref": "#/$defs/InstantMessage" - }, - "maxLength": 10, - "type": "array" - }, - "jobTitle": { - "type": "string" - }, - "lastName": { - "example": "Smith", - "maxLength": 50, - "pattern": "^[\\u0080-\\uFFFFa-zA-Z0-9\\-.,\\(\\)\\@&' ]*$", - "type": "string" - }, - "nickname": { - "description": "Name by which customer should be addressed", - "example": "Fred", - "maxLength": 50, - "pattern": "^[\\u0080-\\uFFFFa-zA-Z0-9\\-.,\\(\\)\\@&' ]*$", - "type": "string" - }, - "organization": { - "example": "GoDaddy", - "format": "organization-name", - "maxLength": 100, - "pattern": "^[\\u0080-\\uFFFFa-zA-Z0-9\\-.,\\(\\)\\\\@&!' +]*$", - "type": "string" - }, - "phones": { - "default": [], - "description": "Array of phone numbers", - "items": { - "$ref": "#/$defs/Phone" - }, - "maxLength": 10, - "type": "array" - }, - "socialProfiles": { - "default": [], - "description": "Array of social profiles associated with the customer", - "items": { - "$ref": "#/$defs/SocialProfile" - }, - "maxLength": 10, - "type": "array" - }, - "urls": { - "default": [], - "description": "Array of urls associated with the customer", - "items": { - "$ref": "#/$defs/Url" - }, - "maxLength": 10, - "type": "array" - } + { + "args": [ + { + "description": "Cursor to paginate forward from — pass the `endCursor` from a previous page. Cursors are opaque; values not issued by this API are rejected.", + "name": "after", + "required": false, + "type": "String" + }, + { + "description": "UUID of the customer whose instruments to list.", + "name": "customerId", + "required": true, + "type": "ID!" + }, + { + "description": "Optional filter: exclude expired cards (defaults to false).", + "name": "excludeExpired", + "required": false, + "type": "Boolean" + }, + { + "description": "Maximum number of items to return (forward pagination). Defaults to 20 and is capped at 100; larger values are clamped, negative values are rejected. Fewer items than requested may be returned even when `pageInfo.hasNextPage` is true — always follow `endCursor` rather than counting edges.", + "name": "first", + "required": false, + "type": "Int" + }, + { + "description": "Sort order (defaults to CREATED_AT ASC).", + "name": "orderBy", + "required": false, + "type": "FinancialInstrumentOrderBy" + } + ], + "deprecated": false, + "description": "Paginated list of financial instruments (saved payment methods) for a customer. Uses Relay cursor-based pagination. NOTE: Only forward pagination is supported (first/after) — the upstream Card-on-File API is page-based and offers no stable key to seek backwards from.", + "kind": "query", + "name": "financialInstruments", + "returnType": "QueryFinancialInstrumentsConnection!" }, - "required": [ - "firstName", - "lastName", - "email", - "phone" - ], - "type": "object" - } - ] - }, - "CustomerCreate": { - "properties": { - "customer": { - "allOf": [ - { - "$ref": "#/$defs/CustomerBase" - }, - { - "$ref": "#/$defs/CustomerAdmin" - }, - { - "$ref": "#/$defs/CustomerExternalIdentifier" - }, - { - "$ref": "#/$defs/ListKeys" - } - ] - }, - "source": { - "$ref": "#/$defs/Source" - } - }, - "required": [ - "customer", - "source" - ], - "type": "object" - }, - "CustomerDataPoint": { - "properties": { - "count": { - "description": "Count of new unique customers", - "format": "integer-positive", - "type": "integer" - }, - "periodEndedAt": { - "$ref": "#/$defs/date-time" - }, - "periodStartedAt": { - "$ref": "#/$defs/date-time" - } - }, - "required": [ - "periodStartedAt", - "periodEndedAt", - "count" - ], - "type": "object" - }, - "CustomerError": { - "allOf": [ - { - "$ref": "#/$defs/CustomerId" - }, - { - "$ref": "#/$defs/Error" - } - ] - }, - "CustomerExternalIdentifier": { - "properties": { - "externalIdentifier": { - "properties": { - "externalId": { - "description": "The external id for the customer in another service", - "maxLength": 255, - "type": "string" - }, - "source": { - "description": "The name of service from which the external id originates", - "example": "INVOICE", - "maxLength": 255, - "type": "string" - } + { + "args": [ + { + "name": "after", + "required": false, + "type": "String" + }, + { + "name": "before", + "required": false, + "type": "String" + }, + { + "description": "Filter by created at.", + "name": "createdAt", + "required": false, + "type": "CreatedAtFilter" + }, + { + "name": "first", + "required": false, + "type": "Int" + }, + { + "description": "Filter by guest status.", + "name": "isGuest", + "required": false, + "type": "Boolean" + }, + { + "name": "last", + "required": false, + "type": "Int" + }, + { + "description": "Order by a specific field. By default, customers are ordered by ID.", + "name": "orderBy", + "required": false, + "type": "CustomerOrderByInput" + }, + { + "description": "Search term for name, email, or phone. Minimum 3 characters required.", + "name": "query", + "required": true, + "type": "String!" + }, + { + "description": "Filter by last update date.", + "name": "updatedAt", + "required": false, + "type": "UpdatedAtFilter" + } + ], + "deprecated": false, + "description": "Search customers by name, email, or phone number. Minimum 3 characters required for search query. For filtering without search, use the 'customers' query.", + "kind": "query", + "name": "searchCustomers", + "returnType": "QuerySearchCustomersConnection" }, - "required": [ - "externalId", - "source" - ], - "type": "object" - } - }, - "type": "object" - }, - "CustomerId": { - "description": "Customer identifier that is unique within current Store", - "properties": { - "customerId": { - "format": "uuid", - "type": "string" - } - }, - "type": "object" - }, - "CustomerId/properties/customerId": { - "format": "uuid", - "type": "string" - }, - "CustomerUpdate": { - "properties": { - "customer": { - "allOf": [ - { - "$ref": "#/$defs/CustomerBase" - }, - { - "$ref": "#/$defs/CustomerAdmin" - }, - { - "$ref": "#/$defs/CustomerExternalIdentifier" - }, - { - "$ref": "#/$defs/ListKeys" - }, - { - "$ref": "#/$defs/UpdatedAt" - } - ] - }, - "source": { - "$ref": "#/$defs/Source" - } - }, - "required": [ - "customer", - "source" - ], - "type": "object" - }, - "Email": { - "properties": { - "default": { - "description": "Indicates whether the email is the primary email.", - "type": "boolean" - }, - "email": { - "$ref": "#/$defs/email-address" - }, - "label": { - "description": "A user provided name for the email address", - "maxLength": 255, - "type": "string" - } - }, - "required": [ - "email" - ] - }, - "Error": { - "properties": { - "code": { - "description": "Short identifier for the error, suitable for indicating the specific error within client code", - "format": "error-code", - "pattern": "^[A-Z_][A-Z0-9_]*$", - "type": "string" - }, - "fields": { - "description": "List of the specific fields, and the errors found with their contents", - "items": { - "$ref": "#/$defs/ErrorField" + { + "args": [ + { + "name": "customerId", + "required": true, + "type": "ID!" + }, + { + "description": "Addresses to add. Must contain between 1 and 10 entries; an empty list is rejected. A store context may hold at most 50 addresses in total.", + "name": "input", + "required": true, + "type": "[AddAddressInput!]!" + } + ], + "deprecated": false, + "description": "Add addresses to a customer within the current store context (x-store-id). Dedups against the customer's existing addresses; associates or creates as needed. Returns the store-scoped address.", + "kind": "mutation", + "name": "addAddressesToCustomer", + "returnType": "AddAddressesToCustomerResponse!" }, - "minItems": 1, - "type": "array" - }, - "message": { - "description": "Human-readable, English description of the error", - "type": "string" - }, - "stack": { - "description": "Stack trace indicating where the error occurred.
NOTE: This attribute MAY be included for Development and Test environments. However, it MUST NOT be exposed from OTE nor Production systems", - "items": { - "type": "string" + { + "args": [ + { + "description": "Optional. Bypass an identity conflict by ignoring the listed existing customers. Pass the `existingCustomerIds` returned by a prior conflict to retry the add.", + "name": "conflictResolution", + "required": false, + "type": "AddIdentitiesConflictResolutionInput" + }, + { + "name": "customerId", + "required": true, + "type": "ID!" + }, + { + "description": "Identities to add. Must contain between 1 and 20 entries; an empty list is rejected. A store context may hold at most 10 identities per type.", + "name": "input", + "required": true, + "type": "[AddIdentityInput!]!" + } + ], + "deprecated": false, + "description": "Add one or more email/phone identities to a customer within the current store context (store-scoped via x-store-id). Additive — existing identities are left untouched.", + "kind": "mutation", + "name": "addIdentitiesToCustomer", + "returnType": "AddIdentitiesToCustomerResponse!" }, - "minItems": 1, - "type": "array" - } - }, - "required": [ - "code" - ], - "type": "object", - "x-error-model": true - }, - "ErrorField": { - "properties": { - "code": { - "description": "Short identifier for the error, suitable for indicating the specific error within client code", - "format": "error-code", - "pattern": "^[A-Z_][A-Z0-9_]*$", - "type": "string" - }, - "message": { - "description": "Human-readable, English description of the error", - "type": "string" - }, - "path": { - "description": "1) JSONPath referring to the field within the data containing an error
or
2) JSONPath referring to an object containing an error", - "example": "$.activity", - "format": "json-path", - "pattern": "^[a-z_]([a-zA-Z0-9_.]*)*$", - "type": "string" - }, - "pathRelated": { - "description": "JSONPath referring to the field on the object referenced by `path` containing an error", - "example": "$.type", - "format": "json-path", - "pattern": "^[a-z_]([a-zA-Z0-9_.]*)*$", - "type": "string" - } - }, - "required": [ - "path", - "code" - ], - "type": "object" - }, - "ErrorLimit": { - "additionalProperties": false, - "allOf": [ - { - "properties": { - "retryAfterSec": { - "description": "Number of seconds to wait before attempting a similar request", - "format": "integer-positive", - "pattern": "^[0-9]+$", - "type": "integer" - } + { + "args": [ + { + "name": "customerId", + "required": true, + "type": "ID!" + }, + { + "name": "input", + "required": true, + "type": "AddReferencesInput!" + } + ], + "deprecated": false, + "description": "Add external system references to a customer. Returns the updated customer.", + "kind": "mutation", + "name": "addReferencesToCustomer", + "returnType": "AddReferencesToCustomerResponse!" }, - "required": [ - "retryAfterSec" - ], - "type": "object" - }, - { - "$ref": "#/$defs/Error" - } - ], - "x-error-model": true - }, - "InstantMessage": { - "properties": { - "accountKey": { - "description": "An accountKey for the instant messaging account", - "maxLength": 255, - "type": "string" - }, - "label": { - "description": "A user provided name for the external service", - "maxLength": 255, - "type": "string" - } - }, - "required": [ - "accountKey" - ] - }, - "ListKeys": { - "properties": { - "listKeys": { - "description": "List memberships that should be changed for the customer", - "items": { - "format": "uuid", - "type": "string" - }, - "type": "array" - } - }, - "required": [ - "listKeys" - ] - }, - "PaginatedResponse": { - "properties": { - "links": { - "description": "HATEOAS link relations", - "items": { - "$ref": "#/$defs/link-description" - }, - "type": "array" - }, - "totalItems": { - "description": "The total number of items in the full result set. Only returned if the `totalRequired` param is true", - "type": "integer" - }, - "totalPages": { - "description": "The total number of pages of results in the full result set. Only returned if the `totalRequired` param is true", - "type": "integer" - } - }, - "required": [ - "links" - ], - "type": "object" - }, - "Phone": { - "properties": { - "default": { - "description": "Indicates whether the phone is the primary phone.", - "type": "boolean" - }, - "label": { - "description": "A user provided name for the phone number", - "maxLength": 255, - "type": "string" - }, - "phone": { - "description": "A customer phone number", - "format": "phone", - "maxLength": 17, - "type": "string" - } - }, - "required": [ - "phone" - ], - "type": "object" - }, - "Request": { - "allOf": [ - { - "$ref": "#/$defs/RequestId" - }, - { - "properties": { - "customerIds": { - "description": "IDs of the customer records affected - created or updated - by the request", - "items": { - "format": "uuid", - "type": "string" + { + "args": [ + { + "name": "customerId", + "required": true, + "type": "ID!" }, - "type": "array" - }, - "errors": { - "items": { - "$ref": "#/$defs/CustomerError" + { + "name": "input", + "required": true, + "type": "TagsInput!" + } + ], + "deprecated": false, + "description": "Append tags to the store context for this customer. Duplicates are ignored. Returns the updated customer.", + "kind": "mutation", + "name": "addTagsToCustomer", + "returnType": "AddTagsToCustomerResponse!" + }, + { + "args": [ + { + "name": "conflictResolution", + "required": false, + "type": "CreateCustomerConflictResolutionInput" }, - "type": "array" - }, - "links": { - "description": "HATEOAS link relations", - "items": { - "$ref": "#/$defs/link-description" + { + "name": "input", + "required": true, + "type": "CreateCustomerInput!" + } + ], + "deprecated": false, + "kind": "mutation", + "name": "createCustomer", + "returnType": "CreateCustomerResponse!" + }, + { + "args": [ + { + "name": "customerId", + "required": true, + "type": "ID!" + } + ], + "deprecated": false, + "description": "Delete the store's customer.", + "kind": "mutation", + "name": "deleteCustomer", + "returnType": "DeleteCustomerResponse!" + }, + { + "args": [ + { + "name": "customerId", + "required": true, + "type": "ID!" }, - "type": "array" - }, - "status": { - "$ref": "#/$defs/ActionStatuses" - }, - "undoSupport": { - "description": "Whether or not the request can be undone automatically", - "type": "boolean" - } + { + "name": "input", + "required": true, + "type": "DeleteMetafieldsInput!" + } + ], + "deprecated": false, + "kind": "mutation", + "name": "deleteMetafields", + "returnType": "DeleteMetafieldsResponse!" }, - "required": [ - "status" - ], - "type": "object" - } - ] - }, - "RequestId": { - "properties": { - "requestId": { - "format": "uuid", - "type": "string" - } - }, - "required": [ - "requestId" - ], - "type": "object" - }, - "SocialProfile": { - "properties": { - "accountKey": { - "description": "An accountKey for the social profile", - "maxLength": 255, - "type": "string" - }, - "label": { - "description": "A user provided name for the external service", - "maxLength": 255, - "type": "string" - } - }, - "required": [ - "accountKey" - ] - }, - "Source": { - "description": "Source application of the interaction", - "enum": [ - "COMMERCE", - "CONVERSATIONS", - "EMAIL_MARKETING", - "GDSOCIAL", - "GOPAY", - "INVOICE", - "POYNT", - "ONLINE_APPOINTMENTS", - "ONLINE_STORE", - "PAYMENTS", - "WEBSITE_BUILDER" - ], - "type": "string" - }, - "UpdatedAt": { - "properties": { - "updatedAt": { - "$ref": "#/$defs/date-time" - } - }, - "required": [ - "updatedAt" - ], - "type": "object" - }, - "Url": { - "properties": { - "label": { - "description": "A user provided name for the url", - "maxLength": 255, - "type": "string" - }, - "url": { - "description": "A url associated with the customer", - "format": "url", - "maxLength": 2083, - "type": "string" - } - }, - "required": [ - "url" - ] - }, - "date-time": { - "$id": "https://godaddy.com/schemas/common/date-time.v1", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "A date and time, in [Internet date and time format](https://tools.ietf.org/html/rfc3339#section-5.6). Note: The regular expression provides static schematic guidance but does not reject all invalid dates.", - "maxLength": 64, - "minLength": 20, - "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])[T,t]([0-1][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)([.][0-9]+)?([Zz]|[+-][0-9]{2}:[0-9]{2})$", - "type": "string" - }, - "email-address": { - "$id": "https://godaddy.com/schemas/common/email-address.v1", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "A valid, internationalized email address. Note: Up to 64 characters are allowed before and 255 characters are allowed after the @ sign. However, the generally accepted maximum length for an email address is 254 characters. The pattern verifies that an unquoted @ sign exists.", - "maxLength": 254, - "minLength": 3, - "pattern": "^.+@[^\"\\-].+$", - "type": "string" - }, - "link-description": { - "$id": "https://godaddy.com/schemas/common/link-description.v1", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "A request-related [HATEOAS link](https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-hyperschema-02).", - "properties": { - "href": { - "description": "The complete target URL, or link, to use in combination with the method to make the related call, as defined by [RFC 6570 - URI Template](https://tools.ietf.org/html/rfc6570), with the addition of the `$`, `(`, and `)` characters for pre-processing. The `href` is the key HATEOAS component that links a completed call with a subsequent call.", - "format": "uri", - "type": "string" - }, - "method": { - "description": "The method to use to request the link target. For example, for HTTP, this might be `GET` or `DELETE`.", - "type": "string" - }, - "rel": { - "description": "The [link relation type](https://tools.ietf.org/html/rfc5988#section-4), which is an identifier for a link that unambiguously describes the semantics of the link. For values, see [Link Relationship Types](https://www.iana.org/assignments/link-relations/link-relations.xhtml).", - "type": "string" - }, - "submissionMediaType": { - "default": "application/json", - "description": "The media type with which to submit data with the request.", - "type": "string" - }, - "submissionSchema": { - "description": "The schema that describes the request data." - }, - "targetMediaType": { - "description": "The [RFC 2046-defined media type](https://www.ietf.org/rfc/rfc2046.txt) that describes the link target.", - "type": "string" - }, - "targetSchema": { - "description": "The schema that describes the link target." - }, - "title": { - "description": "The link title.", - "type": "string" - } - }, - "required": [ - "rel", - "href" - ], - "title": "Link Description", - "type": "object" - } - }, - "baseUrl": "https://api.godaddy.com/v1/commerce", - "description": "This API can be used to retrieve, create, update and delete customers as well as customer information.", - "endpoints": [ - { - "description": "This endpoint can be used to create an actvity for a specific customer using the store ID. Customer activities are the series of actions a customer can perform such as orders, bookings, and payments, which can be tracked for further analysis. Customer data will only be added when the customer does not yet exist.", - "method": "POST", - "operationId": "commerceCustomerCreateActivity", - "parameters": [ - { - "description": "An identifier for a store", - "in": "path", - "name": "storeId", - "required": true, - "schema": { - "format": "uuid", - "type": "string" - } - } - ], - "path": "/stores/{storeId}/customer-activities", - "requestBody": { - "contentType": "application/json", - "description": "Activity and contact data", - "required": true, - "schema": { - "properties": { - "activity": { - "description": "Data about the activity", - "properties": { - "source": { - "$ref": "#/$defs/Source" - }, - "type": { - "description": "The type of activity to associate with the customer", - "enum": [ - "BOOKING_CLAIMED", - "BOOKING_CREATED", - "BOOKING_RESCHEDULED", - "ORDER_CREATED", - "PAYMENT_COMPLETED", - "PAYMENT_REFUNDED", - "PAYMENT_VOIDED" - ], - "type": "string" - } - }, - "required": [ - "source", - "type" - ], - "type": "object" - }, - "customer": { - "allOf": [ - { - "$ref": "#/$defs/CustomerBase" - }, - { - "$ref": "#/$defs/CustomerExternalIdentifier" - }, - { - "$ref": "#/$defs/ListKeys" - } - ], - "description": "Customer data regarding the customer who performed the activity. Customer data will only be added when the customer does not yet exist.", - "type": "object" - } + { + "args": [ + { + "description": "Address ids to remove. Must contain between 1 and 100 ids; an empty list is rejected.", + "name": "addressIds", + "required": true, + "type": "[ID!]!" + }, + { + "name": "customerId", + "required": true, + "type": "ID!" + } + ], + "deprecated": false, + "description": "Remove addresses from the current store context (x-store-id). An address left with no associations across all contexts is deleted (copy-on-write).", + "kind": "mutation", + "name": "removeAddressesFromCustomer", + "returnType": "RemoveAddressesFromCustomerResponse!" + }, + { + "args": [ + { + "description": "Input containing customer ID and instrument ID. All tokens for this instrument in the store will be deactivated.", + "name": "input", + "required": true, + "type": "RemoveFinancialInstrumentFromStoreInput!" + } + ], + "deprecated": false, + "description": "Remove a financial instrument from a store by deactivating all its store-specific tokens. This removes the merchant's ability to charge this instrument at this store without deleting the instrument itself. The instrument remains available at other stores.", + "kind": "mutation", + "name": "removeFinancialInstrumentFromStore", + "returnType": "RemoveFinancialInstrumentFromStoreResponse!" + }, + { + "args": [ + { + "name": "customerId", + "required": true, + "type": "ID!" + }, + { + "description": "Identity ids to remove. Must contain between 1 and 100 ids; an empty list is rejected.", + "name": "identityIds", + "required": true, + "type": "[ID!]!" + } + ], + "deprecated": false, + "description": "Remove identities from a customer within the current store context (store-scoped via x-store-id). An identity left with zero associations across all store contexts is deleted (copy-on-write).", + "kind": "mutation", + "name": "removeIdentitiesFromCustomer", + "returnType": "RemoveIdentitiesFromCustomerResponse!" + }, + { + "args": [ + { + "name": "customerId", + "required": true, + "type": "ID!" + }, + { + "name": "input", + "required": true, + "type": "RemoveReferencesInput!" + } + ], + "deprecated": false, + "description": "Remove external system references from a customer. Returns the updated customer.", + "kind": "mutation", + "name": "removeReferencesFromCustomer", + "returnType": "RemoveReferencesFromCustomerResponse!" + }, + { + "args": [ + { + "name": "customerId", + "required": true, + "type": "ID!" + }, + { + "name": "input", + "required": true, + "type": "TagsInput!" + } + ], + "deprecated": false, + "description": "Remove specific tags from the store context for this customer. Missing tags are ignored. Returns the updated customer.", + "kind": "mutation", + "name": "removeTagsFromCustomer", + "returnType": "RemoveTagsFromCustomerResponse!" + }, + { + "args": [ + { + "description": "Input containing customer ID and payment nonce.", + "name": "input", + "required": true, + "type": "SaveFinancialInstrumentInput!" + } + ], + "deprecated": false, + "description": "Save a new financial instrument (card or bank account) for a customer using a PCI-safe nonce from the payment tokenization flow (e.g., Poynt, Stripe).", + "kind": "mutation", + "name": "saveFinancialInstrumentByNonce", + "returnType": "SaveFinancialInstrumentByNonceResponse!" + }, + { + "args": [ + { + "name": "customerId", + "required": true, + "type": "ID!" + }, + { + "name": "identityId", + "required": true, + "type": "ID!" + } + ], + "deprecated": false, + "description": "Promote an identity to primary within the current store context.", + "kind": "mutation", + "name": "setPrimaryIdentity", + "returnType": "SetPrimaryIdentityResponse!" + }, + { + "args": [ + { + "name": "addressId", + "required": true, + "type": "ID!" + }, + { + "name": "customerId", + "required": true, + "type": "ID!" + }, + { + "name": "input", + "required": true, + "type": "UpdateAddressInput!" + } + ], + "deprecated": false, + "description": "Update an address within the current store context. Updates in place when the address belongs only to this context; otherwise copy-on-write returns a new address id. Can set the per-purpose default via isDefault.", + "kind": "mutation", + "name": "updateAddress", + "returnType": "UpdateAddressResponse!" + }, + { + "args": [ + { + "name": "id", + "required": true, + "type": "ID!" + }, + { + "name": "input", + "required": true, + "type": "UpdateCustomerInput!" + } + ], + "deprecated": false, + "kind": "mutation", + "name": "updateCustomer", + "returnType": "UpdateCustomerResponse!" + } + ], + "schemaRef": "./graphql/schema.graphql", + "sdl": "input AddAddressInput {\n address: CreateAddressInput!\n\n \"\"\"\n Mark this address as the store-context default for its purpose (SHIPPING/BILLING; BOTH sets both). At most one default per purpose per input array.\n \"\"\"\n isDefault: Boolean\n}\n\n\"\"\"Response to an add addresses to customer mutation.\"\"\"\ntype AddAddressesToCustomerResponse implements MutationResponse {\n addresses: [CustomerAddress!]\n\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\ninput AddIdentitiesConflictResolutionInput {\n \"\"\"\n The IDs of the conflicting customers to ignore, allowing the identities to be added despite the conflict. Typically the `existingCustomerIds` returned by a prior failed attempt. Up to 100 IDs.\n \"\"\"\n ignoreDuplicateIds: [ID!]!\n}\n\n\"\"\"Response to an add identities to customer mutation.\"\"\"\ntype AddIdentitiesToCustomerResponse implements MutationResponse {\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n\n \"\"\"\n The fields that caused the conflict. Only returned when the mutation fails due to identity conflicts.\n \"\"\"\n conflictFields: [String!]\n customer: Customer\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n\n \"\"\"\n The IDs of existing customers whose identities conflict with the identities to add. Only returned when mutation fails due to conflicts.\n \"\"\"\n existingCustomerIds: [ID!]\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\ninput AddIdentityInput {\n \"\"\"\n Mark this identity as primary for its type within the store context. At most one identity per type in the input array may set this to true.\n \"\"\"\n isPrimary: Boolean\n type: IdentityType!\n\n \"\"\"Identity value (email address or phone number).\"\"\"\n value: String!\n}\n\ninput AddReferencesInput {\n \"\"\"\n References to add. Must contain between 1 and 100 entries; an empty list is rejected. Duplicate source/externalId pairs are collapsed.\n \"\"\"\n references: [CreateExternalReferenceInput!]!\n}\n\n\"\"\"Response to an add references to customer mutation.\"\"\"\ntype AddReferencesToCustomerResponse implements MutationResponse {\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n customer: Customer\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\n\"\"\"Response to an add tags to customer mutation.\"\"\"\ntype AddTagsToCustomerResponse implements MutationResponse {\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n customer: Customer\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\n\"\"\"\nStructured postal classification details that complement the standard address lines.\n\"\"\"\ntype AddressDetails {\n \"\"\"\n The type of address. Single character representation of a type. For example: 'B' for building, 'F' for organization, 'G' for general delivery, 'H' for high-rise, 'L' for large-volume organization, 'P' for Post Office box or delivery service, 'R' for rural route, 'S' for street, 'U' for unidentified address.\n \"\"\"\n addressType: String\n\n \"\"\"\n A named location that represents the premise. Usually a building name or number or collection of buildings with a common name or number.\n \"\"\"\n buildingName: String\n\n \"\"\"The delivery service. Post office box, bag number, or post office name\"\"\"\n deliveryService: String\n\n \"\"\"The latitude and longitude of the address.\"\"\"\n geoCoordinates: GeoCoordinates\n\n \"\"\"The street name. Just `Drury` in `Drury Lane`.\"\"\"\n streetName: String\n\n \"\"\"The street number.\"\"\"\n streetNumber: String\n\n \"\"\"The street type. For example, avenue, boulevard, road, or expressway.\"\"\"\n streetType: String\n\n \"\"\"\n The first-order entity below a named building or location that represents the sub-premise. Usually a single building within a collection of buildings with a common name. Can be a flat, story, floor, room, or apartment.\n \"\"\"\n subBuilding: String\n}\n\ninput AddressDetailsInput {\n \"\"\"\n The type of address. Single character representation of a type. For example: 'B' for building, 'F' for organization, 'G' for general delivery, 'H' for high-rise, 'L' for large-volume organization, 'P' for Post Office box or delivery service, 'R' for rural route, 'S' for street, 'U' for unidentified address. Exactly 1 character.\n \"\"\"\n addressType: String\n\n \"\"\"\n A named location that represents the premise. Usually a building name or number or collection of buildings with a common name or number. At most 100 characters.\n \"\"\"\n buildingName: String\n\n \"\"\"\n The delivery service. Post office box, bag number, or post office name. At most 100 characters.\n \"\"\"\n deliveryService: String\n geoCoordinates: GeoCoordinatesInput\n\n \"\"\"The street name. Just `Drury` in `Drury Lane`. At most 100 characters.\"\"\"\n streetName: String\n\n \"\"\"The street number. At most 100 characters.\"\"\"\n streetNumber: String\n\n \"\"\"\n The street type. For example, avenue, boulevard, road, or expressway. At most 100 characters.\n \"\"\"\n streetType: String\n\n \"\"\"\n The first-order entity below a named building or location that represents the sub-premise. Usually a single building within a collection of buildings with a common name. Can be a flat, story, floor, room, or apartment. At most 100 characters.\n \"\"\"\n subBuilding: String\n}\n\n\"\"\"Intended use of an address: billing, shipping, or both.\"\"\"\nenum AddressType {\n BILLING\n BOTH\n SHIPPING\n}\n\ninput CreateAddressInput {\n addressDetails: AddressDetailsInput\n\n \"\"\"\n The first line of the address. For example, number and street name. For example, `3032 Bunker Hill Lane`. Required for compliance and risk checks. Must contain the full address.\n \"\"\"\n addressLine1: String!\n\n \"\"\"\n The second line of the address. For example, office suite or apartment number.\n \"\"\"\n addressLine2: String\n\n \"\"\"\n The third line of the address, if needed. For example, a street complement for Brazil; direction text, such as `next to Opera House`; or a landmark reference in an Indian address.\n \"\"\"\n addressLine3: String\n\n \"\"\"\n The highest level sub-division in a country, which is usually a province, state, or ISO-3166-2 subdivision; formatted for postal delivery. For example, `CA` and not `California`. For example, for UK - A county; for USs - A state; for Canada - A province; for Japan - A prefecture; for Switzerland - A kanton.\n \"\"\"\n adminArea1: String\n\n \"\"\"A city, town, or village. Smaller than `adminArea1`.\"\"\"\n adminArea2: String\n\n \"\"\"\n A sub-locality, suburb, neighborhood, or district. Smaller than `adminArea2`. For example, in Brazil - Suburb, bairro, or neighborhood; in India - Sub-locality or district. Street name information may not always available and a sub-locality or district can reference a very small area.\n \"\"\"\n adminArea3: String\n\n \"\"\"\n The neighborhood, ward, or district. Smaller than `adminArea3` or `subLocality`. For example, the postal sorting code that is used in Guernsey and many French territories, such as French Guiana; the fine-grained administrative levels in China.\n \"\"\"\n adminArea4: String\n\n \"\"\"\n The [two-character ISO 3166-1 code](https://en.wikipedia.org/wiki/ISO_3166-1) that identifies the country or region. Note: The country code for Great Britain is `GB` and not `UK` as used in the top-level domain names for that country. Use country code `C2` for China for comparable uncontrolled price (CUP) method, bank-card, and cross-border transactions.\n \"\"\"\n countryCode: String!\n\n \"\"\"First name.\"\"\"\n firstName: String\n\n \"\"\"Last name.\"\"\"\n lastName: String\n\n \"\"\"\n The postal code, which is the zip code or equivalent. Typically required for countries that have a postal code or an equivalent. See [Postal code](https://en.wikipedia.org/wiki/Postal_code).\n \"\"\"\n postalCode: String\n type: AddressType!\n}\n\ninput CreateCustomerConflictResolutionInput {\n \"\"\"The IDs of the duplicates to ignore. Up to 100 IDs.\"\"\"\n ignoreDuplicateIds: [ID!]!\n}\n\n\"\"\"\nInput for creating a new customer. At least one of `emailAddress` or `phoneNumber` must be provided — a customer must always have at least one email or phone.\n\"\"\"\ninput CreateCustomerInput {\n displayName: String\n\n \"\"\"\n At most one initial email address to seed. Associated to the store identified by `storeId` and marked primary for its type. At least one of `emailAddress` or `phoneNumber` is required.\n \"\"\"\n emailAddress: String\n firstName: String\n\n \"\"\"The customer's job title.\"\"\"\n jobTitle: String\n lastName: String\n\n \"\"\"Locale tag (e.g. 'en-US'). 2 to 35 characters.\"\"\"\n locale: String\n marketingOptIn: Boolean\n\n \"\"\"\n Initial note. Omit to create without a note. 1 to 10,000 characters; empty string is rejected.\n \"\"\"\n note: String\n\n \"\"\"The customer's organization.\"\"\"\n organization: String\n\n \"\"\"\n At most one initial phone number to seed. Associated to the store identified by `storeId` and marked primary for its type. At least one of `emailAddress` or `phoneNumber` is required.\n \"\"\"\n phoneNumber: String\n\n \"\"\"\n Channels through which receipts are delivered. At most one entry per channel.\n \"\"\"\n receiptDelivery: [ReceiptDeliveryChannel!]\n\n \"\"\"\n Initial external references. When provided, must contain between 1 and 100 entries; an empty list is rejected.\n \"\"\"\n references: [CreateExternalReferenceInput!]\n\n \"\"\"The customer's tags. Up to 100 tags, each 1 to 100 characters.\"\"\"\n tags: [String!]\n}\n\n\"\"\"Response to a create customer mutation.\"\"\"\ntype CreateCustomerResponse implements MutationResponse {\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n\n \"\"\"\n The fields that caused the conflict. Only returned when the creation fails due to identity conflicts.\n \"\"\"\n conflictFields: [String!]\n customer: Customer\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n\n \"\"\"\n The IDs of existing customers whose identities conflict with the new customer. Only returned when the creation fails due to identity conflicts.\n \"\"\"\n existingCustomerIds: [ID!]\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\ninput CreateExternalReferenceInput {\n \"\"\"Identifier of the customer in the external system.\"\"\"\n externalId: String!\n\n \"\"\"Name of the external system that owns the referenced record.\"\"\"\n source: String!\n}\n\n\"\"\"Filters items based on the date they were created.\"\"\"\ninput CreatedAtFilter {\n gt: DateTime\n lt: DateTime\n}\n\n\"\"\"A store's customer.\"\"\"\ntype Customer {\n \"\"\"The customer's addresses (store-scoped).\"\"\"\n addresses: [CustomerAddress!]\n\n \"\"\"The date and time the customer was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The display name.\"\"\"\n displayName: String\n\n \"\"\"The customer's email addresses (store-scoped).\"\"\"\n emailAddresses: [CustomerEmailAddress!]\n\n \"\"\"The first name.\"\"\"\n firstName: String\n\n \"\"\"The globally-unique ID.\"\"\"\n id: ID!\n\n \"\"\"Whether the customer is a guest.\"\"\"\n isGuest: Boolean!\n\n \"\"\"The job title of the customer.\"\"\"\n jobTitle: String\n\n \"\"\"The last name.\"\"\"\n lastName: String\n\n \"\"\"\n Arbitrary namespaced key/value metadata attached to the customer. Stored in the Metafields service. Paginated with Relay-style cursors; the full set is fetched from the service, so `totalCount` is exact.\n \"\"\"\n metafields(after: String, before: String, first: Int, last: Int): CustomerMetafieldsConnection\n\n \"\"\"A note about the customer.\"\"\"\n note: String\n\n \"\"\"The organization the customer belongs to.\"\"\"\n organization: String\n\n \"\"\"The customer's phone numbers (store-scoped).\"\"\"\n phoneNumbers: [CustomerPhoneNumber!]\n preferences: CustomerPreferences!\n\n \"\"\"\n External system references for this customer (e.g. third-party CRM IDs).\n \"\"\"\n references: [CustomerExternalReference!]\n\n \"\"\"The tags for the customer.\"\"\"\n tags: [String!]\n\n \"\"\"The date and time the customer was last updated.\"\"\"\n updatedAt: DateTime!\n}\n\n\"\"\"A customer's address within a store context.\"\"\"\ntype CustomerAddress {\n \"\"\"The details of the address.\"\"\"\n addressDetails: AddressDetails\n\n \"\"\"The first line of the address.\"\"\"\n addressLine1: String!\n\n \"\"\"The second line of the address.\"\"\"\n addressLine2: String\n\n \"\"\"The third line of the address.\"\"\"\n addressLine3: String\n\n \"\"\"\n The highest level sub-division in a country, such as a province, state, or ISO-3166-2 subdivision.\n \"\"\"\n adminArea1: String\n\n \"\"\"A city, town, or village. Smaller than `adminArea1`.\"\"\"\n adminArea2: String\n\n \"\"\"\n A sub-locality, suburb, neighborhood, or district. Smaller than `adminArea2`.\n \"\"\"\n adminArea3: String\n\n \"\"\"The neighborhood, ward, or district. Smaller than `adminArea3`.\"\"\"\n adminArea4: String\n\n \"\"\"The two-character ISO 3166-1 country code.\"\"\"\n countryCode: String!\n\n \"\"\"The date and time the address was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The first name.\"\"\"\n firstName: String\n\n \"\"\"The globally-unique ID.\"\"\"\n id: ID!\n\n \"\"\"Whether this is the default billing address for the store context.\"\"\"\n isDefaultBilling: Boolean!\n\n \"\"\"Whether this is the default shipping address for the store context.\"\"\"\n isDefaultShipping: Boolean!\n\n \"\"\"The last name.\"\"\"\n lastName: String\n\n \"\"\"The postal code of the address.\"\"\"\n postalCode: String\n\n \"\"\"The purpose of the address, e.g. SHIPPING or BILLING.\"\"\"\n type: AddressType!\n\n \"\"\"The date and time the address was last updated.\"\"\"\n updatedAt: DateTime!\n}\n\n\"\"\"A customer email address.\"\"\"\ntype CustomerEmailAddress {\n \"\"\"The globally-unique ID.\"\"\"\n id: ID!\n\n \"\"\"Whether the email address is the customer's primary email address.\"\"\"\n isPrimary: Boolean!\n\n \"\"\"The email address.\"\"\"\n value: String!\n}\n\n\"\"\"Input to filter customers by email address.\"\"\"\ninput CustomerEmailAddressFilterInput {\n \"\"\"The email address to filter by.\"\"\"\n eq: String!\n}\n\n\"\"\"A reference linking this customer to a record in an external system.\"\"\"\ntype CustomerExternalReference {\n createdAt: DateTime!\n customerId: ID! @deprecated(reason: \"Redundant: references are only reachable through Customer.references, so the customer ID is already known from the parent. Will be removed in a future release.\")\n\n \"\"\"Identifier of the customer in the external system.\"\"\"\n externalId: String!\n id: ID!\n\n \"\"\"Name of the external system that owns the referenced record.\"\"\"\n source: String!\n updatedAt: DateTime!\n}\n\n\"\"\"A contact identity (email or phone) belonging to a customer.\"\"\"\ntype CustomerIdentity {\n createdAt: DateTime!\n customerId: ID! @deprecated(reason: \"Redundant: this type is only returned by setPrimaryIdentity, which already takes the customer ID as an argument. Will be removed in a future release.\")\n id: ID!\n\n \"\"\"\n Whether this identity is the primary for its type within the current store context.\n \"\"\"\n isPrimary: Boolean!\n type: IdentityType!\n updatedAt: DateTime!\n\n \"\"\"The identity value (email address or phone number).\"\"\"\n value: String!\n\n \"\"\"\n Whether this identity has been confirmed (e.g. via an OTP/verification flow).\n \"\"\"\n verified: Boolean!\n}\n\ntype CustomerMetafieldsConnection {\n edges: [CustomerMetafieldsEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype CustomerMetafieldsEdge {\n cursor: String!\n node: Metafield\n}\n\n\"\"\"Input to sort customers by a specific field.\"\"\"\ninput CustomerOrderByInput {\n \"\"\"Sort by creation date.\"\"\"\n createdAt: OrderByDirection\n\n \"\"\"Sort by first name.\"\"\"\n firstName: OrderByDirection\n\n \"\"\"Sort by ID.\"\"\"\n id: OrderByDirection\n\n \"\"\"Sort by last name.\"\"\"\n lastName: OrderByDirection\n\n \"\"\"Sort by last update date.\"\"\"\n updatedAt: OrderByDirection\n}\n\n\"\"\"A customer phone number.\"\"\"\ntype CustomerPhoneNumber {\n \"\"\"The globally-unique ID.\"\"\"\n id: ID!\n\n \"\"\"Whether the phone number is the customer's primary phone number.\"\"\"\n isPrimary: Boolean!\n\n \"\"\"The phone number.\"\"\"\n value: String!\n}\n\n\"\"\"Input to filter customers by phone number.\"\"\"\ninput CustomerPhoneNumberFilterInput {\n \"\"\"The phone number to filter by.\"\"\"\n eq: String!\n}\n\n\"\"\"Customer-level preferences.\"\"\"\ntype CustomerPreferences {\n \"\"\"\n Communication locale (e.g. 'en-US'). Per-store value merged over customer-level default.\n \"\"\"\n locale: String\n marketingOptIn: Boolean\n\n \"\"\"Channels through which receipts are delivered to the customer.\"\"\"\n receiptDelivery: [ReceiptDeliveryChannel!]\n}\n\n\"\"\"\nA date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.\n\"\"\"\nscalar DateTime\n\n\"\"\"Response to a delete customer mutation.\"\"\"\ntype DeleteCustomerResponse implements MutationResponse {\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n\n \"\"\"Id of the customer removed from the store.\"\"\"\n deletedCustomerId: ID\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\ninput DeleteMetafieldsInput {\n \"\"\"\n Metafield ids to delete. Must contain between 1 and 100 ids, each 1 to 255 characters; an empty list is rejected.\n \"\"\"\n metafieldIds: [ID!]!\n}\n\n\"\"\"Response to a delete metafields mutation.\"\"\"\ntype DeleteMetafieldsResponse implements MutationResponse {\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\n\"\"\"\nA saved payment method (card or bank account) for a customer. Managed via the Card-on-File (CoF) service.\n\"\"\"\ntype FinancialInstrument {\n \"\"\"\n Card details (only present when type is CARD). PCI-safe (no full card number).\n \"\"\"\n card: FinancialInstrumentCard\n\n \"\"\"The date and time this instrument was first saved.\"\"\"\n createdAt: DateTime!\n\n \"\"\"UUID of the financial instrument.\"\"\"\n id: ID!\n\n \"\"\"\n Instrument status. Common values: \"ACTIVE\", \"INACTIVE\". Active instruments can be used for payments.\n \"\"\"\n status: String!\n\n \"\"\"Type of payment instrument. Common values: \"CARD\", \"BANK_ACCOUNT\".\"\"\"\n type: String!\n\n \"\"\"The date and time this instrument was last updated.\"\"\"\n updatedAt: DateTime!\n}\n\n\"\"\"Credit or debit card details (PCI-safe, no full card number).\"\"\"\ntype FinancialInstrumentCard {\n \"\"\"Expiration month (1-12).\"\"\"\n expMonth: Int!\n\n \"\"\"Expiration year (4 digits, e.g., 2026).\"\"\"\n expYear: Int!\n\n \"\"\"Name on the card (if provided).\"\"\"\n firstName: String\n\n \"\"\"Name on the card (if provided).\"\"\"\n lastName: String\n\n \"\"\"Last 4 digits of the card number.\"\"\"\n numberLast4: String!\n\n \"\"\"\n Card brand/network. Common values: \"VISA\", \"MASTERCARD\", \"AMEX\", \"DISCOVER\", \"DINERS\", \"JCB\", \"UNKNOWN\".\n \"\"\"\n type: String!\n}\n\n\"\"\"Sorting options for financial instruments list\"\"\"\ninput FinancialInstrumentOrderBy {\n \"\"\"Sort direction\"\"\"\n direction: OrderByDirection!\n\n \"\"\"Field to sort by\"\"\"\n field: FinancialInstrumentSortField!\n}\n\n\"\"\"Fields available for sorting financial instruments\"\"\"\nenum FinancialInstrumentSortField {\n \"\"\"Sort by creation date\"\"\"\n CREATED_AT\n\n \"\"\"Sort by last update date\"\"\"\n UPDATED_AT\n}\n\n\"\"\"The geographic latitude and longitude coordinates.\"\"\"\ntype GeoCoordinates {\n \"\"\"The latitude of the geo coordinates.\"\"\"\n latitude: Float!\n\n \"\"\"The longitude of the geo coordinates.\"\"\"\n longitude: Float!\n}\n\ninput GeoCoordinatesInput {\n \"\"\"\n The latitude of the geo coordinates. Between -90 and 90, to at most 6 decimal places.\n \"\"\"\n latitude: Float!\n\n \"\"\"\n The longitude of the geo coordinates. Between -180 and 180, to at most 6 decimal places.\n \"\"\"\n longitude: Float!\n}\n\n\"\"\"Kind of customer contact identity: email address or phone number.\"\"\"\nenum IdentityType {\n EMAIL\n PHONE\n}\n\n\"\"\"Arbitrary key/value metadata attached to a resource (e.g. a customer).\"\"\"\ntype Metafield {\n createdAt: DateTime\n id: ID\n key: String\n\n \"\"\"Logical grouping for keys to avoid collisions.\"\"\"\n namespace: String\n\n \"\"\"Identifier of the resource this metafield is attached to.\"\"\"\n resourceId: String\n\n \"\"\"Type of resource this metafield is attached to (e.g. 'CUSTOMER').\"\"\"\n resourceType: String\n\n \"\"\"Value type hint (e.g. 'string', 'json', 'integer').\"\"\"\n type: String\n updatedAt: DateTime\n value: String\n}\n\ninput MetafieldEntryInput {\n \"\"\"1 to 255 characters.\"\"\"\n key: String!\n\n \"\"\"1 to 10,000 characters.\"\"\"\n value: String!\n}\n\ntype Mutation {\n \"\"\"\n Add addresses to a customer within the current store context (x-store-id). Dedups against the customer's existing addresses; associates or creates as needed. Returns the store-scoped address.\n \"\"\"\n addAddressesToCustomer(\n customerId: ID!\n\n \"\"\"\n Addresses to add. Must contain between 1 and 10 entries; an empty list is rejected. A store context may hold at most 50 addresses in total.\n \"\"\"\n input: [AddAddressInput!]!\n ): AddAddressesToCustomerResponse!\n\n \"\"\"\n Add one or more email/phone identities to a customer within the current store context (store-scoped via x-store-id). Additive — existing identities are left untouched.\n \"\"\"\n addIdentitiesToCustomer(\n \"\"\"\n Optional. Bypass an identity conflict by ignoring the listed existing customers. Pass the `existingCustomerIds` returned by a prior conflict to retry the add.\n \"\"\"\n conflictResolution: AddIdentitiesConflictResolutionInput\n customerId: ID!\n\n \"\"\"\n Identities to add. Must contain between 1 and 20 entries; an empty list is rejected. A store context may hold at most 10 identities per type.\n \"\"\"\n input: [AddIdentityInput!]!\n ): AddIdentitiesToCustomerResponse!\n\n \"\"\"\n Add external system references to a customer. Returns the updated customer.\n \"\"\"\n addReferencesToCustomer(customerId: ID!, input: AddReferencesInput!): AddReferencesToCustomerResponse!\n\n \"\"\"\n Append tags to the store context for this customer. Duplicates are ignored. Returns the updated customer.\n \"\"\"\n addTagsToCustomer(customerId: ID!, input: TagsInput!): AddTagsToCustomerResponse!\n createCustomer(conflictResolution: CreateCustomerConflictResolutionInput, input: CreateCustomerInput!): CreateCustomerResponse!\n\n \"\"\"Delete the store's customer.\"\"\"\n deleteCustomer(customerId: ID!): DeleteCustomerResponse!\n deleteMetafields(customerId: ID!, input: DeleteMetafieldsInput!): DeleteMetafieldsResponse!\n\n \"\"\"\n Remove addresses from the current store context (x-store-id). An address left with no associations across all contexts is deleted (copy-on-write).\n \"\"\"\n removeAddressesFromCustomer(\n \"\"\"\n Address ids to remove. Must contain between 1 and 100 ids; an empty list is rejected.\n \"\"\"\n addressIds: [ID!]!\n customerId: ID!\n ): RemoveAddressesFromCustomerResponse!\n\n \"\"\"\n Remove a financial instrument from a store by deactivating all its store-specific tokens. This removes the merchant's ability to charge this instrument at this store without deleting the instrument itself. The instrument remains available at other stores.\n \"\"\"\n removeFinancialInstrumentFromStore(\n \"\"\"\n Input containing customer ID and instrument ID. All tokens for this instrument in the store will be deactivated.\n \"\"\"\n input: RemoveFinancialInstrumentFromStoreInput!\n ): RemoveFinancialInstrumentFromStoreResponse!\n\n \"\"\"\n Remove identities from a customer within the current store context (store-scoped via x-store-id). An identity left with zero associations across all store contexts is deleted (copy-on-write).\n \"\"\"\n removeIdentitiesFromCustomer(\n customerId: ID!\n\n \"\"\"\n Identity ids to remove. Must contain between 1 and 100 ids; an empty list is rejected.\n \"\"\"\n identityIds: [ID!]!\n ): RemoveIdentitiesFromCustomerResponse!\n\n \"\"\"\n Remove external system references from a customer. Returns the updated customer.\n \"\"\"\n removeReferencesFromCustomer(customerId: ID!, input: RemoveReferencesInput!): RemoveReferencesFromCustomerResponse!\n\n \"\"\"\n Remove specific tags from the store context for this customer. Missing tags are ignored. Returns the updated customer.\n \"\"\"\n removeTagsFromCustomer(customerId: ID!, input: TagsInput!): RemoveTagsFromCustomerResponse!\n\n \"\"\"\n Save a new financial instrument (card or bank account) for a customer using a PCI-safe nonce from the payment tokenization flow (e.g., Poynt, Stripe).\n \"\"\"\n saveFinancialInstrumentByNonce(\n \"\"\"Input containing customer ID and payment nonce.\"\"\"\n input: SaveFinancialInstrumentInput!\n ): SaveFinancialInstrumentByNonceResponse!\n\n \"\"\"Promote an identity to primary within the current store context.\"\"\"\n setPrimaryIdentity(customerId: ID!, identityId: ID!): SetPrimaryIdentityResponse!\n\n \"\"\"\n Update an address within the current store context. Updates in place when the address belongs only to this context; otherwise copy-on-write returns a new address id. Can set the per-purpose default via isDefault.\n \"\"\"\n updateAddress(addressId: ID!, customerId: ID!, input: UpdateAddressInput!): UpdateAddressResponse!\n updateCustomer(id: ID!, input: UpdateCustomerInput!): UpdateCustomerResponse!\n}\n\n\"\"\"A structured error from a failed mutation.\"\"\"\ntype MutationError {\n \"\"\"Machine-readable error code.\"\"\"\n code: MutationErrorCodeEnum!\n\n \"\"\"Human-readable error description.\"\"\"\n message: String\n\n \"\"\"Field path the error is associated with, if any.\"\"\"\n path: [String!]\n}\n\nenum MutationErrorCodeEnum {\n \"\"\"The request was invalid.\"\"\"\n BAD_REQUEST\n\n \"\"\"The request conflicted with the current state of the resource.\"\"\"\n CONFLICT\n\n \"\"\"The request was forbidden.\"\"\"\n FORBIDDEN\n\n \"\"\"An internal server error occurred.\"\"\"\n INTERNAL_SERVER_ERROR\n\n \"\"\"The resource was not found.\"\"\"\n NOT_FOUND\n\n \"\"\"The service is temporarily unavailable.\"\"\"\n SERVICE_UNAVAILABLE\n\n \"\"\"The request was rate limited.\"\"\"\n TOO_MANY_REQUESTS\n\n \"\"\"The request was not authenticated.\"\"\"\n UNAUTHENTICATED\n\n \"\"\"\n The request input was invalid. See the path field for the specific field that was invalid.\n \"\"\"\n VALIDATION_ERROR\n}\n\ninterface MutationResponse {\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\n\"\"\"The direction in which to order items.\"\"\"\nenum OrderByDirection {\n \"\"\"Sort items in ascending order.\"\"\"\n ASC\n\n \"\"\"Sort items in descending order.\"\"\"\n DESC\n}\n\ntype PageInfo {\n endCursor: String\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n startCursor: String\n}\n\ntype Query {\n \"\"\"Get a customer by ID.\"\"\"\n customer(id: ID!): Customer\n\n \"\"\"Get a collection of customers.\"\"\"\n customers(\n after: String\n before: String\n\n \"\"\"Filter by created at.\"\"\"\n createdAt: CreatedAtFilter\n\n \"\"\"Filter by email address.\"\"\"\n emailAddress: CustomerEmailAddressFilterInput\n first: Int\n\n \"\"\"Filter by is guest.\"\"\"\n isGuest: Boolean\n last: Int\n\n \"\"\"Order by a specific field. By default, customers are ordered by ID.\"\"\"\n orderBy: CustomerOrderByInput\n\n \"\"\"Filter by phone number.\"\"\"\n phoneNumber: CustomerPhoneNumberFilterInput\n\n \"\"\"Filter by updated at.\"\"\"\n updatedAt: UpdatedAtFilter\n ): QueryCustomersConnection\n\n \"\"\"\n Paginated list of financial instruments (saved payment methods) for a customer. Uses Relay cursor-based pagination. NOTE: Only forward pagination is supported (first/after) — the upstream Card-on-File API is page-based and offers no stable key to seek backwards from.\n \"\"\"\n financialInstruments(\n \"\"\"\n Cursor to paginate forward from — pass the `endCursor` from a previous page. Cursors are opaque; values not issued by this API are rejected.\n \"\"\"\n after: String\n\n \"\"\"UUID of the customer whose instruments to list.\"\"\"\n customerId: ID!\n\n \"\"\"Optional filter: exclude expired cards (defaults to false).\"\"\"\n excludeExpired: Boolean\n\n \"\"\"\n Maximum number of items to return (forward pagination). Defaults to 20 and is capped at 100; larger values are clamped, negative values are rejected. Fewer items than requested may be returned even when `pageInfo.hasNextPage` is true — always follow `endCursor` rather than counting edges.\n \"\"\"\n first: Int\n\n \"\"\"Sort order (defaults to CREATED_AT ASC).\"\"\"\n orderBy: FinancialInstrumentOrderBy\n ): QueryFinancialInstrumentsConnection!\n\n \"\"\"\n Search customers by name, email, or phone number. Minimum 3 characters required for search query. For filtering without search, use the 'customers' query.\n \"\"\"\n searchCustomers(\n after: String\n before: String\n\n \"\"\"Filter by created at.\"\"\"\n createdAt: CreatedAtFilter\n first: Int\n\n \"\"\"Filter by guest status.\"\"\"\n isGuest: Boolean\n last: Int\n\n \"\"\"Order by a specific field. By default, customers are ordered by ID.\"\"\"\n orderBy: CustomerOrderByInput\n\n \"\"\"Search term for name, email, or phone. Minimum 3 characters required.\"\"\"\n query: String!\n\n \"\"\"Filter by last update date.\"\"\"\n updatedAt: UpdatedAtFilter\n ): QuerySearchCustomersConnection\n}\n\ntype QueryCustomersConnection {\n edges: [QueryCustomersConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QueryCustomersConnectionEdge {\n cursor: String!\n node: Customer\n}\n\ntype QueryFinancialInstrumentsConnection {\n edges: [QueryFinancialInstrumentsConnectionEdge!]!\n pageInfo: PageInfo!\n\n \"\"\"\n Total number of matching instruments across all pages, as reported by the upstream Card-on-File API.\n \"\"\"\n totalCount: Int!\n}\n\ntype QueryFinancialInstrumentsConnectionEdge {\n cursor: String!\n node: FinancialInstrument\n}\n\ntype QuerySearchCustomersConnection {\n edges: [QuerySearchCustomersConnectionEdge]\n pageInfo: PageInfo!\n totalCount: Int!\n}\n\ntype QuerySearchCustomersConnectionEdge {\n cursor: String!\n node: Customer\n}\n\n\"\"\"A channel through which receipts can be delivered.\"\"\"\nenum ReceiptDeliveryChannel {\n EMAIL\n PRINT\n SMS\n}\n\n\"\"\"Response to a remove addresses from customer mutation.\"\"\"\ntype RemoveAddressesFromCustomerResponse implements MutationResponse {\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\n\"\"\"\nInput for removing a financial instrument from a store by deactivating all its tokens.\n\"\"\"\ninput RemoveFinancialInstrumentFromStoreInput {\n \"\"\"UUID of the customer who owns this payment instrument.\"\"\"\n customerId: ID!\n\n \"\"\"UUID of the financial instrument to remove from the store.\"\"\"\n financialInstrumentId: ID!\n}\n\n\"\"\"Response to a remove financial instrument from store mutation.\"\"\"\ntype RemoveFinancialInstrumentFromStoreResponse implements MutationResponse {\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\n\"\"\"Response to a remove identities from customer mutation.\"\"\"\ntype RemoveIdentitiesFromCustomerResponse implements MutationResponse {\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n customer: Customer\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\n\"\"\"Response to a remove references from customer mutation.\"\"\"\ntype RemoveReferencesFromCustomerResponse implements MutationResponse {\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n customer: Customer\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\ninput RemoveReferencesInput {\n \"\"\"\n Reference ids to remove. Must contain between 1 and 100 ids; an empty list is rejected.\n \"\"\"\n referenceIds: [ID!]!\n}\n\n\"\"\"Response to a remove tags from customer mutation.\"\"\"\ntype RemoveTagsFromCustomerResponse implements MutationResponse {\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n customer: Customer\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\n\"\"\"Response to a save financial instrument by nonce mutation.\"\"\"\ntype SaveFinancialInstrumentByNonceResponse implements MutationResponse {\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n financialInstrument: FinancialInstrument\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\n\"\"\"\nInput for saving a financial instrument (card or bank account) using a PCI-safe nonce from the payment tokenization flow.\n\"\"\"\ninput SaveFinancialInstrumentInput {\n \"\"\"UUID of the customer who owns this payment instrument.\"\"\"\n customerId: ID!\n\n \"\"\"\n PCI-safe payment nonce from frontend tokenization (e.g., Poynt, Stripe).\n \"\"\"\n nonce: String!\n\n \"\"\"\n Type of financial instrument. Currently supported: \"CARD\", \"BANK_ACCOUNT\". Defaults to \"CARD\" if not provided.\n \"\"\"\n type: String\n}\n\n\"\"\"Response to a set primary identity mutation.\"\"\"\ntype SetPrimaryIdentityResponse implements MutationResponse {\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n identity: CustomerIdentity\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\ninput TagsInput {\n \"\"\"\n Must contain between 1 and 100 tags, each 1 to 100 characters; an empty list is rejected. On add, a store context may hold at most 100 tags in total.\n \"\"\"\n tags: [String!]!\n}\n\ninput UpdateAddressInput {\n \"\"\"The details of the address.\"\"\"\n addressDetails: AddressDetailsInput\n\n \"\"\"The first line of the address.\"\"\"\n addressLine1: String\n\n \"\"\"The second line of the address.\"\"\"\n addressLine2: String\n\n \"\"\"The third line of the address.\"\"\"\n addressLine3: String\n\n \"\"\"\n The highest level sub-division in a country, such as a province, state, or ISO-3166-2 subdivision.\n \"\"\"\n adminArea1: String\n\n \"\"\"A city, town, or village. Smaller than `adminArea1`.\"\"\"\n adminArea2: String\n\n \"\"\"\n A sub-locality, suburb, neighborhood, or district. Smaller than `adminArea2`.\n \"\"\"\n adminArea3: String\n\n \"\"\"The neighborhood, ward, or district. Smaller than `adminArea3`.\"\"\"\n adminArea4: String\n\n \"\"\"The two-character ISO 3166-1 country code.\"\"\"\n countryCode: String\n\n \"\"\"The first name.\"\"\"\n firstName: String\n\n \"\"\"\n Mark this address as the store-context default for its purpose (SHIPPING/BILLING; BOTH sets both).\n \"\"\"\n isDefault: Boolean\n\n \"\"\"The last name.\"\"\"\n lastName: String\n\n \"\"\"The postal code of the address.\"\"\"\n postalCode: String\n\n \"\"\"The purpose of the address, e.g. SHIPPING or BILLING.\"\"\"\n type: AddressType\n}\n\n\"\"\"Response to an update address mutation.\"\"\"\ntype UpdateAddressResponse implements MutationResponse {\n address: CustomerAddress\n\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\ninput UpdateCustomerInput {\n displayName: String\n firstName: String\n\n \"\"\"The customer's new job title.\"\"\"\n jobTitle: String\n lastName: String\n\n \"\"\"Locale tag (e.g. 'en-US'). 2 to 35 characters.\"\"\"\n locale: String\n marketingOptIn: Boolean\n\n \"\"\"\n Pass null to delete the note. Omit to leave it unchanged. 1 to 10,000 characters; empty string is rejected.\n \"\"\"\n note: String\n\n \"\"\"The customer's new organization.\"\"\"\n organization: String\n\n \"\"\"\n Channels through which receipts are delivered. At most one entry per channel.\n \"\"\"\n receiptDelivery: [ReceiptDeliveryChannel!]\n}\n\n\"\"\"Response to an update customer mutation.\"\"\"\ntype UpdateCustomerResponse implements MutationResponse {\n \"\"\"\n Similar to HTTP status code, represents the status of the mutation response\n \"\"\"\n code: Int!\n customer: Customer\n\n \"\"\"Structured errors that prevented the mutation from succeeding, if any.\"\"\"\n errors: [MutationError!]\n\n \"\"\"Human-readable message describing the result of the mutation.\"\"\"\n message: String!\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n\n\"\"\"Filters items based on the date they were last updated.\"\"\"\ninput UpdatedAtFilter {\n gt: DateTime\n lt: DateTime\n}\n", + "types": [ + { + "fields": [ + { + "name": "address", + "type": "CreateAddressInput!" + }, + { + "description": "Mark this address as the store-context default for its purpose (SHIPPING/BILLING; BOTH sets both). At most one default per purpose per input array.", + "name": "isDefault", + "type": "Boolean" + } + ], + "kind": "input", + "name": "AddAddressInput" + }, + { + "fields": [ + { + "name": "addresses", + "type": "[CustomerAddress!]" + }, + { + "description": "Similar to HTTP status code, represents the status of the mutation response", + "name": "code", + "type": "Int!" + }, + { + "description": "Structured errors that prevented the mutation from succeeding, if any.", + "name": "errors", + "type": "[MutationError!]" + }, + { + "description": "Human-readable message describing the result of the mutation.", + "name": "message", + "type": "String!" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "AddAddressesToCustomerResponse" + }, + { + "fields": [ + { + "description": "The IDs of the conflicting customers to ignore, allowing the identities to be added despite the conflict. Typically the `existingCustomerIds` returned by a prior failed attempt. Up to 100 IDs.", + "name": "ignoreDuplicateIds", + "type": "[ID!]!" + } + ], + "kind": "input", + "name": "AddIdentitiesConflictResolutionInput" + }, + { + "fields": [ + { + "description": "Similar to HTTP status code, represents the status of the mutation response", + "name": "code", + "type": "Int!" + }, + { + "description": "The fields that caused the conflict. Only returned when the mutation fails due to identity conflicts.", + "name": "conflictFields", + "type": "[String!]" + }, + { + "name": "customer", + "type": "Customer" + }, + { + "description": "Structured errors that prevented the mutation from succeeding, if any.", + "name": "errors", + "type": "[MutationError!]" + }, + { + "description": "The IDs of existing customers whose identities conflict with the identities to add. Only returned when mutation fails due to conflicts.", + "name": "existingCustomerIds", + "type": "[ID!]" + }, + { + "description": "Human-readable message describing the result of the mutation.", + "name": "message", + "type": "String!" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "AddIdentitiesToCustomerResponse" + }, + { + "fields": [ + { + "description": "Mark this identity as primary for its type within the store context. At most one identity per type in the input array may set this to true.", + "name": "isPrimary", + "type": "Boolean" + }, + { + "name": "type", + "type": "IdentityType!" + }, + { + "description": "Identity value (email address or phone number).", + "name": "value", + "type": "String!" + } + ], + "kind": "input", + "name": "AddIdentityInput" + }, + { + "fields": [ + { + "description": "References to add. Must contain between 1 and 100 entries; an empty list is rejected. Duplicate source/externalId pairs are collapsed.", + "name": "references", + "type": "[CreateExternalReferenceInput!]!" + } + ], + "kind": "input", + "name": "AddReferencesInput" + }, + { + "fields": [ + { + "description": "Similar to HTTP status code, represents the status of the mutation response", + "name": "code", + "type": "Int!" + }, + { + "name": "customer", + "type": "Customer" + }, + { + "description": "Structured errors that prevented the mutation from succeeding, if any.", + "name": "errors", + "type": "[MutationError!]" + }, + { + "description": "Human-readable message describing the result of the mutation.", + "name": "message", + "type": "String!" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "AddReferencesToCustomerResponse" + }, + { + "fields": [ + { + "description": "Similar to HTTP status code, represents the status of the mutation response", + "name": "code", + "type": "Int!" + }, + { + "name": "customer", + "type": "Customer" + }, + { + "description": "Structured errors that prevented the mutation from succeeding, if any.", + "name": "errors", + "type": "[MutationError!]" + }, + { + "description": "Human-readable message describing the result of the mutation.", + "name": "message", + "type": "String!" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "AddTagsToCustomerResponse" + }, + { + "fields": [ + { + "description": "The type of address. Single character representation of a type. For example: 'B' for building, 'F' for organization, 'G' for general delivery, 'H' for high-rise, 'L' for large-volume organization, 'P' for Post Office box or delivery service, 'R' for rural route, 'S' for street, 'U' for unidentified address.", + "name": "addressType", + "type": "String" + }, + { + "description": "A named location that represents the premise. Usually a building name or number or collection of buildings with a common name or number.", + "name": "buildingName", + "type": "String" + }, + { + "description": "The delivery service. Post office box, bag number, or post office name", + "name": "deliveryService", + "type": "String" + }, + { + "description": "The latitude and longitude of the address.", + "name": "geoCoordinates", + "type": "GeoCoordinates" + }, + { + "description": "The street name. Just `Drury` in `Drury Lane`.", + "name": "streetName", + "type": "String" + }, + { + "description": "The street number.", + "name": "streetNumber", + "type": "String" + }, + { + "description": "The street type. For example, avenue, boulevard, road, or expressway.", + "name": "streetType", + "type": "String" + }, + { + "description": "The first-order entity below a named building or location that represents the sub-premise. Usually a single building within a collection of buildings with a common name. Can be a flat, story, floor, room, or apartment.", + "name": "subBuilding", + "type": "String" + } + ], + "kind": "object", + "name": "AddressDetails" + }, + { + "fields": [ + { + "description": "The type of address. Single character representation of a type. For example: 'B' for building, 'F' for organization, 'G' for general delivery, 'H' for high-rise, 'L' for large-volume organization, 'P' for Post Office box or delivery service, 'R' for rural route, 'S' for street, 'U' for unidentified address. Exactly 1 character.", + "name": "addressType", + "type": "String" + }, + { + "description": "A named location that represents the premise. Usually a building name or number or collection of buildings with a common name or number. At most 100 characters.", + "name": "buildingName", + "type": "String" + }, + { + "description": "The delivery service. Post office box, bag number, or post office name. At most 100 characters.", + "name": "deliveryService", + "type": "String" + }, + { + "name": "geoCoordinates", + "type": "GeoCoordinatesInput" + }, + { + "description": "The street name. Just `Drury` in `Drury Lane`. At most 100 characters.", + "name": "streetName", + "type": "String" + }, + { + "description": "The street number. At most 100 characters.", + "name": "streetNumber", + "type": "String" + }, + { + "description": "The street type. For example, avenue, boulevard, road, or expressway. At most 100 characters.", + "name": "streetType", + "type": "String" + }, + { + "description": "The first-order entity below a named building or location that represents the sub-premise. Usually a single building within a collection of buildings with a common name. Can be a flat, story, floor, room, or apartment. At most 100 characters.", + "name": "subBuilding", + "type": "String" + } + ], + "kind": "input", + "name": "AddressDetailsInput" + }, + { + "kind": "enum", + "name": "AddressType", + "values": [ + "BILLING", + "BOTH", + "SHIPPING" + ] + }, + { + "fields": [ + { + "name": "addressDetails", + "type": "AddressDetailsInput" + }, + { + "description": "The first line of the address. For example, number and street name. For example, `3032 Bunker Hill Lane`. Required for compliance and risk checks. Must contain the full address.", + "name": "addressLine1", + "type": "String!" + }, + { + "description": "The second line of the address. For example, office suite or apartment number.", + "name": "addressLine2", + "type": "String" + }, + { + "description": "The third line of the address, if needed. For example, a street complement for Brazil; direction text, such as `next to Opera House`; or a landmark reference in an Indian address.", + "name": "addressLine3", + "type": "String" + }, + { + "description": "The highest level sub-division in a country, which is usually a province, state, or ISO-3166-2 subdivision; formatted for postal delivery. For example, `CA` and not `California`. For example, for UK - A county; for USs - A state; for Canada - A province; for Japan - A prefecture; for Switzerland - A kanton.", + "name": "adminArea1", + "type": "String" + }, + { + "description": "A city, town, or village. Smaller than `adminArea1`.", + "name": "adminArea2", + "type": "String" + }, + { + "description": "A sub-locality, suburb, neighborhood, or district. Smaller than `adminArea2`. For example, in Brazil - Suburb, bairro, or neighborhood; in India - Sub-locality or district. Street name information may not always available and a sub-locality or district can reference a very small area.", + "name": "adminArea3", + "type": "String" + }, + { + "description": "The neighborhood, ward, or district. Smaller than `adminArea3` or `subLocality`. For example, the postal sorting code that is used in Guernsey and many French territories, such as French Guiana; the fine-grained administrative levels in China.", + "name": "adminArea4", + "type": "String" + }, + { + "description": "The [two-character ISO 3166-1 code](https://en.wikipedia.org/wiki/ISO_3166-1) that identifies the country or region. Note: The country code for Great Britain is `GB` and not `UK` as used in the top-level domain names for that country. Use country code `C2` for China for comparable uncontrolled price (CUP) method, bank-card, and cross-border transactions.", + "name": "countryCode", + "type": "String!" + }, + { + "description": "First name.", + "name": "firstName", + "type": "String" + }, + { + "description": "Last name.", + "name": "lastName", + "type": "String" + }, + { + "description": "The postal code, which is the zip code or equivalent. Typically required for countries that have a postal code or an equivalent. See [Postal code](https://en.wikipedia.org/wiki/Postal_code).", + "name": "postalCode", + "type": "String" + }, + { + "name": "type", + "type": "AddressType!" + } + ], + "kind": "input", + "name": "CreateAddressInput" + }, + { + "fields": [ + { + "description": "The IDs of the duplicates to ignore. Up to 100 IDs.", + "name": "ignoreDuplicateIds", + "type": "[ID!]!" + } + ], + "kind": "input", + "name": "CreateCustomerConflictResolutionInput" + }, + { + "fields": [ + { + "name": "displayName", + "type": "String" + }, + { + "description": "At most one initial email address to seed. Associated to the store identified by `storeId` and marked primary for its type. At least one of `emailAddress` or `phoneNumber` is required.", + "name": "emailAddress", + "type": "String" + }, + { + "name": "firstName", + "type": "String" + }, + { + "description": "The customer's job title.", + "name": "jobTitle", + "type": "String" + }, + { + "name": "lastName", + "type": "String" + }, + { + "description": "Locale tag (e.g. 'en-US'). 2 to 35 characters.", + "name": "locale", + "type": "String" + }, + { + "name": "marketingOptIn", + "type": "Boolean" + }, + { + "description": "Initial note. Omit to create without a note. 1 to 10,000 characters; empty string is rejected.", + "name": "note", + "type": "String" + }, + { + "description": "The customer's organization.", + "name": "organization", + "type": "String" + }, + { + "description": "At most one initial phone number to seed. Associated to the store identified by `storeId` and marked primary for its type. At least one of `emailAddress` or `phoneNumber` is required.", + "name": "phoneNumber", + "type": "String" + }, + { + "description": "Channels through which receipts are delivered. At most one entry per channel.", + "name": "receiptDelivery", + "type": "[ReceiptDeliveryChannel!]" + }, + { + "description": "Initial external references. When provided, must contain between 1 and 100 entries; an empty list is rejected.", + "name": "references", + "type": "[CreateExternalReferenceInput!]" + }, + { + "description": "The customer's tags. Up to 100 tags, each 1 to 100 characters.", + "name": "tags", + "type": "[String!]" + } + ], + "kind": "input", + "name": "CreateCustomerInput" + }, + { + "fields": [ + { + "description": "Similar to HTTP status code, represents the status of the mutation response", + "name": "code", + "type": "Int!" + }, + { + "description": "The fields that caused the conflict. Only returned when the creation fails due to identity conflicts.", + "name": "conflictFields", + "type": "[String!]" + }, + { + "name": "customer", + "type": "Customer" + }, + { + "description": "Structured errors that prevented the mutation from succeeding, if any.", + "name": "errors", + "type": "[MutationError!]" + }, + { + "description": "The IDs of existing customers whose identities conflict with the new customer. Only returned when the creation fails due to identity conflicts.", + "name": "existingCustomerIds", + "type": "[ID!]" + }, + { + "description": "Human-readable message describing the result of the mutation.", + "name": "message", + "type": "String!" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "CreateCustomerResponse" + }, + { + "fields": [ + { + "description": "Identifier of the customer in the external system.", + "name": "externalId", + "type": "String!" + }, + { + "description": "Name of the external system that owns the referenced record.", + "name": "source", + "type": "String!" + } + ], + "kind": "input", + "name": "CreateExternalReferenceInput" + }, + { + "fields": [ + { + "name": "gt", + "type": "DateTime" + }, + { + "name": "lt", + "type": "DateTime" + } + ], + "kind": "input", + "name": "CreatedAtFilter" + }, + { + "fields": [ + { + "description": "The customer's addresses (store-scoped).", + "name": "addresses", + "type": "[CustomerAddress!]" + }, + { + "description": "The date and time the customer was created.", + "name": "createdAt", + "type": "DateTime!" + }, + { + "description": "The display name.", + "name": "displayName", + "type": "String" + }, + { + "description": "The customer's email addresses (store-scoped).", + "name": "emailAddresses", + "type": "[CustomerEmailAddress!]" + }, + { + "description": "The first name.", + "name": "firstName", + "type": "String" + }, + { + "description": "The globally-unique ID.", + "name": "id", + "type": "ID!" + }, + { + "description": "Whether the customer is a guest.", + "name": "isGuest", + "type": "Boolean!" + }, + { + "description": "The job title of the customer.", + "name": "jobTitle", + "type": "String" + }, + { + "description": "The last name.", + "name": "lastName", + "type": "String" + }, + { + "description": "Arbitrary namespaced key/value metadata attached to the customer. Stored in the Metafields service. Paginated with Relay-style cursors; the full set is fetched from the service, so `totalCount` is exact.", + "name": "metafields", + "type": "CustomerMetafieldsConnection" + }, + { + "description": "A note about the customer.", + "name": "note", + "type": "String" + }, + { + "description": "The organization the customer belongs to.", + "name": "organization", + "type": "String" + }, + { + "description": "The customer's phone numbers (store-scoped).", + "name": "phoneNumbers", + "type": "[CustomerPhoneNumber!]" + }, + { + "name": "preferences", + "type": "CustomerPreferences!" + }, + { + "description": "External system references for this customer (e.g. third-party CRM IDs).", + "name": "references", + "type": "[CustomerExternalReference!]" + }, + { + "description": "The tags for the customer.", + "name": "tags", + "type": "[String!]" + }, + { + "description": "The date and time the customer was last updated.", + "name": "updatedAt", + "type": "DateTime!" + } + ], + "kind": "object", + "name": "Customer" + }, + { + "fields": [ + { + "description": "The details of the address.", + "name": "addressDetails", + "type": "AddressDetails" + }, + { + "description": "The first line of the address.", + "name": "addressLine1", + "type": "String!" + }, + { + "description": "The second line of the address.", + "name": "addressLine2", + "type": "String" + }, + { + "description": "The third line of the address.", + "name": "addressLine3", + "type": "String" + }, + { + "description": "The highest level sub-division in a country, such as a province, state, or ISO-3166-2 subdivision.", + "name": "adminArea1", + "type": "String" + }, + { + "description": "A city, town, or village. Smaller than `adminArea1`.", + "name": "adminArea2", + "type": "String" + }, + { + "description": "A sub-locality, suburb, neighborhood, or district. Smaller than `adminArea2`.", + "name": "adminArea3", + "type": "String" + }, + { + "description": "The neighborhood, ward, or district. Smaller than `adminArea3`.", + "name": "adminArea4", + "type": "String" + }, + { + "description": "The two-character ISO 3166-1 country code.", + "name": "countryCode", + "type": "String!" + }, + { + "description": "The date and time the address was created.", + "name": "createdAt", + "type": "DateTime!" + }, + { + "description": "The first name.", + "name": "firstName", + "type": "String" + }, + { + "description": "The globally-unique ID.", + "name": "id", + "type": "ID!" + }, + { + "description": "Whether this is the default billing address for the store context.", + "name": "isDefaultBilling", + "type": "Boolean!" + }, + { + "description": "Whether this is the default shipping address for the store context.", + "name": "isDefaultShipping", + "type": "Boolean!" + }, + { + "description": "The last name.", + "name": "lastName", + "type": "String" + }, + { + "description": "The postal code of the address.", + "name": "postalCode", + "type": "String" + }, + { + "description": "The purpose of the address, e.g. SHIPPING or BILLING.", + "name": "type", + "type": "AddressType!" + }, + { + "description": "The date and time the address was last updated.", + "name": "updatedAt", + "type": "DateTime!" + } + ], + "kind": "object", + "name": "CustomerAddress" + }, + { + "fields": [ + { + "description": "The globally-unique ID.", + "name": "id", + "type": "ID!" + }, + { + "description": "Whether the email address is the customer's primary email address.", + "name": "isPrimary", + "type": "Boolean!" + }, + { + "description": "The email address.", + "name": "value", + "type": "String!" + } + ], + "kind": "object", + "name": "CustomerEmailAddress" + }, + { + "fields": [ + { + "description": "The email address to filter by.", + "name": "eq", + "type": "String!" + } + ], + "kind": "input", + "name": "CustomerEmailAddressFilterInput" + }, + { + "fields": [ + { + "name": "createdAt", + "type": "DateTime!" + }, + { + "name": "customerId", + "type": "ID!" + }, + { + "description": "Identifier of the customer in the external system.", + "name": "externalId", + "type": "String!" + }, + { + "name": "id", + "type": "ID!" + }, + { + "description": "Name of the external system that owns the referenced record.", + "name": "source", + "type": "String!" + }, + { + "name": "updatedAt", + "type": "DateTime!" + } + ], + "kind": "object", + "name": "CustomerExternalReference" + }, + { + "fields": [ + { + "name": "createdAt", + "type": "DateTime!" + }, + { + "name": "customerId", + "type": "ID!" + }, + { + "name": "id", + "type": "ID!" + }, + { + "description": "Whether this identity is the primary for its type within the current store context.", + "name": "isPrimary", + "type": "Boolean!" + }, + { + "name": "type", + "type": "IdentityType!" + }, + { + "name": "updatedAt", + "type": "DateTime!" + }, + { + "description": "The identity value (email address or phone number).", + "name": "value", + "type": "String!" + }, + { + "description": "Whether this identity has been confirmed (e.g. via an OTP/verification flow).", + "name": "verified", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "CustomerIdentity" + }, + { + "fields": [ + { + "name": "edges", + "type": "[CustomerMetafieldsEdge]" + }, + { + "name": "pageInfo", + "type": "PageInfo!" + }, + { + "name": "totalCount", + "type": "Int!" + } + ], + "kind": "object", + "name": "CustomerMetafieldsConnection" + }, + { + "fields": [ + { + "name": "cursor", + "type": "String!" + }, + { + "name": "node", + "type": "Metafield" + } + ], + "kind": "object", + "name": "CustomerMetafieldsEdge" + }, + { + "fields": [ + { + "description": "Sort by creation date.", + "name": "createdAt", + "type": "OrderByDirection" + }, + { + "description": "Sort by first name.", + "name": "firstName", + "type": "OrderByDirection" + }, + { + "description": "Sort by ID.", + "name": "id", + "type": "OrderByDirection" + }, + { + "description": "Sort by last name.", + "name": "lastName", + "type": "OrderByDirection" + }, + { + "description": "Sort by last update date.", + "name": "updatedAt", + "type": "OrderByDirection" + } + ], + "kind": "input", + "name": "CustomerOrderByInput" + }, + { + "fields": [ + { + "description": "The globally-unique ID.", + "name": "id", + "type": "ID!" + }, + { + "description": "Whether the phone number is the customer's primary phone number.", + "name": "isPrimary", + "type": "Boolean!" + }, + { + "description": "The phone number.", + "name": "value", + "type": "String!" + } + ], + "kind": "object", + "name": "CustomerPhoneNumber" + }, + { + "fields": [ + { + "description": "The phone number to filter by.", + "name": "eq", + "type": "String!" + } + ], + "kind": "input", + "name": "CustomerPhoneNumberFilterInput" + }, + { + "fields": [ + { + "description": "Communication locale (e.g. 'en-US'). Per-store value merged over customer-level default.", + "name": "locale", + "type": "String" + }, + { + "name": "marketingOptIn", + "type": "Boolean" + }, + { + "description": "Channels through which receipts are delivered to the customer.", + "name": "receiptDelivery", + "type": "[ReceiptDeliveryChannel!]" + } + ], + "kind": "object", + "name": "CustomerPreferences" + }, + { + "fields": [ + { + "description": "Similar to HTTP status code, represents the status of the mutation response", + "name": "code", + "type": "Int!" + }, + { + "description": "Id of the customer removed from the store.", + "name": "deletedCustomerId", + "type": "ID" + }, + { + "description": "Structured errors that prevented the mutation from succeeding, if any.", + "name": "errors", + "type": "[MutationError!]" + }, + { + "description": "Human-readable message describing the result of the mutation.", + "name": "message", + "type": "String!" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "DeleteCustomerResponse" + }, + { + "fields": [ + { + "description": "Metafield ids to delete. Must contain between 1 and 100 ids, each 1 to 255 characters; an empty list is rejected.", + "name": "metafieldIds", + "type": "[ID!]!" + } + ], + "kind": "input", + "name": "DeleteMetafieldsInput" + }, + { + "fields": [ + { + "description": "Similar to HTTP status code, represents the status of the mutation response", + "name": "code", + "type": "Int!" + }, + { + "description": "Structured errors that prevented the mutation from succeeding, if any.", + "name": "errors", + "type": "[MutationError!]" + }, + { + "description": "Human-readable message describing the result of the mutation.", + "name": "message", + "type": "String!" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "DeleteMetafieldsResponse" + }, + { + "fields": [ + { + "description": "Card details (only present when type is CARD). PCI-safe (no full card number).", + "name": "card", + "type": "FinancialInstrumentCard" + }, + { + "description": "The date and time this instrument was first saved.", + "name": "createdAt", + "type": "DateTime!" + }, + { + "description": "UUID of the financial instrument.", + "name": "id", + "type": "ID!" + }, + { + "description": "Instrument status. Common values: \"ACTIVE\", \"INACTIVE\". Active instruments can be used for payments.", + "name": "status", + "type": "String!" + }, + { + "description": "Type of payment instrument. Common values: \"CARD\", \"BANK_ACCOUNT\".", + "name": "type", + "type": "String!" + }, + { + "description": "The date and time this instrument was last updated.", + "name": "updatedAt", + "type": "DateTime!" + } + ], + "kind": "object", + "name": "FinancialInstrument" + }, + { + "fields": [ + { + "description": "Expiration month (1-12).", + "name": "expMonth", + "type": "Int!" + }, + { + "description": "Expiration year (4 digits, e.g., 2026).", + "name": "expYear", + "type": "Int!" + }, + { + "description": "Name on the card (if provided).", + "name": "firstName", + "type": "String" + }, + { + "description": "Name on the card (if provided).", + "name": "lastName", + "type": "String" + }, + { + "description": "Last 4 digits of the card number.", + "name": "numberLast4", + "type": "String!" + }, + { + "description": "Card brand/network. Common values: \"VISA\", \"MASTERCARD\", \"AMEX\", \"DISCOVER\", \"DINERS\", \"JCB\", \"UNKNOWN\".", + "name": "type", + "type": "String!" + } + ], + "kind": "object", + "name": "FinancialInstrumentCard" + }, + { + "fields": [ + { + "description": "Sort direction", + "name": "direction", + "type": "OrderByDirection!" + }, + { + "description": "Field to sort by", + "name": "field", + "type": "FinancialInstrumentSortField!" + } + ], + "kind": "input", + "name": "FinancialInstrumentOrderBy" + }, + { + "kind": "enum", + "name": "FinancialInstrumentSortField", + "values": [ + "CREATED_AT", + "UPDATED_AT" + ] + }, + { + "fields": [ + { + "description": "The latitude of the geo coordinates.", + "name": "latitude", + "type": "Float!" + }, + { + "description": "The longitude of the geo coordinates.", + "name": "longitude", + "type": "Float!" + } + ], + "kind": "object", + "name": "GeoCoordinates" + }, + { + "fields": [ + { + "description": "The latitude of the geo coordinates. Between -90 and 90, to at most 6 decimal places.", + "name": "latitude", + "type": "Float!" + }, + { + "description": "The longitude of the geo coordinates. Between -180 and 180, to at most 6 decimal places.", + "name": "longitude", + "type": "Float!" + } + ], + "kind": "input", + "name": "GeoCoordinatesInput" + }, + { + "kind": "enum", + "name": "IdentityType", + "values": [ + "EMAIL", + "PHONE" + ] + }, + { + "fields": [ + { + "name": "createdAt", + "type": "DateTime" + }, + { + "name": "id", + "type": "ID" + }, + { + "name": "key", + "type": "String" + }, + { + "description": "Logical grouping for keys to avoid collisions.", + "name": "namespace", + "type": "String" + }, + { + "description": "Identifier of the resource this metafield is attached to.", + "name": "resourceId", + "type": "String" + }, + { + "description": "Type of resource this metafield is attached to (e.g. 'CUSTOMER').", + "name": "resourceType", + "type": "String" + }, + { + "description": "Value type hint (e.g. 'string', 'json', 'integer').", + "name": "type", + "type": "String" + }, + { + "name": "updatedAt", + "type": "DateTime" + }, + { + "name": "value", + "type": "String" + } + ], + "kind": "object", + "name": "Metafield" + }, + { + "fields": [ + { + "description": "1 to 255 characters.", + "name": "key", + "type": "String!" + }, + { + "description": "1 to 10,000 characters.", + "name": "value", + "type": "String!" + } + ], + "kind": "input", + "name": "MetafieldEntryInput" + }, + { + "fields": [ + { + "description": "Machine-readable error code.", + "name": "code", + "type": "MutationErrorCodeEnum!" + }, + { + "description": "Human-readable error description.", + "name": "message", + "type": "String" + }, + { + "description": "Field path the error is associated with, if any.", + "name": "path", + "type": "[String!]" + } + ], + "kind": "object", + "name": "MutationError" + }, + { + "kind": "enum", + "name": "MutationErrorCodeEnum", + "values": [ + "BAD_REQUEST", + "CONFLICT", + "FORBIDDEN", + "INTERNAL_SERVER_ERROR", + "NOT_FOUND", + "SERVICE_UNAVAILABLE", + "TOO_MANY_REQUESTS", + "UNAUTHENTICATED", + "VALIDATION_ERROR" + ] + }, + { + "kind": "enum", + "name": "OrderByDirection", + "values": [ + "ASC", + "DESC" + ] + }, + { + "fields": [ + { + "name": "endCursor", + "type": "String" + }, + { + "name": "hasNextPage", + "type": "Boolean!" + }, + { + "name": "hasPreviousPage", + "type": "Boolean!" + }, + { + "name": "startCursor", + "type": "String" + } + ], + "kind": "object", + "name": "PageInfo" + }, + { + "fields": [ + { + "name": "edges", + "type": "[QueryCustomersConnectionEdge]" + }, + { + "name": "pageInfo", + "type": "PageInfo!" + }, + { + "name": "totalCount", + "type": "Int!" + } + ], + "kind": "object", + "name": "QueryCustomersConnection" + }, + { + "fields": [ + { + "name": "cursor", + "type": "String!" + }, + { + "name": "node", + "type": "Customer" + } + ], + "kind": "object", + "name": "QueryCustomersConnectionEdge" + }, + { + "fields": [ + { + "name": "edges", + "type": "[QueryFinancialInstrumentsConnectionEdge!]!" + }, + { + "name": "pageInfo", + "type": "PageInfo!" + }, + { + "description": "Total number of matching instruments across all pages, as reported by the upstream Card-on-File API.", + "name": "totalCount", + "type": "Int!" + } + ], + "kind": "object", + "name": "QueryFinancialInstrumentsConnection" + }, + { + "fields": [ + { + "name": "cursor", + "type": "String!" + }, + { + "name": "node", + "type": "FinancialInstrument" + } + ], + "kind": "object", + "name": "QueryFinancialInstrumentsConnectionEdge" + }, + { + "fields": [ + { + "name": "edges", + "type": "[QuerySearchCustomersConnectionEdge]" + }, + { + "name": "pageInfo", + "type": "PageInfo!" + }, + { + "name": "totalCount", + "type": "Int!" + } + ], + "kind": "object", + "name": "QuerySearchCustomersConnection" + }, + { + "fields": [ + { + "name": "cursor", + "type": "String!" + }, + { + "name": "node", + "type": "Customer" + } + ], + "kind": "object", + "name": "QuerySearchCustomersConnectionEdge" + }, + { + "kind": "enum", + "name": "ReceiptDeliveryChannel", + "values": [ + "EMAIL", + "PRINT", + "SMS" + ] + }, + { + "fields": [ + { + "description": "Similar to HTTP status code, represents the status of the mutation response", + "name": "code", + "type": "Int!" + }, + { + "description": "Structured errors that prevented the mutation from succeeding, if any.", + "name": "errors", + "type": "[MutationError!]" + }, + { + "description": "Human-readable message describing the result of the mutation.", + "name": "message", + "type": "String!" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "RemoveAddressesFromCustomerResponse" + }, + { + "fields": [ + { + "description": "UUID of the customer who owns this payment instrument.", + "name": "customerId", + "type": "ID!" + }, + { + "description": "UUID of the financial instrument to remove from the store.", + "name": "financialInstrumentId", + "type": "ID!" + } + ], + "kind": "input", + "name": "RemoveFinancialInstrumentFromStoreInput" + }, + { + "fields": [ + { + "description": "Similar to HTTP status code, represents the status of the mutation response", + "name": "code", + "type": "Int!" + }, + { + "description": "Structured errors that prevented the mutation from succeeding, if any.", + "name": "errors", + "type": "[MutationError!]" + }, + { + "description": "Human-readable message describing the result of the mutation.", + "name": "message", + "type": "String!" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "RemoveFinancialInstrumentFromStoreResponse" + }, + { + "fields": [ + { + "description": "Similar to HTTP status code, represents the status of the mutation response", + "name": "code", + "type": "Int!" + }, + { + "name": "customer", + "type": "Customer" + }, + { + "description": "Structured errors that prevented the mutation from succeeding, if any.", + "name": "errors", + "type": "[MutationError!]" + }, + { + "description": "Human-readable message describing the result of the mutation.", + "name": "message", + "type": "String!" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "RemoveIdentitiesFromCustomerResponse" + }, + { + "fields": [ + { + "description": "Similar to HTTP status code, represents the status of the mutation response", + "name": "code", + "type": "Int!" + }, + { + "name": "customer", + "type": "Customer" + }, + { + "description": "Structured errors that prevented the mutation from succeeding, if any.", + "name": "errors", + "type": "[MutationError!]" + }, + { + "description": "Human-readable message describing the result of the mutation.", + "name": "message", + "type": "String!" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "RemoveReferencesFromCustomerResponse" + }, + { + "fields": [ + { + "description": "Reference ids to remove. Must contain between 1 and 100 ids; an empty list is rejected.", + "name": "referenceIds", + "type": "[ID!]!" + } + ], + "kind": "input", + "name": "RemoveReferencesInput" + }, + { + "fields": [ + { + "description": "Similar to HTTP status code, represents the status of the mutation response", + "name": "code", + "type": "Int!" + }, + { + "name": "customer", + "type": "Customer" + }, + { + "description": "Structured errors that prevented the mutation from succeeding, if any.", + "name": "errors", + "type": "[MutationError!]" + }, + { + "description": "Human-readable message describing the result of the mutation.", + "name": "message", + "type": "String!" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "RemoveTagsFromCustomerResponse" + }, + { + "fields": [ + { + "description": "Similar to HTTP status code, represents the status of the mutation response", + "name": "code", + "type": "Int!" + }, + { + "description": "Structured errors that prevented the mutation from succeeding, if any.", + "name": "errors", + "type": "[MutationError!]" + }, + { + "name": "financialInstrument", + "type": "FinancialInstrument" + }, + { + "description": "Human-readable message describing the result of the mutation.", + "name": "message", + "type": "String!" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "SaveFinancialInstrumentByNonceResponse" + }, + { + "fields": [ + { + "description": "UUID of the customer who owns this payment instrument.", + "name": "customerId", + "type": "ID!" + }, + { + "description": "PCI-safe payment nonce from frontend tokenization (e.g., Poynt, Stripe).", + "name": "nonce", + "type": "String!" + }, + { + "description": "Type of financial instrument. Currently supported: \"CARD\", \"BANK_ACCOUNT\". Defaults to \"CARD\" if not provided.", + "name": "type", + "type": "String" + } + ], + "kind": "input", + "name": "SaveFinancialInstrumentInput" + }, + { + "fields": [ + { + "description": "Similar to HTTP status code, represents the status of the mutation response", + "name": "code", + "type": "Int!" + }, + { + "description": "Structured errors that prevented the mutation from succeeding, if any.", + "name": "errors", + "type": "[MutationError!]" + }, + { + "name": "identity", + "type": "CustomerIdentity" + }, + { + "description": "Human-readable message describing the result of the mutation.", + "name": "message", + "type": "String!" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "SetPrimaryIdentityResponse" + }, + { + "fields": [ + { + "description": "Must contain between 1 and 100 tags, each 1 to 100 characters; an empty list is rejected. On add, a store context may hold at most 100 tags in total.", + "name": "tags", + "type": "[String!]!" + } + ], + "kind": "input", + "name": "TagsInput" + }, + { + "fields": [ + { + "description": "The details of the address.", + "name": "addressDetails", + "type": "AddressDetailsInput" + }, + { + "description": "The first line of the address.", + "name": "addressLine1", + "type": "String" + }, + { + "description": "The second line of the address.", + "name": "addressLine2", + "type": "String" + }, + { + "description": "The third line of the address.", + "name": "addressLine3", + "type": "String" + }, + { + "description": "The highest level sub-division in a country, such as a province, state, or ISO-3166-2 subdivision.", + "name": "adminArea1", + "type": "String" + }, + { + "description": "A city, town, or village. Smaller than `adminArea1`.", + "name": "adminArea2", + "type": "String" + }, + { + "description": "A sub-locality, suburb, neighborhood, or district. Smaller than `adminArea2`.", + "name": "adminArea3", + "type": "String" + }, + { + "description": "The neighborhood, ward, or district. Smaller than `adminArea3`.", + "name": "adminArea4", + "type": "String" + }, + { + "description": "The two-character ISO 3166-1 country code.", + "name": "countryCode", + "type": "String" + }, + { + "description": "The first name.", + "name": "firstName", + "type": "String" + }, + { + "description": "Mark this address as the store-context default for its purpose (SHIPPING/BILLING; BOTH sets both).", + "name": "isDefault", + "type": "Boolean" + }, + { + "description": "The last name.", + "name": "lastName", + "type": "String" + }, + { + "description": "The postal code of the address.", + "name": "postalCode", + "type": "String" + }, + { + "description": "The purpose of the address, e.g. SHIPPING or BILLING.", + "name": "type", + "type": "AddressType" + } + ], + "kind": "input", + "name": "UpdateAddressInput" }, - "required": [ - "activity", - "customer" - ], - "type": "object" - } - }, - "responses": { - "204": { - "description": "An activity for the given contact has been created" - }, - "401": { - "description": "Authentication info not sent or is invalid", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "403": { - "description": "Authenticated user is not allowed access", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "404": { - "description": "Resource not found", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "409": { - "description": "Application-specific server state error", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "422": { - "description": "Application-specific request error", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "500": { - "description": "Internal server error", - "schema": { - "$ref": "#/$defs/Error" - } - } - }, - "scopes": [ - "commerce.customer:create" - ], - "summary": "Create customer activity" - }, - { - "description": "This endpoint can be used to combine two or more customers together to create a single customer. The customer with the most complete basic attributes such as name, organization, and job title will be selected as the primary customer, and any attributes from the other customers will be reverse merged into the primary customer.", - "method": "POST", - "operationId": "CommerceCustomerJoin", - "parameters": [ - { - "description": "An identifier for a store", - "in": "path", - "name": "storeId", - "required": true, - "schema": { - "format": "uuid", - "type": "string" - } - } - ], - "path": "/stores/{storeId}/customer-join", - "requestBody": { - "contentType": "application/json", - "description": "Customer IDs", - "required": true, - "schema": { - "properties": { - "customerIds": { - "description": "Array of Customer IDs to join", - "items": { - "$ref": "#/$defs/CustomerId~1properties~1customerId" - }, - "maxItems": 50, - "minItems": 2, - "type": "array" - } + { + "fields": [ + { + "name": "address", + "type": "CustomerAddress" + }, + { + "description": "Similar to HTTP status code, represents the status of the mutation response", + "name": "code", + "type": "Int!" + }, + { + "description": "Structured errors that prevented the mutation from succeeding, if any.", + "name": "errors", + "type": "[MutationError!]" + }, + { + "description": "Human-readable message describing the result of the mutation.", + "name": "message", + "type": "String!" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "UpdateAddressResponse" }, - "required": [ - "customerIds" - ], - "type": "object" - } - }, - "responses": { - "202": { - "description": "A Join Customers action was successfully created", - "schema": { - "$ref": "#/$defs/CustomerActionResponse" - } - }, - "401": { - "description": "Authentication info not sent or is invalid", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "403": { - "description": "Authenticated user is not allowed access", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "404": { - "description": "Resource not found", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "409": { - "description": "Application-specific server state error", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "422": { - "description": "Application-specific request error", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "429": { - "description": "Too many requests received within interval", - "schema": { - "$ref": "#/$defs/ErrorLimit" - } - }, - "500": { - "description": "Internal server error", - "schema": { - "$ref": "#/$defs/Error" - } - } - }, - "scopes": [ - "commerce.customer:update" - ], - "summary": "Join customers" - }, - { - "description": "This endpoint can be used to retrieve a customer request using the store and request ID.", - "method": "GET", - "operationId": "GetRequest", - "parameters": [ - { - "description": "An identifier for a store", - "in": "path", - "name": "storeId", - "required": true, - "schema": { - "format": "uuid", - "type": "string" - } - }, - { - "description": "Request identifier", - "in": "path", - "name": "requestId", - "required": true, - "schema": { - "format": "uuid", - "type": "string" - } - } - ], - "path": "/stores/{storeId}/customer-requests/{requestId}", - "responses": { - "200": { - "description": "success", - "schema": { - "$ref": "#/$defs/Request" - } - }, - "401": { - "description": "Authentication info not sent or is invalid", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "403": { - "description": "Authenticated user is not allowed access", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "404": { - "description": "Resource not found", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "409": { - "description": "Application-specific server state error", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "429": { - "description": "Too many requests received within interval", - "schema": { - "$ref": "#/$defs/ErrorLimit" - } - }, - "500": { - "description": "Internal server error", - "schema": { - "$ref": "#/$defs/Error" - } - } - }, - "scopes": [ - "commerce.customer:create", - "commerce.customer:update" - ], - "summary": "Get customer request by ID" - }, - { - "description": "This endpoint can be used to retrieve a list of customers for a specific store. Deleted customers are excluded by default.", - "method": "GET", - "operationId": "CustomersList", - "parameters": [ - { - "description": "An identifier for a store", - "in": "path", - "name": "storeId", - "required": true, - "schema": { - "format": "uuid", - "type": "string" - } - }, - { - "description": "The page of results to return for pagination. Only supported up to the first 10 000 records of a result set. Use pageToken rather than page where possible. PageToken and page can not be used in combination, doing so will result in a 422 response.", - "in": "query", - "name": "page", - "required": false, - "schema": { - "default": 1, - "format": "integer-positive", - "type": "integer" - } - }, - { - "description": "Maximum number of items to return. If used with page will return results with an offset of page * pageSize", - "in": "query", - "name": "pageSize", - "required": false, - "schema": { - "default": 25, - "format": "integer-positive", - "maximum": 500, - "type": "integer" - } - }, - { - "description": "Use the `pageToken` returned from a previous search in order to obtain the next set of results. Use pageToken rather than page where possible. PageToken and page can not be used in combination, doing so will result in a 422 response.", - "in": "query", - "name": "pageToken", - "required": false, - "schema": { - "type": "string" - } - }, - { - "description": "Indicates whether the response should include the total number of items and pages through response properties totalItems and totalPages respectively.", - "in": "query", - "name": "totalRequired", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "description": "Search term - this string will be matched as a starts with for all text fields", - "in": "query", - "name": "queryString", - "required": false, - "schema": { - "type": "string" - } - }, - { - "description": "Filter customers by presence of at least one of these fields", - "in": "query", - "name": "nonEmptyFields", - "required": false, - "schema": { - "items": { - "enum": [ - "EMAIL", - "FIRST_NAME", - "LAST_NAME", - "PHONE" - ], - "type": "string" - }, - "type": "array" - } - }, - { - "description": "Filter customers by absence of at least one of these fields", - "in": "query", - "name": "emptyFields", - "required": false, - "schema": { - "items": { - "enum": [ - "EMAIL", - "FIRST_NAME", - "LAST_NAME", - "PHONE" - ], - "type": "string" - }, - "type": "array" - } - }, - { - "description": "Filter customers by presence of all of these fields", - "in": "query", - "name": "allNonEmptyFields", - "required": false, - "schema": { - "items": { - "enum": [ - "EMAIL", - "FIRST_NAME", - "LAST_NAME", - "PHONE" - ], - "type": "string" - }, - "type": "array" - } - }, - { - "description": "Filter customers by absence of all of these fields", - "in": "query", - "name": "allEmptyFields", - "required": false, - "schema": { - "items": { - "enum": [ - "EMAIL", - "FIRST_NAME", - "LAST_NAME", - "PHONE" - ], - "type": "string" - }, - "type": "array" - } - }, - { - "description": "Filter customers by external identifier; provide as comma separated values in the form `type:value` (eg: `poynt:123,asin:B0B9F7WNQH`)", - "in": "query", - "name": "externalIdentifiers", - "required": false, - "schema": { - "items": { - "description": "External identifier type and value separated by a colon, eg `poynt:123`", - "type": "string" - }, - "type": "array" - } - }, - { - "description": "Filter customers whose updatedAt is >= the specified date", - "in": "query", - "name": "updatedAtStart", - "required": false, - "schema": { - "$ref": "#/$defs/date-time" - } - }, - { - "description": "Filter customers whose updatedAt is <= the specified date", - "in": "query", - "name": "updatedAtEnd", - "required": false, - "schema": { - "$ref": "#/$defs/date-time" - } - } - ], - "path": "/stores/{storeId}/customers", - "responses": { - "200": { - "description": "Request was successful", - "schema": { - "allOf": [ + { + "fields": [ + { + "name": "displayName", + "type": "String" + }, + { + "name": "firstName", + "type": "String" + }, + { + "description": "The customer's new job title.", + "name": "jobTitle", + "type": "String" + }, + { + "name": "lastName", + "type": "String" + }, + { + "description": "Locale tag (e.g. 'en-US'). 2 to 35 characters.", + "name": "locale", + "type": "String" + }, + { + "name": "marketingOptIn", + "type": "Boolean" + }, + { + "description": "Pass null to delete the note. Omit to leave it unchanged. 1 to 10,000 characters; empty string is rejected.", + "name": "note", + "type": "String" + }, + { + "description": "The customer's new organization.", + "name": "organization", + "type": "String" + }, + { + "description": "Channels through which receipts are delivered. At most one entry per channel.", + "name": "receiptDelivery", + "type": "[ReceiptDeliveryChannel!]" + } + ], + "kind": "input", + "name": "UpdateCustomerInput" + }, + { + "fields": [ + { + "description": "Similar to HTTP status code, represents the status of the mutation response", + "name": "code", + "type": "Int!" + }, + { + "name": "customer", + "type": "Customer" + }, + { + "description": "Structured errors that prevented the mutation from succeeding, if any.", + "name": "errors", + "type": "[MutationError!]" + }, + { + "description": "Human-readable message describing the result of the mutation.", + "name": "message", + "type": "String!" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "UpdateCustomerResponse" + }, + { + "fields": [ { - "$ref": "#/$defs/PaginatedResponse" + "name": "gt", + "type": "DateTime" }, { - "properties": { - "customers": { - "description": "Array of customers", - "items": { - "$ref": "#/$defs/Customer" - }, - "type": "array" - } - }, - "required": [ - "customers" - ], - "type": "object" + "name": "lt", + "type": "DateTime" } - ] - } - }, - "401": { - "description": "Authentication info not sent or is invalid", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "403": { - "description": "Authenticated user is not allowed access", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "404": { - "description": "Resource not found", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "409": { - "description": "Application-specific server state error", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "422": { - "description": "Application-specific request error", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "429": { - "description": "Too many requests received within interval", - "schema": { - "$ref": "#/$defs/ErrorLimit" + ], + "kind": "input", + "name": "UpdatedAtFilter" } - }, - "500": { - "description": "Internal server error", - "schema": { - "$ref": "#/$defs/Error" - } - } + ] }, - "scopes": [ - "commerce.customer:show" - ], - "summary": "Get customers" - }, - { - "description": "This endpoint can be used to create or de-duplicate - using channel data - and merge into existing customer. If the provided channels differ from existing customer data, a new customer will be created. This endpoint will not remove any existing data and is additive in cases where merges occur.", "method": "POST", - "operationId": "CommerceCustomersCreate", - "parameters": [ - { - "description": "An identifier for a store", - "in": "path", - "name": "storeId", - "required": true, - "schema": { - "format": "uuid", - "type": "string" - } - } - ], - "path": "/stores/{storeId}/customers", - "requestBody": { - "contentType": "application/json", - "description": "Customer data to import", - "required": true, - "schema": { - "$ref": "#/$defs/CustomerCreate" - } - }, - "responses": { - "202": { - "description": "A CUSTOMER_CREATE action was successfully created", - "schema": { - "$ref": "#/$defs/CustomerActionResponse" - } - }, - "401": { - "description": "Authentication info not sent or is invalid", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "403": { - "description": "Authenticated user is not allowed access", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "404": { - "description": "Resource not found", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "409": { - "description": "Application-specific server state error", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "422": { - "description": "Application-specific request error", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "429": { - "description": "Too many requests received within interval", - "schema": { - "$ref": "#/$defs/ErrorLimit" - } - }, - "500": { - "description": "Internal server error", - "schema": { - "$ref": "#/$defs/Error" - } - } - }, - "scopes": [ - "commerce.customer:create" - ], - "summary": "Create a new customer" - }, - { - "description": "Retrieve the information of a single customer using the store and customer IDs.", - "method": "GET", - "operationId": "FetchCustomer", + "operationId": "postCustomerGraphql", "parameters": [ { - "description": "The id of the specific customer", - "in": "path", - "name": "customerId", - "required": true, - "schema": { - "format": "uuid", - "type": "string" - } - }, - { - "description": "An identifier for a store", "in": "path", "name": "storeId", "required": true, "schema": { - "format": "uuid", - "type": "string" - } - } - ], - "path": "/stores/{storeId}/customers/{customerId}", - "responses": { - "200": { - "description": "Request was successful", - "schema": { - "$ref": "#/$defs/Customer" - } - }, - "401": { - "description": "Authentication info not sent or is invalid", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "403": { - "description": "Authenticated user is not allowed access", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "404": { - "description": "Resource not found", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "422": { - "description": "Application-specific request error", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "429": { - "description": "Too many requests received within interval", - "schema": { - "$ref": "#/$defs/ErrorLimit" - } - }, - "500": { - "description": "Internal server error", - "schema": { - "$ref": "#/$defs/Error" - } - } - }, - "scopes": [ - "commerce.customer:read" - ], - "summary": "Get customer by ID" - }, - { - "description": "This endpoint can be used to update the information of a specific customer using the store and customer ID.", - "method": "PATCH", - "operationId": "CommerceCustomersUpdate", - "parameters": [ - { - "description": "The id of the specific customer", - "in": "path", - "name": "customerId", - "required": true, - "schema": { - "format": "uuid", - "type": "string" + "$ref": "#/$defs/uuid" } }, { - "description": "An identifier for a store", - "in": "path", - "name": "storeId", + "description": "Store ID header required by customer subgraph", + "in": "header", + "name": "x-store-id", "required": true, "schema": { - "format": "uuid", - "type": "string" + "$ref": "#/$defs/uuid" } } ], - "path": "/stores/{storeId}/customers/{customerId}", + "path": "/stores/{storeId}/customer-subgraph", "requestBody": { "contentType": "application/json", - "description": "Customer data to import", "required": true, "schema": { - "$ref": "#/$defs/CustomerUpdate" - } - }, - "responses": { - "202": { - "description": "A CUSTOMER_UPDATE action was successfully created", - "schema": { - "$ref": "#/$defs/CustomerActionResponse" - } - }, - "401": { - "description": "Authentication info not sent or is invalid", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "403": { - "description": "Authenticated user is not allowed access", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "404": { - "description": "Resource not found", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "409": { - "description": "Application-specific server state error", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "422": { - "description": "Application-specific request error", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "429": { - "description": "Too many requests received within interval", - "schema": { - "$ref": "#/$defs/ErrorLimit" - } - }, - "500": { - "description": "Internal server error", - "schema": { - "$ref": "#/$defs/Error" - } + "properties": { + "operationName": { + "type": "string" + }, + "query": { + "type": "string" + }, + "variables": { + "additionalProperties": true, + "type": "object" + } + }, + "required": [ + "query" + ], + "type": "object" } }, - "scopes": [ - "commerce.customer:update" - ], - "summary": "Update customer" - }, - { - "description": "Delete the information a single customer using the store and customer IDs.", - "method": "DELETE", - "operationId": "DeleteCustomer", - "parameters": [ - { - "description": "An identifier for a store", - "in": "path", - "name": "storeId", - "required": true, - "schema": { - "format": "uuid", - "type": "string" - } - }, - { - "description": "The id of the specific customer", - "in": "path", - "name": "customerId", - "required": true, - "schema": { - "format": "uuid", - "type": "string" - } - } - ], - "path": "/stores/{storeId}/customers/{customerId}", "responses": { - "202": { - "description": "A Delete action was successfully created", - "schema": { - "$ref": "#/$defs/CustomerActionResponse" - } - }, - "401": { - "description": "Authentication info not sent or is invalid", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "403": { - "description": "Authenticated user is not allowed access", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "404": { - "description": "Resource not found", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "409": { - "description": "Application-specific server state error", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "422": { - "description": "Application-specific request error", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "429": { - "description": "Too many requests received within interval", - "schema": { - "$ref": "#/$defs/ErrorLimit" - } - }, - "500": { - "description": "Internal server error", - "schema": { - "$ref": "#/$defs/Error" - } - } - }, - "scopes": [ - "commerce.customer:update" - ], - "summary": "Delete customer by ID" - }, - { - "description": "This endpoint can be used to undo all previous customer joins for a specific customer. Previously joined customers will now be available as individual customers.", - "method": "POST", - "operationId": "CommerceCustomerUnjoin", - "parameters": [ - { - "description": "An identifier for a store", - "in": "path", - "name": "storeId", - "required": true, + "200": { + "description": "GraphQL response", "schema": { - "format": "uuid", - "type": "string" + "properties": { + "data": { + "additionalProperties": true, + "nullable": true, + "type": "object" + }, + "errors": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array" + } + }, + "type": "object", + "x-sensitivity": { + "classification": "restricted" + } } }, - { - "description": "The id of the specific customer", - "in": "path", - "name": "customerId", - "required": true, - "schema": { - "format": "uuid", - "type": "string" - } - } - ], - "path": "/stores/{storeId}/customers/{customerId}/customer-unjoin", - "responses": { - "202": { - "description": "An Unjoin Customers action was successfully created", - "schema": { - "$ref": "#/$defs/CustomerActionResponse" - } + "400": { + "description": "Invalid request, including a missing x-store-id header" }, "401": { - "description": "Authentication info not sent or is invalid", - "schema": { - "$ref": "#/$defs/Error" - } + "description": "Unauthorized" }, "403": { - "description": "Authenticated user is not allowed access", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "404": { - "description": "Resource not found", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "409": { - "description": "Application-specific server state error", - "schema": { - "$ref": "#/$defs/Error" - } - }, - "422": { - "description": "Application-specific request error", - "schema": { - "$ref": "#/$defs/Error" - } + "description": "Forbidden" }, "429": { - "description": "Too many requests received within interval", - "schema": { - "$ref": "#/$defs/ErrorLimit" - } - }, - "500": { - "description": "Internal server error", - "schema": { - "$ref": "#/$defs/Error" - } + "description": "Rate limit exceeded at the API gateway." } }, "scopes": [ - "commerce.customer:update" + "commerce.customer:read", + "commerce.customer:create", + "commerce.customer:update", + "commerce.customer:delete" ], - "summary": "Separate joined customers" + "summary": "Customer GraphQL endpoint" } ], "name": "customer-profiles", - "title": "Customers API", - "version": "1.1.0" + "title": "Customer GraphQL API", + "version": "2.0.0" } \ No newline at end of file diff --git a/rust/schemas/api/domains.json b/rust/schemas/api/domains.json index 24ac218b..b95ee224 100644 --- a/rust/schemas/api/domains.json +++ b/rust/schemas/api/domains.json @@ -1,5 +1,33 @@ { "$defs": { + "AcknowledgedFee": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/acknowledged-fee.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A fee that the customer explicitly acknowledged before executing a purchase. Used to confirm the customer saw and accepted specific charges (e.g., PREMIUM domain fees) before the irreversible purchase is executed.\n", + "properties": { + "fee": { + "allOf": [ + { + "$ref": "#/$defs/simple-money" + }, + { + "description": "The monetary amount of this fee." + } + ] + }, + "type": { + "description": "Fee type identifying the charge category. Common values include ONE_TIME_PREMIUM_DOMAIN_PURCHASE for premium domain acquisition fees.\n", + "example": "ONE_TIME_PREMIUM_DOMAIN_PURCHASE", + "type": "string" + } + }, + "required": [ + "type", + "fee" + ], + "title": "AcknowledgedFee", + "type": "object" + }, "Agreement": { "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/agreement.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -297,6 +325,11 @@ "type": "string", "x-sensitivity": "confidential" }, + "metadata": { + "description": "The contact eligibility data fields as specified by GET /profile-schemas/{tld} (operationId: getProfileSchema)\n", + "type": "object", + "x-sensitivity": "confidential" + }, "organization": { "description": "Organization or company name. Required for contacts acting on behalf of a legal entity. Leave blank for individual registrants.\n", "example": "Example LLC", @@ -897,6 +930,90 @@ "title": "Domain Operation Type", "type": "string" }, + "DomainQuoteDetails": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/domain-quote-details.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "Shared quote details for a single domain. Contains the domain name, registration period, locked price, fees, availability status, resolved settings, and required agreements. Used as a base for both single-domain quotes (RegistrationQuote) and per-domain details in batch quotes (RegistrationBatchDomain).\n", + "properties": { + "available": { + "description": "Whether the domain is available for registration. When false, no quoteToken is returned (for single quotes) or the domain is excluded from the bulk quote.\n", + "type": "boolean" + }, + "domain": { + "description": "The domain name in punycode A-label form for IDNs.\n", + "example": "example.com", + "type": "string" + }, + "fees": { + "description": "Fees charged at the time of purchase, in addition to the registration price. For PREMIUM domains, includes ONE_TIME_PREMIUM_DOMAIN_PURCHASE.\n", + "items": { + "$ref": "#/$defs/Fee" + }, + "type": "array" + }, + "inventory": { + "allOf": [ + { + "$ref": "#/$defs/InventoryType" + }, + { + "description": "The inventory source for this domain. REGISTRY for standard domains, PREMIUM for aftermarket/premium domains, UNAVAILABLE when not available for registration.\n" + } + ] + }, + "period": { + "default": 1, + "description": "Registration period in years for which the price is quoted.", + "example": 1, + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "price": { + "allOf": [ + { + "$ref": "#/$defs/simple-money" + }, + { + "description": "The locked registration price for the quoted period. Total amount charged on execute is this price plus any fees.\n" + } + ] + }, + "renewalPrice": { + "allOf": [ + { + "$ref": "#/$defs/simple-money" + }, + { + "description": "The standard renewal price at the end of the registration period. This is the price that will be charged for subsequent renewals at non-promotional rates.\n" + } + ] + }, + "requiredAgreements": { + "description": "Legal agreements that must be accepted before executing this quote. The agreementType values from this list must be included in the execute request's consent object.\n", + "items": { + "$ref": "#/$defs/Agreement" + }, + "type": "array" + }, + "resolved": { + "allOf": [ + { + "$ref": "#/$defs/ResolvedSettings" + }, + { + "description": "The effective contact and preference settings that will be applied on execute. Review before execute to verify registrant, contacts, and preferences match intent.\n" + } + ] + } + }, + "required": [ + "domain", + "available" + ], + "title": "DomainQuoteDetails", + "type": "object" + }, "DomainStatus": { "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/domain-status.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -961,47 +1078,6 @@ "title": "Fee Type", "type": "string" }, - "InlineRegistrationProfile": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/inline-registration-profile.v3", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "A one-time, non-persisted set of contacts and purchase preference defaults supplied inline on a quote or execute request. Use to provide registration data for this transaction without creating or updating a saved registration profile.\nShared by the registration quote and execute request bodies. Every field is optional. Omitted fields account identity or other default values. Provided fields override only what is supplied — contact roles replace as a whole block; preference fields replace individually.\nThis is not a saved registration profile and is not JSON Patch. Data here applies only to the current quote or registration request.\n", - "properties": { - "autoRenew": { - "description": "Auto-renew preference for this registration. Omit to inherit from the resolved saved profile or account defaults.\n", - "type": "boolean" - }, - "contacts": { - "allOf": [ - { - "$ref": "#/$defs/Contacts" - }, - { - "description": "Contact records for this request. Each role provided replaces that role from the resolved saved profile or account identity. Omitted roles continue to resolve from the saved profile or cascade from registrant.\n" - } - ] - }, - "nameServers": { - "allOf": [ - { - "$ref": "#/$defs/NameServers" - }, - { - "description": "Authoritative nameservers for this registration. Omit to inherit from the resolved saved profile or platform defaults.\n", - "example": [ - "ns1.example.com", - "ns2.example.com" - ] - } - ] - }, - "privacy": { - "description": "WHOIS privacy preference for this registration. Omit to inherit from the resolved saved profile or account defaults.\n", - "type": "boolean" - } - }, - "title": "Inline Registration Profile", - "type": "object" - }, "InventoryType": { "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/inventory-type.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -1046,6 +1122,54 @@ "title": "Optimization Target", "type": "string" }, + "Profile": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/profile.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A set of contacts and purchase preference defaults supplied on a quote or registration request. Use to provide registration data for a transaction, either inline or via a saved registration profile.\nEvery field is optional at the base level. Each usage site layers its own required constraints. Omitted fields account identity or other default values. Provided fields override only what is supplied — contact roles replace as a whole block; preference fields replace individually.\n", + "properties": { + "autoRenew": { + "description": "Auto-renew preference for this registration. Omit to inherit from the resolved saved profile or account defaults.\n", + "type": "boolean" + }, + "contacts": { + "allOf": [ + { + "$ref": "#/$defs/Contacts" + }, + { + "description": "Contact records for this request. Each role provided replaces that role from the resolved saved profile or account identity. Omitted roles continue to resolve from the saved profile or cascade from registrant.\n" + } + ] + }, + "nameServers": { + "allOf": [ + { + "$ref": "#/$defs/NameServers" + }, + { + "description": "Authoritative nameservers for this registration. Omit to inherit from the resolved saved profile or platform defaults.\n", + "example": [ + "ns1.example.com", + "ns2.example.com" + ] + } + ] + }, + "privacy": { + "description": "WHOIS privacy preference for this registration. Omit to inherit from the resolved saved profile or account defaults.\n", + "type": "boolean" + } + }, + "title": "Profile", + "type": "object" + }, + "ProfileSchema": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/profile-schema.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "TLD-specific JSON Schema describing the fields required to build a profile for a domain under this TLD. The structure varies per TLD and is not further constrained at the API layer. Use the contents to guide construction of POST /registration-quotes and POST /registrations request bodies.\n", + "title": "Profile Schema", + "type": "object" + }, "Registration": { "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -1143,10 +1267,10 @@ "profile": { "allOf": [ { - "$ref": "#/$defs/InlineRegistrationProfile" + "$ref": "#/$defs/Profile" }, { - "description": "One-time inline contacts and purchase preference defaults for this registration. Not persisted. Must match the profile supplied on the quote when a profile was included at quote time.\n" + "description": "One-time contacts and purchase preference defaults for this registration. Not persisted. Must match the profile supplied on the quote when a profile was included at quote time.\n" } ] }, @@ -1214,30 +1338,18 @@ "title": "Registration", "type": "object" }, - "RegistrationPreference": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-preference.v3", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "A purchase preference enabled on a saved registration profile.\nAUTO_RENEW — renew the domain automatically before it expires. PRIVACY — withhold registrant details from public WHOIS. TRUSTEE — local-presence service required by some TLDs. Derived from the contacts supplied rather than set directly, and returned on read when it applies.\nNot a closed set. These are the preferences this version names; a profile may carry a preference that is not among them, and new ones may be named in a later version.\n", - "examples": [ - "AUTO_RENEW", - "PRIVACY", - "TRUSTEE" - ], - "title": "Registration Preference", - "type": "string" - }, - "RegistrationProfile": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-profile.v3", + "RegistrationBatch": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-batch.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "A saved, reusable set of contacts and purchase preference defaults, referenced by profileId on a registration quote or a registration.\nA profile is a registration-time template. Its values are copied into the registration when a quote is executed, and nothing links the profile to the resulting domain afterwards. A profile cannot be edited, and no change to a profile can affect a domain already registered from it. To change saved details, create the replacement first, then delete the profile it supersedes.\nA profile is scoped to the TLDs named on create, because contact requirements are set by the TLD rather than by the contacts supplied. TLDs sharing one set of requirements share a profile; a TLD demanding additional registrant detail needs its own. See GET /registration-schemas/{tld} for what contacts a TLD requires.\nSee profileId on the registration quote for how a saved profile, an inline profile and account identity combine.\n", + "description": "A batch domain registration entity created when a POST /registration-batch request is accepted. Registration batches are a top-level resource with their own stable registrationBatchId; the domain relationships are captured in the domains array.\nOn POST /registration-batch, supply the writable fields (domains array, registrationQuoteBatchToken, consent). The server returns the full RegistrationBatch with readOnly fields populated. Poll links[rel=self] until status reaches COMPLETED or FAILED.\nAll domains are registered atomically (all succeed or all fail). On COMPLETED, each domain in the array includes expiresAt and orderId. On FAILED, no domains were registered and the error field contains the failure reason.\n", "properties": { - "contacts": { + "consent": { "allOf": [ { - "$ref": "#/$defs/Contacts" + "$ref": "#/$defs/Consent" }, { - "description": "Contacts saved on this profile. Every role given here applies to all the TLDs the profile covers, since those TLDs share one set of contact requirements.\n" + "description": "The customer's consent for the legal agreements returned in the quote. On execute, supply agreementTypes and agreedAt; agreedBy is server-derived and returned on the persisted record.\nNOTE: For batch registrations, do NOT include acknowledgedFees in this top-level consent object. Premium domain fees must be acknowledged per-domain in the domains array using the acknowledgedFees field on each RegistrationBatchDomainItem that has fees.\n" } ] }, @@ -1247,271 +1359,192 @@ "$ref": "#/$defs/date-time" }, { - "description": "When the profile was created. Absent for profiles created before this timestamp was recorded.\n", + "description": "Timestamp when this registration batch was initiated.", "readOnly": true } ] }, - "links": { - "description": "HATEOAS link relations. rel=self — the canonical URL for this profile. Profiles are replace-only, so no relation is offered for modifying one.\n", - "items": { - "$ref": "#/$defs/link-description" - }, - "readOnly": true, - "type": "array" + "defaultProfile": { + "allOf": [ + { + "$ref": "#/$defs/Profile" + }, + { + "description": "The default inline profile supplied on the registration request, if any. Applied to all domains unless overridden at the per-domain level. Echoed from the request.\n" + } + ] }, - "name": { - "description": "Optional human-readable label. Recommended, since it is the only human-readable field that tells one profile from another on read. Not required to be unique.\n", - "example": "Acme Corp standard contacts", - "maxLength": 100, - "minLength": 1, - "type": "string" + "defaultProfileId": { + "allOf": [ + { + "$ref": "#/$defs/uuid" + }, + { + "description": "The default profileId supplied on the registration request, if any. Applied to all domains unless overridden at the per-domain level. Echoed from the request.\n" + } + ] }, - "nameServers": { - "description": "Authoritative nameservers applied when this profile is used. Omit to inherit platform defaults at registration time. No minimum count applies to a stored profile, which may carry a partial set or none.\n", - "example": [ - "ns1.example.com", - "ns2.example.com" - ], + "domains": { + "description": "List of domains to register. On execute (POST), supply domain and period for each. On poll (GET), includes per-domain outcomes (expiresAt, status) when COMPLETED.\n", "items": { - "$ref": "#/$defs/NameserverHostname" + "$ref": "#/$defs/RegistrationBatchDomainItem" }, - "maxItems": 13, + "maxItems": 50, + "minItems": 1, "type": "array" }, - "preferences": { - "description": "Purchase preferences to enable when this profile is used. A profile can only enable a preference, never disable one, so leaving a value out of the list means the registration takes the platform default for it: auto-renew on, privacy off. To register without auto-renew, supply the preference inline on that registration instead.\nOn read the list is what the profile will apply, which is not always what was sent: a preference the supplied contacts require is added when the profile is created. Treat it as open — it may name a preference this version does not document.\n", - "example": [ - "AUTO_RENEW", - "PRIVACY" - ], - "items": { - "$ref": "#/$defs/RegistrationPreference" - }, - "type": "array", - "uniqueItems": true - }, - "profileId": { + "error": { "allOf": [ { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/error" }, { - "description": "Server-assigned identifier. Opaque: store it and echo it back on quote and registration requests. Do not parse it or infer meaning from its value.\n", - "example": "14514a29-5fce-4624-8d8a-d8abd56015e2", + "description": "Failure reason when status is FAILED. Absent otherwise.\n", "readOnly": true } ] }, - "tlds": { - "description": "The TLDs this profile is for. Supplied on create and not returned on read, so a caller that needs the mapping should keep its own. All TLDs listed must share one set of contact requirements; if they do not, the request is rejected and the caller should create one profile per requirement set.\n", - "example": [ - "com", - "net" - ], + "links": { + "description": "HATEOAS link relations for this registration batch. rel=self — the canonical URL for this registration batch record. rel=domains — links to each registered domain-name resource once the batch registration is complete.\n", "items": { - "type": "string" - }, - "minItems": 1, - "type": "array", - "writeOnly": true - } - }, - "required": [ - "tlds", - "contacts" - ], - "title": "Registration Profile", - "type": "object", - "x-sensitivity": "confidential" - }, - "RegistrationQuote": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-quote.v3", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "A price quote for registering a single domain. Contains a locked price, resolved contact and preference settings, required legal agreements, and a short-lived single-use quoteToken that must be presented on the subsequent registration execute call. Execution without a valid quoteToken is structurally impossible.\nWhen available is false, no quoteToken is returned — this is not an error; it means the domain cannot be registered as requested.\n", - "properties": { - "available": { - "description": "Whether the domain is available for registration. When false, no quoteToken is returned. The availability check at quote time is authoritative; a name sniped between suggest/availability and quote fails cleanly here.\n", - "type": "boolean" - }, - "domain": { - "description": "The domain name being quoted, in punycode A-label form for IDNs.\n", - "example": "example.com", - "type": "string" - }, - "expiresAt": { - "allOf": [ - { - "$ref": "#/$defs/date-time" - }, - { - "description": "The expiry timestamp of the quoteToken. After this time, presenting the token on execute returns quote_expired and a new quote must be obtained.\n" - } - ] - }, - "fees": { - "description": "Fees charged at the time of purchase, in addition to the registration price. Present when the domain incurs purchase fees beyond the base registration cost.\nThese are the same fees as TermPrice.fees for the selected term (this quote's period) — not a separate term-independent fee list and not additional to term-level fees. Execute cost is price plus this array. Mirrored on Registration.fees after execute.\n", - "items": { - "$ref": "#/$defs/Fee" + "$ref": "#/$defs/link-description" }, + "readOnly": true, "type": "array" }, - "inventory": { + "operationId": { "allOf": [ { - "$ref": "#/$defs/InventoryType" + "$ref": "#/$defs/uuid" }, { - "description": "The inventory type of the quoted domain. Present when available is true.\n", + "description": "Identifier of the DomainOperation tracking this registration batch. Same value returned by GET /operations/{operationId} for abstract operation tracking.\n", + "example": "9f1c2e7a-4b3d-4e8f-a1c2-3d4e5f6a7b8c", "readOnly": true } ] }, - "irreversible": { - "description": "Whether executing this quote is irreversible once accepted. Use to calibrate the explicitness of any confirmation step presented before execute.\n", - "example": false, - "type": "boolean" - }, - "period": { - "description": "Registration period in years for which the price is quoted.", - "example": 1, - "maximum": 10, - "minimum": 1, - "type": "integer" - }, - "price": { - "allOf": [ - { - "$ref": "#/$defs/simple-money" - }, - { - "description": "The locked registration price for the quoted period. Held for the duration of the quoteToken's TTL. Total amount charged on execute is this price plus any fees on this quote.\n" - } - ] + "orderId": { + "description": "The orderId for the batch registration order. All domains in this registration batch are part of a single order. Present only when status is COMPLETED.\n", + "readOnly": true, + "type": "string" }, - "quoteToken": { + "registrationBatchId": { "allOf": [ { "$ref": "#/$defs/uuid" }, { - "description": "Opaque, single-use token with a 10-minute TTL. References the locked price, a hash of this request body, and a hash of the resolved profile values. Absent when available is false. Treat as a capability; do not parse.\n", - "example": "7f3a2b1c-9d8e-4012-a5b6-c1d2e3f4a5b6" - } - ] - }, - "renewalPrice": { - "allOf": [ - { - "$ref": "#/$defs/simple-money" - }, - { - "description": "Indicative renewal cost at current rates. Not a price guarantee; renewal pricing is locked at time of renewal quote.\n" + "description": "Server-assigned stable identifier for this registration batch record.\n", + "readOnly": true } ] }, - "requiredAgreements": { - "description": "Legal agreements that must be accepted before executing this quote. The agreementType values from this list must be included in the execute request's consent object.\n", - "items": { - "$ref": "#/$defs/Agreement" - }, - "type": "array" + "registrationQuoteBatchToken": { + "description": "The single-use opaque token from the preceding quoteRegistrationBatch call. Required. Consumed on first successful execution; idempotent retries with the same Idempotency-Key replay the original operation without re-consuming.\nThe token has a bqt_ prefix followed by a UUID to distinguish it from single-domain quote tokens. Treat as a capability; do not parse.\n", + "example": "bqt_7f3a2b1c-9d8e-4012-a5b6-c1d2e3f4a5b6", + "pattern": "^bqt_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", + "type": "string", + "writeOnly": true }, - "resolved": { + "status": { "allOf": [ { - "$ref": "#/$defs/ResolvedSettings" + "$ref": "#/$defs/DomainOperationStatus" }, { - "description": "The effective contact and preference settings that will be applied on execute. Review before execute to verify registrant, contacts, and preferences match intent.\n" + "description": "Current execution status of this registration batch.", + "readOnly": true } ] } }, "required": [ - "domain", - "available" + "domains", + "registrationQuoteBatchToken", + "consent" ], - "title": "Registration Quote", + "title": "RegistrationBatch", "type": "object" }, - "RegistrationSchema": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-schema.v3", + "RegistrationBatchDomain": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-batch-domain.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "TLD-specific JSON Schema describing the fields required to register a domain under this TLD. The structure varies per TLD and is not further constrained at the API layer. Use the contents to guide construction of the POST /registration-quotes and POST /registrations request bodies.\n", - "title": "Registration Schema", - "type": "object" + "allOf": [ + { + "$ref": "#/$defs/DomainQuoteDetails" + }, + { + "properties": { + "error": { + "allOf": [ + { + "$ref": "#/$defs/error" + }, + { + "description": "Error details for this domain if it could not be quoted or registered. Present only when a per-domain failure occurred.\n", + "readOnly": true + } + ] + } + }, + "type": "object" + } + ], + "description": "A single domain within a batch registration quote response. Extends DomainQuoteDetails with additional fields for per-domain profile overrides and error details. This model is used only for quote responses (RegistrationQuoteBatch); the execute/poll path uses RegistrationBatchDomainItem instead.\n", + "title": "RegistrationBatchDomain" }, - "Renewal": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/renewal.v3", + "RegistrationBatchDomainItem": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-batch-domain-item.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "A domain renewal entity created when a POST /renewals request is accepted. Renewals are a top-level resource with their own stable renewalId; the domain relationship is captured in the representation.\nOn POST /renewals, supply the writable fields (domain, quoteToken, and consent; period is optional). The server returns the full Renewal with readOnly fields populated. Poll links[rel=self] (GET /renewals/{renewalId}) until status reaches COMPLETED or FAILED. The same resource is also reachable via GET /operations/{operationId} for clients operating at the abstract level; operationId is included in the representation for that purpose.\nThe price commitment rides in the quoteToken; consent records when the customer confirmed the charge. Renewals have no legal-agreement or fee acknowledgment surface — use RenewalConsent, not Consent.\n", + "description": "A single domain within a batch registration execution request or poll response. Contains core registration fields (domain, period, price, fees) plus fields for execute requests (acknowledgedFees, profile overrides) and poll responses (status, expiresAt, updatedAt).\n", "properties": { - "consent": { - "allOf": [ - { - "$ref": "#/$defs/RenewalConsent" - }, - { - "description": "The customer's confirmation of the renewal. On execute, supply agreedAt; agreedBy is server-derived and returned on the persisted record.\n" - } - ] + "acknowledgedFees": { + "description": "Fees acknowledged by the customer for this domain. Required on execute when the quote's fees array is non-empty (PREMIUM domains). Must match the quote's fees verbatim. Present only on execute requests.\n", + "items": { + "$ref": "#/$defs/AcknowledgedFee" + }, + "type": "array", + "writeOnly": true }, - "createdAt": { + "domain": { + "description": "The domain name in punycode A-label form for IDNs.\n", + "example": "example.com", + "type": "string" + }, + "error": { "allOf": [ { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/error" }, { - "description": "Timestamp when this renewal was initiated.", + "description": "Per-domain failure detail when this domain's status is FAILED. Absent otherwise.\n", "readOnly": true } ] }, - "domain": { - "description": "The domain name to renew, in punycode A-label form for IDNs. Must match the domain in the quoteToken.\n", - "example": "example.com", - "type": "string" - }, "expiresAt": { "allOf": [ { "$ref": "#/$defs/date-time" }, { - "description": "The domain's new expiry date once the renewal completes. Present only when status is COMPLETED. This is the authoritative post-renewal expiry; RenewalQuote.resolvedNewExpiresAt is only the projected value at quote time.\n", + "description": "The domain's expiry date once the registration completes. Present only on poll responses when this domain's status is COMPLETED.\n", "readOnly": true } ] }, - "links": { - "description": "HATEOAS link relations for this renewal. rel=self — the canonical URL for this renewal record (GET /renewals/{renewalId}). rel=domain — the renewed domain-name resource once status is COMPLETED. rel=operation — the abstract operation at GET /operations/{operationId}.\n", + "fees": { + "description": "Fees charged at the time of purchase, in addition to the registration price. For PREMIUM domains, includes ONE_TIME_PREMIUM_DOMAIN_PURCHASE.\n", "items": { - "$ref": "#/$defs/link-description" + "$ref": "#/$defs/Fee" }, "readOnly": true, "type": "array" }, - "operationId": { - "allOf": [ - { - "$ref": "#/$defs/uuid" - }, - { - "description": "Identifier of the DomainOperation tracking this renewal. Use with GET /operations/{operationId} for abstract operation polling. Both the concrete (GET /renewals/{renewalId}) and abstract poll endpoints resolve the same underlying state.\n", - "example": "9f1c2e7a-4b3d-4e8f-a1c2-3d4e5f6a7b8c", - "readOnly": true - } - ] - }, - "orderId": { - "description": "The orderId of the order that processed this renewal. Present only when status is COMPLETED. Not present for failed or in-progress renewals.\n", - "readOnly": true, - "type": "string" - }, "period": { "default": 1, - "description": "Renewal period in years. Must match the period in the preceding quote. If omitted, defaults to 1 — so omit only when the quote was for 1 year; otherwise echo the quoted period.\n", + "description": "Registration period in years.", "example": 1, "maximum": 10, "minimum": 1, @@ -1523,31 +1556,28 @@ "$ref": "#/$defs/simple-money" }, { - "description": "The locked renewal price charged on execute, taken from the quote. Present once the renewal is accepted.\n", + "description": "The locked registration price for the quoted period. Total amount charged on execute is this price plus any fees.\n", "readOnly": true } ] }, - "quoteToken": { + "profile": { "allOf": [ { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/Profile" }, { - "description": "The single-use opaque token from the preceding quoteRenewal call. Required on execute. Consumed on first successful execution; idempotent retries with the same Idempotency-Key replay the original operation without re-consuming the token.\n", - "example": "7f3a2b1c-9d8e-4012-a5b6-c1d2e3f4a5b6", - "writeOnly": true + "description": "Optional inline profile override for this specific domain. When present, this inline profile is used instead of the batch operation's defaultProfile. Echoed from the request.\n" } ] }, - "renewalId": { + "profileId": { "allOf": [ { "$ref": "#/$defs/uuid" }, { - "description": "Server-assigned stable identifier for this renewal record. Use in GET /renewals/{renewalId} to poll for status.\n", - "readOnly": true + "description": "Optional profileId override for this specific domain. When present, this profile is used instead of the batch operation's defaultProfileId. Echoed from the request.\n" } ] }, @@ -1557,7 +1587,7 @@ "$ref": "#/$defs/DomainOperationStatus" }, { - "description": "Current execution status of this renewal.", + "description": "Current status of this individual domain within the batch registration. Possible values: PENDING, EXECUTING, COMPLETED, FAILED. Each domain progresses independently.\n", "readOnly": true } ] @@ -1568,179 +1598,304 @@ "$ref": "#/$defs/date-time" }, { - "description": "Timestamp of the most recent status update.", + "description": "Timestamp of the most recent status update for this domain.\n", "readOnly": true } ] } }, "required": [ - "domain", - "quoteToken", - "consent" + "domain" ], - "title": "Renewal", + "title": "RegistrationBatchDomainItem", "type": "object" }, - "RenewalConsent": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/renewal-consent.v3", + "RegistrationPreference": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-preference.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "Customer confirmation for a domain renewal. Distinct from Consent: renewals have no legal-agreement set and no purchase fees, so agreementTypes and acknowledgedFees are not part of this type. The caller supplies agreedAt; the server derives agreedBy from the authenticated request context.\n", - "properties": { - "agreedAt": { - "allOf": [ - { - "$ref": "#/$defs/date-time" - }, - { - "description": "The timestamp at which the principal confirmed the renewal. Should reflect when the customer confirmed the charge, not when the API call was made.\n" - } - ] - }, - "agreedBy": { - "allOf": [ - { - "$ref": "#/$defs/ConsentActor" - }, - { - "description": "Who gave consent and how it was transmitted. Server-derived from the execute request's auth context.\n", - "readOnly": true - } - ] - } - }, - "required": [ - "agreedAt" + "description": "A purchase preference enabled on a saved registration profile.\nAUTO_RENEW — renew the domain automatically before it expires. PRIVACY — withhold registrant details from public WHOIS. TRUSTEE — local-presence service required by some TLDs. Derived from the contacts supplied rather than set directly, and returned on read when it applies.\nNot a closed set. These are the preferences this version names; a profile may carry a preference that is not among them, and new ones may be named in a later version.\n", + "examples": [ + "AUTO_RENEW", + "PRIVACY", + "TRUSTEE" ], - "title": "Renewal Consent", - "type": "object" + "title": "Registration Preference", + "type": "string" }, - "RenewalQuote": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/renewal-quote.v3", + "RegistrationProfile": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-profile.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "A price quote for renewing a single owned domain. Contains the locked renewal price, current and projected new expiry dates, and a short-lived single-use quoteToken that must be presented on the subsequent renewal execute call. Returned only when the domain is eligible to renew for the requested period; ineligibility is an HTTP error, not a negative 200.\nThe quoteToken hash binds domain + period + price + currency + currentExpiresAt + iscCode (empty string when not supplied). Binding currentExpiresAt folds in an expiry guard: if the domain is renewed or its expiry changes between quote and execute, the re-hash mismatches and the execute returns QUOTE_MISMATCH, preventing a double renewal. Binding iscCode ensures the locked price applies only when the same pricing context is presented on execute.\n", + "description": "A saved, reusable set of contacts and purchase preference defaults, referenced by profileId on a registration quote or a registration.\nA profile is a registration-time template. Its values are copied into the registration when a quote is executed, and nothing links the profile to the resulting domain afterwards. A profile cannot be edited, and no change to a profile can affect a domain already registered from it. To change saved details, create the replacement first, then delete the profile it supersedes.\nA profile is scoped to the TLDs named on create, because contact requirements are set by the TLD rather than by the contacts supplied. TLDs sharing one set of requirements share a profile; a TLD demanding additional registrant detail needs its own. See GET /profile-schemas/{tld} for what contacts a TLD requires.\nSee profileId on the registration quote for how a saved profile, an inline profile and account identity combine.\n", "properties": { - "currentExpiresAt": { + "contacts": { "allOf": [ { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/Contacts" }, { - "description": "The domain's current expiry date at the moment this quote was issued. Bound into the quoteToken hash. If the domain's expiry changes between quote and execute (e.g. a concurrent renewal or registry update), the re-hash will mismatch and execute returns QUOTE_MISMATCH — preventing an unintended double renewal.\n", - "readOnly": true + "description": "Contacts saved on this profile. Every role given here applies to all the TLDs the profile covers, since those TLDs share one set of contact requirements.\n" } ] }, - "domain": { - "description": "The domain name being quoted for renewal, in punycode A-label form for IDNs.\n", - "example": "example.com", - "type": "string" - }, - "expiresAt": { + "createdAt": { "allOf": [ { "$ref": "#/$defs/date-time" }, { - "description": "The expiry timestamp of the quoteToken. After this time, presenting the token on execute returns QUOTE_EXPIRED and a fresh quote must be obtained.\n" + "description": "When the profile was created. Absent for profiles created before this timestamp was recorded.\n", + "readOnly": true } ] }, - "irreversible": { - "description": "Whether executing this quote is irreversible once accepted. Always true for renewal — a charge is created and the domain's expiry is extended. Provided so agents can calibrate the explicitness of any confirmation step before directing the user to execute.\n", - "example": true, - "type": "boolean" - }, - "period": { - "description": "Renewal period in years for which the price is quoted. Defaults to 1 when not supplied on the quote request.\n", - "example": 1, - "maximum": 10, - "minimum": 1, - "type": "integer" + "links": { + "description": "HATEOAS link relations. rel=self — the canonical URL for this profile. Profiles are replace-only, so no relation is offered for modifying one.\n", + "items": { + "$ref": "#/$defs/link-description" + }, + "readOnly": true, + "type": "array" }, - "price": { + "name": { + "description": "Optional human-readable label. Recommended, since it is the only human-readable field that tells one profile from another on read. Not required to be unique.\n", + "example": "Acme Corp standard contacts", + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "nameServers": { + "description": "Authoritative nameservers applied when this profile is used. Omit to inherit platform defaults at registration time. No minimum count applies to a stored profile, which may carry a partial set or none.\n", + "example": [ + "ns1.example.com", + "ns2.example.com" + ], + "items": { + "$ref": "#/$defs/NameserverHostname" + }, + "maxItems": 13, + "type": "array" + }, + "preferences": { + "description": "Purchase preferences to enable when this profile is used. A profile can only enable a preference, never disable one, so leaving a value out of the list means the registration takes the platform default for it: auto-renew on, privacy off. To register without auto-renew, supply the preference inline on that registration instead.\nOn read the list is what the profile will apply, which is not always what was sent: a preference the supplied contacts require is added when the profile is created. Treat it as open — it may name a preference this version does not document.\n", + "example": [ + "AUTO_RENEW", + "PRIVACY" + ], + "items": { + "$ref": "#/$defs/RegistrationPreference" + }, + "type": "array", + "uniqueItems": true + }, + "profileId": { "allOf": [ { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/uuid" }, { - "description": "The locked renewal price for the quoted period. Held for the duration of the quoteToken's TTL.\n" + "description": "Server-assigned identifier. Opaque: store it and echo it back on quote and registration requests. Do not parse it or infer meaning from its value.\n", + "example": "14514a29-5fce-4624-8d8a-d8abd56015e2", + "readOnly": true } ] }, - "quoteToken": { - "allOf": [ - { - "$ref": "#/$defs/uuid" + "tlds": { + "description": "The TLDs this profile is for. Supplied on create and not returned on read, so a caller that needs the mapping should keep its own. All TLDs listed must share one set of contact requirements; if they do not, the request is rejected and the caller should create one profile per requirement set.\n", + "example": [ + "com", + "net" + ], + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array", + "writeOnly": true + } + }, + "required": [ + "tlds", + "contacts" + ], + "title": "Registration Profile", + "type": "object", + "x-sensitivity": "confidential" + }, + "RegistrationQuote": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-quote.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "allOf": [ + { + "$ref": "#/$defs/DomainQuoteDetails" + }, + { + "properties": { + "expiresAt": { + "allOf": [ + { + "$ref": "#/$defs/date-time" + }, + { + "description": "The expiry timestamp of the quoteToken. After this time, presenting the token on execute returns quote_expired and a new quote must be obtained.\n", + "readOnly": true + } + ] }, - { - "description": "Opaque, single-use token with a 10-minute TTL. Encodes a hash of domain + period + price + currency + currentExpiresAt + iscCode (empty string when not supplied). Treat as a capability; do not parse or persist beyond the immediate execute call.\n", - "example": "7f3a2b1c-9d8e-4012-a5b6-c1d2e3f4a5b6" + "inventory": { + "allOf": [ + { + "$ref": "#/$defs/InventoryType" + }, + { + "description": "The inventory type of the quoted domain. Present when available is true.\n", + "readOnly": true + } + ] + }, + "irreversible": { + "description": "Whether executing this quote is irreversible once accepted. Use to calibrate the explicitness of any confirmation step presented before execute.\n", + "example": false, + "type": "boolean" + }, + "quoteToken": { + "allOf": [ + { + "$ref": "#/$defs/uuid" + }, + { + "description": "Opaque, single-use token with a 10-minute TTL. References the locked price, a hash of this request body, and a hash of the resolved profile values. Absent when available is false. Treat as a capability; do not parse.\n", + "example": "7f3a2b1c-9d8e-4012-a5b6-c1d2e3f4a5b6", + "readOnly": true + } + ] + }, + "renewalPrice": { + "allOf": [ + { + "$ref": "#/$defs/simple-money" + }, + { + "description": "Indicative renewal cost at current rates. Not a price guarantee; renewal pricing is locked at time of renewal quote.\n" + } + ] } - ] + }, + "type": "object" + } + ], + "description": "A price quote for registering a single domain. Contains a locked price, resolved contact and preference settings, required legal agreements, and a short-lived single-use quoteToken that must be presented on the subsequent registration execute call. Execution without a valid quoteToken is structurally impossible.\nWhen available is false, no quoteToken is returned — this is not an error; it means the domain cannot be registered as requested.\n", + "title": "Registration Quote" + }, + "RegistrationQuoteBatch": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-quote-batch.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A batch registration quote returned by POST /registration-quote-batch. Contains locked prices and settings for 1-50 domains, along with a single-use registrationQuoteBatchToken valid for 10 minutes. Free and read-only; safe to call speculatively.\n", + "properties": { + "domains": { + "description": "Per-domain quote results. Each domain includes locked price, resolved settings, and required agreements. Premium domains include fees that must be acknowledged on execute.\n", + "items": { + "$ref": "#/$defs/RegistrationBatchDomain" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" }, - "resolvedNewExpiresAt": { + "expiresAt": { "allOf": [ { "$ref": "#/$defs/date-time" }, { - "description": "The projected expiry date if execution succeeds: currentExpiresAt extended by the quoted period in years. Informational only; the authoritative post-renewal expiry is populated on the Renewal entity once status reaches COMPLETED.\n", - "readOnly": true + "description": "Timestamp when the registrationQuoteBatchToken expires. After this time, the token cannot be used to execute the registration. Obtain a fresh quote if needed.\n" } ] + }, + "irreversible": { + "description": "Whether executing this batch quote is irreversible once accepted. Use to calibrate the explicitness of any confirmation step presented before execute.\n", + "example": false, + "type": "boolean" + }, + "registrationQuoteBatchToken": { + "description": "Single-use opaque token that locks prices and settings for all domains. Valid for 10 minutes. Required when executing the batch registration via POST /registration-batch. Present only when all domains are quotable.\nThe token has a bqt_ prefix followed by a UUID to distinguish it from single-domain quote tokens. Treat as a capability; do not parse.\n", + "example": "bqt_7f3a2b1c-9d8e-4012-a5b6-c1d2e3f4a5b6", + "pattern": "^bqt_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", + "readOnly": true, + "type": "string" } }, "required": [ - "domain", - "period", - "price", - "currentExpiresAt", - "resolvedNewExpiresAt", - "quoteToken", - "expiresAt", - "irreversible" + "domains" ], - "title": "Renewal Quote", + "title": "RegistrationQuoteBatch", "type": "object" }, - "ResolvedSettings": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/resolved-settings.v3", + "RegistrationQuoteBatchInput": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-quote-batch-input.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "A preview of the effective settings that will be applied if the associated quote is executed. Returned in the quote response to eliminate invisible side effects — the caller sees exactly whose contact info and which preferences will be used before making a commitment. contactSource names where the registrant contact came from so an agent can be explicit at the confirmation step.\n", + "description": "Request body for quoting a batch registration of multiple domains. Contains the list of domains to quote (1-50) and optional default/per-domain profile settings for contact resolution.\n", "properties": { - "autoRenew": { - "description": "The effective auto-renew setting that will be applied upon registration.\n", - "type": "boolean" - }, - "contactSource": { + "defaultProfile": { "allOf": [ { - "$ref": "#/$defs/ContactSource" + "$ref": "#/$defs/Profile" }, { - "description": "Indicates where the resolved registrant contact came from. When ACCOUNT, the agent should surface this clearly to the customer before confirmation.\n", - "example": "PROFILE" + "description": "One-time inline contacts and purchase preference defaults for all domains unless overridden at the per-domain level. Not persisted.\n" } ] }, - "nameServers": { + "defaultProfileId": { "allOf": [ { - "$ref": "#/$defs/NameServers" + "$ref": "#/$defs/uuid" }, { - "description": "The effective nameservers that will be provisioned for the domain.\n", - "example": [ - "ns01.domaincontrol.com", - "ns02.domaincontrol.com" - ] + "description": "ID of a saved registration profile. Applied to all domains unless overridden at the per-domain level.\n" } ] }, - "privacy": { - "description": "The effective WHOIS privacy setting that will be applied upon registration.\n", - "type": "boolean" + "domains": { + "description": "List of domains to quote for registration. Minimum 1, maximum 50 domains.\n", + "items": { + "$ref": "#/$defs/RegistrationQuoteDomainInput" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "domains" + ], + "title": "RegistrationQuoteBatchInput", + "type": "object" + }, + "RegistrationQuoteDomainInput": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/registration-quote-domain-input.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A single domain within a batch registration quote request. Contains the domain name, optional registration period, and optional profile overrides for contact resolution.\n", + "properties": { + "domain": { + "description": "The domain name to quote, in punycode A-label form.\n", + "example": "example.com", + "type": "string" + }, + "period": { + "default": 1, + "description": "Registration period in years.", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "profile": { + "allOf": [ + { + "$ref": "#/$defs/Profile" + }, + { + "description": "Optional inline profile override for this specific domain. Uses defaultProfile if not provided.\n" + } + ] }, "profileId": { "allOf": [ @@ -1748,152 +1903,229 @@ "$ref": "#/$defs/uuid" }, { - "description": "The saved registration profile that was applied, if any. Absent when the registrant was derived from account identity.\n", - "example": "14514a29-5fce-4624-8d8a-d8abd56015e2", - "readOnly": true + "description": "Optional profileId override for this specific domain. Uses defaultProfileId if not provided.\n" } ] - }, - "registrantSummary": { - "description": "A human-readable one-line summary of the resolved registrant, suitable for display in a confirmation prompt. When contactSource is ACCOUNT, the summary is suffixed with \"(account identity)\" to make the derivation explicit.\n", - "example": "Jane Smith / jane@example.com", - "type": "string", - "x-sensitivity": "confidential" } }, - "title": "Resolved Settings", + "required": [ + "domain" + ], + "title": "RegistrationQuoteDomainInput", "type": "object" }, - "Suggestion": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/suggestion.v3", + "Renewal": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/renewal.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "A single available domain suggestion returned by the suggest endpoint. Availability is implied by presence in the results (available-only contract) and is best-effort — the availability check at quote time is the authoritative re-check. Indicative pricing may be stale; the locked price is established at quote time only.\n", + "description": "A domain renewal entity created when a POST /renewals request is accepted. Renewals are a top-level resource with their own stable renewalId; the domain relationship is captured in the representation.\nOn POST /renewals, supply the writable fields (domain, quoteToken, and consent; period is optional). The server returns the full Renewal with readOnly fields populated. Poll links[rel=self] (GET /renewals/{renewalId}) until status reaches COMPLETED or FAILED. The same resource is also reachable via GET /operations/{operationId} for clients operating at the abstract level; operationId is included in the representation for that purpose.\nThe price commitment rides in the quoteToken; consent records when the customer confirmed the charge. Renewals have no legal-agreement or fee acknowledgment surface — use RenewalConsent, not Consent.\n", "properties": { + "consent": { + "allOf": [ + { + "$ref": "#/$defs/RenewalConsent" + }, + { + "description": "The customer's confirmation of the renewal. On execute, supply agreedAt; agreedBy is server-derived and returned on the persisted record.\n" + } + ] + }, + "createdAt": { + "allOf": [ + { + "$ref": "#/$defs/date-time" + }, + { + "description": "Timestamp when this renewal was initiated.", + "readOnly": true + } + ] + }, "domain": { - "description": "The suggested domain name in punycode A-label form.\n", - "example": "sunrisebakery.com", + "description": "The domain name to renew, in punycode A-label form for IDNs. Must match the domain in the quoteToken.\n", + "example": "example.com", "type": "string" }, - "inventory": { + "expiresAt": { "allOf": [ { - "$ref": "#/$defs/InventoryType" + "$ref": "#/$defs/date-time" }, { - "description": "The inventory source for this domain. Present when pricing fields are present.\n", - "example": "REGISTRY" + "description": "The domain's new expiry date once the renewal completes. Present only when status is COMPLETED. This is the authoritative post-renewal expiry; RenewalQuote.resolvedNewExpiresAt is only the projected value at quote time.\n", + "readOnly": true } ] }, - "prices": { - "description": "Indicative pricing offered per registration term length, in ascending order of period. Prices are best-effort indicative and are locked only at quote time.\n", + "links": { + "description": "HATEOAS link relations for this renewal. rel=self — the canonical URL for this renewal record (GET /renewals/{renewalId}). rel=domain — the renewed domain-name resource once status is COMPLETED. rel=operation — the abstract operation at GET /operations/{operationId}.\n", "items": { - "$ref": "#/$defs/TermPrice" + "$ref": "#/$defs/link-description" }, + "readOnly": true, "type": "array" + }, + "operationId": { + "allOf": [ + { + "$ref": "#/$defs/uuid" + }, + { + "description": "Identifier of the DomainOperation tracking this renewal. Use with GET /operations/{operationId} for abstract operation polling. Both the concrete (GET /renewals/{renewalId}) and abstract poll endpoints resolve the same underlying state.\n", + "example": "9f1c2e7a-4b3d-4e8f-a1c2-3d4e5f6a7b8c", + "readOnly": true + } + ] + }, + "orderId": { + "description": "The orderId of the order that processed this renewal. Present only when status is COMPLETED. Not present for failed or in-progress renewals.\n", + "readOnly": true, + "type": "string" + }, + "period": { + "default": 1, + "description": "Renewal period in years. Must match the period in the preceding quote. If omitted, defaults to 1 — so omit only when the quote was for 1 year; otherwise echo the quoted period.\n", + "example": 1, + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "price": { + "allOf": [ + { + "$ref": "#/$defs/simple-money" + }, + { + "description": "The locked renewal price charged on execute, taken from the quote. Present once the renewal is accepted.\n", + "readOnly": true + } + ] + }, + "quoteToken": { + "allOf": [ + { + "$ref": "#/$defs/uuid" + }, + { + "description": "The single-use opaque token from the preceding quoteRenewal call. Required on execute. Consumed on first successful execution; idempotent retries with the same Idempotency-Key replay the original operation without re-consuming the token.\n", + "example": "7f3a2b1c-9d8e-4012-a5b6-c1d2e3f4a5b6", + "writeOnly": true + } + ] + }, + "renewalId": { + "allOf": [ + { + "$ref": "#/$defs/uuid" + }, + { + "description": "Server-assigned stable identifier for this renewal record. Use in GET /renewals/{renewalId} to poll for status.\n", + "readOnly": true + } + ] + }, + "status": { + "allOf": [ + { + "$ref": "#/$defs/DomainOperationStatus" + }, + { + "description": "Current execution status of this renewal.", + "readOnly": true + } + ] + }, + "updatedAt": { + "allOf": [ + { + "$ref": "#/$defs/date-time" + }, + { + "description": "Timestamp of the most recent status update.", + "readOnly": true + } + ] } }, "required": [ - "domain" + "domain", + "quoteToken", + "consent" ], - "title": "Suggestion", + "title": "Renewal", "type": "object" }, - "SuggestionSource": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/suggestion-source.v3", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "A suggestion source strategy that generates domain name variations. EXTENSION — vary the TLD. KEYWORD_SPIN — rotate keywords. CC_TLD — vary using country-code TLDs. PREMIUM — include premium-priced variations.\n", - "enum": [ - "CC_TLD", - "EXTENSION", - "KEYWORD_SPIN", - "PREMIUM" - ], - "title": "Suggestion Source", - "type": "string" - }, - "TLSAMatchingType": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/tlsa-matching-type.v3", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "TLSA matching type (RFC 6698 §2.1.3). Specifies how the selected certificate material is compared to the association data. Values outside the defined set (3–255) are not currently supported and will be rejected. 0 — Exact match: association data is compared byte-for-byte to the selected content. 1 — SHA-256: association data is the SHA-256 digest of the selected content. 2 — SHA-512: association data is the SHA-512 digest of the selected content.\n", - "examples": [ - 0, - 1, - 2 - ], - "maximum": 255, - "minimum": 0, - "title": "TLSA Matching Type", - "type": "integer" - }, - "TLSASelector": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/tlsa-selector.v3", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "TLSA selector (RFC 6698 §2.1.2). Specifies which part of the TLS certificate is matched against the association data. Values outside the defined set (2–255) are not currently supported and will be rejected. 0 — Full certificate: the entire DER-encoded certificate. 1 — SubjectPublicKeyInfo: the DER-encoded SubjectPublicKeyInfo of the certificate.\n", - "examples": [ - 0, - 1 - ], - "maximum": 255, - "minimum": 0, - "title": "TLSA Selector", - "type": "integer" - }, - "TLSAUsage": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/tlsa-usage.v3", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "TLSA certificate usage (RFC 6698 §2.1.1). Constrains how the certificate association data is interpreted during DANE authentication. Values outside the defined set (4–255) are not currently supported and will be rejected. 0 — PKIX-TA (CA constraint): association must match a trust anchor in the PKIX validation path. 1 — PKIX-EE (service certificate constraint): association must match the end-entity certificate, which must also pass PKIX validation. 2 — DANE-TA (trust anchor assertion): association is a trust anchor for DANE validation; PKIX path building is not required. 3 — DANE-EE (domain-issued certificate): association must match the end-entity certificate; PKIX validation is not required.\n", - "examples": [ - 0, - 1, - 2, - 3 - ], - "maximum": 255, - "minimum": 0, - "title": "TLSA Usage", - "type": "integer" - }, - "Term": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/term.v3", + "RenewalConsent": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/renewal-consent.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", - "default": "YEAR", - "description": "The unit of measure for a registration period. YEAR — registration period expressed in whole years.\n", - "enum": [ - "YEAR" + "description": "Customer confirmation for a domain renewal. Distinct from Consent: renewals have no legal-agreement set and no purchase fees, so agreementTypes and acknowledgedFees are not part of this type. The caller supplies agreedAt; the server derives agreedBy from the authenticated request context.\n", + "properties": { + "agreedAt": { + "allOf": [ + { + "$ref": "#/$defs/date-time" + }, + { + "description": "The timestamp at which the principal confirmed the renewal. Should reflect when the customer confirmed the charge, not when the API call was made.\n" + } + ] + }, + "agreedBy": { + "allOf": [ + { + "$ref": "#/$defs/ConsentActor" + }, + { + "description": "Who gave consent and how it was transmitted. Server-derived from the execute request's auth context.\n", + "readOnly": true + } + ] + } + }, + "required": [ + "agreedAt" ], - "title": "Term", - "type": "string" + "title": "Renewal Consent", + "type": "object" }, - "TermPrice": { - "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/term-price.v3", + "RenewalQuote": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/renewal-quote.v3", "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "Pricing for one registration term, including sale and list prices for the full term and optional renewal and first-term breakdowns. A term is self-contained: the full cost of choosing it is price plus all fees listed here.\n", + "description": "A price quote for renewing a single owned domain. Contains the locked renewal price, current and projected new expiry dates, and a short-lived single-use quoteToken that must be presented on the subsequent renewal execute call. Returned only when the domain is eligible to renew for the requested period; ineligibility is an HTTP error, not a negative 200.\nThe quoteToken hash binds domain + period + price + currency + currentExpiresAt + iscCode (empty string when not supplied). Binding currentExpiresAt folds in an expiry guard: if the domain is renewed or its expiry changes between quote and execute, the re-hash mismatches and the execute returns QUOTE_MISMATCH, preventing a double renewal. Binding iscCode ensures the locked price applies only when the same pricing context is presented on execute.\n", "properties": { - "fees": { - "description": "Fees charged at the time of purchase for this term, in addition to price. Present when the domain incurs purchase fees beyond the base registration cost. The full cost of choosing this term is price plus these fees.\n", - "items": { - "$ref": "#/$defs/Fee" - }, - "type": "array" + "currentExpiresAt": { + "allOf": [ + { + "$ref": "#/$defs/date-time" + }, + { + "description": "The domain's current expiry date at the moment this quote was issued. Bound into the quoteToken hash. If the domain's expiry changes between quote and execute (e.g. a concurrent renewal or registry update), the re-hash will mismatch and execute returns QUOTE_MISMATCH — preventing an unintended double renewal.\n", + "readOnly": true + } + ] }, - "firstTermPrice": { + "domain": { + "description": "The domain name being quoted for renewal, in punycode A-label form for IDNs.\n", + "example": "example.com", + "type": "string" + }, + "expiresAt": { "allOf": [ { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/date-time" }, { - "description": "Discounted price of only the first term unit within this multi-unit period. Typically omitted when period is 1 (where it equals price). Present when a first-term-only promotion applies to a multi-unit period.\n", - "example": { - "currencyCode": "USD", - "value": 1199 - } + "description": "The expiry timestamp of the quoteToken. After this time, presenting the token on execute returns QUOTE_EXPIRED and a fresh quote must be obtained.\n" } ] }, + "irreversible": { + "description": "Whether executing this quote is irreversible once accepted. Always true for renewal — a charge is created and the domain's expiry is extended. Provided so agents can calibrate the explicitness of any confirmation step before directing the user to execute.\n", + "example": true, + "type": "boolean" + }, "period": { - "description": "The registration period length, in units of term.\n", - "example": 2, + "description": "Renewal period in years for which the price is quoted. Defaults to 1 when not supplied on the quote request.\n", + "example": 1, "maximum": 10, "minimum": 1, "type": "integer" @@ -1904,43 +2136,283 @@ "$ref": "#/$defs/simple-money" }, { - "description": "The price for the full term covered by this price block — the current registration price for `period` units of term. Discounts or promotions may be reflected in this price.\n" + "description": "The locked renewal price for the quoted period. Held for the duration of the quoteToken's TTL.\n" } ] }, - "recommended": { - "description": "When true, this term is the best-value option based on active discounts or promotions. At most one entry in the prices array carries this flag. Absent (not false) when no recommendation applies.\n", - "example": true, - "type": "boolean" - }, - "renewalPrice": { + "quoteToken": { "allOf": [ { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/uuid" }, { - "description": "Sale price that will apply when the domain renews, for the same term and period. Not a guarantee.\n" + "description": "Opaque, single-use token with a 10-minute TTL. Encodes a hash of domain + period + price + currency + currentExpiresAt + iscCode (empty string when not supplied). Treat as a capability; do not parse or persist beyond the immediate execute call.\n", + "example": "7f3a2b1c-9d8e-4012-a5b6-c1d2e3f4a5b6" } ] }, - "term": { + "resolvedNewExpiresAt": { "allOf": [ { - "$ref": "#/$defs/Term" + "$ref": "#/$defs/date-time" }, { - "description": "Unit in which period is expressed. Currently only YEAR is supported.\n", - "example": "YEAR" + "description": "The projected expiry date if execution succeeds: currentExpiresAt extended by the quoted period in years. Informational only; the authoritative post-renewal expiry is populated on the Renewal entity once status reaches COMPLETED.\n", + "readOnly": true } ] } }, "required": [ - "term", + "domain", "period", - "price" - ], - "title": "Term Price", + "price", + "currentExpiresAt", + "resolvedNewExpiresAt", + "quoteToken", + "expiresAt", + "irreversible" + ], + "title": "Renewal Quote", + "type": "object" + }, + "ResolvedSettings": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/resolved-settings.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A preview of the effective settings that will be applied if the associated quote is executed. Returned in the quote response to eliminate invisible side effects — the caller sees exactly whose contact info and which preferences will be used before making a commitment. contactSource names where the registrant contact came from so an agent can be explicit at the confirmation step.\n", + "properties": { + "autoRenew": { + "description": "The effective auto-renew setting that will be applied upon registration.\n", + "type": "boolean" + }, + "contactSource": { + "allOf": [ + { + "$ref": "#/$defs/ContactSource" + }, + { + "description": "Indicates where the resolved registrant contact came from. When ACCOUNT, the agent should surface this clearly to the customer before confirmation.\n", + "example": "PROFILE" + } + ] + }, + "nameServers": { + "allOf": [ + { + "$ref": "#/$defs/NameServers" + }, + { + "description": "The effective nameservers that will be provisioned for the domain.\n", + "example": [ + "ns01.domaincontrol.com", + "ns02.domaincontrol.com" + ] + } + ] + }, + "privacy": { + "description": "The effective WHOIS privacy setting that will be applied upon registration.\n", + "type": "boolean" + }, + "profileId": { + "allOf": [ + { + "$ref": "#/$defs/uuid" + }, + { + "description": "The saved registration profile that was applied, if any. Absent when the registrant was derived from account identity.\n", + "example": "14514a29-5fce-4624-8d8a-d8abd56015e2", + "readOnly": true + } + ] + }, + "registrantSummary": { + "description": "A human-readable one-line summary of the resolved registrant, suitable for display in a confirmation prompt. When contactSource is ACCOUNT, the summary is suffixed with \"(account identity)\" to make the derivation explicit.\n", + "example": "Jane Smith / jane@example.com", + "type": "string", + "x-sensitivity": "confidential" + } + }, + "title": "Resolved Settings", + "type": "object" + }, + "Suggestion": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/suggestion.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A single available domain suggestion returned by the suggest endpoint. Availability is implied by presence in the results (available-only contract) and is best-effort — the availability check at quote time is the authoritative re-check. Indicative pricing may be stale; the locked price is established at quote time only.\n", + "properties": { + "domain": { + "description": "The suggested domain name in punycode A-label form.\n", + "example": "sunrisebakery.com", + "type": "string" + }, + "inventory": { + "allOf": [ + { + "$ref": "#/$defs/InventoryType" + }, + { + "description": "The inventory source for this domain. Present when pricing fields are present.\n", + "example": "REGISTRY" + } + ] + }, + "prices": { + "description": "Indicative pricing offered per registration term length, in ascending order of period. Prices are best-effort indicative and are locked only at quote time.\n", + "items": { + "$ref": "#/$defs/TermPrice" + }, + "type": "array" + } + }, + "required": [ + "domain" + ], + "title": "Suggestion", + "type": "object" + }, + "SuggestionSource": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/suggestion-source.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A suggestion source strategy that generates domain name variations. EXTENSION — vary the TLD. KEYWORD_SPIN — rotate keywords. CC_TLD — vary using country-code TLDs. PREMIUM — include premium-priced variations.\n", + "enum": [ + "CC_TLD", + "EXTENSION", + "KEYWORD_SPIN", + "PREMIUM" + ], + "title": "Suggestion Source", + "type": "string" + }, + "TLSAMatchingType": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/tlsa-matching-type.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "TLSA matching type (RFC 6698 §2.1.3). Specifies how the selected certificate material is compared to the association data. Values outside the defined set (3–255) are not currently supported and will be rejected. 0 — Exact match: association data is compared byte-for-byte to the selected content. 1 — SHA-256: association data is the SHA-256 digest of the selected content. 2 — SHA-512: association data is the SHA-512 digest of the selected content.\n", + "examples": [ + 0, + 1, + 2 + ], + "maximum": 255, + "minimum": 0, + "title": "TLSA Matching Type", + "type": "integer" + }, + "TLSASelector": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/tlsa-selector.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "TLSA selector (RFC 6698 §2.1.2). Specifies which part of the TLS certificate is matched against the association data. Values outside the defined set (2–255) are not currently supported and will be rejected. 0 — Full certificate: the entire DER-encoded certificate. 1 — SubjectPublicKeyInfo: the DER-encoded SubjectPublicKeyInfo of the certificate.\n", + "examples": [ + 0, + 1 + ], + "maximum": 255, + "minimum": 0, + "title": "TLSA Selector", + "type": "integer" + }, + "TLSAUsage": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/tlsa-usage.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "TLSA certificate usage (RFC 6698 §2.1.1). Constrains how the certificate association data is interpreted during DANE authentication. Values outside the defined set (4–255) are not currently supported and will be rejected. 0 — PKIX-TA (CA constraint): association must match a trust anchor in the PKIX validation path. 1 — PKIX-EE (service certificate constraint): association must match the end-entity certificate, which must also pass PKIX validation. 2 — DANE-TA (trust anchor assertion): association is a trust anchor for DANE validation; PKIX path building is not required. 3 — DANE-EE (domain-issued certificate): association must match the end-entity certificate; PKIX validation is not required.\n", + "examples": [ + 0, + 1, + 2, + 3 + ], + "maximum": 255, + "minimum": 0, + "title": "TLSA Usage", + "type": "integer" + }, + "Term": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/term.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "default": "YEAR", + "description": "The unit of measure for a registration period. YEAR — registration period expressed in whole years.\n", + "enum": [ + "YEAR" + ], + "title": "Term", + "type": "string" + }, + "TermPrice": { + "$id": "https://godaddy.com/schemas/domains/domain-lifecycle/term-price.v3", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "Pricing for one registration term, including sale and list prices for the full term and optional renewal and first-term breakdowns. A term is self-contained: the full cost of choosing it is price plus all fees listed here.\n", + "properties": { + "fees": { + "description": "Fees charged at the time of purchase for this term, in addition to price. Present when the domain incurs purchase fees beyond the base registration cost. The full cost of choosing this term is price plus these fees.\n", + "items": { + "$ref": "#/$defs/Fee" + }, + "type": "array" + }, + "firstTermPrice": { + "allOf": [ + { + "$ref": "#/$defs/simple-money" + }, + { + "description": "Discounted price of only the first term unit within this multi-unit period. Typically omitted when period is 1 (where it equals price). Present when a first-term-only promotion applies to a multi-unit period.\n", + "example": { + "currencyCode": "USD", + "value": 1199 + } + } + ] + }, + "period": { + "description": "The registration period length, in units of term.\n", + "example": 2, + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "price": { + "allOf": [ + { + "$ref": "#/$defs/simple-money" + }, + { + "description": "The price for the full term covered by this price block — the current registration price for `period` units of term. Discounts or promotions may be reflected in this price.\n" + } + ] + }, + "recommended": { + "description": "When true, this term is the best-value option based on active discounts or promotions. At most one entry in the prices array carries this flag. Absent (not false) when no recommendation applies.\n", + "example": true, + "type": "boolean" + }, + "renewalPrice": { + "allOf": [ + { + "$ref": "#/$defs/simple-money" + }, + { + "description": "Sale price that will apply when the domain renews, for the same term and period. Not a guarantee.\n" + } + ] + }, + "term": { + "allOf": [ + { + "$ref": "#/$defs/Term" + }, + { + "description": "Unit in which period is expressed. Currently only YEAR is supported.\n", + "example": "YEAR" + } + ] + } + }, + "required": [ + "term", + "period", + "price" + ], + "title": "Term Price", "type": "object" }, "country-code": { @@ -2257,36 +2729,341 @@ "name": "optimizeFor", "required": false, "schema": { - "allOf": [ - { - "$ref": "#/$defs/OptimizationTarget" - } - ], - "default": "SPEED" + "allOf": [ + { + "$ref": "#/$defs/OptimizationTarget" + } + ], + "default": "SPEED" + } + }, + { + "description": "ISC (International Shopper Code) for pricing context. When provided, prices reflect the applicable rates for this ISC.\n", + "in": "query", + "name": "iscCode", + "required": false, + "schema": { + "type": "string" + } + } + ], + "path": "/check-availability", + "responses": { + "200": { + "description": "Availability result for the requested domain.", + "schema": { + "$ref": "#/$defs/Availability" + } + }, + "400": { + "description": "Malformed request syntax, missing required field, or invalid field type.", + "schema": { + "$ref": "#/$defs/error" + } + }, + "401": { + "description": "Authentication credentials are missing or invalid.", + "schema": { + "$ref": "#/$defs/error" + } + }, + "403": { + "description": "Authenticated identity is not authorized to perform this operation.", + "schema": { + "$ref": "#/$defs/error" + } + }, + "422": { + "description": "Semantically invalid request — valid structure but violates a business rule, such as an ineligible contact, unsupported TLD, non-renewable domain status, or quote_mismatch (e.g. iscCode or acknowledgedFees that do not match the locked quote).\n", + "schema": { + "$ref": "#/$defs/error" + } + }, + "429": { + "description": "Too many requests — rate limit exceeded.", + "schema": { + "$ref": "#/$defs/error" + } + } + }, + "scopes": [ + "domains.domain:read" + ], + "summary": "Check availability of a single domain" + }, + { + "description": "Batch controller for domain availability checking. Accepts 1–25 domain\nnames alongside optional check criteria (optimization mode, ISC pricing\ncode). Returns one Availability result per requested domain in input\norder inside `{ items: [...] }`. Domains that cannot be checked carry\nan `error` object on that item.\n\nFor a single domain, GET /check-availability (getDomainAvailability)\noffers the same check semantics and Availability result without a\nrequest body; the response is the lone item unwrapped.\n\nAvailability is best-effort indicative; the authoritative check is\nalways performed at quote time. This controller does not persist the\ncheck — there is no check identity or poll URL.\n", + "method": "POST", + "operationId": "checkAvailability", + "parameters": [ + { + "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", + "in": "header", + "name": "X-Request-Id", + "required": false, + "schema": { + "$ref": "#/$defs/uuid" + } + }, + { + "description": "Reseller acting on behalf of a shopper account. When present, all domain operations are scoped to the specified shopper. Absent, the authenticated entity's own account is used. Only valid for reseller OAuth tokens.\n", + "in": "header", + "name": "X-Shopper-Id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "path": "/check-availability", + "requestBody": { + "contentType": "application/json", + "required": true, + "schema": { + "$ref": "#/$defs/AvailabilityCheckCriteria" + } + }, + "responses": { + "200": { + "description": "Per-domain availability results in request order. Uncheckable items carry an error object.\n", + "schema": { + "properties": { + "items": { + "description": "Availability results in the same order as the domains array in the request body.\n", + "items": { + "$ref": "#/$defs/Availability" + }, + "type": "array" + } + }, + "required": [ + "items" + ], + "type": "object" + } + }, + "400": { + "description": "Malformed request syntax, missing required field, or invalid field type.", + "schema": { + "$ref": "#/$defs/error" + } + }, + "401": { + "description": "Authentication credentials are missing or invalid.", + "schema": { + "$ref": "#/$defs/error" + } + }, + "403": { + "description": "Authenticated identity is not authorized to perform this operation.", + "schema": { + "$ref": "#/$defs/error" + } + }, + "422": { + "description": "Semantically invalid request — valid structure but violates a business rule, such as an ineligible contact, unsupported TLD, non-renewable domain status, or quote_mismatch (e.g. iscCode or acknowledgedFees that do not match the locked quote).\n", + "schema": { + "$ref": "#/$defs/error" + } + }, + "429": { + "description": "Too many requests — rate limit exceeded.", + "schema": { + "$ref": "#/$defs/error" + } + } + }, + "scopes": [ + "domains.domain:read" + ], + "summary": "Check availability of one or more specific domains" + }, + { + "description": "Returns a paginated collection of domain names owned by the authenticated account. Supports filtering by statuses and cursor-based pagination. The statuses and lifecycleGroups parameters are mutually exclusive; supplying both returns 400 Bad Request. An unrecognized value for statuses or lifecycleGroups returns 400 Bad Request.\n", + "method": "GET", + "operationId": "listDomains", + "parameters": [ + { + "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", + "in": "header", + "name": "X-Request-Id", + "required": false, + "schema": { + "$ref": "#/$defs/uuid" + } + }, + { + "description": "Reseller acting on behalf of a shopper account. When present, all domain operations are scoped to the specified shopper. Absent, the authenticated entity's own account is used. Only valid for reseller OAuth tokens.\n", + "in": "header", + "name": "X-Shopper-Id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Opaque cursor from the links[rel=next or rel=prev] href of the previous page. When present, the response begins immediately after the item that produced the token. Omit to start from the beginning of the collection.\n", + "in": "query", + "name": "pageToken", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Optional token direction when `pageToken` is set; ignored otherwise.\n", + "in": "query", + "name": "pageTokenDirection", + "required": false, + "schema": { + "enum": [ + "backward", + "forward" + ], + "type": "string" + } + }, + { + "description": "Maximum number of domains in the response. Defaults to 100 when omitted. Offset-based \"page\" parameter is not supported, only cursor-based \"pageToken\".\n", + "in": "query", + "name": "pageSize", + "required": false, + "schema": { + "default": 100, + "maximum": 200, + "minimum": 1, + "type": "integer" + } + }, + { + "description": "Filter results to domains with one or more lifecycle statuses. Supply multiple values as a single comma-separated list, e.g. `?statuses=ACTIVE,EXPIRED`. Multiple values are combined with logical OR — returns domains matching ANY of the specified statuses. See DomainStatus for accepted values (ACTIVE, EXPIRED, PENDING_REGISTRATION, etc.). Cannot be combined with the lifecycleGroups parameter. Use this for precise filtering on specific known status values; for coarse lifecycle phases, consider lifecycleGroups.\n", + "in": "query", + "name": "statuses", + "required": false, + "schema": { + "items": { + "$ref": "#/$defs/DomainStatus" + }, + "maxItems": 50, + "type": "array" + } + }, + { + "description": "Filter results to domains belonging to one or more status groups. Supply multiple values as a single comma-separated list, e.g. `?lifecycleGroups=REGISTERED,PENDING`. Multiple values are combined with logical OR. Cannot be combined with the statuses parameter. Use this for coarse lifecycle phases that remain stable as new statuses are added; for precise filtering, use statuses.\n", + "in": "query", + "name": "lifecycleGroups", + "required": false, + "schema": { + "items": { + "$ref": "#/$defs/DomainLifecycleGroup" + }, + "type": "array" + } + }, + { + "description": "Return only domains last updated after this timestamp (exclusive). Must be a valid RFC 3339 date-time.\n", + "in": "query", + "name": "updatedAfter", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, + { + "description": "Return only domains whose registration expires before this timestamp (exclusive). Must be a valid RFC 3339 date-time.\n", + "in": "query", + "name": "expiresBefore", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + } + ], + "path": "/domain-names", + "responses": { + "200": { + "description": "Paginated list of domains owned by the account.", + "schema": { + "$ref": "#/$defs/DomainCollection" + } + }, + "400": { + "description": "Malformed request syntax, missing required field, or invalid field type.", + "schema": { + "$ref": "#/$defs/error" + } + }, + "401": { + "description": "Authentication credentials are missing or invalid.", + "schema": { + "$ref": "#/$defs/error" + } + }, + "403": { + "description": "Authenticated identity is not authorized to perform this operation.", + "schema": { + "$ref": "#/$defs/error" + } + }, + "422": { + "description": "Semantically invalid request — valid structure but violates a business rule, such as an ineligible contact, unsupported TLD, non-renewable domain status, or quote_mismatch (e.g. iscCode or acknowledgedFees that do not match the locked quote).\n", + "schema": { + "$ref": "#/$defs/error" + } + }, + "429": { + "description": "Too many requests — rate limit exceeded.", + "schema": { + "$ref": "#/$defs/error" + } + } + }, + "scopes": [ + "domains.domain:read" + ], + "summary": "List registered domains" + }, + { + "description": "Returns the management view of a single registered domain owned by the authenticated account, including status, nameservers, privacy and auto-renew preferences, and expiry date.\n", + "method": "GET", + "operationId": "getDomain", + "parameters": [ + { + "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", + "in": "header", + "name": "X-Request-Id", + "required": false, + "schema": { + "$ref": "#/$defs/uuid" + } + }, + { + "description": "Reseller acting on behalf of a shopper account. When present, all domain operations are scoped to the specified shopper. Absent, the authenticated entity's own account is used. Only valid for reseller OAuth tokens.\n", + "in": "header", + "name": "X-Shopper-Id", + "required": false, + "schema": { + "type": "string" } }, { - "description": "ISC (International Shopper Code) for pricing context. When provided, prices reflect the applicable rates for this ISC.\n", - "in": "query", - "name": "iscCode", - "required": false, + "description": "The domain name in punycode A-label form (e.g., example.com). For IDNs, use the punycode representation.\n", + "in": "path", + "name": "domain-name", + "required": true, "schema": { "type": "string" } } ], - "path": "/check-availability", + "path": "/domain-names/{domain-name}", "responses": { "200": { - "description": "Availability result for the requested domain.", - "schema": { - "$ref": "#/$defs/Availability" - } - }, - "400": { - "description": "Malformed request syntax, missing required field, or invalid field type.", + "description": "Domain found.", "schema": { - "$ref": "#/$defs/error" + "$ref": "#/$defs/Domain" } }, "401": { @@ -2301,8 +3078,8 @@ "$ref": "#/$defs/error" } }, - "422": { - "description": "Semantically invalid request — valid structure but violates a business rule, such as an ineligible contact, unsupported TLD, non-renewable domain status, or quote_mismatch (e.g. iscCode or acknowledgedFees that do not match the locked quote).\n", + "404": { + "description": "The requested resource was not found.", "schema": { "$ref": "#/$defs/error" } @@ -2317,12 +3094,12 @@ "scopes": [ "domains.domain:read" ], - "summary": "Check availability of a single domain" + "summary": "Get a registered domain" }, { - "description": "Batch controller for domain availability checking. Accepts 1–25 domain\nnames alongside optional check criteria (optimization mode, ISC pricing\ncode). Returns one Availability result per requested domain in input\norder inside `{ items: [...] }`. Domains that cannot be checked carry\nan `error` object on that item.\n\nFor a single domain, GET /check-availability (getDomainAvailability)\noffers the same check semantics and Availability result without a\nrequest body; the response is the lone item unwrapped.\n\nAvailability is best-effort indicative; the authoritative check is\nalways performed at quote time. This controller does not persist the\ncheck — there is no check identity or poll URL.\n", + "description": "Sets the auto-renewal preference for the domain. When enabled, the domain will be automatically renewed before expiration using the payment method on file. Returns a DomainOperation; propagation to the registry is asynchronous.\n", "method": "POST", - "operationId": "checkAvailability", + "operationId": "setAutoRenew", "parameters": [ { "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", @@ -2341,33 +3118,42 @@ "schema": { "type": "string" } + }, + { + "description": "The domain name in punycode A-label form (e.g., example.com). For IDNs, use the punycode representation.\n", + "in": "path", + "name": "domain-name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Client-generated unique key (UUID recommended). Retrying a mutating request with the same Idempotency-Key returns the original response without creating a duplicate side effect. Required on all mutation endpoints to ensure safe retries.\n", + "in": "header", + "name": "Idempotency-Key", + "required": true, + "schema": { + "maxLength": 64, + "minLength": 16, + "type": "string" + } } ], - "path": "/check-availability", + "path": "/domain-names/{domain-name}/auto-renew", "requestBody": { "contentType": "application/json", "required": true, "schema": { - "$ref": "#/$defs/AvailabilityCheckCriteria" + "description": "Whether auto-renewal should be enabled for this domain. When true, the domain will be automatically renewed before expiration using the payment method on file.\n", + "type": "boolean" } }, "responses": { - "200": { - "description": "Per-domain availability results in request order. Uncheckable items carry an error object.\n", + "202": { + "description": "Auto-renew update accepted; poll the operation for completion.", "schema": { - "properties": { - "items": { - "description": "Availability results in the same order as the domains array in the request body.\n", - "items": { - "$ref": "#/$defs/Availability" - }, - "type": "array" - } - }, - "required": [ - "items" - ], - "type": "object" + "$ref": "#/$defs/DomainOperation" } }, "400": { @@ -2388,6 +3174,18 @@ "$ref": "#/$defs/error" } }, + "404": { + "description": "The requested resource was not found.", + "schema": { + "$ref": "#/$defs/error" + } + }, + "409": { + "description": "Conflict — the request cannot be completed in the current state. Used for quote lifecycle errors (quote_expired, quote_consumed), domain state conflicts such as domain_already_exists, and immutable DNS records (dns_record_not_mutable) such as GoDaddy-managed SOA and NS records.\n", + "schema": { + "$ref": "#/$defs/error" + } + }, "422": { "description": "Semantically invalid request — valid structure but violates a business rule, such as an ineligible contact, unsupported TLD, non-renewable domain status, or quote_mismatch (e.g. iscCode or acknowledgedFees that do not match the locked quote).\n", "schema": { @@ -2402,14 +3200,14 @@ } }, "scopes": [ - "domains.domain:read" + "domains.domain:update" ], - "summary": "Check availability of one or more specific domains" + "summary": "Set auto-renew setting for a domain" }, { - "description": "Returns a paginated collection of domain names owned by the authenticated account. Supports filtering by statuses and cursor-based pagination. The statuses and lifecycleGroups parameters are mutually exclusive; supplying both returns 400 Bad Request. An unrecognized value for statuses or lifecycleGroups returns 400 Bad Request.\n", - "method": "GET", - "operationId": "listDomains", + "description": "Replaces the authoritative nameservers for the domain with the provided list. Minimum 2, maximum 13. Returns a DomainOperation; propagation to the registry is asynchronous.\n", + "method": "PUT", + "operationId": "updateNameservers", "parameters": [ { "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", @@ -2430,91 +3228,39 @@ } }, { - "description": "Opaque cursor from the links[rel=next or rel=prev] href of the previous page. When present, the response begins immediately after the item that produced the token. Omit to start from the beginning of the collection.\n", - "in": "query", - "name": "pageToken", - "required": false, - "schema": { - "type": "string" - } - }, - { - "description": "Optional token direction when `pageToken` is set; ignored otherwise.\n", - "in": "query", - "name": "pageTokenDirection", - "required": false, - "schema": { - "enum": [ - "backward", - "forward" - ], - "type": "string" - } - }, - { - "description": "Maximum number of domains in the response. Defaults to 100 when omitted. Offset-based \"page\" parameter is not supported, only cursor-based \"pageToken\".\n", - "in": "query", - "name": "pageSize", - "required": false, - "schema": { - "default": 100, - "maximum": 200, - "minimum": 1, - "type": "integer" - } - }, - { - "description": "Filter results to domains with one or more lifecycle statuses. Supply multiple values as a single comma-separated list, e.g. `?statuses=ACTIVE,EXPIRED`. Multiple values are combined with logical OR — returns domains matching ANY of the specified statuses. See DomainStatus for accepted values (ACTIVE, EXPIRED, PENDING_REGISTRATION, etc.). Cannot be combined with the lifecycleGroups parameter. Use this for precise filtering on specific known status values; for coarse lifecycle phases, consider lifecycleGroups.\n", - "in": "query", - "name": "statuses", - "required": false, - "schema": { - "items": { - "$ref": "#/$defs/DomainStatus" - }, - "maxItems": 50, - "type": "array" - } - }, - { - "description": "Filter results to domains belonging to one or more status groups. Supply multiple values as a single comma-separated list, e.g. `?lifecycleGroups=REGISTERED,PENDING`. Multiple values are combined with logical OR. Cannot be combined with the statuses parameter. Use this for coarse lifecycle phases that remain stable as new statuses are added; for precise filtering, use statuses.\n", - "in": "query", - "name": "lifecycleGroups", - "required": false, - "schema": { - "items": { - "$ref": "#/$defs/DomainLifecycleGroup" - }, - "type": "array" - } - }, - { - "description": "Return only domains last updated after this timestamp (exclusive). Must be a valid RFC 3339 date-time.\n", - "in": "query", - "name": "updatedAfter", - "required": false, + "description": "The domain name in punycode A-label form (e.g., example.com). For IDNs, use the punycode representation.\n", + "in": "path", + "name": "domain-name", + "required": true, "schema": { - "format": "date-time", "type": "string" } }, { - "description": "Return only domains whose registration expires before this timestamp (exclusive). Must be a valid RFC 3339 date-time.\n", - "in": "query", - "name": "expiresBefore", - "required": false, + "description": "Client-generated unique key (UUID recommended). Retrying a mutating request with the same Idempotency-Key returns the original response without creating a duplicate side effect. Required on all mutation endpoints to ensure safe retries.\n", + "in": "header", + "name": "Idempotency-Key", + "required": true, "schema": { - "format": "date-time", + "maxLength": 64, + "minLength": 16, "type": "string" } } ], - "path": "/domain-names", + "path": "/domain-names/{domain-name}/nameservers", + "requestBody": { + "contentType": "application/json", + "required": true, + "schema": { + "$ref": "#/$defs/NameServers" + } + }, "responses": { - "200": { - "description": "Paginated list of domains owned by the account.", + "202": { + "description": "Nameserver update accepted; poll the operation for completion.", "schema": { - "$ref": "#/$defs/DomainCollection" + "$ref": "#/$defs/DomainOperation" } }, "400": { @@ -2535,6 +3281,12 @@ "$ref": "#/$defs/error" } }, + "404": { + "description": "The requested resource was not found.", + "schema": { + "$ref": "#/$defs/error" + } + }, "422": { "description": "Semantically invalid request — valid structure but violates a business rule, such as an ineligible contact, unsupported TLD, non-renewable domain status, or quote_mismatch (e.g. iscCode or acknowledgedFees that do not match the locked quote).\n", "schema": { @@ -2549,14 +3301,14 @@ } }, "scopes": [ - "domains.domain:read" + "domains.nameserver:update" ], - "summary": "List registered domains" + "summary": "Replace the nameservers for a domain" }, { - "description": "Returns the management view of a single registered domain owned by the authenticated account, including status, nameservers, privacy and auto-renew preferences, and expiry date.\n", - "method": "GET", - "operationId": "getDomain", + "description": "Sets the transfer-lock (registrar lock / EPP lock) for the domain. When enabled, outbound transfers to another registrar are blocked. Returns a DomainOperation; propagation to the registry is asynchronous.\n", + "method": "POST", + "operationId": "setTransferLock", "parameters": [ { "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", @@ -2584,14 +3336,39 @@ "schema": { "type": "string" } + }, + { + "description": "Client-generated unique key (UUID recommended). Retrying a mutating request with the same Idempotency-Key returns the original response without creating a duplicate side effect. Required on all mutation endpoints to ensure safe retries.\n", + "in": "header", + "name": "Idempotency-Key", + "required": true, + "schema": { + "maxLength": 64, + "minLength": 16, + "type": "string" + } } ], - "path": "/domain-names/{domain-name}", + "path": "/domain-names/{domain-name}/transfer-lock", + "requestBody": { + "contentType": "application/json", + "required": true, + "schema": { + "description": "Whether transfer-lock should be enabled for this domain. When true, outbound transfers to another registrar are blocked. When false, transfers are allowed.\n", + "type": "boolean" + } + }, "responses": { - "200": { - "description": "Domain found.", + "202": { + "description": "Transfer-lock update accepted; poll the operation for completion.", "schema": { - "$ref": "#/$defs/Domain" + "$ref": "#/$defs/DomainOperation" + } + }, + "400": { + "description": "Malformed request syntax, missing required field, or invalid field type.", + "schema": { + "$ref": "#/$defs/error" } }, "401": { @@ -2612,6 +3389,18 @@ "$ref": "#/$defs/error" } }, + "409": { + "description": "Conflict — the request cannot be completed in the current state. Used for quote lifecycle errors (quote_expired, quote_consumed), domain state conflicts such as domain_already_exists, and immutable DNS records (dns_record_not_mutable) such as GoDaddy-managed SOA and NS records.\n", + "schema": { + "$ref": "#/$defs/error" + } + }, + "422": { + "description": "Semantically invalid request — valid structure but violates a business rule, such as an ineligible contact, unsupported TLD, non-renewable domain status, or quote_mismatch (e.g. iscCode or acknowledgedFees that do not match the locked quote).\n", + "schema": { + "$ref": "#/$defs/error" + } + }, "429": { "description": "Too many requests — rate limit exceeded.", "schema": { @@ -2620,14 +3409,14 @@ } }, "scopes": [ - "domains.domain:read" + "domains.domain:update" ], - "summary": "Get a registered domain" + "summary": "Set transfer-lock setting for a domain" }, { - "description": "Sets the auto-renewal preference for the domain. When enabled, the domain will be automatically renewed before expiration using the payment method on file. Returns a DomainOperation; propagation to the registry is asynchronous.\n", - "method": "POST", - "operationId": "setAutoRenew", + "description": "Universal poll endpoint for all asynchronous domain mutations. Returns\nthe current state of the operation. Non-terminal responses include a\n`Retry-After` header.\n\nTerminal statuses:\n- `COMPLETED` — operation succeeded; `result` contains the final outcome.\n- `FAILED` — operation terminated with an error; `error` contains detail.\n\nWhile status is non-terminal (`CONFIRMED`, `EXECUTING`), neither\n`result` nor `error` is present. Poll until a terminal status is reached.\n\nThe poll URL is provided in the `Location` header of the initiating 202\nresponse and in `links[rel=self]`. Clients must not construct this URL\nindependently.\n", + "method": "GET", + "operationId": "getOperation", "parameters": [ { "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", @@ -2648,48 +3437,23 @@ } }, { - "description": "The domain name in punycode A-label form (e.g., example.com). For IDNs, use the punycode representation.\n", + "description": "The server-assigned operation identifier returned in the 202 response of any async domain mutation.\n", "in": "path", - "name": "domain-name", - "required": true, - "schema": { - "type": "string" - } - }, - { - "description": "Client-generated unique key (UUID recommended). Retrying a mutating request with the same Idempotency-Key returns the original response without creating a duplicate side effect. Required on all mutation endpoints to ensure safe retries.\n", - "in": "header", - "name": "Idempotency-Key", + "name": "operationId", "required": true, "schema": { - "maxLength": 64, - "minLength": 16, - "type": "string" + "$ref": "#/$defs/uuid" } } ], - "path": "/domain-names/{domain-name}/auto-renew", - "requestBody": { - "contentType": "application/json", - "required": true, - "schema": { - "description": "Whether auto-renewal should be enabled for this domain. When true, the domain will be automatically renewed before expiration using the payment method on file.\n", - "type": "boolean" - } - }, + "path": "/operations/{operationId}", "responses": { - "202": { - "description": "Auto-renew update accepted; poll the operation for completion.", + "200": { + "description": "Current operation state.", "schema": { "$ref": "#/$defs/DomainOperation" } }, - "400": { - "description": "Malformed request syntax, missing required field, or invalid field type.", - "schema": { - "$ref": "#/$defs/error" - } - }, "401": { "description": "Authentication credentials are missing or invalid.", "schema": { @@ -2708,18 +3472,6 @@ "$ref": "#/$defs/error" } }, - "409": { - "description": "Conflict — the request cannot be completed in the current state. Used for quote lifecycle errors (quote_expired, quote_consumed), domain state conflicts such as domain_already_exists, and immutable DNS records (dns_record_not_mutable) such as GoDaddy-managed SOA and NS records.\n", - "schema": { - "$ref": "#/$defs/error" - } - }, - "422": { - "description": "Semantically invalid request — valid structure but violates a business rule, such as an ineligible contact, unsupported TLD, non-renewable domain status, or quote_mismatch (e.g. iscCode or acknowledgedFees that do not match the locked quote).\n", - "schema": { - "$ref": "#/$defs/error" - } - }, "429": { "description": "Too many requests — rate limit exceeded.", "schema": { @@ -2728,14 +3480,14 @@ } }, "scopes": [ - "domains.domain:update" + "domains.domain:read" ], - "summary": "Set auto-renew setting for a domain" + "summary": "Poll an async domain operation" }, { - "description": "Replaces the authoritative nameservers for the domain with the provided list. Minimum 2, maximum 13. Returns a DomainOperation; propagation to the registry is asynchronous.\n", - "method": "PUT", - "operationId": "updateNameservers", + "description": "Returns the TLD-specific JSON Schema describing the fields required\nwhen calling POST /registration-quotes or POST /registrations for\nthe given TLD. The schema shape varies by TLD; clients should call\nthis endpoint before quoting or registering to discover required\ncontact and eligibility fields.\n", + "method": "GET", + "operationId": "getProfileSchema", "parameters": [ { "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", @@ -2756,39 +3508,21 @@ } }, { - "description": "The domain name in punycode A-label form (e.g., example.com). For IDNs, use the punycode representation.\n", + "description": "The Top-Level Domain (e.g. com, net, io) whose registration schema should be retrieved.\n", "in": "path", - "name": "domain-name", - "required": true, - "schema": { - "type": "string" - } - }, - { - "description": "Client-generated unique key (UUID recommended). Retrying a mutating request with the same Idempotency-Key returns the original response without creating a duplicate side effect. Required on all mutation endpoints to ensure safe retries.\n", - "in": "header", - "name": "Idempotency-Key", + "name": "tld", "required": true, "schema": { - "maxLength": 64, - "minLength": 16, "type": "string" } } ], - "path": "/domain-names/{domain-name}/nameservers", - "requestBody": { - "contentType": "application/json", - "required": true, - "schema": { - "$ref": "#/$defs/NameServers" - } - }, + "path": "/profile-schemas/{tld}", "responses": { - "202": { - "description": "Nameserver update accepted; poll the operation for completion.", + "200": { + "description": "TLD-specific profile schema.", "schema": { - "$ref": "#/$defs/DomainOperation" + "$ref": "#/$defs/ProfileSchema" } }, "400": { @@ -2815,12 +3549,6 @@ "$ref": "#/$defs/error" } }, - "422": { - "description": "Semantically invalid request — valid structure but violates a business rule, such as an ineligible contact, unsupported TLD, non-renewable domain status, or quote_mismatch (e.g. iscCode or acknowledgedFees that do not match the locked quote).\n", - "schema": { - "$ref": "#/$defs/error" - } - }, "429": { "description": "Too many requests — rate limit exceeded.", "schema": { @@ -2829,14 +3557,14 @@ } }, "scopes": [ - "domains.nameserver:update" + "domains.domain:read" ], - "summary": "Replace the nameservers for a domain" + "summary": "Retrieve the profile schema for a TLD" }, { - "description": "Sets the transfer-lock (registrar lock / EPP lock) for the domain. When enabled, outbound transfers to another registrar are blocked. Returns a DomainOperation; propagation to the registry is asynchronous.\n", + "description": "Executes a previously quoted batch domain registration. **Irreversible once\naccepted; creates charges for all domains.** Requires a valid unexpired\nregistrationQuoteBatchToken from `quoteRegistrationBatch`, an `Idempotency-Key` header,\nand a consent record.\n\nAll domains are registered atomically (all succeed or all fail). If any\ndomain fails during execution (registry error, payment failure), the entire\nbatch registration is rolled back and no domains are registered.\n\nIdempotency takes precedence over the single-use check: retrying with the\nsame `Idempotency-Key` replays the original operation even after the token\nis consumed.\n\nReturns a `RegistrationBatch` entity. Poll `links[rel=self]`\n(`GET /registration-batches/{registrationBatchId}`) until status is `COMPLETED`\nor `FAILED`. The `operationId` field is also provided for clients that\nprefer `GET /operations/{operationId}`; both resolve the same resource.\n\n**PREMIUM domains:** when the quote's per-domain `fees` array is non-empty\n(inventory `PREMIUM`), the execute request must include that domain's\n`acknowledgedFees` containing the same fees verbatim — same types, amounts,\nand currencies. This confirms the customer explicitly saw and accepted the\nspecific charge before the irreversible purchase is executed.\n\n- `acknowledgedFees` absent when fees exist → `422` with error name\n `consent_fees_required`.\n- `acknowledgedFees` present but type or amount does not match the locked\n quote → `422` with error name `quote_mismatch`.\n", "method": "POST", - "operationId": "setTransferLock", + "operationId": "registerDomainBatches", "parameters": [ { "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", @@ -2856,15 +3584,6 @@ "type": "string" } }, - { - "description": "The domain name in punycode A-label form (e.g., example.com). For IDNs, use the punycode representation.\n", - "in": "path", - "name": "domain-name", - "required": true, - "schema": { - "type": "string" - } - }, { "description": "Client-generated unique key (UUID recommended). Retrying a mutating request with the same Idempotency-Key returns the original response without creating a duplicate side effect. Required on all mutation endpoints to ensure safe retries.\n", "in": "header", @@ -2875,22 +3594,30 @@ "minLength": 16, "type": "string" } + }, + { + "description": "ISC (International Shopper Code) for pricing context. When provided, prices reflect the applicable rates for this ISC.\n", + "in": "query", + "name": "iscCode", + "required": false, + "schema": { + "type": "string" + } } ], - "path": "/domain-names/{domain-name}/transfer-lock", + "path": "/registration-batches", "requestBody": { "contentType": "application/json", "required": true, "schema": { - "description": "Whether transfer-lock should be enabled for this domain. When true, outbound transfers to another registrar are blocked. When false, transfers are allowed.\n", - "type": "boolean" + "$ref": "#/$defs/RegistrationBatch" } }, "responses": { "202": { - "description": "Transfer-lock update accepted; poll the operation for completion.", + "description": "Registration batch accepted. Poll the self link for status. All domains will be registered atomically.\n", "schema": { - "$ref": "#/$defs/DomainOperation" + "$ref": "#/$defs/RegistrationBatch" } }, "400": { @@ -2911,12 +3638,6 @@ "$ref": "#/$defs/error" } }, - "404": { - "description": "The requested resource was not found.", - "schema": { - "$ref": "#/$defs/error" - } - }, "409": { "description": "Conflict — the request cannot be completed in the current state. Used for quote lifecycle errors (quote_expired, quote_consumed), domain state conflicts such as domain_already_exists, and immutable DNS records (dns_record_not_mutable) such as GoDaddy-managed SOA and NS records.\n", "schema": { @@ -2937,14 +3658,14 @@ } }, "scopes": [ - "domains.domain:update" + "domains.domain:create" ], - "summary": "Set transfer-lock setting for a domain" + "summary": "Register multiple domains atomically (requires registrationQuoteBatchToken)" }, { - "description": "Universal poll endpoint for all asynchronous domain mutations. Returns\nthe current state of the operation. Non-terminal responses include a\n`Retry-After` header.\n\nTerminal statuses:\n- `COMPLETED` — operation succeeded; `result` contains the final outcome.\n- `FAILED` — operation terminated with an error; `error` contains detail.\n\nWhile status is non-terminal (`CONFIRMED`, `EXECUTING`), neither\n`result` nor `error` is present. Poll until a terminal status is reached.\n\nThe poll URL is provided in the `Location` header of the initiating 202\nresponse and in `links[rel=self]`. Clients must not construct this URL\nindependently.\n", + "description": "Returns a single registration batch record by its server-assigned registrationBatchId, including the current execution status and per-domain outcomes once the batch registration completes. This is the concrete poll endpoint for batch registration operations; the abstract equivalent is GET /operations/{operationId}.\nPoll until status is COMPLETED or FAILED. When COMPLETED, the batch-level orderId is populated and each domain in the `domains` array includes expiresAt. When FAILED, the `error` field contains the failure reason and no domains were registered.\n", "method": "GET", - "operationId": "getOperation", + "operationId": "getRegistrationBatch", "parameters": [ { "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", @@ -2965,21 +3686,21 @@ } }, { - "description": "The server-assigned operation identifier returned in the 202 response of any async domain mutation.\n", + "description": "Server-assigned registration batch identifier.", "in": "path", - "name": "operationId", + "name": "registrationBatchId", "required": true, "schema": { "$ref": "#/$defs/uuid" } } ], - "path": "/operations/{operationId}", + "path": "/registration-batches/{registrationBatchId}", "responses": { "200": { - "description": "Current operation state.", + "description": "Registration batch record returned.", "schema": { - "$ref": "#/$defs/DomainOperation" + "$ref": "#/$defs/RegistrationBatch" } }, "401": { @@ -3010,7 +3731,7 @@ "scopes": [ "domains.domain:read" ], - "summary": "Poll an async domain operation" + "summary": "Get a registration batch record" }, { "description": "Saves a reusable set of contacts and purchase preference defaults for the named TLDs and returns it with a server-assigned profileId. Reference that profileId on POST /registration-quotes and POST /registrations instead of repeating contacts on every request.\nCreation is content-addressed. Saving the same details again returns the profileId of the existing profile rather than creating a duplicate, so a caller should save once and reuse.\nProfiles are immutable. To change saved details, create the replacement and delete the profile it supersedes, in that order.\n", @@ -3239,9 +3960,9 @@ "summary": "Delete a registration profile" }, { - "description": "Prices the registration, resolves contact and preference settings,\nreturns required legal agreements, and mints a single-use quoteToken\nwith a 10-minute TTL. Free and read-only; safe to call speculatively.\n\nWhen the domain is unavailable, `available: false` is returned with\nno quoteToken — this is a valid non-error response.\n\nWhen required contact fields are missing, a `422` is returned with\nfield-level details so the agent can collect the missing data and re-quote.\n\nMay pass `iscCode` to lock pricing at applicable rates;\nthe same value must be supplied on /registrations if provided here.\n\n**PREMIUM domains:** when the quoted domain has inventory `PREMIUM`,\nthe response includes a `fees` array containing a\n`ONE_TIME_PREMIUM_DOMAIN_PURCHASE` entry. The execute request must\necho this array verbatim in `consent.acknowledgedFees` to confirm\nthe customer accepted the specific charge before the irreversible\npurchase proceeds.\n", + "description": "Prices the registration of 1-50 domains, resolves contact and preference\nsettings for each, returns required legal agreements, and mints a single-use\nregistrationQuoteBatchToken with a 10-minute TTL. Free and read-only; safe to call\nspeculatively.\n\nAll domains are quoted atomically. If any domain cannot be quoted (unavailable,\ninvalid, unsupported TLD), the entire quote fails with per-domain error details.\n\nWhen all domains are quotable, returns a registrationQuoteBatchToken that locks prices and\nsettings for all domains. Executing the quote consumes all domains atomically\n(all succeed or all fail).\n\n**PREMIUM domains:** when any quoted domain has inventory `PREMIUM`, that\ndomain's result includes a `fees` array containing a\n`ONE_TIME_PREMIUM_DOMAIN_PURCHASE` entry. The execute request must echo all\nfees verbatim in the per-domain `acknowledgedFees` to confirm the customer\naccepted the specific charges before the irreversible purchase proceeds.\n\n**Contact resolution:** Contacts can be supplied via `defaultProfileId` (saved\nprofile) or inline `defaultProfile` (one-time contacts), or derived from account\nidentity. Individual domains can override with their own `profileId` or `profile`.\nDomains without overrides use the default contact source.\n", "method": "POST", - "operationId": "quoteDomainRegistration", + "operationId": "quoteRegistrationBatches", "parameters": [ { "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", @@ -3271,56 +3992,19 @@ } } ], - "path": "/registration-quotes", + "path": "/registration-quote-batches", "requestBody": { "contentType": "application/json", "required": true, "schema": { - "properties": { - "domain": { - "description": "The domain name to quote, in punycode A-label form.", - "example": "example.com", - "type": "string" - }, - "period": { - "default": 1, - "description": "Registration period in years.", - "maximum": 10, - "minimum": 1, - "type": "integer" - }, - "profile": { - "allOf": [ - { - "$ref": "#/$defs/InlineRegistrationProfile" - }, - { - "description": "One-time inline contacts and purchase preference defaults for this quote. Not persisted.\n" - } - ] - }, - "profileId": { - "allOf": [ - { - "$ref": "#/$defs/uuid" - }, - { - "description": "ID of a saved registration profile. Any inline profile overrides it role by role; when neither supplies a registrant, account identity applies. An id that names no profile the caller owns is rejected, never ignored, so a quote never silently applies contacts other than the ones asked for.\n" - } - ] - } - }, - "required": [ - "domain" - ], - "type": "object" + "$ref": "#/$defs/RegistrationQuoteBatchInput" } }, "responses": { "200": { - "description": "Registration quote. When available is false, no quoteToken is returned; this is not an error.\n", + "description": "Registration batch quote. When all domains are quotable, includes a registrationQuoteBatchToken.\n", "schema": { - "$ref": "#/$defs/RegistrationQuote" + "$ref": "#/$defs/RegistrationQuoteBatch" } }, "400": { @@ -3342,7 +4026,7 @@ } }, "422": { - "description": "Semantically invalid request — valid structure but violates a business rule, such as an ineligible contact, unsupported TLD, non-renewable domain status, or quote_mismatch (e.g. iscCode or acknowledgedFees that do not match the locked quote).\n", + "description": "One or more domains cannot be quoted. The response uses the platform's standard error.details[] structure with one entry per failing domain. Each entry includes:\n- target: the domain name that failed - code: machine-readable error code (domain_unavailable, unsupported_tld,\n invalid_domain_format, missing_contact_fields)\n\nThis allows clients to programmatically identify which specific domains need remediation.\n", "schema": { "$ref": "#/$defs/error" } @@ -3357,12 +4041,12 @@ "scopes": [ "domains.domain:read" ], - "summary": "Quote a single-domain registration (no commitment)" + "summary": "Quote a batch registration of multiple domains (no commitment)" }, { - "description": "Returns the TLD-specific JSON Schema describing the fields required\nwhen calling POST /registration-quotes or POST /registrations for\nthe given TLD. The schema shape varies by TLD; clients should call\nthis endpoint before quoting or registering to discover required\ncontact and eligibility fields.\n", - "method": "GET", - "operationId": "getRegistrationSchema", + "description": "Prices the registration, resolves contact and preference settings,\nreturns required legal agreements, and mints a single-use quoteToken\nwith a 10-minute TTL. Free and read-only; safe to call speculatively.\n\nWhen the domain is unavailable, `available: false` is returned with\nno quoteToken — this is a valid non-error response.\n\nWhen required contact fields are missing, a `422` is returned with\nfield-level details so the agent can collect the missing data and re-quote.\n\nMay pass `iscCode` to lock pricing at applicable rates;\nthe same value must be supplied on /registrations if provided here.\n\n**PREMIUM domains:** when the quoted domain has inventory `PREMIUM`,\nthe response includes a `fees` array containing a\n`ONE_TIME_PREMIUM_DOMAIN_PURCHASE` entry. The execute request must\necho this array verbatim in `consent.acknowledgedFees` to confirm\nthe customer accepted the specific charge before the irreversible\npurchase proceeds.\n", + "method": "POST", + "operationId": "quoteDomainRegistration", "parameters": [ { "description": "Optional client-generated request correlation identifier, propagated across services and returned in the response X-Request-Id header.\n", @@ -3383,21 +4067,65 @@ } }, { - "description": "The Top-Level Domain (e.g. com, net, io) whose registration schema should be retrieved.\n", - "in": "path", - "name": "tld", - "required": true, + "description": "ISC (International Shopper Code) for pricing context. When provided, prices reflect the applicable rates for this ISC.\n", + "in": "query", + "name": "iscCode", + "required": false, "schema": { "type": "string" } } ], - "path": "/registration-schemas/{tld}", + "path": "/registration-quotes", + "requestBody": { + "contentType": "application/json", + "required": true, + "schema": { + "properties": { + "domain": { + "description": "The domain name to quote, in punycode A-label form.", + "example": "example.com", + "type": "string" + }, + "period": { + "default": 1, + "description": "Registration period in years.", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "profile": { + "allOf": [ + { + "$ref": "#/$defs/Profile" + }, + { + "description": "One-time inline contacts and purchase preference defaults for this quote. Not persisted.\n" + } + ] + }, + "profileId": { + "allOf": [ + { + "$ref": "#/$defs/uuid" + }, + { + "description": "ID of a saved registration profile. Any inline profile overrides it role by role; when neither supplies a registrant, account identity applies. An id that names no profile the caller owns is rejected, never ignored, so a quote never silently applies contacts other than the ones asked for.\n" + } + ] + } + }, + "required": [ + "domain" + ], + "type": "object" + } + }, "responses": { "200": { - "description": "TLD-specific registration schema.", + "description": "Registration quote. When available is false, no quoteToken is returned; this is not an error.\n", "schema": { - "$ref": "#/$defs/RegistrationSchema" + "$ref": "#/$defs/RegistrationQuote" } }, "400": { @@ -3418,8 +4146,8 @@ "$ref": "#/$defs/error" } }, - "404": { - "description": "The requested resource was not found.", + "422": { + "description": "Semantically invalid request — valid structure but violates a business rule, such as an ineligible contact, unsupported TLD, non-renewable domain status, or quote_mismatch (e.g. iscCode or acknowledgedFees that do not match the locked quote).\n", "schema": { "$ref": "#/$defs/error" } @@ -3434,7 +4162,7 @@ "scopes": [ "domains.domain:read" ], - "summary": "Retrieve the registration schema for a TLD" + "summary": "Quote a single-domain registration (no commitment)" }, { "description": "Executes a previously quoted domain registration. **Irreversible once\naccepted; creates a charge.** Requires a valid unexpired quoteToken from\n`quoteDomainRegistration`, an `Idempotency-Key` header, and a consent\nrecord. The target domain and period are in the request body alongside\nthe quoteToken.\n\nIdempotency takes precedence over the single-use check: retrying with\nthe same `Idempotency-Key` replays the original operation even after\nthe token is consumed.\n\nReturns a `Registration` entity. Poll `links[rel=self]`\n(`GET /registrations/{registrationId}`) until status is `COMPLETED` or\n`FAILED`. The `operationId` field is also provided for clients that\nprefer `GET /operations/{operationId}`; both resolve the same resource.\n\nPoll either until status is `COMPLETED` or `FAILED`. The operation is\nfire-and-forget; always poll at least once even if the server completed\nit synchronously.\n\nWhen `iscCode` was supplied at quote time, the same value must be\nprovided here or the request fails with `422 quote_mismatch`.\n\n**PREMIUM domains:** when the quote's `fees` array is non-empty\n(inventory `PREMIUM`), the execute request must include\n`consent.acknowledgedFees` containing the same fees verbatim —\nsame types, amounts, and currencies. This confirms the customer\nexplicitly saw and accepted the specific charge before the\nirreversible purchase is executed.\n\n- `acknowledgedFees` absent when fees exist → `422` with error\n name `consent_fees_required` (conditionally required by the quote; the\n constraint spans two requests and cannot be expressed in the\n schema).\n- `acknowledgedFees` present but type or amount does not match\n the locked quote → `422` with error name `quote_mismatch`.\n", @@ -4463,5 +5191,5 @@ ], "name": "domains", "title": "Domain Lifecycle Management API", - "version": "3.3.0" + "version": "3.4.0" } \ No newline at end of file diff --git a/rust/schemas/api/hosting.json b/rust/schemas/api/hosting.json index 30f80f0f..2c180fdb 100644 --- a/rust/schemas/api/hosting.json +++ b/rust/schemas/api/hosting.json @@ -3737,6 +3737,6 @@ } ], "name": "hosting", - "title": "Hosting API", + "title": "Hosted Application Lifecycle Management API", "version": "1.0.0" } \ No newline at end of file diff --git a/rust/schemas/api/manifest.json b/rust/schemas/api/manifest.json index 67553fa3..b94f83fb 100644 --- a/rust/schemas/api/manifest.json +++ b/rust/schemas/api/manifest.json @@ -1,10 +1,10 @@ { - "generated": "2026-09-18T19:23:39.098256354+00:00", + "generated": "2026-10-13T01:50:52.688600744+00:00", "domains": { "bulk-operations": { "file": "bulk-operations.json", "title": "Bulk Operations API", - "endpointCount": 27 + "endpointCount": 28 }, "businesses": { "file": "businesses.json", @@ -28,13 +28,13 @@ }, "customer-profiles": { "file": "customer-profiles.json", - "title": "Customers API", - "endpointCount": 9 + "title": "Customer GraphQL API", + "endpointCount": 1 }, "domains": { "file": "domains.json", "title": "Domain Lifecycle Management API", - "endpointCount": 23 + "endpointCount": 26 }, "email": { "file": "email.json", @@ -48,7 +48,7 @@ }, "hosting": { "file": "hosting.json", - "title": "Hosting API", + "title": "Hosted Application Lifecycle Management API", "endpointCount": 25 }, "location-addresses": { diff --git a/rust/schemas/api/orders.json b/rust/schemas/api/orders.json index b936e001..4f63c4d7 100644 --- a/rust/schemas/api/orders.json +++ b/rust/schemas/api/orders.json @@ -1313,6 +1313,7 @@ "description": "The current payment status for an order", "enum": [ "NONE", + "UNPAID", "PROCESSING", "PARTIALLY_PAID", "PAID", diff --git a/rust/shopping-client/openapi/shopping.oas3.json b/rust/shopping-client/openapi/shopping.oas3.json index 92696764..7e7b16cc 100644 --- a/rust/shopping-client/openapi/shopping.oas3.json +++ b/rust/shopping-client/openapi/shopping.oas3.json @@ -35,6 +35,26 @@ } }, "responses": { + "BadRequest": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/error_response" + } + } + }, + "description": "Response" + }, + "Forbidden": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/error_response" + } + } + }, + "description": "Response" + }, "NotFound": { "content": { "application/json": { @@ -64,11 +84,21 @@ } }, "description": "Response" + }, + "UnprocessableEntity": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/error_response" + } + } + }, + "description": "Response" } }, "schemas": { "adjustment": { - "$id": "https://ucp.dev/schemas/shopping/types/adjustment.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/adjustment.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "description": { @@ -116,14 +146,14 @@ "type": "object" }, "amount": { - "$id": "https://ucp.dev/schemas/shopping/types/amount.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/amount.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "minimum": 0, "title": "Amount", "type": "integer" }, "attribution": { - "$id": "https://ucp.dev/schemas/shopping/types/attribution.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/attribution.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": { "type": "string" @@ -132,7 +162,7 @@ "type": "object" }, "available_payment_instrument": { - "$id": "https://ucp.dev/schemas/shopping/types/available_payment_instrument.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/available_payment_instrument.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "constraints": { @@ -147,30 +177,8 @@ "title": "Available Payment Instrument", "type": "object" }, - "base_schema": { - "$id": "https://godaddy.com/ucp/schemas/product-metadata/base.schema.json", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "additionalProperties": true, - "properties": { - "category": { - "type": "string" - }, - "plan": { - "$ref": "#/components/schemas/product-plan_schema" - }, - "product_family": { - "minLength": 1, - "type": "string" - }, - "product_type": { - "type": "string" - } - }, - "title": "GoDaddy base product metadata", - "type": "object" - }, "business_fulfillment_config": { - "$id": "https://ucp.dev/schemas/shopping/types/business_fulfillment_config.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/business_fulfillment_config.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "allows_method_combinations": { @@ -203,7 +211,7 @@ "type": "object" }, "buyer": { - "$id": "https://ucp.dev/schemas/shopping/types/buyer.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/buyer.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": true, "properties": { @@ -365,7 +373,7 @@ "type": "object" } }, - "$id": "https://godaddy.com/ucp/schemas/catalog-offer-included-product.schema.json", + "$id": "https://godaddy.com/schemas/ucp/2026-04-08/shopping/catalog/included-product.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { @@ -604,7 +612,7 @@ "type": "object" }, "category": { - "$id": "https://ucp.dev/schemas/shopping/types/category.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/category.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "taxonomy": { @@ -618,7 +626,7 @@ "type": "object" }, "checkout": { - "$id": "https://ucp.dev/schemas/shopping/checkout.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/checkout.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": true, "name": "dev.ucp.shopping.checkout", @@ -645,7 +653,7 @@ "ucp_request": "omit" }, "fulfillment": { - "$ref": "#/components/schemas/fulfillment" + "$ref": "#/components/schemas/shopping_fulfillment" }, "id": { "type": "string", @@ -682,12 +690,6 @@ "payment": { "$ref": "#/components/schemas/payment" }, - "required_agreements": { - "items": { - "$ref": "#/components/schemas/shopping_required_agreement" - }, - "type": "array" - }, "signals": { "$ref": "#/components/schemas/signals" }, @@ -714,7 +716,7 @@ "type": "object" }, "checkout-complete-request_schema": { - "$id": "https://godaddy.com/ucp/schemas/requests/checkout-complete-request.schema.json", + "$id": "https://godaddy.com/schemas/ucp/2026-04-08/shopping/checkout/requests/complete.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": true, "name": "dev.ucp.shopping.checkout", @@ -723,7 +725,7 @@ "$ref": "#/components/schemas/ucp-refs_schema_attribution" }, "consent": { - "$ref": "#/components/schemas/shopping_consent_acceptance" + "$ref": "#/components/schemas/com_godaddy_shopping_checkout_input_schema_consent_acceptance" }, "payment": { "$ref": "#/components/schemas/ucp-refs_schema_payment" @@ -736,7 +738,7 @@ "type": "object" }, "checkout-writable-request_schema": { - "$id": "https://godaddy.com/ucp/schemas/requests/checkout-writable-request.schema.json", + "$id": "https://godaddy.com/schemas/ucp/2026-04-08/shopping/checkout/requests/writable.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": true, "properties": { @@ -771,6 +773,9 @@ "checkout_complete_request": { "$ref": "#/components/schemas/checkout-complete-request_schema" }, + "checkout_with_agreement_input": { + "$ref": "#/components/schemas/com_godaddy_shopping_checkout_input_schema_dev_ucp_shopping_checkout" + }, "checkout_writable_request": { "$ref": "#/components/schemas/checkout-writable-request_schema" }, @@ -794,6 +799,59 @@ }, "type": "object" }, + "com_godaddy_shopping_checkout_input_schema_consent_acceptance": { + "properties": { + "agreed_at": { + "type": "string" + }, + "agreement_types": { + "items": { + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "type": "object" + }, + "com_godaddy_shopping_checkout_input_schema_dev_ucp_shopping_checkout": { + "allOf": [ + { + "$ref": "#/components/schemas/ucp-refs_schema_checkout" + }, + { + "properties": { + "consent": { + "properties": { + "agreed_at": { + "type": "string" + }, + "agreement_types": { + "items": { + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "type": "object" + }, + "required_agreements": { + "items": { + "$ref": "#/components/schemas/required-agreement_schema" + }, + "type": "array", + "ucp_request": "omit" + } + }, + "type": "object" + } + ] + }, "com_godaddy_shopping_input_schema_input_schema": { "$ref": "#/components/schemas/schema" }, @@ -811,7 +869,7 @@ } }, "context": { - "$id": "https://ucp.dev/schemas/shopping/types/context.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/context.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": true, "properties": { @@ -845,7 +903,7 @@ "type": "object" }, "description": { - "$id": "https://ucp.dev/schemas/shopping/types/description.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/description.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "minProperties": 1, "properties": { @@ -863,7 +921,7 @@ "type": "object" }, "detail_option_value": { - "$id": "https://ucp.dev/schemas/shopping/types/detail_option_value.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/detail_option_value.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { @@ -882,7 +940,7 @@ "type": "object" }, "domain-discovery-search-request_schema": { - "$id": "https://godaddy.com/ucp/schemas/domain-discovery-search-request.schema.json", + "$id": "https://godaddy.com/schemas/ucp/2026-04-08/shopping/catalog/domain-discovery-request.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "domains": { @@ -908,11 +966,11 @@ "type": "array" }, "email_schema": { - "$id": "https://godaddy.com/ucp/schemas/product-metadata/email.schema.json", + "$id": "https://godaddy.com/schemas/ucp/2026-04-08/shopping/catalog/product-metadata/email.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { - "$ref": "#/components/schemas/base_schema" + "$ref": "#/components/schemas/product-metadata_base_schema" }, { "additionalProperties": true, @@ -928,7 +986,7 @@ "title": "GoDaddy email product metadata" }, "embedded_config": { - "$id": "https://ucp.dev/schemas/transports/embedded_config.json", + "$id": "https://ucp.dev/2026-04-08/schemas/transports/embedded_config.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "color_scheme": { @@ -952,7 +1010,7 @@ "type": "object" }, "error_code": { - "$id": "https://ucp.dev/schemas/shopping/types/error_code.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/error_code.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "examples": [ "not_found", @@ -969,7 +1027,7 @@ }, "error_response": {}, "expectation": { - "$id": "https://ucp.dev/schemas/shopping/types/expectation.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/expectation.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "description": { @@ -1011,134 +1069,8 @@ "title": "Expectation", "type": "object" }, - "fulfillment": { - "$defs": { - "dev.ucp.shopping.checkout": { - "allOf": [ - { - "$ref": "#/components/schemas/checkout" - }, - { - "properties": { - "fulfillment": { - "$ref": "#/components/schemas/fulfillment" - } - }, - "type": "object" - } - ], - "title": "Checkout with Fulfillment" - }, - "dev.ucp.shopping.fulfillment": { - "business_schema": { - "allOf": [ - { - "$ref": "#/components/schemas/capability_business_schema" - }, - { - "properties": { - "config": { - "$ref": "#/components/schemas/business_fulfillment_config" - } - } - } - ], - "title": "Fulfillment Capability (Business)" - }, - "platform_schema": { - "allOf": [ - { - "$ref": "#/components/schemas/capability_platform_schema" - }, - { - "properties": { - "config": { - "$ref": "#/components/schemas/platform_fulfillment_config" - } - } - } - ], - "title": "Fulfillment Capability (Platform)" - } - }, - "fulfillment": { - "$ref": "#/components/schemas/fulfillment" - }, - "fulfillment_available_method": { - "$ref": "#/components/schemas/fulfillment_available_method" - }, - "fulfillment_group": { - "$ref": "#/components/schemas/fulfillment_group" - }, - "fulfillment_method": { - "$ref": "#/components/schemas/fulfillment_method" - }, - "fulfillment_option": { - "$ref": "#/components/schemas/fulfillment_option" - } - }, - "$id": "https://ucp.dev/schemas/shopping/fulfillment.json", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "embedded": { - "delegations": [ - "fulfillment.address_change" - ], - "methods": { - "ec.fulfillment.address_change_request": { - "name": "ec.fulfillment.address_change_request", - "params": [ - { - "name": "checkout", - "schema": { - "$ref": "#/components/schemas/checkout" - } - } - ], - "result": { - "name": "addressChangeResult", - "schema": { - "oneOf": [ - { - "properties": { - "checkout": { - "properties": { - "fulfillment": { - "$ref": "#/components/schemas/fulfillment" - } - }, - "type": "object" - }, - "ucp": { - "$ref": "#/components/schemas/ucp_success" - } - }, - "type": "object" - }, - { - "$ref": "#/components/schemas/error_response" - } - ] - } - } - }, - "ec.fulfillment.change": { - "name": "ec.fulfillment.change", - "params": [ - { - "name": "checkout", - "schema": { - "$ref": "#/components/schemas/checkout" - } - } - ] - } - } - }, - "name": "dev.ucp.shopping.fulfillment", - "title": "Fulfillment Extension" - }, "fulfillment_available_method": { - "$id": "https://ucp.dev/schemas/shopping/types/fulfillment_available_method.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/fulfillment_available_method.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": true, "properties": { @@ -1171,7 +1103,7 @@ "ucp_shared_request": true }, "fulfillment_destination": { - "$id": "https://ucp.dev/schemas/shopping/types/fulfillment_destination.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/fulfillment_destination.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "oneOf": [ { @@ -1186,7 +1118,7 @@ "ucp_shared_request": true }, "fulfillment_event": { - "$id": "https://ucp.dev/schemas/shopping/types/fulfillment_event.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/fulfillment_event.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "carrier": { @@ -1230,7 +1162,7 @@ "type": "object" }, "fulfillment_group": { - "$id": "https://ucp.dev/schemas/shopping/types/fulfillment_group.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/fulfillment_group.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": true, "properties": { @@ -1263,7 +1195,7 @@ "type": "object" }, "fulfillment_method": { - "$id": "https://ucp.dev/schemas/shopping/types/fulfillment_method.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/fulfillment_method.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": true, "properties": { @@ -1315,7 +1247,7 @@ "type": "object" }, "fulfillment_option": { - "$id": "https://ucp.dev/schemas/shopping/types/fulfillment_option.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/fulfillment_option.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": true, "properties": { @@ -1358,38 +1290,8 @@ "get_product_request": { "$ref": "#/components/schemas/catalog_lookup_get_product_request" }, - "hosting_schema": { - "$id": "https://godaddy.com/ucp/schemas/product-metadata/hosting.schema.json", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "allOf": [ - { - "$ref": "#/components/schemas/base_schema" - }, - { - "additionalProperties": true, - "properties": { - "control_panel": { - "type": "string" - }, - "performance_tier": { - "type": "string" - }, - "storage_gb": { - "minimum": 0, - "type": "integer" - }, - "websites": { - "minimum": 0, - "type": "integer" - } - }, - "type": "object" - } - ], - "title": "GoDaddy hosting product metadata" - }, "info_code": { - "$id": "https://ucp.dev/schemas/shopping/types/info_code.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/info_code.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "examples": [ "identity_optional", @@ -1401,7 +1303,7 @@ "type": "string" }, "input_correlation": { - "$id": "https://ucp.dev/schemas/shopping/types/input_correlation.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/input_correlation.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "id": { @@ -1419,7 +1321,7 @@ "type": "object" }, "item": { - "$id": "https://ucp.dev/schemas/shopping/types/item.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/item.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "category": { @@ -1444,7 +1346,7 @@ "type": "object" }, "line_item": { - "$id": "https://ucp.dev/schemas/shopping/types/line_item.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/line_item.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "id": { @@ -1490,7 +1392,7 @@ "type": "object" }, "link": { - "$id": "https://ucp.dev/schemas/shopping/types/link.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/link.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "title": { @@ -1513,7 +1415,7 @@ "$ref": "#/components/schemas/catalog_lookup_lookup_response" }, "media": { - "$id": "https://ucp.dev/schemas/shopping/types/media.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/media.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "alt_text": { @@ -1538,7 +1440,7 @@ "type": "object" }, "message": { - "$id": "https://ucp.dev/schemas/shopping/types/message.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/message.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "oneOf": [ { @@ -1555,7 +1457,7 @@ "type": "object" }, "message_error": { - "$id": "https://ucp.dev/schemas/shopping/types/message_error.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/message_error.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "code": { @@ -1593,7 +1495,7 @@ "type": "object" }, "message_info": { - "$id": "https://ucp.dev/schemas/shopping/types/message_info.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/message_info.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "code": { @@ -1622,7 +1524,7 @@ "type": "object" }, "message_warning": { - "$id": "https://ucp.dev/schemas/shopping/types/message_warning.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/message_warning.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "code": { @@ -1661,7 +1563,7 @@ "type": "object" }, "option_value": { - "$id": "https://ucp.dev/schemas/shopping/types/option_value.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/option_value.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "id": { @@ -1686,7 +1588,7 @@ "type": "object" } }, - "$id": "https://ucp.dev/schemas/shopping/order.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/order.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "name": "dev.ucp.shopping.order", "properties": { @@ -1755,7 +1657,7 @@ "type": "object" }, "order_confirmation": { - "$id": "https://ucp.dev/schemas/shopping/types/order_confirmation.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/order_confirmation.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "id": { @@ -1772,7 +1674,7 @@ "type": "object" }, "order_line_item": { - "$id": "https://ucp.dev/schemas/shopping/types/order_line_item.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/order_line_item.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "id": { @@ -1857,7 +1759,7 @@ "type": "object" }, "payment": { - "$id": "https://ucp.dev/schemas/shopping/payment.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/payment.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "instruments": { @@ -1871,7 +1773,7 @@ "type": "object" }, "payment_credential": { - "$id": "https://ucp.dev/schemas/shopping/types/payment_credential.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/payment_credential.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": true, "properties": { @@ -2014,7 +1916,7 @@ "title": "Selected Payment Instrument" }, "platform_fulfillment_config": { - "$id": "https://ucp.dev/schemas/shopping/types/platform_fulfillment_config.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/platform_fulfillment_config.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "supports_multi_group": { @@ -2026,7 +1928,7 @@ "type": "object" }, "postal_address": { - "$id": "https://ucp.dev/schemas/shopping/types/postal_address.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/postal_address.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "address_country": { @@ -2061,7 +1963,7 @@ "type": "object" }, "price": { - "$id": "https://ucp.dev/schemas/shopping/types/price.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/price.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "amount": { @@ -2075,7 +1977,7 @@ "type": "object" }, "price_filter": { - "$id": "https://ucp.dev/schemas/shopping/types/price_filter.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/price_filter.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "max": { @@ -2089,7 +1991,7 @@ "type": "object" }, "price_range": { - "$id": "https://ucp.dev/schemas/shopping/types/price_range.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/price_range.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "max": { @@ -2103,7 +2005,7 @@ "type": "object" }, "product": { - "$id": "https://ucp.dev/schemas/shopping/types/product.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/product.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "action_required": { @@ -2155,6 +2057,13 @@ "rating": { "$ref": "#/components/schemas/rating" }, + "required_agreements": { + "items": { + "$ref": "#/components/schemas/required-agreement_schema" + }, + "type": "array", + "ucp_request": "omit" + }, "tags": { "items": { "type": "string" @@ -2178,8 +2087,60 @@ "title": "Product", "type": "object" }, + "product-metadata_base_schema": { + "$id": "https://godaddy.com/schemas/ucp/2026-04-08/shopping/catalog/product-metadata/base.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "properties": { + "category": { + "type": "string" + }, + "plan": { + "$ref": "#/components/schemas/product-plan_schema" + }, + "product_family": { + "minLength": 1, + "type": "string" + }, + "product_type": { + "type": "string" + } + }, + "title": "GoDaddy base product metadata", + "type": "object" + }, + "product-metadata_hosting_schema": { + "$id": "https://godaddy.com/schemas/ucp/2026-04-08/shopping/catalog/product-metadata/hosting.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "allOf": [ + { + "$ref": "#/components/schemas/product-metadata_base_schema" + }, + { + "additionalProperties": true, + "properties": { + "control_panel": { + "type": "string" + }, + "performance_tier": { + "type": "string" + }, + "storage_gb": { + "minimum": 0, + "type": "integer" + }, + "websites": { + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + } + ], + "title": "GoDaddy hosting product metadata" + }, "product-metadata_schema": { - "$id": "https://godaddy.com/ucp/schemas/product-metadata.schema.json", + "$id": "https://godaddy.com/schemas/ucp/2026-04-08/shopping/catalog/product-metadata.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": true, "allOf": [ @@ -2187,7 +2148,7 @@ "$ref": "#/components/schemas/email_schema" }, { - "$ref": "#/components/schemas/hosting_schema" + "$ref": "#/components/schemas/product-metadata_hosting_schema" }, { "$ref": "#/components/schemas/ssl_schema" @@ -2197,14 +2158,14 @@ "type": "object" }, "product-plan_schema": { - "$id": "https://godaddy.com/ucp/schemas/product-plan.schema.json", + "$id": "https://godaddy.com/schemas/ucp/2026-04-08/shopping/catalog/product-plan.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "minLength": 1, "title": "GoDaddy product plan", "type": "string" }, "product_option": { - "$id": "https://ucp.dev/schemas/shopping/types/product_option.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/product_option.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "name": { @@ -2222,7 +2183,7 @@ "type": "object" }, "rating": { - "$id": "https://ucp.dev/schemas/shopping/types/rating.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/rating.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "count": { @@ -2246,8 +2207,34 @@ "title": "Rating", "type": "object" }, + "required-agreement_schema": { + "$id": "https://godaddy.com/schemas/ucp/2026-04-08/shopping/checkout/required-agreement.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "properties": { + "content": { + "minLength": 1, + "type": "string" + }, + "key": { + "minLength": 1, + "type": "string" + }, + "required": { + "type": "boolean" + }, + "title": { + "minLength": 1, + "type": "string" + }, + "url": { + "type": "string" + } + }, + "title": "Required Agreement", + "type": "object" + }, "retail_location": { - "$id": "https://ucp.dev/schemas/shopping/types/retail_location.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/retail_location.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": true, "properties": { @@ -2267,14 +2254,14 @@ "ucp_shared_request": true }, "reverse_domain_name": { - "$id": "https://ucp.dev/schemas/shopping/types/reverse_domain_name.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/reverse_domain_name.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Reverse Domain Name", "type": "string" }, "schema": {}, "search_filters": { - "$id": "https://ucp.dev/schemas/shopping/types/search_filters.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/search_filters.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": true, "properties": { @@ -2298,7 +2285,7 @@ "$ref": "#/components/schemas/catalog_search_search_response" }, "selected_option": { - "$id": "https://ucp.dev/schemas/shopping/types/selected_option.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/selected_option.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "id": { @@ -2529,7 +2516,7 @@ "title": "Service (Response Schema)" }, "shipping_destination": { - "$id": "https://ucp.dev/schemas/shopping/types/shipping_destination.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/shipping_destination.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { @@ -2549,42 +2536,134 @@ "type": "object", "ucp_shared_request": true }, - "shopping_consent_acceptance": { - "properties": { - "agreed_at": { - "type": "string" + "shopping_fulfillment": { + "$defs": { + "dev.ucp.shopping.checkout": { + "allOf": [ + { + "$ref": "#/components/schemas/checkout" + }, + { + "properties": { + "fulfillment": { + "$ref": "#/components/schemas/types_fulfillment" + } + }, + "type": "object" + } + ], + "title": "Checkout with Fulfillment" }, - "agreement_types": { - "items": { - "type": "string" + "dev.ucp.shopping.fulfillment": { + "business_schema": { + "allOf": [ + { + "$ref": "#/components/schemas/capability_business_schema" + }, + { + "properties": { + "config": { + "$ref": "#/components/schemas/business_fulfillment_config" + } + } + } + ], + "title": "Fulfillment Capability (Business)" }, - "type": "array" - } - }, - "type": "object" - }, - "shopping_required_agreement": { - "properties": { - "content": { - "type": "string" + "platform_schema": { + "allOf": [ + { + "$ref": "#/components/schemas/capability_platform_schema" + }, + { + "properties": { + "config": { + "$ref": "#/components/schemas/platform_fulfillment_config" + } + } + } + ], + "title": "Fulfillment Capability (Platform)" + } }, - "key": { - "type": "string" + "fulfillment": { + "$ref": "#/components/schemas/types_fulfillment" }, - "required": { - "type": "boolean" + "fulfillment_available_method": { + "$ref": "#/components/schemas/fulfillment_available_method" }, - "title": { - "type": "string" + "fulfillment_group": { + "$ref": "#/components/schemas/fulfillment_group" }, - "url": { - "type": "string" + "fulfillment_method": { + "$ref": "#/components/schemas/fulfillment_method" + }, + "fulfillment_option": { + "$ref": "#/components/schemas/fulfillment_option" } }, - "type": "object" + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/fulfillment.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "embedded": { + "delegations": [ + "fulfillment.address_change" + ], + "methods": { + "ec.fulfillment.address_change_request": { + "name": "ec.fulfillment.address_change_request", + "params": [ + { + "name": "checkout", + "schema": { + "$ref": "#/components/schemas/checkout" + } + } + ], + "result": { + "name": "addressChangeResult", + "schema": { + "oneOf": [ + { + "properties": { + "checkout": { + "properties": { + "fulfillment": { + "$ref": "#/components/schemas/types_fulfillment" + } + }, + "type": "object" + }, + "ucp": { + "$ref": "#/components/schemas/ucp_success" + } + }, + "type": "object" + }, + { + "$ref": "#/components/schemas/error_response" + } + ] + } + } + }, + "ec.fulfillment.change": { + "name": "ec.fulfillment.change", + "params": [ + { + "name": "checkout", + "schema": { + "$ref": "#/components/schemas/checkout" + } + } + ] + } + } + }, + "name": "dev.ucp.shopping.fulfillment", + "title": "Fulfillment Extension" }, "signals": { - "$id": "https://ucp.dev/schemas/shopping/types/signals.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/signals.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": true, "properties": { @@ -2600,17 +2679,17 @@ "type": "object" }, "signed_amount": { - "$id": "https://ucp.dev/schemas/shopping/types/signed_amount.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/signed_amount.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Signed Amount", "type": "integer" }, "ssl_schema": { - "$id": "https://godaddy.com/ucp/schemas/product-metadata/ssl.schema.json", + "$id": "https://godaddy.com/schemas/ucp/2026-04-08/shopping/catalog/product-metadata/ssl.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { - "$ref": "#/components/schemas/base_schema" + "$ref": "#/components/schemas/product-metadata_base_schema" }, { "additionalProperties": true, @@ -2635,7 +2714,7 @@ "title": "GoDaddy SSL product metadata" }, "total": { - "$id": "https://ucp.dev/schemas/shopping/types/total.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/total.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { @@ -2696,7 +2775,7 @@ "type": "object" }, "totals": { - "$id": "https://ucp.dev/schemas/shopping/types/totals.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/totals.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ { @@ -2772,6 +2851,28 @@ "title": "Totals", "type": "array" }, + "types_fulfillment": { + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/fulfillment.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "properties": { + "available_methods": { + "items": { + "$ref": "#/components/schemas/fulfillment_available_method" + }, + "type": "array", + "ucp_request": "omit" + }, + "methods": { + "items": { + "$ref": "#/components/schemas/fulfillment_method" + }, + "type": "array" + } + }, + "title": "Fulfillment", + "type": "object", + "ucp_shared_request": true + }, "ucp-refs_schema_attribution": { "$ref": "#/components/schemas/attribution" }, @@ -2785,7 +2886,7 @@ "$ref": "#/components/schemas/context" }, "ucp-refs_schema_fulfillment": { - "$ref": "#/components/schemas/fulfillment" + "$ref": "#/components/schemas/shopping_fulfillment" }, "ucp-refs_schema_get_product_request": { "$ref": "#/components/schemas/catalog_lookup_get_product_request" @@ -3079,7 +3180,7 @@ ] }, "variant": { - "$id": "https://ucp.dev/schemas/shopping/types/variant.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/variant.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "availability": { @@ -3239,17 +3340,63 @@ "title": "Variant", "type": "object" }, + "variant-metadata_base_schema": { + "$id": "https://godaddy.com/schemas/ucp/2026-04-08/shopping/catalog/variant-metadata/base.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "properties": { + "default": { + "type": "boolean" + } + }, + "title": "GoDaddy base variant metadata", + "type": "object" + }, + "variant-metadata_hosting_schema": { + "$id": "https://godaddy.com/schemas/ucp/2026-04-08/shopping/catalog/variant-metadata/hosting.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "allOf": [ + { + "$ref": "#/components/schemas/variant-metadata_base_schema" + }, + { + "additionalProperties": true, + "properties": { + "control_panel": { + "type": "string" + }, + "performance_tier": { + "type": "string" + }, + "storage_gb": { + "minimum": 0, + "type": "integer" + }, + "websites": { + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + } + ], + "title": "GoDaddy hosting variant metadata" + }, "variant-metadata_schema": { - "$id": "https://godaddy.com/ucp/schemas/variant-metadata.schema.json", + "$id": "https://godaddy.com/schemas/ucp/2026-04-08/shopping/catalog/variant-metadata.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ - {}, - {} + { + "$ref": "#/components/schemas/variant-metadata_base_schema" + }, + { + "$ref": "#/components/schemas/variant-metadata_hosting_schema" + } ], "title": "GoDaddy variant metadata" }, "warning_code": { - "$id": "https://ucp.dev/schemas/shopping/types/warning_code.json", + "$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/warning_code.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "examples": [ "final_sale", @@ -3477,7 +3624,7 @@ "schema": { "oneOf": [ { - "$ref": "#/components/schemas/checkout" + "$ref": "#/components/schemas/checkout_with_agreement_input" }, { "$ref": "#/components/schemas/error_response" @@ -3521,7 +3668,7 @@ "schema": { "oneOf": [ { - "$ref": "#/components/schemas/checkout" + "$ref": "#/components/schemas/checkout_with_agreement_input" }, { "$ref": "#/components/schemas/error_response" @@ -3581,7 +3728,7 @@ "schema": { "oneOf": [ { - "$ref": "#/components/schemas/checkout" + "$ref": "#/components/schemas/checkout_with_agreement_input" }, { "$ref": "#/components/schemas/error_response" @@ -3643,7 +3790,7 @@ "schema": { "oneOf": [ { - "$ref": "#/components/schemas/checkout" + "$ref": "#/components/schemas/checkout_with_agreement_input" }, { "$ref": "#/components/schemas/error_response" diff --git a/rust/src/domain/contacts_file.rs b/rust/src/domain/contacts_file.rs index 6350d7fe..2ddc1ef0 100644 --- a/rust/src/domain/contacts_file.rs +++ b/rust/src/domain/contacts_file.rs @@ -98,13 +98,6 @@ impl Contact { /// the country isn't shaped like an ISO-3166 alpha-2 code (see /// [`validate_country`] — a format check, not list membership) or the phone /// can't be parsed. - /// - /// v3's `Contact` is leaner than v2's: it has no middle name, job title, fax, - /// or character-encoding field, and the phone is a structured object - /// (`countryCode`/`nationalNumber`) rather than a dotted `+1.4805551212` - /// string. `name_middle`/`job_title`/`fax` are not part of the struct schema; - /// a leftover such key in a v1/v2-era `contacts.toml` is simply ignored (serde - /// skips unknown keys). pub fn to_api(&self, role: Role) -> Result { let country_upper = self.country.to_ascii_uppercase(); validate_country(&country_upper, role)?; @@ -121,6 +114,7 @@ impl Contact { email: api::EmailAddress(self.email.clone()), first_name: self.name_first.clone(), last_name: self.name_last.clone(), + metadata: Default::default(), organization: empty_to_none(&self.organization), phone, }) diff --git a/rust/src/domain/purchase.rs b/rust/src/domain/purchase.rs index 3bdca85b..74e6fdf8 100644 --- a/rust/src/domain/purchase.rs +++ b/rust/src/domain/purchase.rs @@ -223,17 +223,16 @@ pub(super) fn command() -> RuntimeCommandSpec { // as a confusing server-side QUOTE_MISMATCH. A clear re-quote message // is better than a mismatched charge attempt. let profile = match cached.profile.as_ref() { - Some(v) => Some( - serde_json::from_value::(v.clone()).map_err( - |e| { - CliCoreError::message(format!( - "the cached quote for {domain} is corrupt or from an older CLI \ - version (could not read its registration profile: {e}); re-run \ - `gddy domain quote {domain}` for a fresh quote." - )) - }, - )?, - ), + Some(v) => Some(serde_json::from_value::(v.clone()).map_err( + |e| { + CliCoreError::message(format!( + "the cached quote for {domain} is corrupt or from \ + an older CLI version (could not read its \ + registration profile: {e}); re-run \ + `gddy domain quote {domain}` for a fresh quote." + )) + }, + )?), None => None, }; diff --git a/rust/src/domain/quote.rs b/rust/src/domain/quote.rs index 9dd5735b..d3a58155 100644 --- a/rust/src/domain/quote.rs +++ b/rust/src/domain/quote.rs @@ -50,7 +50,7 @@ fn build_profile( privacy: bool, renew_auto: bool, name_servers: &[String], -) -> Result { +) -> Result { let file = super::contacts_file::load().map_err(|e| CliCoreError::message(e.to_string()))?; let to_api = |role| file.to_api(role).map_err(CliCoreError::message); let registrant = to_api(super::contacts_file::Role::Registrant)?; @@ -85,7 +85,7 @@ fn build_profile( ) }); - Ok(types::InlineRegistrationProfile { + Ok(types::Profile { auto_renew: Some(renew_auto), contacts: contacts_obj, name_servers, @@ -129,10 +129,8 @@ fn quote_to_json(quote: &types::RegistrationQuote, request_domain: &str) -> serd if let Some(renewal) = quote.renewal_price.as_ref().and_then(format_money) { out["renewalPrice"] = json!(renewal); } - if let Some(period) = quote.period { - out["period"] = json!(period.get()); - out["periodLabel"] = json!(period_label(period.get())); - } + out["period"] = json!(quote.period.get()); + out["periodLabel"] = json!(period_label(quote.period.get())); if let Some(token) = quote.quote_token.as_ref() { out["quoteToken"] = json!(token.to_string()); } @@ -375,7 +373,7 @@ pub(super) fn command() -> RuntimeCommandSpec { }; let cached = super::quote_cache::CachedQuote { domain: quote.domain.clone().unwrap_or_else(|| domain.clone()), - period: quote.period.map_or(period, |p| p.get()), + period: quote.period.get(), agreement_types, agreement_titles, price: view diff --git a/rust/src/domain/quote_cache.rs b/rust/src/domain/quote_cache.rs index 9ca8f522..522dfdd3 100644 --- a/rust/src/domain/quote_cache.rs +++ b/rust/src/domain/quote_cache.rs @@ -51,7 +51,7 @@ pub struct CachedQuote { /// if the API returned no expiry (then the entry never expires locally). #[serde(default)] pub expires_at: Option, - /// The exact `InlineRegistrationProfile` the quote was taken with, serialized. + /// The exact `Profile` the quote was taken with, serialized. /// `register` must re-send it verbatim or the server rejects the mismatch /// (the token binds a hash of the domain/price/profile). `None` when the quote /// carried no profile. diff --git a/rust/src/shopping/checkout/complete.rs b/rust/src/shopping/checkout/complete.rs index 56e77507..356a1e1f 100644 --- a/rust/src/shopping/checkout/complete.rs +++ b/rust/src/shopping/checkout/complete.rs @@ -3,14 +3,16 @@ use std::collections::BTreeMap; use cli_engine::{CommandResult, CommandSpec, NextActionParam, RuntimeCommandSpec, Tier}; use serde_json::{Map, Value}; use shopping_client::types::{ - CatalogLookupLookupRequest, Checkout, CheckoutCompleteRequest, CheckoutCompleteRequestSchema, - LookupCatalogResponse, LookupRequest, ShoppingConsentAcceptance, UcpRefsSchemaPayment, + CatalogLookupLookupRequest, CheckoutCompleteRequest, CheckoutCompleteRequestSchema, + ComGodaddyShoppingCheckoutInputSchemaConsentAcceptance as ConsentAcceptance, + ComGodaddyShoppingCheckoutInputSchemaConsentAcceptanceAgreementTypesItem as AgreementType, + LookupCatalogResponse, LookupRequest, UcpRefsSchemaPayment, }; use crate::next_action::next_action; use crate::shopping::AGENT_PURCHASE_CONFIRMATION_INSTRUCTIONS; use crate::shopping::SHOPPING_PURCHASE_SCOPES; -use crate::shopping::client::ClientError; +use crate::shopping::client::{Checkout, ClientError}; use crate::shopping::common::{ CheckoutInput, client_err, make_client, payment_selection_body, reject_response_errors, require_selected_payment_instrument, selected_payment_id, update_response, @@ -143,13 +145,14 @@ fn required_agreements(checkout: &Checkout) -> Vec<(&str, &str, Option<&str>)> { .iter() .filter(|agreement| agreement.required == Some(true)) .filter_map(|agreement| { - let key = agreement.key.as_deref()?; + let key = agreement.key.as_ref()?.as_str(); if key.trim().is_empty() { return None; } let title = agreement .title - .as_deref() + .as_ref() + .map(|title| title.as_str()) .filter(|title| !title.trim().is_empty()) .unwrap_or(key); Some((key, title, agreement.url.as_deref())) @@ -202,16 +205,18 @@ fn agreement_gate( .into_cli_error()) } -fn completion_consent(checkout: &Checkout) -> Option { +fn completion_consent(checkout: &Checkout) -> Option { let agreement_types = required_agreements(checkout) .into_iter() - .map(|(key, _, _)| key.to_owned()) + .map(|(key, _, _)| { + AgreementType::try_from(key).expect("agreement keys were read from validated keys") + }) .collect::>(); if agreement_types.is_empty() { return None; } - Some(ShoppingConsentAcceptance { - agreement_types, + Some(ConsentAcceptance { + agreement_types: Some(agreement_types), agreed_at: Some(chrono::Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Secs, true)), }) } @@ -349,7 +354,8 @@ mod tests { use serde_json::json; use shopping_client::types::{ CatalogLookupLookupResponse, ErrorResponse, LookupResponse, Message, MessageError, Payment, - PaymentInstrumentSelectedPaymentInstrument, ShoppingRequiredAgreement, + PaymentInstrumentSelectedPaymentInstrument, RequiredAgreementSchema, + RequiredAgreementSchemaKey, RequiredAgreementSchemaTitle, }; use super::*; @@ -400,16 +406,48 @@ mod tests { title: Option<&str>, url: Option<&str>, required: bool, - ) -> ShoppingRequiredAgreement { - ShoppingRequiredAgreement { - key: Some(key.to_owned()), - title: title.map(str::to_owned), + ) -> RequiredAgreementSchema { + RequiredAgreementSchema { + key: Some(RequiredAgreementSchemaKey::try_from(key).expect("non-empty key")), + title: title.map(|title| { + RequiredAgreementSchemaTitle::try_from(title).expect("non-empty title") + }), url: url.map(str::to_owned), required: Some(required), content: None, } } + #[test] + fn checkout_response_agreements_keep_their_required_flag() { + let checkout: Checkout = serde_json::from_value(json!({ + "id": "checkout-1", + "required_agreements": [ + {"key": "terms", "title": "Terms", "required": true, "url": "https://example.com/terms"}, + {"key": "promo", "title": "Promotions", "required": false, "content": "Optional."} + ] + })) + .expect("checkout response decodes"); + + assert_eq!( + required_agreements(&checkout), + vec![("terms", "Terms", Some("https://example.com/terms"))] + ); + } + + #[test] + fn completion_consent_serializes_as_agreement_keys_and_a_timestamp() { + let checkout = Checkout { + required_agreements: vec![required_agreement("terms", None, None, true)], + ..Default::default() + }; + let consent = serde_json::to_value(completion_consent(&checkout).expect("consent")) + .expect("serialize consent"); + + assert_eq!(consent["agreement_types"], json!(["terms"])); + assert!(consent["agreed_at"].is_string(), "{consent}"); + } + #[test] fn agreement_gate_requires_agree() { let checkout = Checkout { @@ -490,8 +528,13 @@ mod tests { let consent = completion_consent(&checkout).expect("required consent"); assert_eq!( - consent.agreement_types, - vec!["ssl".to_owned(), "terms".to_owned()] + consent + .agreement_types + .expect("agreement types") + .iter() + .map(|agreement_type| agreement_type.as_str()) + .collect::>(), + vec!["ssl", "terms"] ); assert!( chrono::DateTime::parse_from_rfc3339(consent.agreed_at.as_deref().expect("timestamp")) diff --git a/rust/src/shopping/checkout/get.rs b/rust/src/shopping/checkout/get.rs index f159b716..98244646 100644 --- a/rust/src/shopping/checkout/get.rs +++ b/rust/src/shopping/checkout/get.rs @@ -1,8 +1,8 @@ use cli_engine::{CommandResult, CommandSpec, Result, RuntimeCommandSpec, Tier}; use serde_json::Value; -use shopping_client::types::Checkout; use crate::shopping::SHOPPING_PURCHASE_SCOPES; +use crate::shopping::client::Checkout; use crate::shopping::common::{client_err, make_client, reject_response_errors}; use crate::shopping::human::{CHECKOUT_VIEW_ID, checkout_response}; diff --git a/rust/src/shopping/checkout/update.rs b/rust/src/shopping/checkout/update.rs index f66878ad..c7d600e2 100644 --- a/rust/src/shopping/checkout/update.rs +++ b/rust/src/shopping/checkout/update.rs @@ -1,8 +1,8 @@ use cli_engine::{CommandResult, CommandSpec, NextAction, RuntimeCommandSpec, Tier}; -use shopping_client::types::Checkout; use super::create::agreement_review_action; use crate::shopping::SHOPPING_PURCHASE_SCOPES; +use crate::shopping::client::Checkout; use crate::shopping::common::{ CheckoutInput, client_err, currency_code, make_client, no_saved_payment_method_action, reject_multiple_payment_instruments, reject_response_errors, update_response, @@ -219,7 +219,9 @@ pub(super) fn command() -> RuntimeCommandSpec { #[cfg(test)] mod tests { - use shopping_client::types::{Checkout, Payment, PaymentInstrumentSelectedPaymentInstrument}; + use shopping_client::types::{Payment, PaymentInstrumentSelectedPaymentInstrument}; + + use crate::shopping::client::Checkout; use super::{update_review_action, validate_requested_payment, validate_selected_payment}; diff --git a/rust/src/shopping/client.rs b/rust/src/shopping/client.rs index 5cec26ec..cbc0b81f 100644 --- a/rust/src/shopping/client.rs +++ b/rust/src/shopping/client.rs @@ -1,10 +1,14 @@ use std::time::Duration; use shopping_client::types::{ - Checkout, CheckoutCompleteRequest, CheckoutWritableRequest, CompleteCheckoutResponse, + CheckoutCompleteRequest, CheckoutWritableRequest, CompleteCheckoutResponse, CreateCheckoutResponse, GetCheckoutResponse, GetOrderResponse, Order, UpdateCheckoutResponse, }; +/// A checkout session as the API returns it, including its required agreements. +pub(crate) type Checkout = + shopping_client::types::ComGodaddyShoppingCheckoutInputSchemaDevUcpShoppingCheckout; + const USER_AGENT: &str = concat!("godaddy-cli/", env!("CARGO_PKG_VERSION")); #[derive(Debug, thiserror::Error)] pub enum ClientError { @@ -174,7 +178,7 @@ macro_rules! impl_into_checkout { $(impl IntoCheckout for $response { fn into_checkout(self) -> Result { match self { - Self::Checkout(checkout) => Ok(checkout), + Self::CheckoutWithAgreementInput(checkout) => Ok(checkout.0), Self::ErrorResponse(payload) => { Err(ClientError::UnexpectedErrorPayload(payload.into())) } @@ -617,7 +621,10 @@ mod tests { let error_payload = json!({"error": "something went wrong", "code": "invalid_checkout"}); let decoded: GetCheckoutResponse = serde_json::from_value(error_payload).expect("should decode as *something*"); - assert!(matches!(decoded, GetCheckoutResponse::Checkout(_))); + assert!(matches!( + decoded, + GetCheckoutResponse::CheckoutWithAgreementInput(_) + )); } #[tokio::test] diff --git a/rust/src/shopping/common.rs b/rust/src/shopping/common.rs index a0b6a00e..1f1dd9cf 100644 --- a/rust/src/shopping/common.rs +++ b/rust/src/shopping/common.rs @@ -1,15 +1,15 @@ use cli_engine::{CliCoreError, CommandContext, Result}; use shopping_client::types::{ - Buyer, Checkout, CheckoutCompleteRequest, CheckoutCompleteRequestSchema, - CheckoutWritableRequest, CheckoutWritableRequestSchema, Context, Item, LineItem, Message, - Payment, PaymentInstrumentSelectedPaymentInstrument, UcpRefsSchemaAttribution, - UcpRefsSchemaBuyer, UcpRefsSchemaContext, UcpRefsSchemaFulfillment, UcpRefsSchemaLineItem, - UcpRefsSchemaPayment, UcpRefsSchemaSignals, + Buyer, CheckoutCompleteRequest, CheckoutCompleteRequestSchema, CheckoutWritableRequest, + CheckoutWritableRequestSchema, Context, Item, LineItem, Message, Payment, + PaymentInstrumentSelectedPaymentInstrument, UcpRefsSchemaAttribution, UcpRefsSchemaBuyer, + UcpRefsSchemaContext, UcpRefsSchemaFulfillment, UcpRefsSchemaLineItem, UcpRefsSchemaPayment, + UcpRefsSchemaSignals, }; use crate::error::GddyError; use crate::next_action::next_action; -use crate::shopping::client::{ClientError, build_client}; +use crate::shopping::client::{Checkout, ClientError, build_client}; pub(crate) async fn make_client(ctx: &CommandContext) -> Result { crate::http::ensure_generated_client_transport_observer_registered(); diff --git a/rust/src/shopping/product_actions.rs b/rust/src/shopping/product_actions.rs index 2d7f87c2..a7a10573 100644 --- a/rust/src/shopping/product_actions.rs +++ b/rust/src/shopping/product_actions.rs @@ -1,7 +1,9 @@ use std::collections::BTreeSet; use cli_engine::NextAction; -use shopping_client::types::{Checkout, LookupResponse}; +use shopping_client::types::LookupResponse; + +use crate::shopping::client::Checkout; use crate::next_action::next_action; @@ -45,11 +47,12 @@ pub(crate) fn post_purchase_actions(catalog_response: &LookupResponse) -> Vec) -> LineItem { LineItem { diff --git a/rust/tools/generate-api-catalog/src/dereference.rs b/rust/tools/generate-api-catalog/src/dereference.rs index 493f320e..7b2ad7a0 100644 --- a/rust/tools/generate-api-catalog/src/dereference.rs +++ b/rust/tools/generate-api-catalog/src/dereference.rs @@ -1,13 +1,14 @@ -use std::{ - collections::HashSet, - path::{Path, PathBuf}, -}; +use std::{collections::HashSet, path::Path}; use anyhow::{Context, Result}; use indexmap::IndexMap; use serde_json::Value; use crate::github::parse_yaml_or_json; +use crate::ref_paths::{ + has_conflicting_namesake, id_ref_to_file_ref, normalize_path, resolve_case_insensitive, + resolve_common_types_path, specification_root, +}; // --------------------------------------------------------------------------- // $ref resolution @@ -94,6 +95,23 @@ fn derive_defs_key_for_path(ref_str: &str) -> String { } } +/// Prefix `key` with the file's parent directory when another schema file in +/// the specification has the same name but a different `$id` (e.g. +/// `product-metadata/base.schema.json` and +/// `variant-metadata/base.schema.json`); otherwise they would share one `$defs` +/// entry and whichever was seen first would silently win. +fn qualify_ambiguous_key(key: String, ref_str: &str, spec_dir: &Path) -> String { + let file = normalize_path(&spec_dir.join(ref_str.split('#').next().unwrap_or(ref_str))); + let file = file.as_path(); + let qualifier = file.parent().and_then(Path::file_name); + match (qualifier, specification_root(spec_dir)) { + (Some(qualifier), Some(root)) if has_conflicting_namesake(&root.join("schemas"), file) => { + sanitize_defs_key(&format!("{}_{key}", qualifier.to_string_lossy())) + } + _ => key, + } +} + fn sanitize_defs_key(s: &str) -> String { let sanitized: String = s .chars() @@ -113,16 +131,28 @@ fn dereference( current: Value, spec_dir: &Path, common_types_dir: Option<&Path>, + qualify_namesakes: bool, defs: &mut IndexMap, depth: usize, ) -> Value { - if depth > 64 { + // Backstop only: circular refs are caught by the `defs` placeholder below. Depth + // counts structural nesting plus every external file hop, and real spec chains + // (e.g. UCP schemas routed through a shared refs document) run past 90. + if depth > 256 { return current; } match current { Value::Object(mut map) => { if let Some(Value::String(ref_str)) = map.get("$ref").cloned() { + // Key and resolve `$id` URLs by the file that declares them, so lifted + // `$defs` keys follow file names rather than generic URL tails. + let ref_str = id_ref_to_file_ref(&ref_str, spec_dir).unwrap_or(ref_str); if let Some(key) = should_lift_to_defs(&ref_str) { + let key = if qualify_namesakes && !ref_str.starts_with('#') { + qualify_ambiguous_key(key, &ref_str, spec_dir) + } else { + key + }; // Already registered — return the local pointer immediately (dedup) if defs.contains_key(&key) { return serde_json::json!({"$ref": format!("#/$defs/{}", json_pointer_escape(&key))}); @@ -132,11 +162,27 @@ fn dereference( let resolved_opt = if ref_str.starts_with('#') { // Local component ref: resolve from this spec's root resolve_local_ref(root, &ref_str).cloned().map(|v| { - dereference(root, v, spec_dir, common_types_dir, defs, depth + 1) + dereference( + root, + v, + spec_dir, + common_types_dir, + qualify_namesakes, + defs, + depth + 1, + ) }) } else { // External file/URL ref - resolve_ref(root, &ref_str, spec_dir, common_types_dir, defs, depth + 1) + resolve_ref( + root, + &ref_str, + spec_dir, + common_types_dir, + qualify_namesakes, + defs, + depth + 1, + ) }; if let Some(content) = resolved_opt { defs.insert(key.clone(), content); @@ -148,21 +194,54 @@ fn dereference( return Value::Object(map); } // Non-liftable local ref (e.g. #/paths/...) — inline as before - let resolved = - resolve_ref(root, &ref_str, spec_dir, common_types_dir, defs, depth + 1); + let resolved = resolve_ref( + root, + &ref_str, + spec_dir, + common_types_dir, + qualify_namesakes, + defs, + depth + 1, + ); return resolved - .map(|v| dereference(root, v, spec_dir, common_types_dir, defs, depth + 1)) + .map(|v| { + dereference( + root, + v, + spec_dir, + common_types_dir, + qualify_namesakes, + defs, + depth + 1, + ) + }) .unwrap_or(Value::Object(map)); } // Recurse into all values for v in map.values_mut() { - *v = dereference(root, v.take(), spec_dir, common_types_dir, defs, depth + 1); + *v = dereference( + root, + v.take(), + spec_dir, + common_types_dir, + qualify_namesakes, + defs, + depth + 1, + ); } Value::Object(map) } Value::Array(mut arr) => { for v in &mut arr { - *v = dereference(root, v.take(), spec_dir, common_types_dir, defs, depth + 1); + *v = dereference( + root, + v.take(), + spec_dir, + common_types_dir, + qualify_namesakes, + defs, + depth + 1, + ); } Value::Array(arr) } @@ -175,6 +254,7 @@ fn resolve_ref( ref_str: &str, spec_dir: &Path, common_types_dir: Option<&Path>, + qualify_namesakes: bool, defs: &mut IndexMap, depth: usize, ) -> Option { @@ -198,7 +278,13 @@ fn resolve_ref( .unwrap_or(""), ); let local_path = ct_dir.join(url_path.trim_start_matches('/')); - return load_external_ref(&local_path, common_types_dir, defs, depth); + return load_external_ref( + &local_path, + common_types_dir, + qualify_namesakes, + defs, + depth, + ); } if let Some(url_path) = ref_str.strip_prefix("https://godaddy.com/ucp/schemas/") { @@ -206,7 +292,14 @@ fn resolve_ref( let local_path = specification_root(spec_dir)? .join("schemas") .join(file_part); - return resolve_external_fragment(&local_path, fragment, common_types_dir, defs, depth); + return resolve_external_fragment( + &local_path, + fragment, + common_types_dir, + qualify_namesakes, + defs, + depth, + ); } if let Some(url_path) = ref_str.strip_prefix("https://ucp.dev/schemas/shopping/") { @@ -214,7 +307,14 @@ fn resolve_ref( let local_path = specification_root(spec_dir)? .join("schemas/ucp/shopping") .join(file_part); - return resolve_external_fragment(&local_path, fragment, common_types_dir, defs, depth); + return resolve_external_fragment( + &local_path, + fragment, + common_types_dir, + qualify_namesakes, + defs, + depth, + ); } // Relative file reference — strip fragment @@ -233,11 +333,19 @@ fn resolve_ref( // inside it (e.g. `v2/models/` instead of `v2/schemas/models/`). Try the // parent of spec_dir as a fallback so both layouts resolve correctly. let external_root = - load_external_ref(&file_path, common_types_dir, defs, depth).or_else(|| { - spec_dir.parent().and_then(|parent| { - load_external_ref(&parent.join(file_part), common_types_dir, defs, depth) - }) - })?; + load_external_ref(&file_path, common_types_dir, qualify_namesakes, defs, depth).or_else( + || { + spec_dir.parent().and_then(|parent| { + load_external_ref( + &parent.join(file_part), + common_types_dir, + qualify_namesakes, + defs, + depth, + ) + }) + }, + )?; if let Some(frag) = fragment && !frag.is_empty() @@ -258,29 +366,20 @@ fn resolve_external_fragment( path: &Path, fragment: Option<&str>, common_types_dir: Option<&Path>, + qualify_namesakes: bool, defs: &mut IndexMap, depth: usize, ) -> Option { - let root = load_external_ref(path, common_types_dir, defs, depth)?; + let root = load_external_ref(path, common_types_dir, qualify_namesakes, defs, depth)?; fragment.map_or(Some(root.clone()), |fragment| { resolve_local_ref(&root, fragment).cloned() }) } -fn specification_root(spec_dir: &Path) -> Option<&Path> { - let mut current = Some(spec_dir); - while let Some(path) = current { - if path.join("schemas").is_dir() { - return Some(path); - } - current = path.parent(); - } - None -} - fn load_external_ref( path: &Path, common_types_dir: Option<&Path>, + qualify_namesakes: bool, defs: &mut IndexMap, depth: usize, ) -> Option { @@ -321,93 +420,12 @@ fn load_external_ref( parsed, dir, common_types_dir, + qualify_namesakes, defs, depth + 1, )) } -/// Try to find `path` in its parent directory with a case-insensitive filename match. -/// Returns the first candidate whose lowercased name equals the lowercased target, -/// or `None` if no unique match is found. -fn resolve_case_insensitive(path: &Path) -> Option { - let dir = path.parent()?; - let target = path.file_name()?.to_string_lossy().to_lowercase(); - let mut matches: Vec = std::fs::read_dir(dir) - .ok()? - .filter_map(|e| e.ok()) - .filter(|e| e.file_name().to_string_lossy().to_lowercase() == target) - .map(|e| e.path()) - .collect(); - if matches.len() == 1 { - matches.pop() - } else { - None - } -} - -/// Normalize a path by resolving `.` and `..` components without hitting the filesystem. -fn normalize_path(path: &Path) -> PathBuf { - let mut out = PathBuf::new(); - for component in path.components() { - match component { - std::path::Component::ParentDir => { - out.pop(); - } - std::path::Component::CurDir => {} - c => out.push(c), - } - } - out -} - -/// When a path contains a `common-types` segment and does not exist, try to locate the -/// file in the standalone common-types-specification clone. Mirrors the TypeScript -/// `resolveCommonTypesFile` helper. -fn resolve_common_types_path(path: &Path, common_types_dir: Option<&Path>) -> Option { - let ct_dir = common_types_dir?; - let path_str = path.to_string_lossy(); - let ct_marker = "common-types/"; - let idx = path_str.find(ct_marker)?; - - let rel = &path_str[idx + ct_marker.len()..]; - // 1. Try path as-is relative to the clone root - let direct = ct_dir.join(rel); - if direct.exists() { - return Some(direct); - } - - // 2. Try v1/schemas/{yaml,json}/ (covering both extension variants) - let basename = path.file_name()?; - let basename_str = basename.to_string_lossy(); - let ext = path.extension().and_then(|e| e.to_str()).unwrap_or(""); - let (primary_sub, alt_sub, alt_ext) = if ext == "json" { - ("json", "yaml", "yaml") - } else { - ("yaml", "json", "json") - }; - - let nested = ct_dir - .join("v1") - .join("schemas") - .join(primary_sub) - .join(basename_str.as_ref()); - if nested.exists() { - return Some(nested); - } - let stem = path.file_stem()?.to_string_lossy(); - let alt_name = format!("{stem}.{alt_ext}"); - let alt = ct_dir - .join("v1") - .join("schemas") - .join(alt_sub) - .join(&alt_name); - if alt.exists() { - return Some(alt); - } - - None -} - /// Walk a dereferenced value and collect any remaining external `$ref` strings. /// External refs are anything that is not a local JSON pointer (`#/...`). pub(crate) fn collect_unresolved_refs(value: &Value) -> Vec { @@ -497,6 +515,24 @@ fn rewrite_discriminator_mappings(value: &mut Value, def_keys: &HashSet) pub(crate) fn load_and_dereference( spec_file: &Path, common_types_dir: Option<&Path>, +) -> Result<(Value, IndexMap)> { + load_and_dereference_with(spec_file, common_types_dir, false) +} + +/// Like [`load_and_dereference`], but lifts schema files that share a file name yet +/// declare different `$id`s under distinct `$defs` keys instead of letting one +/// silently replace the other. Opt-in so specs already generated keep their keys. +pub(crate) fn load_and_dereference_distinguishing_namesakes( + spec_file: &Path, + common_types_dir: Option<&Path>, +) -> Result<(Value, IndexMap)> { + load_and_dereference_with(spec_file, common_types_dir, true) +} + +fn load_and_dereference_with( + spec_file: &Path, + common_types_dir: Option<&Path>, + qualify_namesakes: bool, ) -> Result<(Value, IndexMap)> { let src = std::fs::read_to_string(spec_file) .with_context(|| format!("failed to read {}", spec_file.display()))?; @@ -508,6 +544,7 @@ pub(crate) fn load_and_dereference( parsed, spec_dir, common_types_dir, + qualify_namesakes, &mut defs, 0, ); diff --git a/rust/tools/generate-api-catalog/src/main.rs b/rust/tools/generate-api-catalog/src/main.rs index d48c01da..49a87c56 100644 --- a/rust/tools/generate-api-catalog/src/main.rs +++ b/rust/tools/generate-api-catalog/src/main.rs @@ -6,6 +6,7 @@ mod graphql; mod hosting_spec; mod manifest; mod openapi; +mod ref_paths; mod shopping_spec; mod spec_normalize; diff --git a/rust/tools/generate-api-catalog/src/ref_paths.rs b/rust/tools/generate-api-catalog/src/ref_paths.rs new file mode 100644 index 00000000..f52418ce --- /dev/null +++ b/rust/tools/generate-api-catalog/src/ref_paths.rs @@ -0,0 +1,295 @@ +//! Filesystem lookups used when resolving external `$ref` targets. + +use std::path::{Path, PathBuf}; + +use serde_json::Value; + +use crate::github::parse_yaml_or_json; + +pub(crate) fn specification_root(spec_dir: &Path) -> Option<&Path> { + let mut current = Some(spec_dir); + while let Some(path) = current { + if path.join("schemas").is_dir() { + return Some(path); + } + current = path.parent(); + } + None +} + +/// Rewrite an absolute-URL `$ref` that names a schema by its `$id` (e.g. the dated +/// `https://godaddy.com/schemas/ucp//...` URLs) into a reference to the file +/// that declares it, keeping any fragment. The URL does not mirror the file layout, +/// so the declaring file has to be found. Returns `None` for any other ref. +pub(crate) fn id_ref_to_file_ref(ref_str: &str, spec_dir: &Path) -> Option { + if !ref_str.starts_with("https://") { + return None; + } + let (id, fragment) = match ref_str.split_once('#') { + Some((id, fragment)) => (id, Some(fragment)), + None => (ref_str, None), + }; + let file = find_schema_by_id(&specification_root(spec_dir)?.join("schemas"), id)?; + Some(match fragment { + Some(fragment) => format!("{}#{fragment}", file.display()), + None => file.display().to_string(), + }) +} + +/// Find the JSON/YAML file under `dir` whose top-level `$id` is exactly `id`. +fn find_schema_by_id(dir: &Path, id: &str) -> Option { + let mut entries: Vec<_> = std::fs::read_dir(dir) + .ok()? + .filter_map(|e| e.ok()) + .collect(); + // Deterministic result if two files ever claim the same `$id`. + entries.sort_by_key(|e| e.file_name()); + for entry in entries { + let path = entry.path(); + // `file_type` does not follow symlinks, so a link cannot cause a cycle. + let Ok(file_type) = entry.file_type() else { + continue; + }; + if file_type.is_dir() { + if let Some(found) = find_schema_by_id(&path, id) { + return Some(found); + } + continue; + } + if !file_type.is_file() + || !matches!( + path.extension().and_then(|e| e.to_str()), + Some("json" | "yaml" | "yml") + ) + { + continue; + } + let Ok(src) = std::fs::read_to_string(&path) else { + continue; + }; + // Cheap prefilter before parsing. + if !src.contains(id) { + continue; + } + if let Ok(parsed) = parse_yaml_or_json(&src, &path) + && parsed.get("$id").and_then(Value::as_str) == Some(id) + { + return Some(path); + } + } + None +} + +/// Try to find `path` in its parent directory with a case-insensitive filename match. +/// Returns the first candidate whose lowercased name equals the lowercased target, +/// or `None` if no unique match is found. +pub(crate) fn resolve_case_insensitive(path: &Path) -> Option { + let dir = path.parent()?; + let target = path.file_name()?.to_string_lossy().to_lowercase(); + let mut matches: Vec = std::fs::read_dir(dir) + .ok()? + .filter_map(|e| e.ok()) + .filter(|e| e.file_name().to_string_lossy().to_lowercase() == target) + .map(|e| e.path()) + .collect(); + if matches.len() == 1 { + matches.pop() + } else { + None + } +} + +/// Normalize a path by resolving `.` and `..` components without hitting the filesystem. +pub(crate) fn normalize_path(path: &Path) -> PathBuf { + let mut out = PathBuf::new(); + for component in path.components() { + match component { + std::path::Component::ParentDir => { + out.pop(); + } + std::path::Component::CurDir => {} + c => out.push(c), + } + } + out +} + +/// When a path contains a `common-types` segment and does not exist, try to locate the +/// file in the standalone common-types-specification clone. Mirrors the TypeScript +/// `resolveCommonTypesFile` helper. +pub(crate) fn resolve_common_types_path( + path: &Path, + common_types_dir: Option<&Path>, +) -> Option { + let ct_dir = common_types_dir?; + let path_str = path.to_string_lossy(); + let ct_marker = "common-types/"; + let idx = path_str.find(ct_marker)?; + + let rel = &path_str[idx + ct_marker.len()..]; + // 1. Try path as-is relative to the clone root + let direct = ct_dir.join(rel); + if direct.exists() { + return Some(direct); + } + + // 2. Try v1/schemas/{yaml,json}/ (covering both extension variants) + let basename = path.file_name()?; + let basename_str = basename.to_string_lossy(); + let ext = path.extension().and_then(|e| e.to_str()).unwrap_or(""); + let (primary_sub, alt_sub, alt_ext) = if ext == "json" { + ("json", "yaml", "yaml") + } else { + ("yaml", "json", "json") + }; + + let nested = ct_dir + .join("v1") + .join("schemas") + .join(primary_sub) + .join(basename_str.as_ref()); + if nested.exists() { + return Some(nested); + } + let stem = path.file_stem()?.to_string_lossy(); + let alt_name = format!("{stem}.{alt_ext}"); + let alt = ct_dir + .join("v1") + .join("schemas") + .join(alt_sub) + .join(&alt_name); + if alt.exists() { + return Some(alt); + } + + None +} + +/// Whether another schema file under `dir` has the same file name as `file` but a +/// different top-level `$id`. `$defs` keys follow file names, so such files would +/// otherwise share one definition. Files without an `$id` are never reported: +/// same-named copies (e.g. a spec's `json/` and `yaml/` variants) are not known to differ. +pub(crate) fn has_conflicting_namesake(dir: &Path, file: &Path) -> bool { + fn schema_id(path: &Path) -> Option { + let src = std::fs::read_to_string(path).ok()?; + let parsed = parse_yaml_or_json(&src, path).ok()?; + parsed.get("$id")?.as_str().map(str::to_owned) + } + fn any_conflict(dir: &Path, file: &Path, id: &str) -> bool { + let Ok(entries) = std::fs::read_dir(dir) else { + return false; + }; + entries.filter_map(|e| e.ok()).any(|entry| { + let path = entry.path(); + match entry.file_type() { + Ok(t) if t.is_dir() => any_conflict(&path, file, id), + Ok(t) + if t.is_file() && entry.file_name() == file.file_name().unwrap_or_default() => + { + schema_id(&path).is_some_and(|other| other != id) + } + _ => false, + } + }) + } + schema_id(file).is_some_and(|id| any_conflict(dir, file, &id)) +} + +#[cfg(test)] +mod tests { + use std::fs; + + use crate::dereference::{ + collect_unresolved_refs, load_and_dereference, + load_and_dereference_distinguishing_namesakes, + }; + + #[test] + fn dereference_resolves_absolute_url_ref_by_schema_id() { + // The URL does not mirror the file layout: the file is found by its `$id`. + let dir = tempfile::tempdir().expect("tempdir"); + let schemas_dir = dir.path().join("schemas"); + let model_dir = schemas_dir.join("models"); + fs::create_dir_all(&model_dir).expect("create model dir"); + + let id = "https://example.com/schemas/2026-01-01/shopping/widget.json"; + fs::write( + model_dir.join("widget.schema.json"), + format!( + r#"{{"$id": "{id}", "$defs": {{"size": {{"type": "integer"}}}}, "type": "object"}}"# + ), + ) + .expect("write model"); + + let spec_path = schemas_dir.join("openapi.yaml"); + fs::write( + &spec_path, + format!( + "openapi: '3.0.0'\ncomponents:\n schemas:\n Widget:\n $ref: '{id}'\n Size:\n $ref: '{id}#/$defs/size'\n" + ), + ) + .expect("write spec"); + + let (result, defs) = load_and_dereference(&spec_path, None).expect("dereference"); + let unresolved = collect_unresolved_refs(&result); + assert!( + unresolved.is_empty(), + "expected zero unresolved $refs, got: {unresolved:?}" + ); + assert_eq!(defs["widget_schema"]["type"], "object"); + assert_eq!(defs["widget_schema_size"]["type"], "integer"); + } + + #[test] + fn dereference_keeps_same_named_files_in_different_directories_apart() { + let dir = tempfile::tempdir().expect("tempdir"); + let schemas_dir = dir.path().join("schemas"); + for (sub, field) in [("product", "category"), ("variant", "default")] { + let sub_dir = schemas_dir.join("models").join(sub); + fs::create_dir_all(&sub_dir).expect("create dir"); + fs::write( + sub_dir.join("base.schema.json"), + format!( + r#"{{"$id": "https://example.com/{sub}/base.json", "type": "object", "properties": {{"{field}": {{"type": "string"}}}}}}"# + ), + ) + .expect("write model"); + } + let spec_path = schemas_dir.join("openapi.yaml"); + fs::write( + &spec_path, + "openapi: '3.0.0'\ncomponents:\n schemas:\n P:\n $ref: 'https://example.com/product/base.json'\n V:\n $ref: 'https://example.com/variant/base.json'\n", + ) + .expect("write spec"); + + let (_result, defs) = + load_and_dereference_distinguishing_namesakes(&spec_path, None).expect("dereference"); + assert!(defs["product_base_schema"]["properties"]["category"].is_object()); + assert!(defs["variant_base_schema"]["properties"]["default"].is_object()); + + // The default entry point keeps file-name keys, so specs already generated + // that way are not renamed. + let (_result, defs) = load_and_dereference(&spec_path, None).expect("dereference"); + assert!(defs.contains_key("base_schema")); + assert!(!defs.contains_key("product_base_schema")); + } + + #[test] + fn dereference_leaves_absolute_url_ref_without_matching_id_unresolved() { + let dir = tempfile::tempdir().expect("tempdir"); + let schemas_dir = dir.path().join("schemas"); + fs::create_dir_all(&schemas_dir).expect("create schemas dir"); + let spec_path = schemas_dir.join("openapi.yaml"); + fs::write( + &spec_path, + "openapi: '3.0.0'\ncomponents:\n schemas:\n Widget:\n $ref: 'https://example.com/missing.json'\n", + ) + .expect("write spec"); + + let (result, _defs) = load_and_dereference(&spec_path, None).expect("dereference"); + assert_eq!( + collect_unresolved_refs(&result), + vec!["https://example.com/missing.json".to_owned()] + ); + } +} diff --git a/rust/tools/generate-api-catalog/src/shopping_spec.rs b/rust/tools/generate-api-catalog/src/shopping_spec.rs index 74507686..6e3e265e 100644 --- a/rust/tools/generate-api-catalog/src/shopping_spec.rs +++ b/rust/tools/generate-api-catalog/src/shopping_spec.rs @@ -21,13 +21,14 @@ pub(crate) fn refresh( common_types: Option<&Path>, out_path: &Path, ) -> Result<()> { - let (mut spec, defs) = crate::dereference::load_and_dereference(spec_path, common_types) - .with_context(|| { - format!( - "failed to dereference Shopping spec {}", - spec_path.display() - ) - })?; + let (mut spec, defs) = + crate::dereference::load_and_dereference_distinguishing_namesakes(spec_path, common_types) + .with_context(|| { + format!( + "failed to dereference Shopping spec {}", + spec_path.display() + ) + })?; let object = spec .as_object_mut() .context("Shopping spec is not a JSON object")?; @@ -44,9 +45,13 @@ pub(crate) fn refresh( schemas.insert(name, definition); } crate::spec_normalize::rewrite_defs_refs(&mut spec); - crate::spec_normalize::remove_remaining_relative_refs(&mut spec); + ensure_refs_resolved(&spec)?; crate::spec_normalize::remove_self_referencing_schemas(&mut spec); - dealias_name_colliding_schemas( + + // `get_product_response` is a bare `$ref` alias whose derived Rust name + // (`GetProductResponse`) collides with the name progenitor gives the + // `get_product` operation's `oneOf` response enum. + repoint_schema_refs( &mut spec, &[( "get_product_response", @@ -68,7 +73,6 @@ pub(crate) fn refresh( relax_response_schemas(&mut spec); preserve_dynamic_ucp_response_metadata(&mut spec)?; preserve_payment_instrument_fields(&mut spec)?; - add_completion_consent(&mut spec)?; add_idempotency_headers(&mut spec)?; prune_documentation_fields(&mut spec); crate::spec_normalize::add_required_response_descriptions(&mut spec); @@ -82,18 +86,20 @@ pub(crate) fn refresh( Ok(()) } -/// Progenitor names an operation's `oneOf` response enum from its -/// `operationId` (`get_product` -> `GetProductResponse`), independently of -/// how it names the schema-alias newtype it generates for a bare `$ref` -/// schema (`get_product_response` -> `GetProductResponse`). When those two -/// derived names collide, progenitor silently reuses the schema newtype as -/// the operation's response type instead of generating the `oneOf` enum, -/// so the `error_response` branch has no Rust variant to match against at -/// all — unlike every other operation in this contract, whose schema and -/// operationId names differ enough not to collide. Point every reference -/// to `alias` directly at what it aliases and drop the now-unreferenced -/// alias schema, freeing its derived name for the operation's own enum. -fn dealias_name_colliding_schemas(spec: &mut Value, aliases: &[(&str, &str)]) { +/// Fails if any `$ref` still points outside the document, so a missing or moved +/// schema file stops the refresh instead of leaving a weakened type behind. +fn ensure_refs_resolved(spec: &Value) -> Result<()> { + let unresolved = crate::dereference::collect_unresolved_refs(spec); + anyhow::ensure!( + unresolved.is_empty(), + "Shopping spec has unresolved external $refs: {unresolved:?}" + ); + Ok(()) +} + +/// Rewrites every `$ref` to each `alias` schema so it points at its `target`, then +/// removes the `alias` from `components.schemas`. +fn repoint_schema_refs(spec: &mut Value, aliases: &[(&str, &str)]) { for (alias, target) in aliases { let from = format!("#/components/schemas/{alias}"); let to = format!("#/components/schemas/{target}"); @@ -207,65 +213,6 @@ fn preserve_payment_instrument_fields(spec: &mut Value) -> Result<()> { Ok(()) } -fn add_completion_consent(spec: &mut Value) -> Result<()> { - let schemas = spec - .get_mut("components") - .and_then(|components| components.get_mut("schemas")) - .and_then(Value::as_object_mut) - .context("Shopping component schemas are missing")?; - - schemas.insert( - "shopping_consent_acceptance".to_owned(), - serde_json::json!({ - "type": "object", - "properties": { - "agreement_types": { - "type": "array", - "items": {"type": "string"} - }, - "agreed_at": {"type": "string"} - } - }), - ); - schemas.insert( - "shopping_required_agreement".to_owned(), - serde_json::json!({ - "type": "object", - "properties": { - "key": {"type": "string"}, - "title": {"type": "string"}, - "url": {"type": "string"}, - "content": {"type": "string"}, - "required": {"type": "boolean"} - } - }), - ); - - let completion_properties = schemas - .get_mut("checkout-complete-request_schema") - .and_then(|schema| schema.get_mut("properties")) - .and_then(Value::as_object_mut) - .context("Shopping completion request properties are missing")?; - completion_properties.insert( - "consent".to_owned(), - serde_json::json!({"$ref": "#/components/schemas/shopping_consent_acceptance"}), - ); - - let checkout_properties = schemas - .get_mut("checkout") - .and_then(|schema| schema.get_mut("properties")) - .and_then(Value::as_object_mut) - .context("Shopping checkout response properties are missing")?; - checkout_properties.insert( - "required_agreements".to_owned(), - serde_json::json!({ - "type": "array", - "items": {"$ref": "#/components/schemas/shopping_required_agreement"} - }), - ); - Ok(()) -} - fn add_idempotency_headers(spec: &mut Value) -> Result<()> { let paths = spec .get_mut("paths") @@ -367,6 +314,17 @@ fn relax_response_schemas(spec: &mut Value) { } } +/// Relaxes each property's schema without touching the `properties` map itself: its +/// keys are field names, so a field that happens to be called `required`, `format` or +/// `pattern` must survive. +fn relax_property_schemas(properties: &mut Value) { + if let Value::Object(map) = properties { + for schema in map.values_mut() { + relax(schema); + } + } +} + fn relax(value: &mut Value) { match value { Value::Object(map) => { @@ -385,8 +343,30 @@ fn relax(value: &mut Value) { map.remove("type"); } } - for child in map.values_mut() { - relax(child); + for (key, child) in map.iter_mut() { + if key == "properties" { + relax_property_schemas(child); + } else { + relax(child); + } + } + // "One of these fields is required" is written as an `anyOf`/`oneOf` of + // `required`-only branches. With `required` stripped every branch is an + // empty schema, and progenitor turns that into a pair of redundant + // flattened sub-structs, so drop the combinator. + for combinator in ["anyOf", "oneOf"] { + let all_empty = + map.get(combinator) + .and_then(Value::as_array) + .is_some_and(|branches| { + !branches.is_empty() + && branches + .iter() + .all(|branch| branch.as_object().is_some_and(|b| b.is_empty())) + }); + if all_empty { + map.remove(combinator); + } } } Value::Array(values) => { @@ -403,10 +383,77 @@ mod tests { use serde_json::json; use super::{ - dealias_name_colliding_schemas, preserve_payment_instrument_fields, - prune_documentation_fields, + ensure_refs_resolved, preserve_payment_instrument_fields, prune_documentation_fields, + relax, repoint_schema_refs, }; + #[test] + fn relaxing_drops_the_required_keyword_but_keeps_properties_named_like_keywords() { + let mut schema = json!({ + "type": "object", + "required": ["key", "required"], + "properties": { + "key": {"type": "string", "format": "uri", "pattern": "^a"}, + "required": {"type": "boolean"}, + "format": {"type": "string"}, + "pattern": {"type": "string"} + } + }); + + relax(&mut schema); + + assert!(schema.get("required").is_none(), "{schema}"); + assert_eq!( + schema["properties"]["key"], + json!({"type": "string"}), + "keyword-level format/pattern are still dropped" + ); + for name in ["required", "format", "pattern"] { + assert!( + schema["properties"].get(name).is_some(), + "property {name:?} was removed: {schema}" + ); + } + } + + #[test] + fn relaxing_drops_combinators_that_only_expressed_which_field_is_required() { + let mut schema = json!({ + "type": "object", + "properties": {"url": {"type": "string"}, "content": {"type": "string"}}, + "anyOf": [{"required": ["url"]}, {"required": ["content"]}] + }); + + relax(&mut schema); + + assert!(schema.get("anyOf").is_none(), "{schema}"); + assert!(schema["properties"].get("url").is_some(), "{schema}"); + + // A combinator whose branches carry real schemas is left alone. + let mut response = json!({ + "oneOf": [ + {"$ref": "#/components/schemas/checkout"}, + {"$ref": "#/components/schemas/error_response"} + ] + }); + let expected = response.clone(); + relax(&mut response); + assert_eq!(response, expected); + } + + #[test] + fn unresolved_refs_fail_the_refresh_instead_of_being_dropped() { + let relative = json!({"components": {"schemas": {"a": {"$ref": "./models/Missing.yaml"}}}}); + let error = ensure_refs_resolved(&relative).expect_err("relative ref is unresolved"); + assert!(error.to_string().contains("Missing.yaml"), "{error}"); + + let absolute = json!({"a": {"$ref": "https://example.com/missing.json"}}); + assert!(ensure_refs_resolved(&absolute).is_err()); + + let local = json!({"a": {"$ref": "#/components/schemas/b"}, "b": {"type": "string"}}); + assert!(ensure_refs_resolved(&local).is_ok()); + } + #[test] fn pruning_removes_documentation_and_examples_recursively() { let mut spec = json!({ @@ -541,7 +588,7 @@ mod tests { } #[test] - fn dealiasing_points_references_at_the_target_and_drops_the_alias_schema() { + fn repointing_points_references_at_the_target_and_drops_the_alias_schema() { let mut spec = json!({ "components": { "schemas": { @@ -571,7 +618,7 @@ mod tests { } }); - dealias_name_colliding_schemas( + repoint_schema_refs( &mut spec, &[( "get_product_response",