From e92202f2afa6d49a14d4475d7dda6ef6a6d92bcd Mon Sep 17 00:00:00 2001 From: Jacob Page Date: Tue, 3 Nov 2026 13:57:30 -0800 Subject: [PATCH 1/4] fix(api-catalog): resync spec drift with the latest App Registry, Customer Profiles, Domains, Hosting and Orders APIs Refreshes the embedded API catalog and the Domains, Hosting and platform app codegen specs so `gddy api` reflects the current upstream definitions: - App Registry: new operations to list, create and revoke OAuth client secrets - Customer Profiles: `deleteMetafields` is replaced by `removeMetafieldsFromCustomer` and `upsertCustomerMetafields` - Domains 3.7.0 and Hosting 1.1.0: documentation updates only; no new commands or endpoints - Orders 1.12.0: money fields use the new positive-money type Also documents how to resolve a failing API catalog drift check in the maintainers guide, with a pointer from CONTRIBUTING.md. Co-Authored-By: Claude Sonnet 5.5 --- CONTRIBUTING.md | 4 +- docs/maintainers.md | 19 ++ rust/domains-client/openapi/domains.oas3.json | 34 +++- rust/hosting-client/openapi/hosting.oas3.json | 2 +- .../graphql/schema.graphql | 106 +++++++++- rust/schemas/api/app-registry.json | 192 +++++++++++++++++- rust/schemas/api/customer-profiles.json | 186 +++++++++++------ rust/schemas/api/domains.json | 4 +- rust/schemas/api/hosting.json | 70 +++---- rust/schemas/api/manifest.json | 2 +- rust/schemas/api/orders.json | 111 +++++----- 11 files changed, 565 insertions(+), 165 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9aee0645..71aa9704 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -81,10 +81,12 @@ cargo fmt # Type-check only (fast) cargo check -# Regenerate the embedded API catalog +# Regenerate the embedded API catalog (needs access to GoDaddy's internal spec repos) cargo run -p generate-api-catalog ``` +If the CI "API catalog drift" check fails, see [Updating embedded API specs](docs/maintainers.md#updating-embedded-api-specs). + Adding a pre-release command, or wondering why one is hidden behind the default build? See [`docs/feature-flags.md`](docs/feature-flags.md). ## Code Review diff --git a/docs/maintainers.md b/docs/maintainers.md index bc417236..83073a6e 100644 --- a/docs/maintainers.md +++ b/docs/maintainers.md @@ -10,6 +10,7 @@ If you are a new developer on this project, read the following to get started: - [This repo's docs](../docs/) - [Command authoring checklist](./command-authoring.md) covers conventions for adding commands and command groups. - [`CONTRIBUTING.md`](../CONTRIBUTING.md) gives some general tips for setting up your workspace for development. +- [Updating embedded API specs](#updating-embedded-api-specs) explains how to resolve a failing API catalog drift check. If you are doing agentic coding and see your agent struggling with following standards correctly, contributions to [`AGENTS.md`](../AGENTS.md) are greatly appreciated. @@ -52,3 +53,21 @@ To update this file: 1. Edit [`reviewers.json`](../.github/scripts/reviewers.json) to add per-product paths, reviewer GitHub usernames, or new per-product config sections. Sort entries alphabetically so it's easy to navigate. 2. Run `bash .github/scripts/generate-codeowners.sh` to regenerate the file from that configuration (it uses Bash-only features, so plain `sh` fails on some systems). + +## Updating embedded API specs + +The CLI embeds a catalog of upstream API specs (browsable with `gddy api ...`) and generates some typed clients from them. The [API catalog drift](../.github/workflows/catalog-drift.yml) workflow regenerates everything weekly and on every push to `main`, and fails when the committed copy is stale. To fix a failure: + +1. Get a token that can read the spec repositories in the `gdcorp-platform` org. `gh auth token` works if your account has access; CI uses a read-only GitHub App instead. +1. From `rust/`, run `GITHUB_TOKEN= cargo run -p generate-api-catalog`. Which specs are pulled is configured in [`api-catalog-sources.json`](../rust/api-catalog-sources.json). +1. Review the diff. The generator rewrites these paths, which are exactly what the workflow compares: + - [`rust/schemas/api/`](../rust/schemas/api) — the embedded catalog. `manifest.json` carries a generated-at timestamp that changes on every run; the workflow ignores it, so a timestamp-only change is not drift. + - `rust/domains-client/openapi/domains.oas3.json` and `rust/hosting-client/openapi/hosting.oas3.json` — inputs to the generated clients. + - `rust/platform-app-client/graphql/schema.graphql` — input to the platform app client. +1. Run the checks in [`AGENTS.md`](../AGENTS.md#verification-checklist-required-before-finishing-work). Generated clients are rebuilt from the updated specs, so an upstream breaking change shows up as a compile error or test failure here; fix the affected commands in the same PR. +1. Commit the result as `fix(api-catalog): resync spec drift with ...` and name the APIs that changed (see [#321](https://github.com/godaddy/cli/pull/321)), since the commit title is surfaced in release notes. + +Notes: + +- The domains v1 `agreements` spec comes from a public endpoint and is best-effort: if the fetch fails, the generator logs a warning and leaves `domains.oas3.json` untouched. Set `SKIP_DOMAINS_REFRESH` to skip that fetch deliberately, for example when working offline. Don't commit with it set unless you mean to leave that file alone. +- Operations the upstream spec marks `x-visibility: private` are intentionally dropped from the catalog, so they will not appear after a refresh. diff --git a/rust/domains-client/openapi/domains.oas3.json b/rust/domains-client/openapi/domains.oas3.json index 95e12f50..f95f31b6 100644 --- a/rust/domains-client/openapi/domains.oas3.json +++ b/rust/domains-client/openapi/domains.oas3.json @@ -23,6 +23,17 @@ } }, "parameters": { + "allowNameserverChange": { + "description": "Consent to move the whole domain to GoDaddy's nameservers when it does not already use them; forwarding only works on GoDaddy nameservers. Without it, such a request fails with 409 NAMESERVER_CHANGE_REQUIRED; it has no other effect on a domain already on GoDaddy nameservers. The domain then gets a GoDaddy DNS zone with only default records, so records from the previous DNS provider, such as MX for email, are lost. The change propagates asynchronously (watch nameServers on GET /domain-names/{domain-name}) and is not undone when the forwarding is deleted. Callers who set it to true must also hold domains.nameserver:update, whatever the domain's nameservers; without it the request fails with 403.\n", + "example": true, + "in": "query", + "name": "allowNameserverChange", + "required": false, + "schema": { + "default": false, + "type": "boolean" + } + }, "domainNamePath": { "description": "The domain name in punycode A-label form (e.g., example.com). For IDNs, use the punycode representation.\n", "example": "example.com", @@ -43,6 +54,16 @@ "type": "string" } }, + "fqdnPath": { + "description": "The forwarded name in punycode A-label form: the domain itself (example.com), one of its subdomains (shop.example.com), or a wildcard directly on the domain (*.example.com), without a trailing dot. Matched case-insensitively.\n", + "example": "shop.example.com", + "in": "path", + "name": "fqdn", + "required": true, + "schema": { + "type": "string" + } + }, "idempotencyKey": { "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", @@ -2143,16 +2164,17 @@ }, "securitySchemes": { "oauth2": { - "description": "GoDaddy OAuth 2.0 access token. The scope(s) listed on each operation are enforced per-operation. A token requires at least one of the scopes listed for that operation.\n", + "description": "GoDaddy OAuth 2.0 access token. The scope(s) listed on each operation are enforced per-operation. A token requires at least one of the scopes listed for that operation. Some parameters require an additional scope; this is stated on the parameter and on the operation's 403 response.\n", "flows": { "authorizationCode": { "authorizationUrl": "https://api.godaddy.com/v2/oauth2/authorize", "scopes": { "domains.dns:update": "Create, update, and delete DNS zone records.\n", "domains.domain:create": "Register domains. Requires a prior quoteToken.\n", - "domains.domain:read": "Read domain records, availability, suggestions, quotes, and operations.\n", - "domains.domain:update": "Update domain-level properties such as auto-renew, transfer-lock settings, and renewing owned domains. Requires a prior quoteToken for renewal. This scope covers mutations to the domain resource itself; use resource-specific scopes for nameservers (domains.nameserver:update) and DNS records (domains.dns:update).\n", - "domains.nameserver:update": "Manage authoritative nameservers for a domain, including setting custom nameservers and resetting to registry defaults.\n", + "domains.domain:read": "Read domain records, availability, suggestions, quotes, operations, and forwarding.\n", + "domains.domain:update": "Update domain-level properties such as auto-renew, transfer-lock settings, and renewing owned domains. Requires a prior quoteToken for renewal. This scope covers mutations to the domain resource itself; use resource-specific scopes for nameservers (domains.nameserver:update), DNS records (domains.dns:update), and forwarding (domains.forwarding:update).\n", + "domains.forwarding:update": "Create, replace, and delete forwarding for a domain and its subdomains. Setting allowNameserverChange=true, which moves the domain to GoDaddy nameservers, also requires domains.nameserver:update.\n", + "domains.nameserver:update": "Manage authoritative nameservers for a domain, including setting custom nameservers and resetting to registry defaults. Also required to create or replace forwarding with allowNameserverChange=true, which moves the domain to GoDaddy nameservers.\n", "domains.registration-profile:create": "Create saved registration profiles.\n", "domains.registration-profile:delete": "Delete saved registration profiles.\n", "domains.registration-profile:read": "Read saved registration profiles, including the contact records stored on them.\n" @@ -2165,9 +2187,9 @@ } }, "info": { - "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", + "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, except DNS records\nand forwarding, which are applied synchronously.\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`,\n`forwards`) only exist in the context of a specific domain-name instance.\nThe `/check-availability` controller accepts GET (single domain) or POST\n(1–25 domains) and carries no persistent 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.5.0", + "version": "3.7.0", "x-visibility": { "extent": "public" } diff --git a/rust/hosting-client/openapi/hosting.oas3.json b/rust/hosting-client/openapi/hosting.oas3.json index 12181ffe..1b35fd65 100644 --- a/rust/hosting-client/openapi/hosting.oas3.json +++ b/rust/hosting-client/openapi/hosting.oas3.json @@ -1280,7 +1280,7 @@ "url": "https://www.godaddy.com/legal/agreements/software-license-agreement" }, "title": "Hosted Application Lifecycle Management API", - "version": "1.0.0" + "version": "1.1.0" }, "openapi": "3.0.3", "paths": { diff --git a/rust/platform-app-client/graphql/schema.graphql b/rust/platform-app-client/graphql/schema.graphql index 52e83924..b35c13c8 100644 --- a/rust/platform-app-client/graphql/schema.graphql +++ b/rust/platform-app-client/graphql/schema.graphql @@ -778,6 +778,37 @@ type CreateMediaUploadUrlResponse { uploadUrl: String! } +""" +Result of creating an OAuth client secret. Includes the secret value once; store it immediately — it cannot be retrieved again. +""" +type CreatedOauthClientSecret { + """OAuth client id this secret belongs to, or null when unknown.""" + clientId: String + + """Description of the secret, or null when unknown.""" + clientSecretDescription: String + + """Id of this secret (used to revoke).""" + clientSecretId: String! + + """Display name of the secret, or null when unknown.""" + clientSecretName: String + + """ + The secret value, returned only on create. Store it immediately — it cannot be retrieved again. + """ + clientSecretValue: String! + + """When this secret was created (ISO-8601), or null when unknown.""" + createdAt: String + + """When this secret was revoked (ISO-8601), or null if still active.""" + deletedAt: String + + """When this secret expires (ISO-8601), or null when unknown.""" + expiresOn: String +} + """A date-time string in ISO 8601 format (e.g. 2022-01-01T00:00:00Z).""" scalar DateTime @@ -935,7 +966,7 @@ type GenerateReleaseUploadUrlResponse { } """A JSON object scalar type.""" -scalar JSONObject +scalar JSONObject @specifiedBy(url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf") """Allowed MIME types for listing media uploads.""" enum ListingMediaContentType { @@ -1028,6 +1059,15 @@ type Mutation { """Create a new Application.""" createApplication(input: MutationCreateApplicationInput!): Application + """ + Create an additional OAuth client secret on the application's primary OAuth client. Returns the secret value once. Fails when the active-secret limit is reached. + """ + createApplicationOauthClientSecret( + """The application to create a secret for.""" + applicationId: String! + input: MutationCreateApplicationOauthClientSecretInput! + ): CreatedOauthClientSecret + """ Create a pending listing media record and return a pre-signed S3 PUT URL. """ @@ -1111,6 +1151,15 @@ type Mutation { mediaObjectId: ID! ): MediaObject + """ + Revoke one OAuth client secret on the application's primary OAuth client. Cannot revoke the last active secret — create another first. + """ + revokeApplicationOauthClientSecret( + """The application whose secret to revoke.""" + applicationId: String! + input: MutationRevokeApplicationOauthClientSecretInput! + ): RevokedOauthClientSecret + """ Create or update the listing for an application. Idempotent — safe to call multiple times for the same application. """ @@ -1165,6 +1214,14 @@ input MutationCreateApplicationInput { url: String } +input MutationCreateApplicationOauthClientSecretInput { + """Description for the new secret. Cannot be blank.""" + clientSecretDescription: String! + + """Display name for the new secret.""" + clientSecretName: String! +} + input MutationCreateReleaseInput { """The actions associated with the release.""" actions: [ApplicationActionCreateInput!] @@ -1248,6 +1305,11 @@ input MutationGenerateReleaseUploadUrlInput { target: String } +input MutationRevokeApplicationOauthClientSecretInput { + """Id of the secret to revoke.""" + clientSecretId: String! +} + input MutationUpdateApplicationInput { """ The authorization scopes of the application. Defines the GoDaddy permissions for the application. @@ -1293,6 +1355,32 @@ enum NativeExtensionPlatform { """Represents a null value.""" scalar Null +""" +Metadata for one OAuth client secret on an application's primary OAuth client. Secret values are never included. +""" +type OauthClientSecret { + """OAuth client id this secret belongs to, or null when unknown.""" + clientId: String + + """Description of the secret, or null when unknown.""" + clientSecretDescription: String + + """Id of this secret (used to revoke).""" + clientSecretId: String! + + """Display name of the secret, or null when unknown.""" + clientSecretName: String + + """When this secret was created (ISO-8601), or null when unknown.""" + createdAt: String + + """When this secret was revoked (ISO-8601), or null if still active.""" + deletedAt: String + + """When this secret expires (ISO-8601), or null when unknown.""" + expiresOn: String +} + """Direction for ordering results in queries.""" enum OrderByDirectionEnum { """Sort in ascending order.""" @@ -1323,7 +1411,7 @@ type Query { ): Application """ - Paginated listings. Defaults to publicly LISTED listings for active PUBLIC-distribution apps. Pass visibility filter to query owner/admin contexts. + Paginated listings. Defaults to publicly LISTED listings for active PUBLIC-distribution apps with an active release. Pass visibility filter to query owner/admin contexts. """ applicationListings( after: String @@ -1335,6 +1423,14 @@ type Query { last: Int ): QueryApplicationListingsConnection + """ + List OAuth client secrets (metadata only) for an application's primary OAuth client. Requires application write access. + """ + applicationOauthClientSecrets( + """The application whose primary OAuth client secrets to list.""" + applicationId: String! + ): [OauthClientSecret!]! + """ Get paginated applications. Returns all public applications for service requests, or only applications owned by the authenticated customer's organization. Multi-org users may pass an explicit `organizationId` to select which organization's apps to list. """ @@ -1595,6 +1691,12 @@ enum ReleaseUploadStatus { UPLOADED } +"""Result of revoking an OAuth client secret.""" +type RevokedOauthClientSecret { + """Id of the revoked secret.""" + clientSecretId: String! +} + """Filter for fields that are lists/sets of strings.""" input StringListFilter { """Field must contain this value.""" diff --git a/rust/schemas/api/app-registry.json b/rust/schemas/api/app-registry.json index 39698ea0..bf7d204f 100644 --- a/rust/schemas/api/app-registry.json +++ b/rust/schemas/api/app-registry.json @@ -1,11 +1,11 @@ { "baseUrl": "https://api.godaddy.com", - "description": "GraphQL API with 28 operations", + "description": "GraphQL API with 31 operations", "endpoints": [ { - "description": "GraphQL endpoint with 28 operations", + "description": "GraphQL endpoint with 31 operations", "graphql": { - "operationCount": 28, + "operationCount": 31, "operations": [ { "args": [ @@ -64,11 +64,26 @@ } ], "deprecated": false, - "description": "Paginated listings. Defaults to publicly LISTED listings for active PUBLIC-distribution apps. Pass visibility filter to query owner/admin contexts.", + "description": "Paginated listings. Defaults to publicly LISTED listings for active PUBLIC-distribution apps with an active release. Pass visibility filter to query owner/admin contexts.", "kind": "query", "name": "applicationListings", "returnType": "QueryApplicationListingsConnection" }, + { + "args": [ + { + "description": "The application whose primary OAuth client secrets to list.", + "name": "applicationId", + "required": true, + "type": "String!" + } + ], + "deprecated": false, + "description": "List OAuth client secrets (metadata only) for an application's primary OAuth client. Requires application write access.", + "kind": "query", + "name": "applicationOauthClientSecrets", + "returnType": "[OauthClientSecret!]!" + }, { "args": [ { @@ -429,6 +444,26 @@ "name": "createApplication", "returnType": "Application" }, + { + "args": [ + { + "description": "The application to create a secret for.", + "name": "applicationId", + "required": true, + "type": "String!" + }, + { + "name": "input", + "required": true, + "type": "MutationCreateApplicationOauthClientSecretInput!" + } + ], + "deprecated": false, + "description": "Create an additional OAuth client secret on the application's primary OAuth client. Returns the secret value once. Fails when the active-secret limit is reached.", + "kind": "mutation", + "name": "createApplicationOauthClientSecret", + "returnType": "CreatedOauthClientSecret" + }, { "args": [ { @@ -630,6 +665,26 @@ "name": "removeListingMediaObject", "returnType": "MediaObject" }, + { + "args": [ + { + "description": "The application whose secret to revoke.", + "name": "applicationId", + "required": true, + "type": "String!" + }, + { + "name": "input", + "required": true, + "type": "MutationRevokeApplicationOauthClientSecretInput!" + } + ], + "deprecated": false, + "description": "Revoke one OAuth client secret on the application's primary OAuth client. Cannot revoke the last active secret — create another first.", + "kind": "mutation", + "name": "revokeApplicationOauthClientSecret", + "returnType": "RevokedOauthClientSecret" + }, { "args": [ { @@ -672,7 +727,7 @@ } ], "schemaRef": "./schema.graphql", - "sdl": "type Application {\n \"\"\"The timestamp of when the Application was activated.\"\"\"\n activatedAt: DateTime\n\n \"\"\"The timestamp of when the Application was archived.\"\"\"\n archivedAt: DateTime\n\n \"\"\"\n The authorization scopes that the OAuth2 client has access to and will use to call API endpoints.\n \"\"\"\n authorizationScopes: [String!]!\n\n \"\"\"\n Earliest linked OAuth client ID for this application by createdAt then id (includes NULL-secret and ARCHIVED apps).\n \"\"\"\n clientId: ID\n\n \"\"\"\n The primary OAuth client secret for this application. Only returned on application creation.\n \"\"\"\n clientSecret: String\n\n \"\"\"The timestamp of when the Application was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The timestamp of when the Application was deactivated.\"\"\"\n deactivatedAt: DateTime\n\n \"\"\"General information about your application.\"\"\"\n description: String\n\n \"\"\"The distribution type for this application.\"\"\"\n distributionType: DistributionType!\n\n \"\"\"The globally-unique ID of the Application.\"\"\"\n id: ID!\n\n \"\"\"A human-readable label of the Application for display purposes.\"\"\"\n label: String!\n\n \"\"\"\n Paginated listings for this application. Requires read scope. When using the filter, `applicationIds` is ignored — results are always scoped to this application.\n \"\"\"\n listings(\n after: String\n before: String\n\n \"\"\"Optional filter for the listings.\"\"\"\n filter: ApplicationListingFilterInput\n first: Int\n last: Int\n ): ApplicationListingsConnection\n\n \"\"\"A url-friendly name for the Application.\"\"\"\n name: String!\n\n \"\"\"The ID of the organization that owns this Application.\"\"\"\n organizationId: ID!\n\n \"\"\"\n The base URL of your application. This is the endpoint that the GoDaddy Commerce platform will call when integrated with actions.\n \"\"\"\n proxyUrl: String\n\n \"\"\"\n The public key (base64 encoded) for verifying action requests to your application.\n \"\"\"\n publicKey: String\n\n \"\"\"\n Additional OAuth redirect URIs on the application's OAuth client(s). URL-derived defaults (the application URL and {url}/api/godaddy/callback) are omitted so this list can be submitted unchanged on create or update.\n \"\"\"\n redirectUris: [String!]!\n\n \"\"\"The releases of the Application.\"\"\"\n releases(\n after: String\n before: String\n first: Int\n last: Int\n\n \"\"\"The order in which to sort the releases.\"\"\"\n orderBy: ReleaseOrderBy\n\n \"\"\"Filter by release status.\"\"\"\n status: ReleaseStatusFilter\n ): ApplicationReleasesConnection\n\n \"\"\"\n The secret for verifying webhook requests to your application. Copy and secure this secret. You will not see it again.\n \"\"\"\n secret: String\n\n \"\"\"The status of the application.\"\"\"\n status: ApplicationStatus!\n\n \"\"\"The timestamp of when the Application was updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The public website of the application.\"\"\"\n url: String\n}\n\n\"\"\"An action that can be executed by an application within the platform.\"\"\"\ntype ApplicationAction {\n \"\"\"The timestamp of when the action was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the action.\"\"\"\n id: String!\n\n \"\"\"A unique identifier for the action within the application.\"\"\"\n name: String!\n\n \"\"\"The timestamp of when the action was last updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The endpoint URL that will be called when this action is triggered.\"\"\"\n url: String!\n}\n\n\"\"\"Input for creating a new application action.\"\"\"\ninput ApplicationActionCreateInput {\n \"\"\"A unique identifier for the action within the application.\"\"\"\n name: String!\n\n \"\"\"\n The path of the endpoint URL that will be called when this action is triggered.\n \"\"\"\n url: String!\n}\n\n\"\"\"\nA dependency an application release declares on another application (the application's id, the name it was declared under, and its required/excluded/enabled state).\n\"\"\"\ntype ApplicationDependency {\n \"\"\"\n The immutable id of the application depended upon. Unaffected by renames of that application.\n \"\"\"\n applicationId: ID!\n\n \"\"\"\n The application name this dependency was declared under. A record of what was declared, not a live reference — it is not rewritten when the depended-upon application is renamed, so it can differ from that application's current name. Use `applicationId` to identify the application.\n \"\"\"\n name: String!\n\n \"\"\"The declared state for this application dependency.\"\"\"\n state: ApplicationDependencyState!\n}\n\n\"\"\"\nInput for declaring a dependency on another application from a release.\n\"\"\"\ninput ApplicationDependencyInput {\n \"\"\"\n The name of the application depended upon. Must match a non-archived application.\n \"\"\"\n name: String!\n\n \"\"\"The declared state for this application dependency.\"\"\"\n state: ApplicationDependencyState!\n}\n\n\"\"\"The state of an application dependency declaration.\"\"\"\nenum ApplicationDependencyState {\n \"\"\"\n The dependency application is enabled by default but can be overridden.\n \"\"\"\n ENABLED\n\n \"\"\"\n The dependency application is excluded and must not be enabled alongside this release.\n \"\"\"\n EXCLUDED\n\n \"\"\"\n The dependency application is required and cannot be disabled while this release is live.\n \"\"\"\n REQUIRED\n}\n\n\"\"\"\nAn enablement represents an application installed for a specific entity (e.g. a store).\n\"\"\"\ntype ApplicationEnablement {\n \"\"\"When the enablement was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"When the application was disabled.\"\"\"\n disabledAt: DateTime\n\n \"\"\"When the application was enabled.\"\"\"\n enabledAt: DateTime\n\n \"\"\"The ID of the entity this application is enabled for.\"\"\"\n entityId: String!\n\n \"\"\"The type of entity (e.g. STORE).\"\"\"\n entityType: String!\n\n \"\"\"The globally-unique ID of the enablement.\"\"\"\n id: String!\n\n \"\"\"When the enablement was last updated.\"\"\"\n updatedAt: DateTime!\n}\n\n\"\"\"A listing for an application.\"\"\"\ntype ApplicationListing {\n \"\"\"The ID of the application this listing belongs to.\"\"\"\n applicationId: ID!\n\n \"\"\"The timestamp when the listing was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"\n Taxonomy facets for this listing (region, industry, category, tag, etc.).\n \"\"\"\n facets: [ApplicationListingFacet!]!\n\n \"\"\"CDN URL of the confirmed HIGHLIGHT asset, or null if not uploaded.\"\"\"\n highlightImageUrl: String\n\n \"\"\"CDN URL of the confirmed ICON asset, or null if not uploaded.\"\"\"\n iconUrl: String\n\n \"\"\"The globally-unique ID of the listing.\"\"\"\n id: ID!\n\n \"\"\"A description for the listing (plain text, max 4000 chars).\"\"\"\n listingDescription: String\n\n \"\"\"HTTPS URL for the privacy policy. Null when not set.\"\"\"\n privacyPolicyUrl: String\n\n \"\"\"CDN URLs of confirmed SCREENSHOT assets, ordered by sort_order.\"\"\"\n screenshotUrls: [String!]!\n\n \"\"\"The lifecycle status of the listing.\"\"\"\n status: ListingStatus!\n\n \"\"\"A short marketing pitch for the listing (plain text, max 160 chars).\"\"\"\n tagline: String\n\n \"\"\"HTTPS URL for the terms and conditions. Null when not set.\"\"\"\n termsAndConditionsUrl: String\n\n \"\"\"The timestamp when the listing was last updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"CDN URLs of confirmed VIDEO assets, ordered by sort_order.\"\"\"\n videoUrls: [String!]!\n\n \"\"\"The visibility of the listing.\"\"\"\n visibility: ListingVisibility!\n}\n\n\"\"\"A taxonomy facet attached to a listing.\"\"\"\ntype ApplicationListingFacet {\n \"\"\"The facet namespace (e.g. 'region', 'industry', 'category', 'tag').\"\"\"\n namespace: String!\n\n \"\"\"The facet value (e.g. 'US', 'retail', 'ecommerce').\"\"\"\n value: String!\n}\n\n\"\"\"\nFilter listings by facet. Returns listings that either have no facets in the given namespace (unrestricted), or have at least one facet in that namespace matching any of the provided values.\n\"\"\"\ninput ApplicationListingFacetFilterInput {\n \"\"\"The facet namespace to filter on (e.g. 'region').\"\"\"\n namespace: String!\n\n \"\"\"\n Accepted facet values (OR semantics within this filter). An empty array is treated as a no-op for this facet filter, not as a filter that matches nothing.\n \"\"\"\n values: [String!]!\n}\n\n\"\"\"A namespace + value pair for a listing facet.\"\"\"\ninput ApplicationListingFacetInput {\n \"\"\"The facet namespace (e.g. 'region', 'industry', 'category', 'tag').\"\"\"\n namespace: String!\n\n \"\"\"The facet value.\"\"\"\n value: String!\n}\n\n\"\"\"Filter options for listing queries.\"\"\"\ninput ApplicationListingFilterInput {\n \"\"\"\n Restrict results to listings for these application IDs (max 50, duplicates ignored).\n \"\"\"\n applicationIds: [ID!]\n\n \"\"\"\n Filter by taxonomy facets. All provided filters must match (AND semantics across namespaces).\n \"\"\"\n facets: [ApplicationListingFacetFilterInput!]\n\n \"\"\"\n Filter by listing lifecycle status. Defaults to ACTIVE for public LISTED discovery. Pass [ACTIVE, INACTIVE] to include deactivated listings (e.g. My Apps by applicationIds).\n \"\"\"\n status: [ListingStatus!]\n\n \"\"\"\n Filter by visibility. Defaults to [LISTED] for public discovery. Pass [LISTED, UNLISTED, HIDDEN] to see all listings for an owner context.\n \"\"\"\n visibility: [ListingVisibility!]\n}\n\n\"\"\"Fields to create or update a listing.\"\"\"\ninput ApplicationListingInput {\n \"\"\"\n Taxonomy facets for the listing. When provided, replaces all existing facets atomically.\n \"\"\"\n facets: [ApplicationListingFacetInput!]\n\n \"\"\"A description for the listing (plain text, max 4000 chars).\"\"\"\n listingDescription: String\n\n \"\"\"\n HTTPS URL for the privacy policy (max 255 chars). Pass null or empty string to clear.\n \"\"\"\n privacyPolicyUrl: String\n\n \"\"\"\n The lifecycle status of the listing. Defaults to INACTIVE on create. ACTIVE requires listing description, privacy URL, terms URL, categories, industries, icon, and screenshots.\n \"\"\"\n status: ListingStatus\n\n \"\"\"A short marketing pitch (plain text, max 160 chars).\"\"\"\n tagline: String\n\n \"\"\"\n HTTPS URL for the terms and conditions (max 255 chars). Pass null or empty string to clear.\n \"\"\"\n termsAndConditionsUrl: String\n\n \"\"\"The visibility of the listing. Defaults to LISTED.\"\"\"\n visibility: ListingVisibility\n}\n\ntype ApplicationListingsConnection {\n edges: [ApplicationListingsConnectionEdge]\n pageInfo: PageInfo!\n}\n\ntype ApplicationListingsConnectionEdge {\n cursor: String!\n node: ApplicationListing\n}\n\n\"\"\"\nAn MCP (Model Context Protocol) server registered with an application release.\n\"\"\"\ntype ApplicationMcpServer {\n \"\"\"The timestamp of when the MCP server was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the MCP server.\"\"\"\n id: String!\n\n \"\"\"Additional configuration for the MCP server.\"\"\"\n metadata: JSONObject\n\n \"\"\"A unique identifier for the MCP server within the release.\"\"\"\n name: String!\n\n \"\"\"The MCP protocol version supported by this server.\"\"\"\n protocolVersion: String\n\n \"\"\"The timestamp of when the MCP server was last updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"\n The path of the endpoint URL that Traefik will route to (e.g., '/mcp/inventory').\n \"\"\"\n url: String!\n}\n\n\"\"\"Input for creating a new MCP server registration.\"\"\"\ninput ApplicationMcpServerCreateInput {\n \"\"\"\n Additional configuration for the MCP server (e.g., tool descriptions, capabilities).\n \"\"\"\n metadata: JSONObject\n\n \"\"\"A unique identifier for the MCP server within the release.\"\"\"\n name: String!\n\n \"\"\"The MCP protocol version supported by this server.\"\"\"\n protocolVersion: String\n\n \"\"\"\n The path of the endpoint URL that Traefik will route to (e.g., '/mcp/inventory').\n \"\"\"\n url: String!\n}\n\n\"\"\"\nA native extension registered with an application release. The target platform is indicated by `platform`.\n\"\"\"\ntype ApplicationNativeExtension {\n \"\"\"The ID of the associated application.\"\"\"\n applicationId: String!\n\n \"\"\"Support contact for the native extension.\"\"\"\n contact: String @deprecated(reason: \"Support contact belongs at the application-registration level, not on an individual extension. Retained temporarily and will be removed once an application-level contact exists.\")\n\n \"\"\"The timestamp of when the native extension was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the native extension.\"\"\"\n id: String!\n\n \"\"\"The display name of the native extension.\"\"\"\n name: String\n\n \"\"\"\n The platform package identifier, in reverse-DNS form (e.g. 'com.example.app'). Optional: not every native deployment is installed through a package manager.\n \"\"\"\n packageName: String\n\n \"\"\"The platform for this native extension.\"\"\"\n platform: NativeExtensionPlatform!\n\n \"\"\"The ID of the associated release.\"\"\"\n releaseId: String!\n\n \"\"\"The timestamp of when the native extension was last updated.\"\"\"\n updatedAt: DateTime!\n}\n\n\"\"\"Input for creating a new native extension.\"\"\"\ninput ApplicationNativeExtensionCreateInput {\n \"\"\"Support contact for the native extension.\"\"\"\n contact: String @deprecated(reason: \"Support contact belongs at the application-registration level, not on an individual extension. Retained temporarily and will be removed once an application-level contact exists.\")\n\n \"\"\"The display name of the native extension.\"\"\"\n name: String\n\n \"\"\"\n The platform package identifier, in reverse-DNS form (e.g. 'com.example.app'). Optional: not every native deployment is installed through a package manager.\n \"\"\"\n packageName: String\n\n \"\"\"The platform for this native extension.\"\"\"\n platform: NativeExtensionPlatform!\n}\n\n\"\"\"Fields by which applications can be ordered.\"\"\"\ninput ApplicationOrderBy {\n \"\"\"Order applications by creation date.\"\"\"\n createdAt: OrderByDirectionEnum\n\n \"\"\"Order applications by ID.\"\"\"\n id: OrderByDirectionEnum\n\n \"\"\"Order applications by name.\"\"\"\n name: OrderByDirectionEnum\n\n \"\"\"Order applications by last update date.\"\"\"\n updatedAt: OrderByDirectionEnum\n}\n\ntype ApplicationRelease {\n \"\"\"The actions registered with this release.\"\"\"\n actions: [ApplicationAction!]!\n\n \"\"\"The timestamp of when the Application was activated.\"\"\"\n activatedAt: DateTime\n\n \"\"\"\n The other applications this release depends on, and the state it declares for each.\n \"\"\"\n applicationDependencies: [ApplicationDependency!]!\n\n \"\"\"The timestamp of when the Application was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The timestamp of when the release was deactivated.\"\"\"\n deactivatedAt: DateTime\n\n \"\"\"\n Information about the new release. Provide information about what has changed and any implications that it might have on your users.\n \"\"\"\n description: String\n\n \"\"\"The feature dependencies declared by this release.\"\"\"\n featureDependencies: [FeatureDependency!]!\n\n \"\"\"The globally-unique ID of the release.\"\"\"\n id: String!\n\n \"\"\"The MCP servers registered with this release.\"\"\"\n mcpServers: [ApplicationMcpServer!]!\n\n \"\"\"The native extensions registered with this release.\"\"\"\n nativeExtensions: [ApplicationNativeExtension!]!\n\n \"\"\"The settings capabilities registered with this release.\"\"\"\n settings(\n \"\"\"Filter settings by Commerce settings group slug.\"\"\"\n groupSlug: String\n ): [ApplicationSetting!]!\n\n \"\"\"The lifecycle status of the release.\"\"\"\n status: ApplicationReleaseStatus!\n\n \"\"\"The webhook subscriptions registered with this release.\"\"\"\n subscriptions: [ApplicationSubscription!]!\n\n \"\"\"The UI extensions registered with this release.\"\"\"\n uiExtensions(\n \"\"\"\n Optional UI extension target filter. Supports has (single match) and hasAny (any match).\n \"\"\"\n target: StringListFilter\n ): [ApplicationUiExtension!]!\n\n \"\"\"The timestamp of when the Application was updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The version number of this release.\"\"\"\n version: String!\n}\n\n\"\"\"The status of an application release.\"\"\"\nenum ApplicationReleaseStatus {\n \"\"\"Release is active and available for use.\"\"\"\n ACTIVE\n\n \"\"\"Release is created but not active.\"\"\"\n INACTIVE\n}\n\ntype ApplicationReleasesConnection {\n edges: [ApplicationReleasesConnectionEdge]\n pageInfo: PageInfo!\n}\n\ntype ApplicationReleasesConnectionEdge {\n cursor: String!\n node: ApplicationRelease\n}\n\n\"\"\"\nA settings capability registered with an application release and placed into a Commerce-owned settings group.\n\"\"\"\ntype ApplicationSetting {\n \"\"\"The app-owned slug for this setting registration.\"\"\"\n appSettingSlug: String!\n\n \"\"\"Lifecycle capabilities supported by this setting.\"\"\"\n capabilities: [String!]!\n\n \"\"\"The timestamp of when the setting was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"Display description for this setting.\"\"\"\n description: String\n\n \"\"\"Localization key for the display description.\"\"\"\n descriptionKey: String\n\n \"\"\"The GPA settings namespace path that lifecycle endpoints live beneath.\"\"\"\n entryPath: String!\n\n \"\"\"The Commerce-owned settings group slug.\"\"\"\n groupSlug: String!\n\n \"\"\"Optional icon library for display.\"\"\"\n iconLibrary: String\n\n \"\"\"Optional icon name for display.\"\"\"\n iconName: String\n\n \"\"\"The globally-unique ID of the application setting.\"\"\"\n id: String!\n\n \"\"\"Additional app-defined settings metadata.\"\"\"\n metadata: JSONObject\n\n \"\"\"Sort order within the settings group.\"\"\"\n order: Int!\n\n \"\"\"The client-renderable presentation contract for this setting.\"\"\"\n presentation: JSONObject!\n\n \"\"\"Display title for this setting.\"\"\"\n title: String\n\n \"\"\"Localization key for the display title.\"\"\"\n titleKey: String\n\n \"\"\"The timestamp of when the setting was last updated.\"\"\"\n updatedAt: DateTime!\n}\n\n\"\"\"Input for creating a new application settings registration.\"\"\"\ninput ApplicationSettingCreateInput {\n \"\"\"The app-owned slug for this setting registration.\"\"\"\n appSettingSlug: String!\n\n \"\"\"\n Lifecycle capabilities supported by this setting (read, write, validate, test, delete, open, config). config requires metadata.configKeys.\n \"\"\"\n capabilities: [String!]\n\n \"\"\"Display description for this setting.\"\"\"\n description: String\n\n \"\"\"Localization key for the display description.\"\"\"\n descriptionKey: String\n\n \"\"\"The GPA settings namespace path that lifecycle endpoints live beneath.\"\"\"\n entryPath: String!\n\n \"\"\"The Commerce-owned settings group slug.\"\"\"\n groupSlug: String!\n\n \"\"\"Optional icon library for display.\"\"\"\n iconLibrary: String\n\n \"\"\"Optional icon name for display.\"\"\"\n iconName: String\n\n \"\"\"Additional app-defined settings metadata.\"\"\"\n metadata: JSONObject\n\n \"\"\"Sort order within the settings group.\"\"\"\n order: Int\n\n \"\"\"\n The settings-form-v1 or settings-link-v1 presentation contract for this setting.\n \"\"\"\n presentation: JSONObject!\n\n \"\"\"Display title for this setting.\"\"\"\n title: String\n\n \"\"\"Localization key for the display title.\"\"\"\n titleKey: String\n}\n\n\"\"\"The current status of an application in the platform.\"\"\"\nenum ApplicationStatus {\n \"\"\"Application is active and can be used.\"\"\"\n ACTIVE\n\n \"\"\"Application has been archived and is no longer available.\"\"\"\n ARCHIVED\n\n \"\"\"Application has been blocked from use due to policy violations.\"\"\"\n BLOCKED\n\n \"\"\"Application is registered but not active.\"\"\"\n INACTIVE\n\n \"\"\"Application is being verified and is not yet active.\"\"\"\n VERIFYING\n}\n\n\"\"\"Filter applications by status.\"\"\"\ninput ApplicationStatusFilter {\n \"\"\"Filter by exact status match.\"\"\"\n eq: ApplicationStatus\n\n \"\"\"Filter by any of the specified statuses.\"\"\"\n in: [ApplicationStatus!]\n\n \"\"\"Filter by status not equal to the specified value.\"\"\"\n ne: ApplicationStatus\n}\n\n\"\"\"\nWebhook subscriptions that an application has opted to subscribe to. Each subscription has one or many events.\n\"\"\"\ntype ApplicationSubscription {\n \"\"\"The timestamp of when the Application was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"A list of events that the subscription will receive.\"\"\"\n events: [String!]!\n\n \"\"\"The globally-unique ID of the release.\"\"\"\n id: String!\n\n \"\"\"The name of the webhook subscription\"\"\"\n name: String!\n\n \"\"\"The timestamp of when the Application was updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The delivery URL of the webhook.\"\"\"\n url: String!\n}\n\n\"\"\"Input for creating a new application webhook subscription.\"\"\"\ninput ApplicationSubscriptionCreateInput {\n \"\"\"List of event types this subscription will receive.\"\"\"\n events: [String!]!\n\n \"\"\"A unique name for the subscription.\"\"\"\n name: String!\n\n \"\"\"The webhook URL that will receive the events.\"\"\"\n url: String!\n}\n\n\"\"\"\nA UI extension registered with an application release (e.g., embed, checkout, blocks).\n\"\"\"\ntype ApplicationUiExtension {\n \"\"\"The base CDN URL for packaged UI extension assets.\"\"\"\n cdnUrl: String\n\n \"\"\"The timestamp of when the UI extension was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The unique handle/identifier for the extension (e.g., 'my-extension').\"\"\"\n handle: String\n\n \"\"\"The globally-unique ID of the UI extension.\"\"\"\n id: String!\n\n \"\"\"The display name of the extension.\"\"\"\n name: String\n\n \"\"\"\n The source file path for the extension (e.g., 'extensions/my-ext/index.ts').\n \"\"\"\n source: String\n\n \"\"\"\n The target location for the extension (e.g., 'body.end', 'checkout.header').\n \"\"\"\n target: String\n\n \"\"\"The type of UI extension (e.g., 'embed', 'checkout', 'blocks').\"\"\"\n type: String!\n\n \"\"\"The timestamp of when the UI extension was last updated.\"\"\"\n updatedAt: DateTime!\n}\n\n\"\"\"Input for creating a new application UI extension.\"\"\"\ninput ApplicationUiExtensionCreateInput {\n \"\"\"\n The unique handle/identifier for the extension (e.g., 'my-extension'). Optional for blocks extensions.\n \"\"\"\n handle: String\n\n \"\"\"The display name of the extension. Optional for blocks extensions.\"\"\"\n name: String\n\n \"\"\"\n The source file path for the extension (e.g., 'extensions/my-ext/index.ts'). Optional for blocks extensions.\n \"\"\"\n source: String\n\n \"\"\"\n The target location for the extension (e.g., 'body.end', 'checkout.header'). Required for targeted extensions, optional for block-type extensions.\n \"\"\"\n target: String\n\n \"\"\"The type of UI extension (e.g., 'embed', 'checkout', 'blocks').\"\"\"\n type: String!\n}\n\n\"\"\"Pre-signed upload URL and metadata for listing media.\"\"\"\ntype CreateMediaUploadUrlResponse {\n expiresAt: DateTime!\n maxSizeBytes: Int!\n mediaObjectId: ID!\n requiredHeaders: [String!]!\n uploadUrl: String!\n}\n\n\"\"\"A date-time string in ISO 8601 format (e.g. 2022-01-01T00:00:00Z).\"\"\"\nscalar DateTime\n\n\"\"\"The distribution type for an application.\"\"\"\nenum DistributionType {\n \"\"\"Application has custom distribution.\"\"\"\n CUSTOM\n\n \"\"\"Application is publicly available.\"\"\"\n PUBLIC\n}\n\ntype EnabledApplication {\n \"\"\"The timestamp of when the Application was activated.\"\"\"\n activatedAt: DateTime\n\n \"\"\"The timestamp of when the Application was archived.\"\"\"\n archivedAt: DateTime\n\n \"\"\"\n The authorization scopes that the OAuth2 client has access to and will use to call API endpoints.\n \"\"\"\n authorizationScopes: [String!]!\n\n \"\"\"\n Earliest linked OAuth client ID for this application by createdAt then id (includes NULL-secret and ARCHIVED apps).\n \"\"\"\n clientId: ID\n\n \"\"\"\n The primary OAuth client secret for this application. Only returned on application creation.\n \"\"\"\n clientSecret: String\n\n \"\"\"The timestamp of when the Application was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The timestamp of when the Application was deactivated.\"\"\"\n deactivatedAt: DateTime\n\n \"\"\"General information about your application.\"\"\"\n description: String\n\n \"\"\"The globally-unique ID of the Application.\"\"\"\n id: ID!\n\n \"\"\"A human-readable label of the Application for display purposes.\"\"\"\n label: String!\n\n \"\"\"A url-friendly name for the Application.\"\"\"\n name: String!\n\n \"\"\"The ID of the organization that owns this Application.\"\"\"\n organizationId: ID!\n\n \"\"\"\n The base URL of your application. This is the endpoint that the GoDaddy Commerce platform will call when integrated with actions.\n \"\"\"\n proxyUrl: String\n\n \"\"\"\n The public key (base64 encoded) for verifying action requests to your application.\n \"\"\"\n publicKey: String\n\n \"\"\"\n Additional OAuth redirect URIs on the application's OAuth client(s). URL-derived defaults (the application URL and {url}/api/godaddy/callback) are omitted so this list can be submitted unchanged on create or update.\n \"\"\"\n redirectUris: [String!]!\n\n \"\"\"The release/version enabled for this application\"\"\"\n release: ApplicationRelease\n\n \"\"\"\n The secret for verifying webhook requests to your application. Copy and secure this secret. You will not see it again.\n \"\"\"\n secret: String\n\n \"\"\"The status of the application.\"\"\"\n status: ApplicationStatus!\n\n \"\"\"The timestamp of when the Application was updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The public website of the application.\"\"\"\n url: String\n}\n\n\"\"\"Fields by which enablements can be ordered.\"\"\"\ninput EnablementOrderBy {\n \"\"\"Order enablements by creation date.\"\"\"\n createdAt: OrderByDirectionEnum\n\n \"\"\"Order enablements by ID.\"\"\"\n id: OrderByDirectionEnum\n\n \"\"\"Order enablements by last update date.\"\"\"\n updatedAt: OrderByDirectionEnum\n}\n\n\"\"\"\nA feature dependency declared by an application release (a feature name and its required/excluded/enabled/disabled state).\n\"\"\"\ntype FeatureDependency {\n \"\"\"The feature name from the available features list.\"\"\"\n name: String!\n\n \"\"\"The declared state for this feature.\"\"\"\n state: FeatureDependencyState!\n}\n\n\"\"\"Input for declaring a feature dependency on a release.\"\"\"\ninput FeatureDependencyInput {\n \"\"\"The feature name from the available features list.\"\"\"\n name: String!\n\n \"\"\"The declared state for this feature.\"\"\"\n state: FeatureDependencyState!\n}\n\n\"\"\"The state of a feature dependency declaration.\"\"\"\nenum FeatureDependencyState {\n \"\"\"Feature is disabled by default but can be overridden.\"\"\"\n DISABLED\n\n \"\"\"Feature is enabled by default but can be overridden.\"\"\"\n ENABLED\n\n \"\"\"Feature is excluded and cannot be required by other apps.\"\"\"\n EXCLUDED\n\n \"\"\"Feature is required and cannot be excluded by other apps.\"\"\"\n REQUIRED\n}\n\n\"\"\"Response containing pre-signed upload URL and metadata.\"\"\"\ntype GenerateReleaseUploadUrlResponse {\n \"\"\"The timestamp when the upload URL expires.\"\"\"\n expiresAt: DateTime!\n\n \"\"\"The S3 key where the file should be uploaded.\"\"\"\n key: String!\n\n \"\"\"Maximum allowed file size in bytes.\"\"\"\n maxSizeBytes: Int!\n\n \"\"\"Required headers for the upload as key:value pairs.\"\"\"\n requiredHeaders: [String!]!\n\n \"\"\"The unique upload identifier for tracking.\"\"\"\n uploadId: String!\n\n \"\"\"The pre-signed URL for uploading the file.\"\"\"\n url: String!\n}\n\n\"\"\"A JSON object scalar type.\"\"\"\nscalar JSONObject\n\n\"\"\"Allowed MIME types for listing media uploads.\"\"\"\nenum ListingMediaContentType {\n IMAGE_JPEG\n IMAGE_PNG\n VIDEO_MP4\n}\n\n\"\"\"The merchandising role of a listing media asset.\"\"\"\nenum ListingMediaRole {\n HIGHLIGHT\n ICON\n SCREENSHOT\n VIDEO\n}\n\n\"\"\"The lifecycle status of a listing media upload.\"\"\"\nenum ListingMediaStatus {\n CONFIRMED\n FAILED\n PENDING\n REMOVED\n SUPERSEDED\n}\n\n\"\"\"The lifecycle status of a listing.\"\"\"\nenum ListingStatus {\n \"\"\"Listing is active and eligible for marketplace discovery.\"\"\"\n ACTIVE\n\n \"\"\"Listing is inactive until activation requirements are met.\"\"\"\n INACTIVE\n}\n\n\"\"\"The visibility of a listing.\"\"\"\nenum ListingVisibility {\n \"\"\"Listing is hidden from discovery surfaces.\"\"\"\n HIDDEN\n\n \"\"\"Listing is publicly visible.\"\"\"\n LISTED\n\n \"\"\"Listing is not shown in search.\"\"\"\n UNLISTED\n}\n\n\"\"\"A media asset attached to an application listing.\"\"\"\ntype MediaObject {\n applicationId: ID!\n contentType: String\n createdAt: DateTime!\n failureReason: String\n filename: String\n id: ID!\n listingId: ID\n role: ListingMediaRole\n sortOrder: Int!\n status: ListingMediaStatus!\n updatedAt: DateTime!\n url: String\n}\n\ntype Mutation {\n \"\"\"\n Activate a release and, when permitted, promote its parent application to ACTIVE.\n \"\"\"\n activateRelease(\n \"\"\"The ID of the application.\"\"\"\n applicationId: ID!\n\n \"\"\"The ID of the release to activate.\"\"\"\n releaseId: ID!\n ): ApplicationRelease\n\n \"\"\"Archive an existing Application.\"\"\"\n archiveApplication(\n \"\"\"The ID of the application to archive.\"\"\"\n id: String!\n ): Application\n\n \"\"\"Confirm a listing media upload after the client PUTs the file to S3.\"\"\"\n confirmMediaObject(\n \"\"\"The application that owns the media object — used for authorization.\"\"\"\n applicationId: ID!\n\n \"\"\"The media object ID returned from createMediaUploadUrl.\"\"\"\n mediaObjectId: ID!\n ): MediaObject\n\n \"\"\"Create a new Application.\"\"\"\n createApplication(input: MutationCreateApplicationInput!): Application\n\n \"\"\"\n Create a pending listing media record and return a pre-signed S3 PUT URL.\n \"\"\"\n createMediaUploadUrl(\n \"\"\"The application that owns the listing (1:1).\"\"\"\n applicationId: ID!\n\n \"\"\"MIME type of the file to upload.\"\"\"\n contentType: ListingMediaContentType!\n\n \"\"\"\n Declared file size in bytes. Rejected if it exceeds the role cap before issuing the presigned URL.\n \"\"\"\n fileSizeBytes: Int!\n\n \"\"\"Original filename from the client.\"\"\"\n filename: String!\n\n \"\"\"Merchandising role for this asset.\"\"\"\n role: ListingMediaRole!\n\n \"\"\"\n Optional ordering for screenshots/videos (0–7). Defaults to next slot. Ignored for other roles (defaults to 0).\n \"\"\"\n sortOrder: Int\n ): CreateMediaUploadUrlResponse\n\n \"\"\"Create a new release for an application.\"\"\"\n createRelease(input: MutationCreateReleaseInput!): ApplicationRelease\n\n \"\"\"\n Deactivate an application through its lifecycle operation. Activate it again by activating a release.\n \"\"\"\n deactivateApplication(\n \"\"\"The ID of the application to deactivate.\"\"\"\n id: String!\n ): Application\n\n \"\"\"\n Deactivate a release. When it is the last active release, its application listing is also deactivated.\n \"\"\"\n deactivateRelease(\n \"\"\"The ID of the application.\"\"\"\n applicationId: ID!\n\n \"\"\"The ID of the release to deactivate.\"\"\"\n releaseId: ID!\n ): ApplicationRelease\n\n \"\"\"Soft-delete the listing for an application.\"\"\"\n deleteApplicationListing(\n \"\"\"The ID of the application.\"\"\"\n applicationId: ID!\n ): Boolean\n\n \"\"\"Disable an application on a customer\"\"\"\n disableCustomerApplication(input: MutationDisableCustomerApplicationInput!): Application\n\n \"\"\"Disable an application in a store\"\"\"\n disableStoreApplication(input: MutationDisableStoreApplicationInput!): Application\n\n \"\"\"Enable an application on a customer\"\"\"\n enableCustomerApplication(input: MutationEnableCustomerApplicationInput!): Application\n\n \"\"\"Enable an application on a store\"\"\"\n enableStoreApplication(input: MutationEnableStoreApplicationInput!): Application\n\n \"\"\"Generate a pre-signed URL for uploading UI extension artifacts.\"\"\"\n generateReleaseUploadUrl(input: MutationGenerateReleaseUploadUrlInput!): GenerateReleaseUploadUrlResponse\n\n \"\"\"\n Remove a confirmed listing media object. Sets status to REMOVED, deletes the promoted S3 object, and invalidates the CDN path.\n \"\"\"\n removeListingMediaObject(\n \"\"\"\n The application that owns the media object — prevents cross-app removal.\n \"\"\"\n applicationId: ID!\n\n \"\"\"The confirmed media object ID to remove.\"\"\"\n mediaObjectId: ID!\n ): MediaObject\n\n \"\"\"\n Create or update the listing for an application. Idempotent — safe to call multiple times for the same application.\n \"\"\"\n setApplicationListing(\n \"\"\"The ID of the application.\"\"\"\n applicationId: ID!\n\n \"\"\"The listing fields to create or update.\"\"\"\n input: ApplicationListingInput!\n ): ApplicationListing\n\n \"\"\"Update an existing Application.\"\"\"\n updateApplication(id: String!, input: MutationUpdateApplicationInput!): Application\n}\n\ninput MutationCreateApplicationInput {\n \"\"\"\n The authorization scopes of the application. Defines the GoDaddy permissions for the application.\n \"\"\"\n authorizationScopes: [String!]\n\n \"\"\"The description of the application.\"\"\"\n description: String\n\n \"\"\"The distribution type for the application. Defaults to PUBLIC.\"\"\"\n distributionType: DistributionType = PUBLIC\n\n \"\"\"The label of the application.\"\"\"\n label: String!\n\n \"\"\"The name of the application.\"\"\"\n name: String!\n\n \"\"\"\n Optional organization ID for multi-org users. If omitted, the organization is auto-resolved from the user's session. If provided, the user must be an admin of the specified organization.\n \"\"\"\n organizationId: String\n\n \"\"\"\n The proxy URL of the application. This is the base URL for all API endpoints.\n \"\"\"\n proxyUrl: String\n\n \"\"\"\n Additional OAuth redirect URI allowlist. Supports up to 5 unique HTTPS URLs. Entries equal to the application URL or its default callback are rejected; those defaults are registered automatically.\n \"\"\"\n redirectUris: [String!]\n\n \"\"\"\n The public URL of the application. This is typically the URL of the application's website.\n \"\"\"\n url: String\n}\n\ninput MutationCreateReleaseInput {\n \"\"\"The actions associated with the release.\"\"\"\n actions: [ApplicationActionCreateInput!]\n\n \"\"\"\n The other applications this release depends on, and the state it declares for each.\n \"\"\"\n applicationDependencies: [ApplicationDependencyInput!]\n\n \"\"\"The ID of the application.\"\"\"\n applicationId: ID!\n\n \"\"\"The description of the release.\"\"\"\n description: String\n\n \"\"\"The feature dependencies declared by the release.\"\"\"\n featureDependencies: [FeatureDependencyInput!]\n\n \"\"\"The MCP servers associated with the release.\"\"\"\n mcpServers: [ApplicationMcpServerCreateInput!]\n\n \"\"\"The native extensions associated with the release.\"\"\"\n nativeExtensions: [ApplicationNativeExtensionCreateInput!]\n\n \"\"\"The settings capabilities associated with the release.\"\"\"\n settings: [ApplicationSettingCreateInput!]\n\n \"\"\"The subscriptions associated with the release.\"\"\"\n subscriptions: [ApplicationSubscriptionCreateInput!]\n\n \"\"\"The UI extensions associated with the release.\"\"\"\n uiExtensions: [ApplicationUiExtensionCreateInput!]\n\n \"\"\"The version of the release.\"\"\"\n version: String!\n}\n\ninput MutationDisableCustomerApplicationInput {\n \"\"\"The name of the application to disable.\"\"\"\n applicationName: String!\n\n \"\"\"The ID of the customer to disable the application on.\"\"\"\n customerId: String!\n}\n\ninput MutationDisableStoreApplicationInput {\n \"\"\"The name of the application to disable.\"\"\"\n applicationName: String!\n\n \"\"\"The ID of the store to disable the application on.\"\"\"\n storeId: String!\n}\n\ninput MutationEnableCustomerApplicationInput {\n \"\"\"The name of the application to enable.\"\"\"\n applicationName: String!\n\n \"\"\"The ID of the customer to enable the application on.\"\"\"\n customerId: String!\n}\n\ninput MutationEnableStoreApplicationInput {\n \"\"\"The name of the application to enable.\"\"\"\n applicationName: String!\n\n \"\"\"The ID of the store to enable the application on.\"\"\"\n storeId: String!\n}\n\ninput MutationGenerateReleaseUploadUrlInput {\n \"\"\"The ID of the application.\"\"\"\n applicationId: ID!\n\n \"\"\"The content type of the file to be uploaded.\"\"\"\n contentType: UploadContentType!\n\n \"\"\"The ID of the release.\"\"\"\n releaseId: ID!\n\n \"\"\"The target for the upload.\"\"\"\n target: String\n}\n\ninput MutationUpdateApplicationInput {\n \"\"\"\n The authorization scopes of the application. Defines the GoDaddy permissions for the application.\n \"\"\"\n authorizationScopes: [String!]\n\n \"\"\"The description of the application.\"\"\"\n description: String\n\n \"\"\"\n The distribution type for the application (PUBLIC or CUSTOM). Omit to leave unchanged.\n \"\"\"\n distributionType: DistributionType\n\n \"\"\"The label of the application.\"\"\"\n label: String\n\n \"\"\"The name of the application.\"\"\"\n name: String\n\n \"\"\"\n The proxy URL of the application. This is the base URL for all API endpoints.\n \"\"\"\n proxyUrl: String\n\n \"\"\"\n Additional OAuth redirect URI allowlist. Supports up to 5 unique HTTPS URLs. Entries equal to the effective application URL or its default callback are rejected. On URL changes, both old defaults are replaced; submit any old URI explicitly to retain it as an extra.\n \"\"\"\n redirectUris: [String!]\n\n \"\"\"\n The public URL of the application. This is typically the URL of the application's website.\n \"\"\"\n url: String\n}\n\n\"\"\"The platform for a native extension.\"\"\"\nenum NativeExtensionPlatform {\n \"\"\"Android platform (APK distribution).\"\"\"\n ANDROID\n}\n\n\"\"\"Represents a null value.\"\"\"\nscalar Null\n\n\"\"\"Direction for ordering results in queries.\"\"\"\nenum OrderByDirectionEnum {\n \"\"\"Sort in ascending order.\"\"\"\n ASC\n\n \"\"\"Sort 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 single application by ID or name.\"\"\"\n application(\n \"\"\"The OAuth client ID of the application to retrieve.\"\"\"\n clientId: String\n\n \"\"\"The unique ID of the application to retrieve.\"\"\"\n id: String\n\n \"\"\"The unique name of the application to retrieve.\"\"\"\n name: String\n ): Application\n\n \"\"\"\n Paginated listings. Defaults to publicly LISTED listings for active PUBLIC-distribution apps. Pass visibility filter to query owner/admin contexts.\n \"\"\"\n applicationListings(\n after: String\n before: String\n\n \"\"\"Filter options for the query.\"\"\"\n filter: ApplicationListingFilterInput\n first: Int\n last: Int\n ): QueryApplicationListingsConnection\n\n \"\"\"\n Get paginated applications. Returns all public applications for service requests, or only applications owned by the authenticated customer's organization. Multi-org users may pass an explicit `organizationId` to select which organization's apps to list.\n \"\"\"\n applications(\n after: String\n before: String\n first: Int\n last: Int\n\n \"\"\"The order in which to sort the applications.\"\"\"\n orderBy: ApplicationOrderBy\n\n \"\"\"\n Optional organization ID. When provided, lists apps for that specific organization. Customer tokens must be admin of the organization; service tokens may specify any organization.\n \"\"\"\n organizationId: String\n\n \"\"\"Filter by application status. Defaults to ACTIVE applications only.\"\"\"\n status: ApplicationStatusFilter\n ): QueryApplicationsConnection\n\n \"\"\"\n Get all applications enabled for an entity by entity ID and type, with optional filtering by actions, UI extensions, and settings.\n \"\"\"\n enabledApplications(\n \"\"\"\n Filter by action names. Supports has (single match) and hasAny (any match).\n \"\"\"\n actionNames: StringListFilter\n\n \"\"\"The ID of the entity to get enabled applications for.\"\"\"\n entityId: String!\n\n \"\"\"\n The type of the entity the applications are enabled on. Currently STORE.\n \"\"\"\n entityType: String!\n\n \"\"\"Filter by Commerce settings group slug.\"\"\"\n settingGroupSlug: String\n\n \"\"\"\n Filter by application setting slugs. Supports has (single match) and hasAny (any match).\n \"\"\"\n settingSlugs: StringListFilter\n\n \"\"\"\n Filter by UI extension targets. Supports has (single match) and hasAny (any match).\n \"\"\"\n uiExtensionTargets: StringListFilter\n\n \"\"\"\n Filter by UI extension types. Supports has (single match) and hasAny (any match).\n \"\"\"\n uiExtensionTypes: StringListFilter\n ): [EnabledApplication!]\n\n \"\"\"\n Get all applications enabled for a store by store ID, with optional filtering by actions, UI extensions, and settings.\n \"\"\"\n enabledStoreApplications(\n \"\"\"\n Filter by action names. Supports has (single match) and hasAny (any match).\n \"\"\"\n actionNames: StringListFilter\n\n \"\"\"Filter by Commerce settings group slug.\"\"\"\n settingGroupSlug: String\n\n \"\"\"\n Filter by application setting slugs. Supports has (single match) and hasAny (any match).\n \"\"\"\n settingSlugs: StringListFilter\n\n \"\"\"The ID of the store to get enabled applications for.\"\"\"\n storeId: String!\n\n \"\"\"\n Filter by UI extension targets. Supports has (single match) and hasAny (any match).\n \"\"\"\n uiExtensionTargets: StringListFilter\n\n \"\"\"\n Filter by UI extension types. Supports has (single match) and hasAny (any match).\n \"\"\"\n uiExtensionTypes: StringListFilter\n ): [EnabledApplication!]\n\n \"\"\"Returns a paginated list of enablements for a specific release.\"\"\"\n enablementsByRelease(\n after: String\n before: String\n first: Int\n last: Int\n\n \"\"\"The order in which to sort the enablements.\"\"\"\n orderBy: EnablementOrderBy\n\n \"\"\"The release ID to query enablements for.\"\"\"\n releaseId: ID!\n ): QueryEnablementsByReleaseConnection!\n\n \"\"\"Get the status of a release upload by upload ID.\"\"\"\n getReleaseUpload(\n \"\"\"The application ID to verify authorization.\"\"\"\n applicationId: ID!\n\n \"\"\"The unique upload identifier.\"\"\"\n uploadId: String!\n ): ReleaseUpload\n\n \"\"\"Get a single native extension by ID.\"\"\"\n nativeExtension(\n \"\"\"The ID of the native extension to retrieve.\"\"\"\n id: ID!\n ): ApplicationNativeExtension\n\n \"\"\"\n List native extensions by application or release. At least one of applicationId or releaseId must be provided.\n \"\"\"\n nativeExtensions(\n \"\"\"Filter by application ID.\"\"\"\n applicationId: ID\n\n \"\"\"Maximum number of results to return.\"\"\"\n limit: Int\n\n \"\"\"Filter by release ID.\"\"\"\n releaseId: ID\n ): [ApplicationNativeExtension!]!\n\n \"\"\"\n Get the resolved feature states for a store, after reconciling all active app declarations.\n \"\"\"\n storeFeatures(\n \"\"\"The ID of the store to resolve features for.\"\"\"\n storeId: String!\n ): [FeatureDependency!]!\n\n \"\"\"Returns webhook subscription IDs for a specific release/entity pair.\"\"\"\n webhookSubscriptionInstancesByRelease(\n \"\"\"The entity ID to scope the query to.\"\"\"\n entityId: ID!\n\n \"\"\"The entity type to scope the query to (e.g. STORE).\"\"\"\n entityType: String!\n\n \"\"\"The release ID to query webhook subscriptions for.\"\"\"\n releaseId: ID!\n ): [String!]!\n}\n\ntype QueryApplicationListingsConnection {\n edges: [QueryApplicationListingsConnectionEdge]\n pageInfo: PageInfo!\n}\n\ntype QueryApplicationListingsConnectionEdge {\n cursor: String!\n node: ApplicationListing\n}\n\ntype QueryApplicationsConnection {\n edges: [QueryApplicationsConnectionEdge]\n pageInfo: PageInfo!\n}\n\ntype QueryApplicationsConnectionEdge {\n cursor: String!\n node: Application\n}\n\ntype QueryEnablementsByReleaseConnection {\n edges: [QueryEnablementsByReleaseConnectionEdge]\n pageInfo: PageInfo!\n}\n\ntype QueryEnablementsByReleaseConnectionEdge {\n cursor: String!\n node: ApplicationEnablement\n}\n\n\"\"\"Fields by which application releases can be ordered.\"\"\"\ninput ReleaseOrderBy {\n \"\"\"Order releases by activation date.\"\"\"\n activatedAt: OrderByDirectionEnum\n\n \"\"\"Order releases by creation date.\"\"\"\n createdAt: OrderByDirectionEnum\n\n \"\"\"Order releases by ID.\"\"\"\n id: OrderByDirectionEnum\n\n \"\"\"Order releases by last update date.\"\"\"\n updatedAt: OrderByDirectionEnum\n\n \"\"\"Order releases by version number. Must be in {major}.{minor} format.\"\"\"\n version: OrderByDirectionEnum\n}\n\n\"\"\"Filter releases by status.\"\"\"\ninput ReleaseStatusFilter {\n \"\"\"Filter by exact status match.\"\"\"\n eq: ApplicationReleaseStatus\n\n \"\"\"Filter by any of the specified statuses.\"\"\"\n in: [ApplicationReleaseStatus!]\n\n \"\"\"Filter by status not equal to the specified value.\"\"\"\n ne: ApplicationReleaseStatus\n}\n\n\"\"\"A release upload record tracking the status of uploaded artifacts.\"\"\"\ntype ReleaseUpload {\n \"\"\"The ID of the associated application.\"\"\"\n applicationId: String!\n\n \"\"\"The timestamp when the upload was completed or failed.\"\"\"\n completedAt: DateTime\n\n \"\"\"The MIME type of the uploaded content.\"\"\"\n contentType: UploadContentType!\n\n \"\"\"The timestamp when the upload was requested.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The reason for failure if status is FAILED.\"\"\"\n failureReason: String\n\n \"\"\"The globally-unique ID of the upload record.\"\"\"\n id: String!\n\n \"\"\"The ID of the associated release.\"\"\"\n releaseId: String!\n\n \"\"\"The size of the uploaded file in bytes.\"\"\"\n sizeBytes: Int\n\n \"\"\"The current status of the upload.\"\"\"\n status: ReleaseUploadStatus!\n\n \"\"\"The unique upload identifier used for correlation.\"\"\"\n uploadId: String!\n}\n\n\"\"\"The status of a release upload.\"\"\"\nenum ReleaseUploadStatus {\n \"\"\"Upload or processing failed.\"\"\"\n FAILED\n\n \"\"\"File has been processed and deployed successfully.\"\"\"\n PROCESSED\n\n \"\"\"Upload URL has been generated and is awaiting upload.\"\"\"\n REQUESTED\n\n \"\"\"File has been uploaded and is awaiting processing.\"\"\"\n UPLOADED\n}\n\n\"\"\"Filter for fields that are lists/sets of strings.\"\"\"\ninput StringListFilter {\n \"\"\"Field must contain this value.\"\"\"\n has: String\n\n \"\"\"Field must contain at least one of these values.\"\"\"\n hasAny: [String!]\n}\n\n\"\"\"Supported content types for release uploads.\"\"\"\nenum UploadContentType {\n \"\"\"JavaScript file\"\"\"\n JS\n\n \"\"\"TAR archive\"\"\"\n TAR\n\n \"\"\"ZIP archive\"\"\"\n ZIP\n}", + "sdl": "type Application {\n \"\"\"The timestamp of when the Application was activated.\"\"\"\n activatedAt: DateTime\n\n \"\"\"The timestamp of when the Application was archived.\"\"\"\n archivedAt: DateTime\n\n \"\"\"\n The authorization scopes that the OAuth2 client has access to and will use to call API endpoints.\n \"\"\"\n authorizationScopes: [String!]!\n\n \"\"\"\n Earliest linked OAuth client ID for this application by createdAt then id (includes NULL-secret and ARCHIVED apps).\n \"\"\"\n clientId: ID\n\n \"\"\"\n The primary OAuth client secret for this application. Only returned on application creation.\n \"\"\"\n clientSecret: String\n\n \"\"\"The timestamp of when the Application was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The timestamp of when the Application was deactivated.\"\"\"\n deactivatedAt: DateTime\n\n \"\"\"General information about your application.\"\"\"\n description: String\n\n \"\"\"The distribution type for this application.\"\"\"\n distributionType: DistributionType!\n\n \"\"\"The globally-unique ID of the Application.\"\"\"\n id: ID!\n\n \"\"\"A human-readable label of the Application for display purposes.\"\"\"\n label: String!\n\n \"\"\"\n Paginated listings for this application. Requires read scope. When using the filter, `applicationIds` is ignored — results are always scoped to this application.\n \"\"\"\n listings(\n after: String\n before: String\n\n \"\"\"Optional filter for the listings.\"\"\"\n filter: ApplicationListingFilterInput\n first: Int\n last: Int\n ): ApplicationListingsConnection\n\n \"\"\"A url-friendly name for the Application.\"\"\"\n name: String!\n\n \"\"\"The ID of the organization that owns this Application.\"\"\"\n organizationId: ID!\n\n \"\"\"\n The base URL of your application. This is the endpoint that the GoDaddy Commerce platform will call when integrated with actions.\n \"\"\"\n proxyUrl: String\n\n \"\"\"\n The public key (base64 encoded) for verifying action requests to your application.\n \"\"\"\n publicKey: String\n\n \"\"\"\n Additional OAuth redirect URIs on the application's OAuth client(s). URL-derived defaults (the application URL and {url}/api/godaddy/callback) are omitted so this list can be submitted unchanged on create or update.\n \"\"\"\n redirectUris: [String!]!\n\n \"\"\"The releases of the Application.\"\"\"\n releases(\n after: String\n before: String\n first: Int\n last: Int\n\n \"\"\"The order in which to sort the releases.\"\"\"\n orderBy: ReleaseOrderBy\n\n \"\"\"Filter by release status.\"\"\"\n status: ReleaseStatusFilter\n ): ApplicationReleasesConnection\n\n \"\"\"\n The secret for verifying webhook requests to your application. Copy and secure this secret. You will not see it again.\n \"\"\"\n secret: String\n\n \"\"\"The status of the application.\"\"\"\n status: ApplicationStatus!\n\n \"\"\"The timestamp of when the Application was updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The public website of the application.\"\"\"\n url: String\n}\n\n\"\"\"An action that can be executed by an application within the platform.\"\"\"\ntype ApplicationAction {\n \"\"\"The timestamp of when the action was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the action.\"\"\"\n id: String!\n\n \"\"\"A unique identifier for the action within the application.\"\"\"\n name: String!\n\n \"\"\"The timestamp of when the action was last updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The endpoint URL that will be called when this action is triggered.\"\"\"\n url: String!\n}\n\n\"\"\"Input for creating a new application action.\"\"\"\ninput ApplicationActionCreateInput {\n \"\"\"A unique identifier for the action within the application.\"\"\"\n name: String!\n\n \"\"\"\n The path of the endpoint URL that will be called when this action is triggered.\n \"\"\"\n url: String!\n}\n\n\"\"\"\nA dependency an application release declares on another application (the application's id, the name it was declared under, and its required/excluded/enabled state).\n\"\"\"\ntype ApplicationDependency {\n \"\"\"\n The immutable id of the application depended upon. Unaffected by renames of that application.\n \"\"\"\n applicationId: ID!\n\n \"\"\"\n The application name this dependency was declared under. A record of what was declared, not a live reference — it is not rewritten when the depended-upon application is renamed, so it can differ from that application's current name. Use `applicationId` to identify the application.\n \"\"\"\n name: String!\n\n \"\"\"The declared state for this application dependency.\"\"\"\n state: ApplicationDependencyState!\n}\n\n\"\"\"\nInput for declaring a dependency on another application from a release.\n\"\"\"\ninput ApplicationDependencyInput {\n \"\"\"\n The name of the application depended upon. Must match a non-archived application.\n \"\"\"\n name: String!\n\n \"\"\"The declared state for this application dependency.\"\"\"\n state: ApplicationDependencyState!\n}\n\n\"\"\"The state of an application dependency declaration.\"\"\"\nenum ApplicationDependencyState {\n \"\"\"\n The dependency application is enabled by default but can be overridden.\n \"\"\"\n ENABLED\n\n \"\"\"\n The dependency application is excluded and must not be enabled alongside this release.\n \"\"\"\n EXCLUDED\n\n \"\"\"\n The dependency application is required and cannot be disabled while this release is live.\n \"\"\"\n REQUIRED\n}\n\n\"\"\"\nAn enablement represents an application installed for a specific entity (e.g. a store).\n\"\"\"\ntype ApplicationEnablement {\n \"\"\"When the enablement was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"When the application was disabled.\"\"\"\n disabledAt: DateTime\n\n \"\"\"When the application was enabled.\"\"\"\n enabledAt: DateTime\n\n \"\"\"The ID of the entity this application is enabled for.\"\"\"\n entityId: String!\n\n \"\"\"The type of entity (e.g. STORE).\"\"\"\n entityType: String!\n\n \"\"\"The globally-unique ID of the enablement.\"\"\"\n id: String!\n\n \"\"\"When the enablement was last updated.\"\"\"\n updatedAt: DateTime!\n}\n\n\"\"\"A listing for an application.\"\"\"\ntype ApplicationListing {\n \"\"\"The ID of the application this listing belongs to.\"\"\"\n applicationId: ID!\n\n \"\"\"The timestamp when the listing was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"\n Taxonomy facets for this listing (region, industry, category, tag, etc.).\n \"\"\"\n facets: [ApplicationListingFacet!]!\n\n \"\"\"CDN URL of the confirmed HIGHLIGHT asset, or null if not uploaded.\"\"\"\n highlightImageUrl: String\n\n \"\"\"CDN URL of the confirmed ICON asset, or null if not uploaded.\"\"\"\n iconUrl: String\n\n \"\"\"The globally-unique ID of the listing.\"\"\"\n id: ID!\n\n \"\"\"A description for the listing (plain text, max 4000 chars).\"\"\"\n listingDescription: String\n\n \"\"\"HTTPS URL for the privacy policy. Null when not set.\"\"\"\n privacyPolicyUrl: String\n\n \"\"\"CDN URLs of confirmed SCREENSHOT assets, ordered by sort_order.\"\"\"\n screenshotUrls: [String!]!\n\n \"\"\"The lifecycle status of the listing.\"\"\"\n status: ListingStatus!\n\n \"\"\"A short marketing pitch for the listing (plain text, max 160 chars).\"\"\"\n tagline: String\n\n \"\"\"HTTPS URL for the terms and conditions. Null when not set.\"\"\"\n termsAndConditionsUrl: String\n\n \"\"\"The timestamp when the listing was last updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"CDN URLs of confirmed VIDEO assets, ordered by sort_order.\"\"\"\n videoUrls: [String!]!\n\n \"\"\"The visibility of the listing.\"\"\"\n visibility: ListingVisibility!\n}\n\n\"\"\"A taxonomy facet attached to a listing.\"\"\"\ntype ApplicationListingFacet {\n \"\"\"The facet namespace (e.g. 'region', 'industry', 'category', 'tag').\"\"\"\n namespace: String!\n\n \"\"\"The facet value (e.g. 'US', 'retail', 'ecommerce').\"\"\"\n value: String!\n}\n\n\"\"\"\nFilter listings by facet. Returns listings that either have no facets in the given namespace (unrestricted), or have at least one facet in that namespace matching any of the provided values.\n\"\"\"\ninput ApplicationListingFacetFilterInput {\n \"\"\"The facet namespace to filter on (e.g. 'region').\"\"\"\n namespace: String!\n\n \"\"\"\n Accepted facet values (OR semantics within this filter). An empty array is treated as a no-op for this facet filter, not as a filter that matches nothing.\n \"\"\"\n values: [String!]!\n}\n\n\"\"\"A namespace + value pair for a listing facet.\"\"\"\ninput ApplicationListingFacetInput {\n \"\"\"The facet namespace (e.g. 'region', 'industry', 'category', 'tag').\"\"\"\n namespace: String!\n\n \"\"\"The facet value.\"\"\"\n value: String!\n}\n\n\"\"\"Filter options for listing queries.\"\"\"\ninput ApplicationListingFilterInput {\n \"\"\"\n Restrict results to listings for these application IDs (max 50, duplicates ignored).\n \"\"\"\n applicationIds: [ID!]\n\n \"\"\"\n Filter by taxonomy facets. All provided filters must match (AND semantics across namespaces).\n \"\"\"\n facets: [ApplicationListingFacetFilterInput!]\n\n \"\"\"\n Filter by listing lifecycle status. Defaults to ACTIVE for public LISTED discovery. Pass [ACTIVE, INACTIVE] to include deactivated listings (e.g. My Apps by applicationIds).\n \"\"\"\n status: [ListingStatus!]\n\n \"\"\"\n Filter by visibility. Defaults to [LISTED] for public discovery. Pass [LISTED, UNLISTED, HIDDEN] to see all listings for an owner context.\n \"\"\"\n visibility: [ListingVisibility!]\n}\n\n\"\"\"Fields to create or update a listing.\"\"\"\ninput ApplicationListingInput {\n \"\"\"\n Taxonomy facets for the listing. When provided, replaces all existing facets atomically.\n \"\"\"\n facets: [ApplicationListingFacetInput!]\n\n \"\"\"A description for the listing (plain text, max 4000 chars).\"\"\"\n listingDescription: String\n\n \"\"\"\n HTTPS URL for the privacy policy (max 255 chars). Pass null or empty string to clear.\n \"\"\"\n privacyPolicyUrl: String\n\n \"\"\"\n The lifecycle status of the listing. Defaults to INACTIVE on create. ACTIVE requires listing description, privacy URL, terms URL, categories, industries, icon, and screenshots.\n \"\"\"\n status: ListingStatus\n\n \"\"\"A short marketing pitch (plain text, max 160 chars).\"\"\"\n tagline: String\n\n \"\"\"\n HTTPS URL for the terms and conditions (max 255 chars). Pass null or empty string to clear.\n \"\"\"\n termsAndConditionsUrl: String\n\n \"\"\"The visibility of the listing. Defaults to LISTED.\"\"\"\n visibility: ListingVisibility\n}\n\ntype ApplicationListingsConnection {\n edges: [ApplicationListingsConnectionEdge]\n pageInfo: PageInfo!\n}\n\ntype ApplicationListingsConnectionEdge {\n cursor: String!\n node: ApplicationListing\n}\n\n\"\"\"\nAn MCP (Model Context Protocol) server registered with an application release.\n\"\"\"\ntype ApplicationMcpServer {\n \"\"\"The timestamp of when the MCP server was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the MCP server.\"\"\"\n id: String!\n\n \"\"\"Additional configuration for the MCP server.\"\"\"\n metadata: JSONObject\n\n \"\"\"A unique identifier for the MCP server within the release.\"\"\"\n name: String!\n\n \"\"\"The MCP protocol version supported by this server.\"\"\"\n protocolVersion: String\n\n \"\"\"The timestamp of when the MCP server was last updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"\n The path of the endpoint URL that Traefik will route to (e.g., '/mcp/inventory').\n \"\"\"\n url: String!\n}\n\n\"\"\"Input for creating a new MCP server registration.\"\"\"\ninput ApplicationMcpServerCreateInput {\n \"\"\"\n Additional configuration for the MCP server (e.g., tool descriptions, capabilities).\n \"\"\"\n metadata: JSONObject\n\n \"\"\"A unique identifier for the MCP server within the release.\"\"\"\n name: String!\n\n \"\"\"The MCP protocol version supported by this server.\"\"\"\n protocolVersion: String\n\n \"\"\"\n The path of the endpoint URL that Traefik will route to (e.g., '/mcp/inventory').\n \"\"\"\n url: String!\n}\n\n\"\"\"\nA native extension registered with an application release. The target platform is indicated by `platform`.\n\"\"\"\ntype ApplicationNativeExtension {\n \"\"\"The ID of the associated application.\"\"\"\n applicationId: String!\n\n \"\"\"Support contact for the native extension.\"\"\"\n contact: String @deprecated(reason: \"Support contact belongs at the application-registration level, not on an individual extension. Retained temporarily and will be removed once an application-level contact exists.\")\n\n \"\"\"The timestamp of when the native extension was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The globally-unique ID of the native extension.\"\"\"\n id: String!\n\n \"\"\"The display name of the native extension.\"\"\"\n name: String\n\n \"\"\"\n The platform package identifier, in reverse-DNS form (e.g. 'com.example.app'). Optional: not every native deployment is installed through a package manager.\n \"\"\"\n packageName: String\n\n \"\"\"The platform for this native extension.\"\"\"\n platform: NativeExtensionPlatform!\n\n \"\"\"The ID of the associated release.\"\"\"\n releaseId: String!\n\n \"\"\"The timestamp of when the native extension was last updated.\"\"\"\n updatedAt: DateTime!\n}\n\n\"\"\"Input for creating a new native extension.\"\"\"\ninput ApplicationNativeExtensionCreateInput {\n \"\"\"Support contact for the native extension.\"\"\"\n contact: String @deprecated(reason: \"Support contact belongs at the application-registration level, not on an individual extension. Retained temporarily and will be removed once an application-level contact exists.\")\n\n \"\"\"The display name of the native extension.\"\"\"\n name: String\n\n \"\"\"\n The platform package identifier, in reverse-DNS form (e.g. 'com.example.app'). Optional: not every native deployment is installed through a package manager.\n \"\"\"\n packageName: String\n\n \"\"\"The platform for this native extension.\"\"\"\n platform: NativeExtensionPlatform!\n}\n\n\"\"\"Fields by which applications can be ordered.\"\"\"\ninput ApplicationOrderBy {\n \"\"\"Order applications by creation date.\"\"\"\n createdAt: OrderByDirectionEnum\n\n \"\"\"Order applications by ID.\"\"\"\n id: OrderByDirectionEnum\n\n \"\"\"Order applications by name.\"\"\"\n name: OrderByDirectionEnum\n\n \"\"\"Order applications by last update date.\"\"\"\n updatedAt: OrderByDirectionEnum\n}\n\ntype ApplicationRelease {\n \"\"\"The actions registered with this release.\"\"\"\n actions: [ApplicationAction!]!\n\n \"\"\"The timestamp of when the Application was activated.\"\"\"\n activatedAt: DateTime\n\n \"\"\"\n The other applications this release depends on, and the state it declares for each.\n \"\"\"\n applicationDependencies: [ApplicationDependency!]!\n\n \"\"\"The timestamp of when the Application was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The timestamp of when the release was deactivated.\"\"\"\n deactivatedAt: DateTime\n\n \"\"\"\n Information about the new release. Provide information about what has changed and any implications that it might have on your users.\n \"\"\"\n description: String\n\n \"\"\"The feature dependencies declared by this release.\"\"\"\n featureDependencies: [FeatureDependency!]!\n\n \"\"\"The globally-unique ID of the release.\"\"\"\n id: String!\n\n \"\"\"The MCP servers registered with this release.\"\"\"\n mcpServers: [ApplicationMcpServer!]!\n\n \"\"\"The native extensions registered with this release.\"\"\"\n nativeExtensions: [ApplicationNativeExtension!]!\n\n \"\"\"The settings capabilities registered with this release.\"\"\"\n settings(\n \"\"\"Filter settings by Commerce settings group slug.\"\"\"\n groupSlug: String\n ): [ApplicationSetting!]!\n\n \"\"\"The lifecycle status of the release.\"\"\"\n status: ApplicationReleaseStatus!\n\n \"\"\"The webhook subscriptions registered with this release.\"\"\"\n subscriptions: [ApplicationSubscription!]!\n\n \"\"\"The UI extensions registered with this release.\"\"\"\n uiExtensions(\n \"\"\"\n Optional UI extension target filter. Supports has (single match) and hasAny (any match).\n \"\"\"\n target: StringListFilter\n ): [ApplicationUiExtension!]!\n\n \"\"\"The timestamp of when the Application was updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The version number of this release.\"\"\"\n version: String!\n}\n\n\"\"\"The status of an application release.\"\"\"\nenum ApplicationReleaseStatus {\n \"\"\"Release is active and available for use.\"\"\"\n ACTIVE\n\n \"\"\"Release is created but not active.\"\"\"\n INACTIVE\n}\n\ntype ApplicationReleasesConnection {\n edges: [ApplicationReleasesConnectionEdge]\n pageInfo: PageInfo!\n}\n\ntype ApplicationReleasesConnectionEdge {\n cursor: String!\n node: ApplicationRelease\n}\n\n\"\"\"\nA settings capability registered with an application release and placed into a Commerce-owned settings group.\n\"\"\"\ntype ApplicationSetting {\n \"\"\"The app-owned slug for this setting registration.\"\"\"\n appSettingSlug: String!\n\n \"\"\"Lifecycle capabilities supported by this setting.\"\"\"\n capabilities: [String!]!\n\n \"\"\"The timestamp of when the setting was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"Display description for this setting.\"\"\"\n description: String\n\n \"\"\"Localization key for the display description.\"\"\"\n descriptionKey: String\n\n \"\"\"The GPA settings namespace path that lifecycle endpoints live beneath.\"\"\"\n entryPath: String!\n\n \"\"\"The Commerce-owned settings group slug.\"\"\"\n groupSlug: String!\n\n \"\"\"Optional icon library for display.\"\"\"\n iconLibrary: String\n\n \"\"\"Optional icon name for display.\"\"\"\n iconName: String\n\n \"\"\"The globally-unique ID of the application setting.\"\"\"\n id: String!\n\n \"\"\"Additional app-defined settings metadata.\"\"\"\n metadata: JSONObject\n\n \"\"\"Sort order within the settings group.\"\"\"\n order: Int!\n\n \"\"\"The client-renderable presentation contract for this setting.\"\"\"\n presentation: JSONObject!\n\n \"\"\"Display title for this setting.\"\"\"\n title: String\n\n \"\"\"Localization key for the display title.\"\"\"\n titleKey: String\n\n \"\"\"The timestamp of when the setting was last updated.\"\"\"\n updatedAt: DateTime!\n}\n\n\"\"\"Input for creating a new application settings registration.\"\"\"\ninput ApplicationSettingCreateInput {\n \"\"\"The app-owned slug for this setting registration.\"\"\"\n appSettingSlug: String!\n\n \"\"\"\n Lifecycle capabilities supported by this setting (read, write, validate, test, delete, open, config). config requires metadata.configKeys.\n \"\"\"\n capabilities: [String!]\n\n \"\"\"Display description for this setting.\"\"\"\n description: String\n\n \"\"\"Localization key for the display description.\"\"\"\n descriptionKey: String\n\n \"\"\"The GPA settings namespace path that lifecycle endpoints live beneath.\"\"\"\n entryPath: String!\n\n \"\"\"The Commerce-owned settings group slug.\"\"\"\n groupSlug: String!\n\n \"\"\"Optional icon library for display.\"\"\"\n iconLibrary: String\n\n \"\"\"Optional icon name for display.\"\"\"\n iconName: String\n\n \"\"\"Additional app-defined settings metadata.\"\"\"\n metadata: JSONObject\n\n \"\"\"Sort order within the settings group.\"\"\"\n order: Int\n\n \"\"\"\n The settings-form-v1 or settings-link-v1 presentation contract for this setting.\n \"\"\"\n presentation: JSONObject!\n\n \"\"\"Display title for this setting.\"\"\"\n title: String\n\n \"\"\"Localization key for the display title.\"\"\"\n titleKey: String\n}\n\n\"\"\"The current status of an application in the platform.\"\"\"\nenum ApplicationStatus {\n \"\"\"Application is active and can be used.\"\"\"\n ACTIVE\n\n \"\"\"Application has been archived and is no longer available.\"\"\"\n ARCHIVED\n\n \"\"\"Application has been blocked from use due to policy violations.\"\"\"\n BLOCKED\n\n \"\"\"Application is registered but not active.\"\"\"\n INACTIVE\n\n \"\"\"Application is being verified and is not yet active.\"\"\"\n VERIFYING\n}\n\n\"\"\"Filter applications by status.\"\"\"\ninput ApplicationStatusFilter {\n \"\"\"Filter by exact status match.\"\"\"\n eq: ApplicationStatus\n\n \"\"\"Filter by any of the specified statuses.\"\"\"\n in: [ApplicationStatus!]\n\n \"\"\"Filter by status not equal to the specified value.\"\"\"\n ne: ApplicationStatus\n}\n\n\"\"\"\nWebhook subscriptions that an application has opted to subscribe to. Each subscription has one or many events.\n\"\"\"\ntype ApplicationSubscription {\n \"\"\"The timestamp of when the Application was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"A list of events that the subscription will receive.\"\"\"\n events: [String!]!\n\n \"\"\"The globally-unique ID of the release.\"\"\"\n id: String!\n\n \"\"\"The name of the webhook subscription\"\"\"\n name: String!\n\n \"\"\"The timestamp of when the Application was updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The delivery URL of the webhook.\"\"\"\n url: String!\n}\n\n\"\"\"Input for creating a new application webhook subscription.\"\"\"\ninput ApplicationSubscriptionCreateInput {\n \"\"\"List of event types this subscription will receive.\"\"\"\n events: [String!]!\n\n \"\"\"A unique name for the subscription.\"\"\"\n name: String!\n\n \"\"\"The webhook URL that will receive the events.\"\"\"\n url: String!\n}\n\n\"\"\"\nA UI extension registered with an application release (e.g., embed, checkout, blocks).\n\"\"\"\ntype ApplicationUiExtension {\n \"\"\"The base CDN URL for packaged UI extension assets.\"\"\"\n cdnUrl: String\n\n \"\"\"The timestamp of when the UI extension was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The unique handle/identifier for the extension (e.g., 'my-extension').\"\"\"\n handle: String\n\n \"\"\"The globally-unique ID of the UI extension.\"\"\"\n id: String!\n\n \"\"\"The display name of the extension.\"\"\"\n name: String\n\n \"\"\"\n The source file path for the extension (e.g., 'extensions/my-ext/index.ts').\n \"\"\"\n source: String\n\n \"\"\"\n The target location for the extension (e.g., 'body.end', 'checkout.header').\n \"\"\"\n target: String\n\n \"\"\"The type of UI extension (e.g., 'embed', 'checkout', 'blocks').\"\"\"\n type: String!\n\n \"\"\"The timestamp of when the UI extension was last updated.\"\"\"\n updatedAt: DateTime!\n}\n\n\"\"\"Input for creating a new application UI extension.\"\"\"\ninput ApplicationUiExtensionCreateInput {\n \"\"\"\n The unique handle/identifier for the extension (e.g., 'my-extension'). Optional for blocks extensions.\n \"\"\"\n handle: String\n\n \"\"\"The display name of the extension. Optional for blocks extensions.\"\"\"\n name: String\n\n \"\"\"\n The source file path for the extension (e.g., 'extensions/my-ext/index.ts'). Optional for blocks extensions.\n \"\"\"\n source: String\n\n \"\"\"\n The target location for the extension (e.g., 'body.end', 'checkout.header'). Required for targeted extensions, optional for block-type extensions.\n \"\"\"\n target: String\n\n \"\"\"The type of UI extension (e.g., 'embed', 'checkout', 'blocks').\"\"\"\n type: String!\n}\n\n\"\"\"Pre-signed upload URL and metadata for listing media.\"\"\"\ntype CreateMediaUploadUrlResponse {\n expiresAt: DateTime!\n maxSizeBytes: Int!\n mediaObjectId: ID!\n requiredHeaders: [String!]!\n uploadUrl: String!\n}\n\n\"\"\"\nResult of creating an OAuth client secret. Includes the secret value once; store it immediately — it cannot be retrieved again.\n\"\"\"\ntype CreatedOauthClientSecret {\n \"\"\"OAuth client id this secret belongs to, or null when unknown.\"\"\"\n clientId: String\n\n \"\"\"Description of the secret, or null when unknown.\"\"\"\n clientSecretDescription: String\n\n \"\"\"Id of this secret (used to revoke).\"\"\"\n clientSecretId: String!\n\n \"\"\"Display name of the secret, or null when unknown.\"\"\"\n clientSecretName: String\n\n \"\"\"\n The secret value, returned only on create. Store it immediately — it cannot be retrieved again.\n \"\"\"\n clientSecretValue: String!\n\n \"\"\"When this secret was created (ISO-8601), or null when unknown.\"\"\"\n createdAt: String\n\n \"\"\"When this secret was revoked (ISO-8601), or null if still active.\"\"\"\n deletedAt: String\n\n \"\"\"When this secret expires (ISO-8601), or null when unknown.\"\"\"\n expiresOn: String\n}\n\n\"\"\"A date-time string in ISO 8601 format (e.g. 2022-01-01T00:00:00Z).\"\"\"\nscalar DateTime\n\n\"\"\"The distribution type for an application.\"\"\"\nenum DistributionType {\n \"\"\"Application has custom distribution.\"\"\"\n CUSTOM\n\n \"\"\"Application is publicly available.\"\"\"\n PUBLIC\n}\n\ntype EnabledApplication {\n \"\"\"The timestamp of when the Application was activated.\"\"\"\n activatedAt: DateTime\n\n \"\"\"The timestamp of when the Application was archived.\"\"\"\n archivedAt: DateTime\n\n \"\"\"\n The authorization scopes that the OAuth2 client has access to and will use to call API endpoints.\n \"\"\"\n authorizationScopes: [String!]!\n\n \"\"\"\n Earliest linked OAuth client ID for this application by createdAt then id (includes NULL-secret and ARCHIVED apps).\n \"\"\"\n clientId: ID\n\n \"\"\"\n The primary OAuth client secret for this application. Only returned on application creation.\n \"\"\"\n clientSecret: String\n\n \"\"\"The timestamp of when the Application was created.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The timestamp of when the Application was deactivated.\"\"\"\n deactivatedAt: DateTime\n\n \"\"\"General information about your application.\"\"\"\n description: String\n\n \"\"\"The globally-unique ID of the Application.\"\"\"\n id: ID!\n\n \"\"\"A human-readable label of the Application for display purposes.\"\"\"\n label: String!\n\n \"\"\"A url-friendly name for the Application.\"\"\"\n name: String!\n\n \"\"\"The ID of the organization that owns this Application.\"\"\"\n organizationId: ID!\n\n \"\"\"\n The base URL of your application. This is the endpoint that the GoDaddy Commerce platform will call when integrated with actions.\n \"\"\"\n proxyUrl: String\n\n \"\"\"\n The public key (base64 encoded) for verifying action requests to your application.\n \"\"\"\n publicKey: String\n\n \"\"\"\n Additional OAuth redirect URIs on the application's OAuth client(s). URL-derived defaults (the application URL and {url}/api/godaddy/callback) are omitted so this list can be submitted unchanged on create or update.\n \"\"\"\n redirectUris: [String!]!\n\n \"\"\"The release/version enabled for this application\"\"\"\n release: ApplicationRelease\n\n \"\"\"\n The secret for verifying webhook requests to your application. Copy and secure this secret. You will not see it again.\n \"\"\"\n secret: String\n\n \"\"\"The status of the application.\"\"\"\n status: ApplicationStatus!\n\n \"\"\"The timestamp of when the Application was updated.\"\"\"\n updatedAt: DateTime!\n\n \"\"\"The public website of the application.\"\"\"\n url: String\n}\n\n\"\"\"Fields by which enablements can be ordered.\"\"\"\ninput EnablementOrderBy {\n \"\"\"Order enablements by creation date.\"\"\"\n createdAt: OrderByDirectionEnum\n\n \"\"\"Order enablements by ID.\"\"\"\n id: OrderByDirectionEnum\n\n \"\"\"Order enablements by last update date.\"\"\"\n updatedAt: OrderByDirectionEnum\n}\n\n\"\"\"\nA feature dependency declared by an application release (a feature name and its required/excluded/enabled/disabled state).\n\"\"\"\ntype FeatureDependency {\n \"\"\"The feature name from the available features list.\"\"\"\n name: String!\n\n \"\"\"The declared state for this feature.\"\"\"\n state: FeatureDependencyState!\n}\n\n\"\"\"Input for declaring a feature dependency on a release.\"\"\"\ninput FeatureDependencyInput {\n \"\"\"The feature name from the available features list.\"\"\"\n name: String!\n\n \"\"\"The declared state for this feature.\"\"\"\n state: FeatureDependencyState!\n}\n\n\"\"\"The state of a feature dependency declaration.\"\"\"\nenum FeatureDependencyState {\n \"\"\"Feature is disabled by default but can be overridden.\"\"\"\n DISABLED\n\n \"\"\"Feature is enabled by default but can be overridden.\"\"\"\n ENABLED\n\n \"\"\"Feature is excluded and cannot be required by other apps.\"\"\"\n EXCLUDED\n\n \"\"\"Feature is required and cannot be excluded by other apps.\"\"\"\n REQUIRED\n}\n\n\"\"\"Response containing pre-signed upload URL and metadata.\"\"\"\ntype GenerateReleaseUploadUrlResponse {\n \"\"\"The timestamp when the upload URL expires.\"\"\"\n expiresAt: DateTime!\n\n \"\"\"The S3 key where the file should be uploaded.\"\"\"\n key: String!\n\n \"\"\"Maximum allowed file size in bytes.\"\"\"\n maxSizeBytes: Int!\n\n \"\"\"Required headers for the upload as key:value pairs.\"\"\"\n requiredHeaders: [String!]!\n\n \"\"\"The unique upload identifier for tracking.\"\"\"\n uploadId: String!\n\n \"\"\"The pre-signed URL for uploading the file.\"\"\"\n url: String!\n}\n\n\"\"\"A JSON object scalar type.\"\"\"\nscalar JSONObject @specifiedBy(url: \"http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf\")\n\n\"\"\"Allowed MIME types for listing media uploads.\"\"\"\nenum ListingMediaContentType {\n IMAGE_JPEG\n IMAGE_PNG\n VIDEO_MP4\n}\n\n\"\"\"The merchandising role of a listing media asset.\"\"\"\nenum ListingMediaRole {\n HIGHLIGHT\n ICON\n SCREENSHOT\n VIDEO\n}\n\n\"\"\"The lifecycle status of a listing media upload.\"\"\"\nenum ListingMediaStatus {\n CONFIRMED\n FAILED\n PENDING\n REMOVED\n SUPERSEDED\n}\n\n\"\"\"The lifecycle status of a listing.\"\"\"\nenum ListingStatus {\n \"\"\"Listing is active and eligible for marketplace discovery.\"\"\"\n ACTIVE\n\n \"\"\"Listing is inactive until activation requirements are met.\"\"\"\n INACTIVE\n}\n\n\"\"\"The visibility of a listing.\"\"\"\nenum ListingVisibility {\n \"\"\"Listing is hidden from discovery surfaces.\"\"\"\n HIDDEN\n\n \"\"\"Listing is publicly visible.\"\"\"\n LISTED\n\n \"\"\"Listing is not shown in search.\"\"\"\n UNLISTED\n}\n\n\"\"\"A media asset attached to an application listing.\"\"\"\ntype MediaObject {\n applicationId: ID!\n contentType: String\n createdAt: DateTime!\n failureReason: String\n filename: String\n id: ID!\n listingId: ID\n role: ListingMediaRole\n sortOrder: Int!\n status: ListingMediaStatus!\n updatedAt: DateTime!\n url: String\n}\n\ntype Mutation {\n \"\"\"\n Activate a release and, when permitted, promote its parent application to ACTIVE.\n \"\"\"\n activateRelease(\n \"\"\"The ID of the application.\"\"\"\n applicationId: ID!\n\n \"\"\"The ID of the release to activate.\"\"\"\n releaseId: ID!\n ): ApplicationRelease\n\n \"\"\"Archive an existing Application.\"\"\"\n archiveApplication(\n \"\"\"The ID of the application to archive.\"\"\"\n id: String!\n ): Application\n\n \"\"\"Confirm a listing media upload after the client PUTs the file to S3.\"\"\"\n confirmMediaObject(\n \"\"\"The application that owns the media object — used for authorization.\"\"\"\n applicationId: ID!\n\n \"\"\"The media object ID returned from createMediaUploadUrl.\"\"\"\n mediaObjectId: ID!\n ): MediaObject\n\n \"\"\"Create a new Application.\"\"\"\n createApplication(input: MutationCreateApplicationInput!): Application\n\n \"\"\"\n Create an additional OAuth client secret on the application's primary OAuth client. Returns the secret value once. Fails when the active-secret limit is reached.\n \"\"\"\n createApplicationOauthClientSecret(\n \"\"\"The application to create a secret for.\"\"\"\n applicationId: String!\n input: MutationCreateApplicationOauthClientSecretInput!\n ): CreatedOauthClientSecret\n\n \"\"\"\n Create a pending listing media record and return a pre-signed S3 PUT URL.\n \"\"\"\n createMediaUploadUrl(\n \"\"\"The application that owns the listing (1:1).\"\"\"\n applicationId: ID!\n\n \"\"\"MIME type of the file to upload.\"\"\"\n contentType: ListingMediaContentType!\n\n \"\"\"\n Declared file size in bytes. Rejected if it exceeds the role cap before issuing the presigned URL.\n \"\"\"\n fileSizeBytes: Int!\n\n \"\"\"Original filename from the client.\"\"\"\n filename: String!\n\n \"\"\"Merchandising role for this asset.\"\"\"\n role: ListingMediaRole!\n\n \"\"\"\n Optional ordering for screenshots/videos (0–7). Defaults to next slot. Ignored for other roles (defaults to 0).\n \"\"\"\n sortOrder: Int\n ): CreateMediaUploadUrlResponse\n\n \"\"\"Create a new release for an application.\"\"\"\n createRelease(input: MutationCreateReleaseInput!): ApplicationRelease\n\n \"\"\"\n Deactivate an application through its lifecycle operation. Activate it again by activating a release.\n \"\"\"\n deactivateApplication(\n \"\"\"The ID of the application to deactivate.\"\"\"\n id: String!\n ): Application\n\n \"\"\"\n Deactivate a release. When it is the last active release, its application listing is also deactivated.\n \"\"\"\n deactivateRelease(\n \"\"\"The ID of the application.\"\"\"\n applicationId: ID!\n\n \"\"\"The ID of the release to deactivate.\"\"\"\n releaseId: ID!\n ): ApplicationRelease\n\n \"\"\"Soft-delete the listing for an application.\"\"\"\n deleteApplicationListing(\n \"\"\"The ID of the application.\"\"\"\n applicationId: ID!\n ): Boolean\n\n \"\"\"Disable an application on a customer\"\"\"\n disableCustomerApplication(input: MutationDisableCustomerApplicationInput!): Application\n\n \"\"\"Disable an application in a store\"\"\"\n disableStoreApplication(input: MutationDisableStoreApplicationInput!): Application\n\n \"\"\"Enable an application on a customer\"\"\"\n enableCustomerApplication(input: MutationEnableCustomerApplicationInput!): Application\n\n \"\"\"Enable an application on a store\"\"\"\n enableStoreApplication(input: MutationEnableStoreApplicationInput!): Application\n\n \"\"\"Generate a pre-signed URL for uploading UI extension artifacts.\"\"\"\n generateReleaseUploadUrl(input: MutationGenerateReleaseUploadUrlInput!): GenerateReleaseUploadUrlResponse\n\n \"\"\"\n Remove a confirmed listing media object. Sets status to REMOVED, deletes the promoted S3 object, and invalidates the CDN path.\n \"\"\"\n removeListingMediaObject(\n \"\"\"\n The application that owns the media object — prevents cross-app removal.\n \"\"\"\n applicationId: ID!\n\n \"\"\"The confirmed media object ID to remove.\"\"\"\n mediaObjectId: ID!\n ): MediaObject\n\n \"\"\"\n Revoke one OAuth client secret on the application's primary OAuth client. Cannot revoke the last active secret — create another first.\n \"\"\"\n revokeApplicationOauthClientSecret(\n \"\"\"The application whose secret to revoke.\"\"\"\n applicationId: String!\n input: MutationRevokeApplicationOauthClientSecretInput!\n ): RevokedOauthClientSecret\n\n \"\"\"\n Create or update the listing for an application. Idempotent — safe to call multiple times for the same application.\n \"\"\"\n setApplicationListing(\n \"\"\"The ID of the application.\"\"\"\n applicationId: ID!\n\n \"\"\"The listing fields to create or update.\"\"\"\n input: ApplicationListingInput!\n ): ApplicationListing\n\n \"\"\"Update an existing Application.\"\"\"\n updateApplication(id: String!, input: MutationUpdateApplicationInput!): Application\n}\n\ninput MutationCreateApplicationInput {\n \"\"\"\n The authorization scopes of the application. Defines the GoDaddy permissions for the application.\n \"\"\"\n authorizationScopes: [String!]\n\n \"\"\"The description of the application.\"\"\"\n description: String\n\n \"\"\"The distribution type for the application. Defaults to PUBLIC.\"\"\"\n distributionType: DistributionType = PUBLIC\n\n \"\"\"The label of the application.\"\"\"\n label: String!\n\n \"\"\"The name of the application.\"\"\"\n name: String!\n\n \"\"\"\n Optional organization ID for multi-org users. If omitted, the organization is auto-resolved from the user's session. If provided, the user must be an admin of the specified organization.\n \"\"\"\n organizationId: String\n\n \"\"\"\n The proxy URL of the application. This is the base URL for all API endpoints.\n \"\"\"\n proxyUrl: String\n\n \"\"\"\n Additional OAuth redirect URI allowlist. Supports up to 5 unique HTTPS URLs. Entries equal to the application URL or its default callback are rejected; those defaults are registered automatically.\n \"\"\"\n redirectUris: [String!]\n\n \"\"\"\n The public URL of the application. This is typically the URL of the application's website.\n \"\"\"\n url: String\n}\n\ninput MutationCreateApplicationOauthClientSecretInput {\n \"\"\"Description for the new secret. Cannot be blank.\"\"\"\n clientSecretDescription: String!\n\n \"\"\"Display name for the new secret.\"\"\"\n clientSecretName: String!\n}\n\ninput MutationCreateReleaseInput {\n \"\"\"The actions associated with the release.\"\"\"\n actions: [ApplicationActionCreateInput!]\n\n \"\"\"\n The other applications this release depends on, and the state it declares for each.\n \"\"\"\n applicationDependencies: [ApplicationDependencyInput!]\n\n \"\"\"The ID of the application.\"\"\"\n applicationId: ID!\n\n \"\"\"The description of the release.\"\"\"\n description: String\n\n \"\"\"The feature dependencies declared by the release.\"\"\"\n featureDependencies: [FeatureDependencyInput!]\n\n \"\"\"The MCP servers associated with the release.\"\"\"\n mcpServers: [ApplicationMcpServerCreateInput!]\n\n \"\"\"The native extensions associated with the release.\"\"\"\n nativeExtensions: [ApplicationNativeExtensionCreateInput!]\n\n \"\"\"The settings capabilities associated with the release.\"\"\"\n settings: [ApplicationSettingCreateInput!]\n\n \"\"\"The subscriptions associated with the release.\"\"\"\n subscriptions: [ApplicationSubscriptionCreateInput!]\n\n \"\"\"The UI extensions associated with the release.\"\"\"\n uiExtensions: [ApplicationUiExtensionCreateInput!]\n\n \"\"\"The version of the release.\"\"\"\n version: String!\n}\n\ninput MutationDisableCustomerApplicationInput {\n \"\"\"The name of the application to disable.\"\"\"\n applicationName: String!\n\n \"\"\"The ID of the customer to disable the application on.\"\"\"\n customerId: String!\n}\n\ninput MutationDisableStoreApplicationInput {\n \"\"\"The name of the application to disable.\"\"\"\n applicationName: String!\n\n \"\"\"The ID of the store to disable the application on.\"\"\"\n storeId: String!\n}\n\ninput MutationEnableCustomerApplicationInput {\n \"\"\"The name of the application to enable.\"\"\"\n applicationName: String!\n\n \"\"\"The ID of the customer to enable the application on.\"\"\"\n customerId: String!\n}\n\ninput MutationEnableStoreApplicationInput {\n \"\"\"The name of the application to enable.\"\"\"\n applicationName: String!\n\n \"\"\"The ID of the store to enable the application on.\"\"\"\n storeId: String!\n}\n\ninput MutationGenerateReleaseUploadUrlInput {\n \"\"\"The ID of the application.\"\"\"\n applicationId: ID!\n\n \"\"\"The content type of the file to be uploaded.\"\"\"\n contentType: UploadContentType!\n\n \"\"\"The ID of the release.\"\"\"\n releaseId: ID!\n\n \"\"\"The target for the upload.\"\"\"\n target: String\n}\n\ninput MutationRevokeApplicationOauthClientSecretInput {\n \"\"\"Id of the secret to revoke.\"\"\"\n clientSecretId: String!\n}\n\ninput MutationUpdateApplicationInput {\n \"\"\"\n The authorization scopes of the application. Defines the GoDaddy permissions for the application.\n \"\"\"\n authorizationScopes: [String!]\n\n \"\"\"The description of the application.\"\"\"\n description: String\n\n \"\"\"\n The distribution type for the application (PUBLIC or CUSTOM). Omit to leave unchanged.\n \"\"\"\n distributionType: DistributionType\n\n \"\"\"The label of the application.\"\"\"\n label: String\n\n \"\"\"The name of the application.\"\"\"\n name: String\n\n \"\"\"\n The proxy URL of the application. This is the base URL for all API endpoints.\n \"\"\"\n proxyUrl: String\n\n \"\"\"\n Additional OAuth redirect URI allowlist. Supports up to 5 unique HTTPS URLs. Entries equal to the effective application URL or its default callback are rejected. On URL changes, both old defaults are replaced; submit any old URI explicitly to retain it as an extra.\n \"\"\"\n redirectUris: [String!]\n\n \"\"\"\n The public URL of the application. This is typically the URL of the application's website.\n \"\"\"\n url: String\n}\n\n\"\"\"The platform for a native extension.\"\"\"\nenum NativeExtensionPlatform {\n \"\"\"Android platform (APK distribution).\"\"\"\n ANDROID\n}\n\n\"\"\"Represents a null value.\"\"\"\nscalar Null\n\n\"\"\"\nMetadata for one OAuth client secret on an application's primary OAuth client. Secret values are never included.\n\"\"\"\ntype OauthClientSecret {\n \"\"\"OAuth client id this secret belongs to, or null when unknown.\"\"\"\n clientId: String\n\n \"\"\"Description of the secret, or null when unknown.\"\"\"\n clientSecretDescription: String\n\n \"\"\"Id of this secret (used to revoke).\"\"\"\n clientSecretId: String!\n\n \"\"\"Display name of the secret, or null when unknown.\"\"\"\n clientSecretName: String\n\n \"\"\"When this secret was created (ISO-8601), or null when unknown.\"\"\"\n createdAt: String\n\n \"\"\"When this secret was revoked (ISO-8601), or null if still active.\"\"\"\n deletedAt: String\n\n \"\"\"When this secret expires (ISO-8601), or null when unknown.\"\"\"\n expiresOn: String\n}\n\n\"\"\"Direction for ordering results in queries.\"\"\"\nenum OrderByDirectionEnum {\n \"\"\"Sort in ascending order.\"\"\"\n ASC\n\n \"\"\"Sort 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 single application by ID or name.\"\"\"\n application(\n \"\"\"The OAuth client ID of the application to retrieve.\"\"\"\n clientId: String\n\n \"\"\"The unique ID of the application to retrieve.\"\"\"\n id: String\n\n \"\"\"The unique name of the application to retrieve.\"\"\"\n name: String\n ): Application\n\n \"\"\"\n Paginated listings. Defaults to publicly LISTED listings for active PUBLIC-distribution apps with an active release. Pass visibility filter to query owner/admin contexts.\n \"\"\"\n applicationListings(\n after: String\n before: String\n\n \"\"\"Filter options for the query.\"\"\"\n filter: ApplicationListingFilterInput\n first: Int\n last: Int\n ): QueryApplicationListingsConnection\n\n \"\"\"\n List OAuth client secrets (metadata only) for an application's primary OAuth client. Requires application write access.\n \"\"\"\n applicationOauthClientSecrets(\n \"\"\"The application whose primary OAuth client secrets to list.\"\"\"\n applicationId: String!\n ): [OauthClientSecret!]!\n\n \"\"\"\n Get paginated applications. Returns all public applications for service requests, or only applications owned by the authenticated customer's organization. Multi-org users may pass an explicit `organizationId` to select which organization's apps to list.\n \"\"\"\n applications(\n after: String\n before: String\n first: Int\n last: Int\n\n \"\"\"The order in which to sort the applications.\"\"\"\n orderBy: ApplicationOrderBy\n\n \"\"\"\n Optional organization ID. When provided, lists apps for that specific organization. Customer tokens must be admin of the organization; service tokens may specify any organization.\n \"\"\"\n organizationId: String\n\n \"\"\"Filter by application status. Defaults to ACTIVE applications only.\"\"\"\n status: ApplicationStatusFilter\n ): QueryApplicationsConnection\n\n \"\"\"\n Get all applications enabled for an entity by entity ID and type, with optional filtering by actions, UI extensions, and settings.\n \"\"\"\n enabledApplications(\n \"\"\"\n Filter by action names. Supports has (single match) and hasAny (any match).\n \"\"\"\n actionNames: StringListFilter\n\n \"\"\"The ID of the entity to get enabled applications for.\"\"\"\n entityId: String!\n\n \"\"\"\n The type of the entity the applications are enabled on. Currently STORE.\n \"\"\"\n entityType: String!\n\n \"\"\"Filter by Commerce settings group slug.\"\"\"\n settingGroupSlug: String\n\n \"\"\"\n Filter by application setting slugs. Supports has (single match) and hasAny (any match).\n \"\"\"\n settingSlugs: StringListFilter\n\n \"\"\"\n Filter by UI extension targets. Supports has (single match) and hasAny (any match).\n \"\"\"\n uiExtensionTargets: StringListFilter\n\n \"\"\"\n Filter by UI extension types. Supports has (single match) and hasAny (any match).\n \"\"\"\n uiExtensionTypes: StringListFilter\n ): [EnabledApplication!]\n\n \"\"\"\n Get all applications enabled for a store by store ID, with optional filtering by actions, UI extensions, and settings.\n \"\"\"\n enabledStoreApplications(\n \"\"\"\n Filter by action names. Supports has (single match) and hasAny (any match).\n \"\"\"\n actionNames: StringListFilter\n\n \"\"\"Filter by Commerce settings group slug.\"\"\"\n settingGroupSlug: String\n\n \"\"\"\n Filter by application setting slugs. Supports has (single match) and hasAny (any match).\n \"\"\"\n settingSlugs: StringListFilter\n\n \"\"\"The ID of the store to get enabled applications for.\"\"\"\n storeId: String!\n\n \"\"\"\n Filter by UI extension targets. Supports has (single match) and hasAny (any match).\n \"\"\"\n uiExtensionTargets: StringListFilter\n\n \"\"\"\n Filter by UI extension types. Supports has (single match) and hasAny (any match).\n \"\"\"\n uiExtensionTypes: StringListFilter\n ): [EnabledApplication!]\n\n \"\"\"Returns a paginated list of enablements for a specific release.\"\"\"\n enablementsByRelease(\n after: String\n before: String\n first: Int\n last: Int\n\n \"\"\"The order in which to sort the enablements.\"\"\"\n orderBy: EnablementOrderBy\n\n \"\"\"The release ID to query enablements for.\"\"\"\n releaseId: ID!\n ): QueryEnablementsByReleaseConnection!\n\n \"\"\"Get the status of a release upload by upload ID.\"\"\"\n getReleaseUpload(\n \"\"\"The application ID to verify authorization.\"\"\"\n applicationId: ID!\n\n \"\"\"The unique upload identifier.\"\"\"\n uploadId: String!\n ): ReleaseUpload\n\n \"\"\"Get a single native extension by ID.\"\"\"\n nativeExtension(\n \"\"\"The ID of the native extension to retrieve.\"\"\"\n id: ID!\n ): ApplicationNativeExtension\n\n \"\"\"\n List native extensions by application or release. At least one of applicationId or releaseId must be provided.\n \"\"\"\n nativeExtensions(\n \"\"\"Filter by application ID.\"\"\"\n applicationId: ID\n\n \"\"\"Maximum number of results to return.\"\"\"\n limit: Int\n\n \"\"\"Filter by release ID.\"\"\"\n releaseId: ID\n ): [ApplicationNativeExtension!]!\n\n \"\"\"\n Get the resolved feature states for a store, after reconciling all active app declarations.\n \"\"\"\n storeFeatures(\n \"\"\"The ID of the store to resolve features for.\"\"\"\n storeId: String!\n ): [FeatureDependency!]!\n\n \"\"\"Returns webhook subscription IDs for a specific release/entity pair.\"\"\"\n webhookSubscriptionInstancesByRelease(\n \"\"\"The entity ID to scope the query to.\"\"\"\n entityId: ID!\n\n \"\"\"The entity type to scope the query to (e.g. STORE).\"\"\"\n entityType: String!\n\n \"\"\"The release ID to query webhook subscriptions for.\"\"\"\n releaseId: ID!\n ): [String!]!\n}\n\ntype QueryApplicationListingsConnection {\n edges: [QueryApplicationListingsConnectionEdge]\n pageInfo: PageInfo!\n}\n\ntype QueryApplicationListingsConnectionEdge {\n cursor: String!\n node: ApplicationListing\n}\n\ntype QueryApplicationsConnection {\n edges: [QueryApplicationsConnectionEdge]\n pageInfo: PageInfo!\n}\n\ntype QueryApplicationsConnectionEdge {\n cursor: String!\n node: Application\n}\n\ntype QueryEnablementsByReleaseConnection {\n edges: [QueryEnablementsByReleaseConnectionEdge]\n pageInfo: PageInfo!\n}\n\ntype QueryEnablementsByReleaseConnectionEdge {\n cursor: String!\n node: ApplicationEnablement\n}\n\n\"\"\"Fields by which application releases can be ordered.\"\"\"\ninput ReleaseOrderBy {\n \"\"\"Order releases by activation date.\"\"\"\n activatedAt: OrderByDirectionEnum\n\n \"\"\"Order releases by creation date.\"\"\"\n createdAt: OrderByDirectionEnum\n\n \"\"\"Order releases by ID.\"\"\"\n id: OrderByDirectionEnum\n\n \"\"\"Order releases by last update date.\"\"\"\n updatedAt: OrderByDirectionEnum\n\n \"\"\"Order releases by version number. Must be in {major}.{minor} format.\"\"\"\n version: OrderByDirectionEnum\n}\n\n\"\"\"Filter releases by status.\"\"\"\ninput ReleaseStatusFilter {\n \"\"\"Filter by exact status match.\"\"\"\n eq: ApplicationReleaseStatus\n\n \"\"\"Filter by any of the specified statuses.\"\"\"\n in: [ApplicationReleaseStatus!]\n\n \"\"\"Filter by status not equal to the specified value.\"\"\"\n ne: ApplicationReleaseStatus\n}\n\n\"\"\"A release upload record tracking the status of uploaded artifacts.\"\"\"\ntype ReleaseUpload {\n \"\"\"The ID of the associated application.\"\"\"\n applicationId: String!\n\n \"\"\"The timestamp when the upload was completed or failed.\"\"\"\n completedAt: DateTime\n\n \"\"\"The MIME type of the uploaded content.\"\"\"\n contentType: UploadContentType!\n\n \"\"\"The timestamp when the upload was requested.\"\"\"\n createdAt: DateTime!\n\n \"\"\"The reason for failure if status is FAILED.\"\"\"\n failureReason: String\n\n \"\"\"The globally-unique ID of the upload record.\"\"\"\n id: String!\n\n \"\"\"The ID of the associated release.\"\"\"\n releaseId: String!\n\n \"\"\"The size of the uploaded file in bytes.\"\"\"\n sizeBytes: Int\n\n \"\"\"The current status of the upload.\"\"\"\n status: ReleaseUploadStatus!\n\n \"\"\"The unique upload identifier used for correlation.\"\"\"\n uploadId: String!\n}\n\n\"\"\"The status of a release upload.\"\"\"\nenum ReleaseUploadStatus {\n \"\"\"Upload or processing failed.\"\"\"\n FAILED\n\n \"\"\"File has been processed and deployed successfully.\"\"\"\n PROCESSED\n\n \"\"\"Upload URL has been generated and is awaiting upload.\"\"\"\n REQUESTED\n\n \"\"\"File has been uploaded and is awaiting processing.\"\"\"\n UPLOADED\n}\n\n\"\"\"Result of revoking an OAuth client secret.\"\"\"\ntype RevokedOauthClientSecret {\n \"\"\"Id of the revoked secret.\"\"\"\n clientSecretId: String!\n}\n\n\"\"\"Filter for fields that are lists/sets of strings.\"\"\"\ninput StringListFilter {\n \"\"\"Field must contain this value.\"\"\"\n has: String\n\n \"\"\"Field must contain at least one of these values.\"\"\"\n hasAny: [String!]\n}\n\n\"\"\"Supported content types for release uploads.\"\"\"\nenum UploadContentType {\n \"\"\"JavaScript file\"\"\"\n JS\n\n \"\"\"TAR archive\"\"\"\n TAR\n\n \"\"\"ZIP archive\"\"\"\n ZIP\n}", "types": [ { "fields": [ @@ -1794,6 +1849,52 @@ "kind": "object", "name": "CreateMediaUploadUrlResponse" }, + { + "fields": [ + { + "description": "OAuth client id this secret belongs to, or null when unknown.", + "name": "clientId", + "type": "String" + }, + { + "description": "Description of the secret, or null when unknown.", + "name": "clientSecretDescription", + "type": "String" + }, + { + "description": "Id of this secret (used to revoke).", + "name": "clientSecretId", + "type": "String!" + }, + { + "description": "Display name of the secret, or null when unknown.", + "name": "clientSecretName", + "type": "String" + }, + { + "description": "The secret value, returned only on create. Store it immediately — it cannot be retrieved again.", + "name": "clientSecretValue", + "type": "String!" + }, + { + "description": "When this secret was created (ISO-8601), or null when unknown.", + "name": "createdAt", + "type": "String" + }, + { + "description": "When this secret was revoked (ISO-8601), or null if still active.", + "name": "deletedAt", + "type": "String" + }, + { + "description": "When this secret expires (ISO-8601), or null when unknown.", + "name": "expiresOn", + "type": "String" + } + ], + "kind": "object", + "name": "CreatedOauthClientSecret" + }, { "kind": "enum", "name": "DistributionType", @@ -2159,6 +2260,22 @@ "kind": "input", "name": "MutationCreateApplicationInput" }, + { + "fields": [ + { + "description": "Description for the new secret. Cannot be blank.", + "name": "clientSecretDescription", + "type": "String!" + }, + { + "description": "Display name for the new secret.", + "name": "clientSecretName", + "type": "String!" + } + ], + "kind": "input", + "name": "MutationCreateApplicationOauthClientSecretInput" + }, { "fields": [ { @@ -2310,6 +2427,17 @@ "kind": "input", "name": "MutationGenerateReleaseUploadUrlInput" }, + { + "fields": [ + { + "description": "Id of the secret to revoke.", + "name": "clientSecretId", + "type": "String!" + } + ], + "kind": "input", + "name": "MutationRevokeApplicationOauthClientSecretInput" + }, { "fields": [ { @@ -2363,6 +2491,47 @@ "ANDROID" ] }, + { + "fields": [ + { + "description": "OAuth client id this secret belongs to, or null when unknown.", + "name": "clientId", + "type": "String" + }, + { + "description": "Description of the secret, or null when unknown.", + "name": "clientSecretDescription", + "type": "String" + }, + { + "description": "Id of this secret (used to revoke).", + "name": "clientSecretId", + "type": "String!" + }, + { + "description": "Display name of the secret, or null when unknown.", + "name": "clientSecretName", + "type": "String" + }, + { + "description": "When this secret was created (ISO-8601), or null when unknown.", + "name": "createdAt", + "type": "String" + }, + { + "description": "When this secret was revoked (ISO-8601), or null if still active.", + "name": "deletedAt", + "type": "String" + }, + { + "description": "When this secret expires (ISO-8601), or null when unknown.", + "name": "expiresOn", + "type": "String" + } + ], + "kind": "object", + "name": "OauthClientSecret" + }, { "kind": "enum", "name": "OrderByDirectionEnum", @@ -2595,6 +2764,17 @@ "UPLOADED" ] }, + { + "fields": [ + { + "description": "Id of the revoked secret.", + "name": "clientSecretId", + "type": "String!" + } + ], + "kind": "object", + "name": "RevokedOauthClientSecret" + }, { "fields": [ { @@ -2636,5 +2816,5 @@ ], "name": "app-registry", "title": "app-registry GraphQL API", - "version": "570a114" + "version": "03494d6" } \ No newline at end of file diff --git a/rust/schemas/api/customer-profiles.json b/rust/schemas/api/customer-profiles.json index 22be415f..78a17ccb 100644 --- a/rust/schemas/api/customer-profiles.json +++ b/rust/schemas/api/customer-profiles.json @@ -13,7 +13,7 @@ "endpoints": [ { "graphql": { - "operationCount": 20, + "operationCount": 21, "operations": [ { "args": [ @@ -308,24 +308,6 @@ "name": "deleteCustomer", "returnType": "DeleteCustomerResponse!" }, - { - "args": [ - { - "name": "customerId", - "required": true, - "type": "ID!" - }, - { - "name": "input", - "required": true, - "type": "DeleteMetafieldsInput!" - } - ], - "deprecated": false, - "kind": "mutation", - "name": "deleteMetafields", - "returnType": "DeleteMetafieldsResponse!" - }, { "args": [ { @@ -381,6 +363,25 @@ "name": "removeIdentitiesFromCustomer", "returnType": "RemoveIdentitiesFromCustomerResponse!" }, + { + "args": [ + { + "name": "customerId", + "required": true, + "type": "ID!" + }, + { + "name": "input", + "required": true, + "type": "RemoveMetafieldsInput!" + } + ], + "deprecated": false, + "description": "Remove metafields from a customer within the current store context (x-store-id), by metafield id.", + "kind": "mutation", + "name": "removeMetafieldsFromCustomer", + "returnType": "RemoveMetafieldsFromCustomerResponse!" + }, { "args": [ { @@ -494,10 +495,29 @@ "kind": "mutation", "name": "updateCustomer", "returnType": "UpdateCustomerResponse!" + }, + { + "args": [ + { + "name": "customerId", + "required": true, + "type": "ID!" + }, + { + "name": "input", + "required": true, + "type": "UpsertCustomerMetafieldsInput!" + } + ], + "deprecated": false, + "description": "Create or update metafields on a customer within the current store context (x-store-id). Accepts between 1 and 100 entries per call; entries are identified by `namespace` and `key` on the customer. The entries are sent to the Metafields service as a single bulk request and the mutation succeeds or fails as a whole: on success `metafields` contains the upserted metafields; on failure it is `null` and details are in `errors`.", + "kind": "mutation", + "name": "upsertCustomerMetafields", + "returnType": "UpsertCustomerMetafieldsResponse!" } ], "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", + "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\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 \"\"\"Metafield namespace. 1 to 255 characters.\"\"\"\n namespace: String!\n\n \"\"\"Metafield value type (e.g. string, number, json).\"\"\"\n type: 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\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 metafields from a customer within the current store context (x-store-id), by metafield id.\n \"\"\"\n removeMetafieldsFromCustomer(customerId: ID!, input: RemoveMetafieldsInput!): RemoveMetafieldsFromCustomerResponse!\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 Create or update metafields on a customer within the current store context (x-store-id). Accepts between 1 and 100 entries per call; entries are identified by `namespace` and `key` on the customer. The entries are sent to the Metafields service as a single bulk request and the mutation succeeds or fails as a whole: on success `metafields` contains the upserted metafields; on failure it is `null` and details are in `errors`.\n \"\"\"\n upsertCustomerMetafields(customerId: ID!, input: UpsertCustomerMetafieldsInput!): UpsertCustomerMetafieldsResponse!\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 metafields mutation.\"\"\"\ntype RemoveMetafieldsFromCustomerResponse 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\ninput RemoveMetafieldsInput {\n \"\"\"\n Metafield ids to remove. 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 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\ninput UpsertCustomerMetafieldsInput {\n \"\"\"Metafields to upsert. Must contain between 1 and 100 entries.\"\"\"\n metafields: [MetafieldEntryInput!]!\n}\n\n\"\"\"Response to an upsert customer metafields mutation.\"\"\"\ntype UpsertCustomerMetafieldsResponse 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 \"\"\"\n The metafields that were created or updated. Populated only when `success` is true; `null` (not an empty list) when the mutation fails.\n \"\"\"\n metafields: [Metafield!]\n\n \"\"\"Indicates whether the mutation was successful.\"\"\"\n success: Boolean!\n}\n", "types": [ { "fields": [ @@ -1440,43 +1460,6 @@ "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": [ { @@ -1666,6 +1649,16 @@ "name": "key", "type": "String!" }, + { + "description": "Metafield namespace. 1 to 255 characters.", + "name": "namespace", + "type": "String!" + }, + { + "description": "Metafield value type (e.g. string, number, json).", + "name": "type", + "type": "String!" + }, { "description": "1 to 10,000 characters.", "name": "value", @@ -1945,6 +1938,43 @@ "kind": "object", "name": "RemoveIdentitiesFromCustomerResponse" }, + { + "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": "RemoveMetafieldsFromCustomerResponse" + }, + { + "fields": [ + { + "description": "Metafield ids to remove. Must contain between 1 and 100 ids, each 1 to 255 characters; an empty list is rejected.", + "name": "metafieldIds", + "type": "[ID!]!" + } + ], + "kind": "input", + "name": "RemoveMetafieldsInput" + }, { "fields": [ { @@ -2304,6 +2334,48 @@ ], "kind": "input", "name": "UpdatedAtFilter" + }, + { + "fields": [ + { + "description": "Metafields to upsert. Must contain between 1 and 100 entries.", + "name": "metafields", + "type": "[MetafieldEntryInput!]!" + } + ], + "kind": "input", + "name": "UpsertCustomerMetafieldsInput" + }, + { + "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": "The metafields that were created or updated. Populated only when `success` is true; `null` (not an empty list) when the mutation fails.", + "name": "metafields", + "type": "[Metafield!]" + }, + { + "description": "Indicates whether the mutation was successful.", + "name": "success", + "type": "Boolean!" + } + ], + "kind": "object", + "name": "UpsertCustomerMetafieldsResponse" } ] }, diff --git a/rust/schemas/api/domains.json b/rust/schemas/api/domains.json index 07e68444..b5bb976f 100644 --- a/rust/schemas/api/domains.json +++ b/rust/schemas/api/domains.json @@ -1840,7 +1840,7 @@ } }, "baseUrl": "https://api.godaddy.com/v3/domains", - "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", + "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, except DNS records\nand forwarding, which are applied synchronously.\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`,\n`forwards`) only exist in the context of a specific domain-name instance.\nThe `/check-availability` controller accepts GET (single domain) or POST\n(1–25 domains) and carries no persistent 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", "endpoints": [ { "description": "Returns an indicative availability result for one domain, including\nper-term pricing when available. Availability is best-effort; the\nauthoritative check is performed at quote time. This operation does\nnot persist the check — there is no check identity or poll URL.\n\nEquivalent to POST /check-availability with `domains: [domain]` and the\nsame optional criteria (`optimizeFor`, `iscCode`). The response is that\nsingle `Availability` item unwrapped for convenience — POST returns the\nsame result inside `{ items: [...] }`. Use POST when checking multiple\ndomains in one request.\n\nA domain that cannot be checked is still returned as a `200` with an\n`error` object on the body (the same per-item contract as POST); request-\nlevel failures use the `4xx` responses.\n", @@ -3411,5 +3411,5 @@ ], "name": "domains", "title": "Domain Lifecycle Management API", - "version": "3.5.0" + "version": "3.7.0" } \ No newline at end of file diff --git a/rust/schemas/api/hosting.json b/rust/schemas/api/hosting.json index 12906ed5..01344eb4 100644 --- a/rust/schemas/api/hosting.json +++ b/rust/schemas/api/hosting.json @@ -68,7 +68,8 @@ "id": { "description": "Server-assigned identifier of the created application, in the same form as `Application.id`. Use it for all subsequent calls.\n", "examples": [ - "NODEJS-aBcDeFgHiJ" + "NODEJS-aBcDeFgHiJ", + "MHWP-a1b2c3d4e5" ], "pattern": "^[A-Z][A-Z0-9_]*-[A-Za-z0-9_-]+$", "readOnly": true, @@ -144,9 +145,10 @@ "AppType": { "$id": "https://godaddy.com/schemas/hosting/enums/app-type.v1", "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "The product type for a hosted application. Required on list and create operations. Each application id is prefixed with its application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier (e.g. `NODEJS-v1StcMHAbqMs`), so item-scoped requests do not require this parameter. Additional product types will be added to this enum as they come online. Clients must tolerate values not listed here.\n", + "description": "The product type for a hosted application. Required on list and create operations. Each application id is prefixed with its application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier (e.g. `NODEJS-v1StcMHAbqMs`, `MHWP-a1b2c3d4e5`), so item-scoped requests do not require this parameter. Additional product types will be added to this enum as they come online. Clients must tolerate values not listed here.\n", "examples": [ - "NODEJS" + "NODEJS", + "MHWP" ], "title": "AppType", "type": "string" @@ -163,9 +165,10 @@ "$ref": "#/$defs/date-time" }, "id": { - "description": "Server-assigned identifier. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then a product-specific suffix. For `NODEJS`, the suffix is a 10-character nanoid (e.g. `NODEJS-aBcDeFgHiJ`).\nThe prefix lets you identify the product type from the id without an extra lookup. Immutable.\n", + "description": "Server-assigned identifier. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then a product-specific suffix. For `NODEJS`, the suffix is a 10-character nanoid (e.g. `NODEJS-aBcDeFgHiJ`). For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only (e.g. `MHWP-a1b2c3d4e5`).\nThe prefix lets you identify the product type from the id without an extra lookup. Immutable.\n", "examples": [ - "NODEJS-aBcDeFgHiJ" + "NODEJS-aBcDeFgHiJ", + "MHWP-a1b2c3d4e5" ], "pattern": "^[A-Z][A-Z0-9_]*-[A-Za-z0-9_-]+$", "readOnly": true, @@ -186,7 +189,7 @@ "type": "string" }, "region": { - "description": "Datacenter region the application is provisioned into, in the same form as `AppOperationApplication.region`. Emitted today only on the items of `GET /apps`; omitted on `GET /apps/{appId}` and whenever the platform does not report one. Today `na` and `eu` are emitted; this is not a closed set, so treat an unlisted value as valid.\n", + "description": "Datacenter region the application is provisioned into, in the same form as `AppOperationApplication.region`. Emitted today only on the items of `GET /apps`; omitted on `GET /apps/{appId}` and whenever the platform does not report one. Today `na` and `eu` are emitted; this is not a closed set, so treat an unlisted value as valid. Not emitted for `MHWP` applications.\n", "examples": [ "na", "eu" @@ -219,12 +222,9 @@ "description": "Environment URLs assigned to this application.", "properties": { "preview": { - "description": "Preview environment URL.", + "description": "Preview environment URL. `MHWP` applications have no preview environment, so the key is omitted for them.\n", "format": "uri", - "type": [ - "string", - "null" - ] + "type": "string" }, "publish": { "description": "Publish environment URL.", @@ -1416,7 +1416,7 @@ } }, "baseUrl": "https://api.godaddy.com/v1/hosting", - "description": "Manage hosted applications across GoDaddy hosting products.\n\n## Async operations\n\nAny operation that takes time returns `202 Accepted` with a resource body and a `links[rel=self]` URL. The same URL is also returned in the `Location` response header. Poll that URL until the status field reaches a terminal state.\n\n## Correlation\n\nEvery response carries an `X-Request-Id` header. Include this value when reporting issues so the request can be traced end to end. Clients should send a W3C `traceparent` header on every request so the trace can be correlated across services.\n\n## Rate limiting\n\nA `429 Too Many Requests` response may come in one of two shapes: an empty body with `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers; or a JSON `Error` body with `Retry-After` and `RateLimit-*` headers. Clients should honour whichever headers are present and should not assume a JSON body is available.\n\n## Forward compatibility\n\nSeveral of the enumerations in this specification are expected to gain members as new products, environments and states come online. Where an enumeration's description says so, clients must not fail on a member they do not recognise — treat it as an unhandled value and continue.\n", + "description": "Manage hosted applications across GoDaddy hosting products.\n\n## Supported product types\n\n`appType` selects the product. Each value maps to a GoDaddy hosting product:\n- `NODEJS` — Node.js hosted applications. - `MHWP` — Managed Hosting for WordPress applications.\nNot every operation applies to every product. An operation a product does not offer returns `501` with `details[].issue` `NOT_APPLICABLE`. Each operation's description states which products it serves.\n\n## Async operations\n\nAny operation that takes time returns `202 Accepted` with a resource body and a `links[rel=self]` URL. The same URL is also returned in the `Location` response header. Poll that URL until the status field reaches a terminal state.\n\n## Correlation\n\nEvery response carries an `X-Request-Id` header. Include this value when reporting issues so the request can be traced end to end. Clients should send a W3C `traceparent` header on every request so the trace can be correlated across services.\n\n## Rate limiting\n\nA `429 Too Many Requests` response may come in one of two shapes: an empty body with `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers; or a JSON `Error` body with `Retry-After` and `RateLimit-*` headers. Clients should honour whichever headers are present and should not assume a JSON body is available.\n\n## Forward compatibility\n\nSeveral of the enumerations in this specification are expected to gain members as new products, environments and states come online. Where an enumeration's description says so, clients must not fail on a member they do not recognise — treat it as an unhandled value and continue.\n", "endpoints": [ { "description": "Returns the current state of an application-creation operation. Use this as the poll target after `POST /apps` until `status` reaches `COMPLETED` or `FAILED`. On `COMPLETED`, the response includes the created `Application` with `status: ACTIVE`.\n", @@ -1584,7 +1584,7 @@ "summary": "List applications" }, { - "description": "Creates a new hosted application. Because no `appId` exists until provisioning has assigned one, this endpoint returns `202 Accepted` with an `AppOperation` resource carrying an `operationId`. Poll `GET /app-operations/{operationId}` until `status` is `COMPLETED` or `FAILED`. On `COMPLETED` the operation result includes the created `Application` with `status: ACTIVE`; use its `id` for any further calls.\n\nCurrently only `NODEJS` applications can be created through this endpoint. The request body is product-specific; the fields below apply to Node.js. Support for additional product types will be documented when those paths are available.\n", + "description": "Creates a new hosted application. Because no `appId` exists until provisioning has assigned one, this endpoint returns `202 Accepted` with an `AppOperation` resource carrying an `operationId`. Poll `GET /app-operations/{operationId}` until `status` is `COMPLETED` or `FAILED`. On `COMPLETED` the operation result includes the created `Application` with `status: ACTIVE`; use its `id` for any further calls.\n\nCurrently only `NODEJS` and `MHWP` applications can be created through this endpoint. The request body is product-specific; the fields below apply to Node.js and MHWP. Support for additional product types will be documented when those paths are available.\n", "method": "POST", "operationId": "createApp", "parameters": [ @@ -1697,7 +1697,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -1752,7 +1752,7 @@ "summary": "Get an application" }, { - "description": "Partial update via [JSON Patch (RFC 6902)](https://datatracker.ietf.org/doc/html/rfc6902). The request body is an array of operations applied in order and atomically. At least one operation must be present.\n\nOnly the `replace` operation is supported, and only against the `/name` and `/rootPath` paths. Any other op or path returns `400 Bad Request`.\n\n- `/name` — human-readable display name. String, 1–200 characters. - `/rootPath` — subdirectory within the repository to treat as\n the application root. Write-only; not returned on the\n `Application` resource.\n\n\nCurrently only supported for `NODEJS` applications. Additional product-specific paths will be documented when those paths are available.\n", + "description": "Partial update via [JSON Patch (RFC 6902)](https://datatracker.ietf.org/doc/html/rfc6902). The request body is an array of operations applied in order and atomically. At least one operation must be present.\n\nOnly the `replace` operation is supported, and only against the `/name` and `/rootPath` paths. Any other op or path returns `400 Bad Request`.\n\n- `/name` — human-readable display name. String, 1–200 characters. - `/rootPath` — subdirectory within the repository to treat as\n the application root. Write-only; not returned on the\n `Application` resource.\n\n\nCurrently only supported for `NODEJS` and `MHWP` applications. Additional product-specific paths will be documented when those paths are available.\n", "method": "PATCH", "operationId": "updateApp", "parameters": [ @@ -1767,7 +1767,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -1856,7 +1856,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -1923,7 +1923,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -2026,7 +2026,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -2124,7 +2124,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -2209,7 +2209,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -2285,7 +2285,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -2396,7 +2396,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -2481,7 +2481,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -2563,7 +2563,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -2674,7 +2674,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -2759,7 +2759,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -2920,7 +2920,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -3025,7 +3025,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -3098,7 +3098,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -3183,7 +3183,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -3303,7 +3303,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -3379,7 +3379,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -3455,7 +3455,7 @@ } }, { - "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`.\n", + "description": "Application identifier in `{PRODUCT}-{id}` form. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then the identifier. For `NODEJS`, the suffix is a 10-character nanoid. Example: `NODEJS-aBcDeFgHiJ`. For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only. Example: `MHWP-a1b2c3d4e5`.\n", "in": "path", "name": "appId", "required": true, @@ -3618,5 +3618,5 @@ ], "name": "hosting", "title": "Hosted Application Lifecycle Management API", - "version": "1.0.0" + "version": "1.1.0" } \ No newline at end of file diff --git a/rust/schemas/api/manifest.json b/rust/schemas/api/manifest.json index 0f5423e3..d5e4cc82 100644 --- a/rust/schemas/api/manifest.json +++ b/rust/schemas/api/manifest.json @@ -1,5 +1,5 @@ { - "generated": "2026-10-20T23:14:50.464341388+00:00", + "generated": "2026-11-03T21:21:53.466952543+00:00", "domains": { "app-registry": { "file": "app-registry.json", diff --git a/rust/schemas/api/orders.json b/rust/schemas/api/orders.json index 4f63c4d7..137f70ae 100644 --- a/rust/schemas/api/orders.json +++ b/rust/schemas/api/orders.json @@ -41,7 +41,7 @@ "description": "A discount can be applied at two levels: the broad order level and the individual line item level", "properties": { "amount": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "appliedBeforeTax": { "default": false, @@ -188,7 +188,7 @@ "description": "A miscellaneous fee can be applied at two levels: the broad order level (shipping fee or handling cost) and the individual line item level", "properties": { "amount": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "appliedBeforeTax": { "default": false, @@ -550,19 +550,19 @@ "$ref": "#/$defs/simple-money" }, "discountTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "feeTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "subTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "taxTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "total": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" } }, "required": [ @@ -577,7 +577,7 @@ "$ref": "#/$defs/LineItemType" }, "unitAmount": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "updatedAt": { "$ref": "#/$defs/date-time" @@ -600,26 +600,23 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "description": "Grouped return totals for a line item.", "properties": { - "addonsTotal": { - "$ref": "#/$defs/simple-money" - }, "discountTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "feeTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "shippingTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "subTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "taxTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "total": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" } }, "title": "LineItemReturnTotals", @@ -1134,26 +1131,23 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "description": "Grouped return totals for an order. Includes order level and item level adjustments in the totals.", "properties": { - "addonsTotal": { - "$ref": "#/$defs/simple-money" - }, "discountTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "feeTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "shippingTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "subTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "taxTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "total": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" } }, "title": "OrderReturnTotals", @@ -1183,7 +1177,7 @@ "type": "boolean" }, "amount": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "exempted": { "default": false, @@ -1412,7 +1406,7 @@ "type": "string" }, "totalAdjustments": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "updatedAt": { "$ref": "#/$defs/date-time" @@ -1431,7 +1425,7 @@ "description": "An adjustment for a return. Can be order level or line item level.", "properties": { "amount": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "createdAt": { "$ref": "#/$defs/date-time" @@ -1528,7 +1522,7 @@ "type": "string" }, "totalAdjustments": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "updatedAt": { "$ref": "#/$defs/date-time" @@ -1549,7 +1543,7 @@ "description": "Base schema for return preview adjustments", "properties": { "amount": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "name": { "description": "The name of the adjustment", @@ -1582,7 +1576,7 @@ "description": "Base schema for return preview adjustments", "properties": { "amount": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "name": { "description": "The name of the adjustment", @@ -1649,7 +1643,7 @@ "description": "Base schema for return preview adjustments", "properties": { "amount": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "name": { "description": "The name of the adjustment", @@ -1915,7 +1909,7 @@ "description": "A shipping line details a shipping method used for an order", "properties": { "amount": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "discounts": { "description": "Discounts applied to this shipping line", @@ -1976,19 +1970,19 @@ "description": "Grouped totals for a shipping line", "properties": { "discountTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "feeTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "subTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "taxTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "total": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" } }, "required": [ @@ -2012,7 +2006,7 @@ "description": "An Order Item tax can be applied at the level of an individual line item or shipping line", "properties": { "amount": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "exempted": { "default": false, @@ -2076,25 +2070,25 @@ "$ref": "#/$defs/simple-money" }, "discountTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "feeTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "productDiscountTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "shippingDiscountTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "shippingTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "subTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "taxTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/positive-money" }, "total": { "$ref": "#/$defs/simple-money" @@ -2220,6 +2214,15 @@ "pattern": "^([A-Z]{2}|C2)$", "type": "string" }, + "currency-code": { + "$id": "https://godaddy.com/schemas/common/currency-code.v1", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A three-character ISO-4217 currency code.", + "maxLength": 3, + "minLength": 3, + "title": "Currency Code", + "type": "string" + }, "date-time": { "$id": "https://godaddy.com/schemas/common/date-time.v1", "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -2392,20 +2395,20 @@ "pattern": "^((-?[0-9]+)|(-?([0-9]+)?[.][0-9]+))$", "type": "string" }, + "positive-money": { + "$ref": "#/$defs/simple-money" + }, "simple-money": { "$id": "https://godaddy.com/schemas/common/simple-money.v1", "$schema": "http://json-schema.org/draft/2020-12/schema", "description": "The currency and amount for a financial transaction, such as a balance or payment due. Use for value representations with default transactable-value precision.", "properties": { "currencyCode": { - "description": "A three-character ISO-4217 currency code.", - "maxLength": 3, - "minLength": 3, - "type": "string" + "$ref": "#/$defs/currency-code" }, "value": { "description": "The value, which might represent intergrals for currencies like `JPY` that are not typically fractional; or, with an implied decimal fraction for currencies like `TND` that are subdivided into thousandths. For the implied number of decimal places for a currency code, see [ISO-4217 Currency Codes](https://en.wikipedia.org/wiki/ISO_4217).", - "minimum": 0, + "format": "int64", "type": "integer" } }, @@ -2413,7 +2416,7 @@ "currencyCode", "value" ], - "title": "Simple Money with Fixed Precision", + "title": "Simple Money", "type": "object" } }, @@ -4210,5 +4213,5 @@ ], "name": "orders", "title": "Order Service", - "version": "1.11.0" + "version": "1.12.0" } \ No newline at end of file From 683b60d3d2cf6f01100fea72343bf67f4de4af3f Mon Sep 17 00:00:00 2001 From: Jacob Page Date: Tue, 3 Nov 2026 14:27:25 -0800 Subject: [PATCH 2/4] fix(api-catalog): keep constraints and annotations that sit beside a $ref The catalog generator replaced every `$ref` with a bare pointer, discarding sibling keywords. That dropped constraints such as the `minimum: 0` that Orders' `positive-money` adds to `simple-money`, and per-field annotations such as `description`, `readOnly`, `nullable` and `example`. Sibling keywords are now kept beside the lifted `$ref`, and the embedded catalog and codegen specs are regenerated so `gddy api schema get` shows the constraints the upstream specs declare. Co-Authored-By: Claude Sonnet 5.5 --- rust/domains-client/openapi/domains.oas3.json | 18 +- rust/email-client/openapi/email.oas3.json | 39 +- rust/hosting-client/openapi/hosting.oas3.json | 60 ++- rust/schemas/api/bulk-operations.json | 138 +++-- rust/schemas/api/businesses.json | 61 ++- rust/schemas/api/channels.json | 64 ++- rust/schemas/api/chargebacks.json | 3 +- rust/schemas/api/domains.json | 18 +- rust/schemas/api/email.json | 39 +- rust/schemas/api/fulfillments.json | 76 ++- rust/schemas/api/hosting.json | 92 +++- rust/schemas/api/location-addresses.json | 9 +- rust/schemas/api/manifest.json | 2 +- rust/schemas/api/metafields.json | 33 +- rust/schemas/api/onboarding.json | 9 +- rust/schemas/api/orders.json | 370 +++++++++---- rust/schemas/api/payment-requests.json | 57 +- rust/schemas/api/payments.json | 134 +++-- rust/schemas/api/price-adjustments.json | 29 +- rust/schemas/api/recommendations.json | 3 +- rust/schemas/api/shipping.json | 27 +- rust/schemas/api/stores.json | 64 ++- rust/schemas/api/subscriptions.json | 57 +- rust/schemas/api/transactions.json | 218 +++++--- .../openapi/shopping.oas3.json | 79 ++- .../generate-api-catalog/src/dereference.rs | 485 +++-------------- .../src/dereference_tests.rs | 497 ++++++++++++++++++ 27 files changed, 1774 insertions(+), 907 deletions(-) create mode 100644 rust/tools/generate-api-catalog/src/dereference_tests.rs diff --git a/rust/domains-client/openapi/domains.oas3.json b/rust/domains-client/openapi/domains.oas3.json index f95f31b6..44a0501b 100644 --- a/rust/domains-client/openapi/domains.oas3.json +++ b/rust/domains-client/openapi/domains.oas3.json @@ -775,7 +775,9 @@ "type": "integer" }, "matchingType": { - "$ref": "#/components/schemas/TLSAMatchingType" + "$ref": "#/components/schemas/TLSAMatchingType", + "description": "TLSA matching type (RFC 6698; TLSA only). Specifies how the selected certificate material is compared to the association data. Supplying this field for any other record type is ignored.\n", + "example": 1 }, "name": { "description": "The DNS record name (label), relative to the zone apex. Use @ to represent the zone apex itself. Wildcards (*) are supported for A, AAAA, and CNAME records.\n", @@ -811,7 +813,9 @@ "type": "string" }, "selector": { - "$ref": "#/components/schemas/TLSASelector" + "$ref": "#/components/schemas/TLSASelector", + "description": "TLSA selector (RFC 6698; TLSA only). Specifies which part of the TLS certificate is matched against the association data. Supplying this field for any other record type is ignored.\n", + "example": 1 }, "service": { "description": "Service name for SRV records, prefixed with an underscore (e.g. `_http`, `_smtp`). Combined with the protocol to form the record name as `_service._proto.name`.\n", @@ -842,7 +846,9 @@ ] }, "usage": { - "$ref": "#/components/schemas/TLSAUsage" + "$ref": "#/components/schemas/TLSAUsage", + "description": "TLSA certificate usage (RFC 6698; TLSA only). Determines how certificate association data is interpreted during DANE authentication. Supplying this field for any other record type is ignored.\n", + "example": 3 }, "weight": { "description": "Relative weight for load distribution among SRV records with equal priority. Higher values increase the probability of selection. Use 0 when only one target exists at a given priority.\n", @@ -1991,7 +1997,8 @@ "links": { "description": "An array of error-related HATEOAS links.", "items": { - "$ref": "#/components/schemas/link-description" + "$ref": "#/components/schemas/link-description", + "readOnly": true }, "nullable": true, "readOnly": true, @@ -2111,7 +2118,8 @@ "type": "string" }, "countryCode": { - "$ref": "#/components/schemas/country-code" + "$ref": "#/components/schemas/country-code", + "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." }, "line1": { "description": "The first line of the address. For example, number or street.", diff --git a/rust/email-client/openapi/email.oas3.json b/rust/email-client/openapi/email.oas3.json index 170209a6..46d073eb 100644 --- a/rust/email-client/openapi/email.oas3.json +++ b/rust/email-client/openapi/email.oas3.json @@ -289,7 +289,9 @@ "description": "An account that can be used to provision a mailbox for a given email address, returned by GET /check-mailbox-eligibility. Pass the accountId to POST /mailboxes to provision against this account.\n", "properties": { "accountId": { - "$ref": "#/components/schemas/uuid" + "$ref": "#/components/schemas/uuid", + "description": "Account ID to pass to POST /mailboxes when provisioning a mailbox.", + "example": "00000000-0000-0000-0000-000000000001" }, "accountName": { "description": "Human-readable product name for the account.", @@ -302,7 +304,8 @@ "type": "boolean" }, "mailboxType": { - "$ref": "#/components/schemas/MailboxType" + "$ref": "#/components/schemas/MailboxType", + "description": "Email platform type backing this account." }, "requirements": { "description": "Agreements that must be submitted in the consents field of POST /mailboxes before a mailbox can be provisioned for this account.\n", @@ -353,7 +356,8 @@ "links": { "description": "An array of error-related HATEOAS links.", "items": { - "$ref": "#/components/schemas/Link" + "$ref": "#/components/schemas/Link", + "readOnly": true }, "readOnly": true, "type": "array" @@ -459,7 +463,10 @@ "description": "An email mailbox associated with a domain owned by the authenticated account. On creation (POST /mailboxes), provide emailAddress and optionally firstName, lastName, accountId, and consents. All other fields are server-assigned and returned in responses.\n", "properties": { "accountId": { - "$ref": "#/components/schemas/uuid" + "$ref": "#/components/schemas/uuid", + "description": "Account UID from the eligibleAccounts list in GET /check-mailbox-eligibility. Defaults to the account with default: true when omitted.\n", + "example": "00000000-0000-0000-0000-000000000001", + "writeOnly": true }, "consents": { "description": "Agreements the customer has accepted, as required by GET /check-mailbox-eligibility.\n", @@ -475,7 +482,10 @@ "writeOnly": true }, "createdAt": { - "$ref": "#/components/schemas/date-time" + "$ref": "#/components/schemas/date-time", + "description": "ISO 8601 timestamp when this mailbox was provisioned. Timezone is UTC.", + "example": "2024-03-15T10:30:00Z", + "readOnly": true }, "displayName": { "description": "Human-readable display name for the mailbox owner, used as the From name in outgoing messages. Server-derived from firstName and lastName.\n", @@ -520,16 +530,27 @@ "type": "array" }, "mailboxId": { - "$ref": "#/components/schemas/uuid" + "$ref": "#/components/schemas/uuid", + "description": "Opaque server-assigned identifier for this mailbox. Stable for the lifetime of the mailbox.\n", + "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "readOnly": true }, "mailboxType": { - "$ref": "#/components/schemas/MailboxType" + "$ref": "#/components/schemas/MailboxType", + "description": "The email service platform that backs this mailbox.", + "readOnly": true }, "status": { - "$ref": "#/components/schemas/MailboxStatus" + "$ref": "#/components/schemas/MailboxStatus", + "description": "Lifecycle status of the mailbox. EXECUTING — initial state; provisioning is actively in progress, keep polling. COMPLETED — terminal success. FAILED — terminal failure. DELETED — mailbox has been deleted.\n", + "example": "COMPLETED", + "readOnly": true }, "updatedAt": { - "$ref": "#/components/schemas/date-time" + "$ref": "#/components/schemas/date-time", + "description": "ISO 8601 timestamp of the most recent modification to this mailbox.", + "example": "2024-06-01T08:00:00Z", + "readOnly": true } }, "title": "Mailbox", diff --git a/rust/hosting-client/openapi/hosting.oas3.json b/rust/hosting-client/openapi/hosting.oas3.json index 1b35fd65..f0e896d6 100644 --- a/rust/hosting-client/openapi/hosting.oas3.json +++ b/rust/hosting-client/openapi/hosting.oas3.json @@ -289,7 +289,8 @@ "readOnly": true }, "createdAt": { - "$ref": "#/components/schemas/date-time" + "$ref": "#/components/schemas/date-time", + "readOnly": true }, "error": { "$ref": "#/components/schemas/error", @@ -309,7 +310,8 @@ "type": "string" }, "status": { - "$ref": "#/components/schemas/OperationStatus" + "$ref": "#/components/schemas/OperationStatus", + "readOnly": true } }, "title": "AppOperation", @@ -320,7 +322,8 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "createdAt": { - "$ref": "#/components/schemas/date-time" + "$ref": "#/components/schemas/date-time", + "readOnly": true }, "id": { "readOnly": true, @@ -339,7 +342,8 @@ "type": "string" }, "status": { - "$ref": "#/components/schemas/AppStatus" + "$ref": "#/components/schemas/AppStatus", + "readOnly": true } }, "title": "AppOperationApplication", @@ -374,10 +378,12 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "appType": { - "$ref": "#/components/schemas/AppType" + "$ref": "#/components/schemas/AppType", + "readOnly": true }, "createdAt": { - "$ref": "#/components/schemas/date-time" + "$ref": "#/components/schemas/date-time", + "readOnly": true }, "id": { "readOnly": true, @@ -399,7 +405,8 @@ "type": "string" }, "source": { - "$ref": "#/components/schemas/AppSource" + "$ref": "#/components/schemas/AppSource", + "readOnly": true }, "sourceDetails": { "$ref": "#/components/schemas/GitHubSource", @@ -407,10 +414,12 @@ "readOnly": true }, "status": { - "$ref": "#/components/schemas/AppStatus" + "$ref": "#/components/schemas/AppStatus", + "readOnly": true }, "updatedAt": { - "$ref": "#/components/schemas/date-time" + "$ref": "#/components/schemas/date-time", + "readOnly": true }, "urls": { "properties": { @@ -500,7 +509,8 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "createdAt": { - "$ref": "#/components/schemas/date-time" + "$ref": "#/components/schemas/date-time", + "readOnly": true }, "deploymentId": { "readOnly": true, @@ -532,10 +542,12 @@ "type": "array" }, "status": { - "$ref": "#/components/schemas/OperationStatus" + "$ref": "#/components/schemas/OperationStatus", + "readOnly": true }, "updatedAt": { - "$ref": "#/components/schemas/date-time" + "$ref": "#/components/schemas/date-time", + "readOnly": true } }, "title": "Deployment", @@ -563,7 +575,8 @@ "type": "string" }, "domainType": { - "$ref": "#/components/schemas/DomainType" + "$ref": "#/components/schemas/DomainType", + "readOnly": true }, "hostname": { "readOnly": true, @@ -578,10 +591,12 @@ "type": "array" }, "role": { - "$ref": "#/components/schemas/DomainRole" + "$ref": "#/components/schemas/DomainRole", + "readOnly": true }, "verificationStatus": { - "$ref": "#/components/schemas/DomainVerificationStatus" + "$ref": "#/components/schemas/DomainVerificationStatus", + "readOnly": true } }, "title": "Domain", @@ -686,7 +701,8 @@ "type": "array" }, "paidThroughDate": { - "$ref": "#/components/schemas/date-time" + "$ref": "#/components/schemas/date-time", + "readOnly": true }, "slotLimit": { "minimum": 0, @@ -1025,7 +1041,8 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "createdAt": { - "$ref": "#/components/schemas/date-time" + "$ref": "#/components/schemas/date-time", + "readOnly": true }, "error": { "$ref": "#/components/schemas/error", @@ -1041,7 +1058,8 @@ "type": "string" }, "importType": { - "$ref": "#/components/schemas/ImportType" + "$ref": "#/components/schemas/ImportType", + "readOnly": true }, "links": { "items": { @@ -1052,7 +1070,8 @@ "type": "array" }, "status": { - "$ref": "#/components/schemas/OperationStatus" + "$ref": "#/components/schemas/OperationStatus", + "readOnly": true } }, "title": "SourceImport", @@ -1119,7 +1138,8 @@ }, "links": { "items": { - "$ref": "#/components/schemas/link-description" + "$ref": "#/components/schemas/link-description", + "readOnly": true }, "nullable": true, "readOnly": true, diff --git a/rust/schemas/api/bulk-operations.json b/rust/schemas/api/bulk-operations.json index 2cb20591..0faacda8 100644 --- a/rust/schemas/api/bulk-operations.json +++ b/rust/schemas/api/bulk-operations.json @@ -6,10 +6,15 @@ "description": "A bulk export object", "properties": { "canceledAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The canceled date of the bulk export", + "nullable": true, + "readOnly": true }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The creation date of the bulk export", + "readOnly": true }, "errorMessage": { "description": "Message from error that occurred during the bulk export", @@ -22,10 +27,15 @@ "type": "string" }, "exportedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date of the bulk export file was exported", + "nullable": true, + "readOnly": true }, "id": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The unique identifier for the bulk export", + "readOnly": true }, "query": { "description": "The query for the bulk export", @@ -76,7 +86,9 @@ "type": "string" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The update date of the bulk export", + "readOnly": true } }, "title": "Bulk Export", @@ -95,10 +107,13 @@ "type": "array" }, "canceledAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The canceled date of the bulk ingestion", + "nullable": true }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The creation date of the bulk ingestion" }, "entityType": { "default": "PRODUCT", @@ -111,7 +126,9 @@ "type": "integer" }, "executedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The executed date of the bulk ingestion", + "nullable": true }, "executedCount": { "default": 0, @@ -119,7 +136,8 @@ "type": "integer" }, "id": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The unique identifier for the bulk ingestion" }, "intent": { "default": "WRITE", @@ -189,7 +207,9 @@ "type": "object" }, "parsedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The parsed date of the bulk ingestion", + "nullable": true }, "parsedCount": { "default": 0, @@ -216,10 +236,14 @@ "type": "integer" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The update date of the bulk ingestion", + "nullable": true }, "validatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The validated date of the bulk ingestion", + "nullable": true }, "validatedCount": { "default": 0, @@ -236,10 +260,12 @@ "description": "A bulk ingestion item object", "properties": { "bulkIngestionId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The unique identifier for the bulk ingestion" }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The creation date of the bulk ingestion item" }, "data": { "description": "The data for the bulk ingestion item", @@ -260,13 +286,18 @@ "type": "string" }, "executedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The executed date of the bulk ingestion item", + "nullable": true }, "expiresAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The expiry date of the bulk ingestion item", + "nullable": true }, "id": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The unique identifier for the bulk ingestion item" }, "index": { "description": "The index of the bulk ingestion item", @@ -282,10 +313,13 @@ "type": "string" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The update date of the bulk ingestion item" }, "validatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The validated date of the bulk ingestion item", + "nullable": true } }, "title": "Bulk Ingestion Item", @@ -297,13 +331,16 @@ "description": "A bulk ingestion override object", "properties": { "bulkIngestionId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The unique identifier for the bulk ingestion" }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The creation date of the override" }, "id": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The unique identifier for the bulk ingestion override" }, "op": { "default": "replace", @@ -320,7 +357,9 @@ "type": "string" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The update date of the override", + "nullable": true }, "value": { "description": "The value of the override", @@ -336,13 +375,18 @@ "description": "A bulk operation object", "properties": { "canceledAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The canceled date of the bulk operation", + "nullable": true }, "completedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The completed date of the bulk operation", + "nullable": true }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The creation date of the bulk operation" }, "endCursor": { "description": "Optional Query-Transform-Set pagination cursor persisted while the\ntarget worker pages through query results. Used to resume discovery\nafter retries; clients typically treat this as read-only progress\nmetadata.\n", @@ -366,7 +410,8 @@ "type": "string" }, "id": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The unique identifier for the bulk operation" }, "method": { "default": "PATCH", @@ -386,7 +431,8 @@ "type": "array" }, "operation": { - "$ref": "#/$defs/BulkOperationOperation" + "$ref": "#/$defs/BulkOperationOperation", + "description": "Optional Query-Transform-Set GraphQL operation. Present only for GraphQL\nQTS transports; omit/ignore for REST bulk operations. When present, the\nservice queries resources, applies transforms, and executes the mutation\nper item.\n" }, "processedCount": { "default": 0, @@ -427,7 +473,9 @@ "type": "integer" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The update date of the bulk operation", + "nullable": true } }, "title": "Bulk Operation", @@ -873,10 +921,13 @@ "type": "array" }, "canceledAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The canceled date of the bulk ingestion", + "nullable": true }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The creation date of the bulk ingestion" }, "entityType": { "default": "PRODUCT", @@ -889,7 +940,9 @@ "type": "integer" }, "executedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The executed date of the bulk ingestion", + "nullable": true }, "executedCount": { "default": 0, @@ -897,7 +950,8 @@ "type": "integer" }, "id": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The unique identifier for the bulk ingestion" }, "intent": { "default": "WRITE", @@ -967,7 +1021,9 @@ "type": "object" }, "parsedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The parsed date of the bulk ingestion", + "nullable": true }, "parsedCount": { "default": 0, @@ -994,10 +1050,14 @@ "type": "integer" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The update date of the bulk ingestion", + "nullable": true }, "validatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The validated date of the bulk ingestion", + "nullable": true }, "validatedCount": { "default": 0, @@ -1065,7 +1125,8 @@ "links": { "description": "An array of error-related HATEOAS links.", "items": { - "$ref": "#/$defs/link-description" + "$ref": "#/$defs/link-description", + "readOnly": true }, "readOnly": true, "type": "array" @@ -2261,7 +2322,8 @@ "contentType": "application/json", "required": false, "schema": { - "$ref": "#/$defs/JSONPatch" + "$ref": "#/$defs/JSONPatch", + "required": true } }, "responses": { diff --git a/rust/schemas/api/businesses.json b/rust/schemas/api/businesses.json index 71de2b33..baf6bc84 100644 --- a/rust/schemas/api/businesses.json +++ b/rust/schemas/api/businesses.json @@ -13,7 +13,8 @@ "type": "string" }, "featureConfig": { - "$ref": "#/$defs/Dictionary" + "$ref": "#/$defs/Dictionary", + "description": "Optional configs for each feature in the list." }, "featureList": { "description": "List of features the bundle contains.", @@ -24,7 +25,8 @@ "type": "array" }, "id": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The id of the bundle. " }, "name": { "description": "Name of bundle.", @@ -61,10 +63,12 @@ "type": "string" }, "address": { - "$ref": "#/$defs/address" + "$ref": "#/$defs/address", + "description": "The main business address." }, "attributes": { - "$ref": "#/$defs/Dictionary" + "$ref": "#/$defs/Dictionary", + "description": "A name/value pair list that could be persisted and later retreived." }, "businessUrl": { "description": "The url of the business' website.", @@ -107,7 +111,8 @@ "type": "string" }, "domicileCountry": { - "$ref": "#/$defs/country-code" + "$ref": "#/$defs/country-code", + "type": "string" }, "emailAddress": { "description": "The main business email address.", @@ -115,7 +120,8 @@ "type": "string" }, "id": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The id of the business. This id could be generated by the client and passed in. If not passed in, it is generated internally during create business." }, "industryType": { "deprecated": true, @@ -140,16 +146,21 @@ "type": "string" }, "organizationId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The unique identifier of the organization that this business is associated with." }, "ownerId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The id of the business owner." }, "paymentDetails": { - "$ref": "#/$defs/BusinessPaymentDetails" + "$ref": "#/$defs/BusinessPaymentDetails", + "description": "Contains payment details used by the business.", + "nullable": true }, "phone": { - "$ref": "#/$defs/PhoneWithType" + "$ref": "#/$defs/PhoneWithType", + "description": "The main business phone." }, "scrubbed": { "description": "Indicates if business information is scrubbed to protect privacy of the merchant.", @@ -180,7 +191,8 @@ "type": "array" }, "timezone": { - "$ref": "#/$defs/time-zone" + "$ref": "#/$defs/time-zone", + "description": "The timezone that the headquarters belong to." }, "type": { "default": "MERCHANT", @@ -221,7 +233,8 @@ "type": "array" }, "links": { - "$ref": "#/$defs/Links" + "$ref": "#/$defs/Links", + "description": "Array of HATEOAS link relations that should be used to navigate across pages of Businesses" }, "totalItems": { "description": "Total number of Businesses matching the search criteria. Returned only when totalRequired is set to true.", @@ -242,17 +255,20 @@ "description": "Contains payment details used by the business.", "properties": { "acquirer": { - "$ref": "#/$defs/Processor" + "$ref": "#/$defs/Processor", + "description": "The merchant acquirer to facilitate card payments for this business. This value is required." }, "externalMerchantId": { "description": "This is the unique identifier assigned by the acquirer to the business. It is a business level MID.", "type": "string" }, "processor": { - "$ref": "#/$defs/Processor" + "$ref": "#/$defs/Processor", + "description": "The payment processor to facilitate payments for this business." }, "processorData": { - "$ref": "#/$defs/Dictionary" + "$ref": "#/$defs/Dictionary", + "description": "The processor related data to be used by the business." }, "underwritingLevel": { "description": "The application level of the business for underwriting.", @@ -300,10 +316,12 @@ "description": "Contact Phone", "properties": { "details": { - "$ref": "#/$defs/phone" + "$ref": "#/$defs/phone", + "description": "Phone number details" }, "type": { - "$ref": "#/$defs/phone-type" + "$ref": "#/$defs/phone-type", + "description": "Phone type" } }, "required": [ @@ -389,7 +407,8 @@ "type": "string" }, "geoCoordinates": { - "$ref": "#/$defs/geo-coordinates" + "$ref": "#/$defs/geo-coordinates", + "description": "The latitude and longitude of the address. For example, `37.42242` and `-122.08585`." }, "streetName": { "description": "The street name. Just `Drury` in `Drury Lane`.", @@ -451,7 +470,8 @@ "type": "string" }, "countryCode": { - "$ref": "#/$defs/country-code" + "$ref": "#/$defs/country-code", + "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." }, "postalCode": { "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).", @@ -506,7 +526,8 @@ "links": { "description": "An array of error-related HATEOAS links.", "items": { - "$ref": "#/$defs/link-description" + "$ref": "#/$defs/link-description", + "readOnly": true }, "readOnly": true, "type": "array" diff --git a/rust/schemas/api/channels.json b/rust/schemas/api/channels.json index 7dfebe81..73b072f5 100644 --- a/rust/schemas/api/channels.json +++ b/rust/schemas/api/channels.json @@ -6,13 +6,17 @@ "description": "Resource representing the Basic Channel", "properties": { "channelId": { - "$ref": "#/$defs/Id" + "$ref": "#/$defs/Id", + "description": "Globally unique Id of the channel that can be used to reference" }, "channelProviderId": { - "$ref": "#/$defs/Id" + "$ref": "#/$defs/Id", + "description": "Identifier of the channel provider (defaulted based on the caller's auth credentials)" }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the channel was created.", + "readOnly": true }, "externalChannelId": { "description": "External identifier of the channel", @@ -20,7 +24,9 @@ "type": "string" }, "links": { - "$ref": "#/$defs/Links" + "$ref": "#/$defs/Links", + "description": "Links pointing to external resource", + "readOnly": true }, "name": { "description": "Name of the channel", @@ -43,7 +49,9 @@ "type": "string" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the channel was updated.", + "readOnly": true } }, "required": [ @@ -112,7 +120,8 @@ "type": "array" }, "links": { - "$ref": "#/$defs/Links" + "$ref": "#/$defs/Links", + "description": "Array of HATEOAS link relations that should be used to navigate across pages of Channels" }, "totalItems": { "description": "Total number of Channels matching the search criteria. Returned only when totalRequired is set to true.", @@ -132,7 +141,8 @@ "description": "Resource representing the Channel Provider", "properties": { "channelProviderId": { - "$ref": "#/$defs/Id" + "$ref": "#/$defs/Id", + "description": "Globally unique Id of the channel provider that can be used to reference" }, "name": { "description": "Name of the channel provider", @@ -169,7 +179,8 @@ "type": "array" }, "links": { - "$ref": "#/$defs/Links" + "$ref": "#/$defs/Links", + "description": "Array of HATEOAS link relations that should be used to navigate across pages of Channel providers" }, "totalItems": { "description": "Total number of Channel Providers matching the search criteria. Returned only when totalRequired is set to true.", @@ -295,7 +306,8 @@ "additionalProperties": false, "properties": { "from": { - "$ref": "#/$defs/path" + "$ref": "#/$defs/path", + "description": "A JSON Pointer path pointing to the location to move/copy from." }, "op": { "description": "The operation to perform.", @@ -376,13 +388,17 @@ "type": "boolean" }, "links": { - "$ref": "#/$defs/Links" + "$ref": "#/$defs/Links", + "description": "Links pointing to external resource", + "readOnly": true }, "status": { - "$ref": "#/$defs/RegisteredStoreStatus" + "$ref": "#/$defs/RegisteredStoreStatus", + "description": "Status of the registration" }, "storeId": { - "$ref": "#/$defs/Id" + "$ref": "#/$defs/Id", + "description": "Id of the store that can be used to reference" } }, "required": [ @@ -414,7 +430,8 @@ "description": "Resource representing a Retail Channel", "properties": { "location": { - "$ref": "#/$defs/RetailLocation" + "$ref": "#/$defs/RetailLocation", + "description": "Location details of the retail channel" } }, "title": "Retail Channel", @@ -425,10 +442,12 @@ "RetailLocationContact": { "properties": { "phone": { - "$ref": "#/$defs/phone" + "$ref": "#/$defs/phone", + "description": "Phone number details" }, "type": { - "$ref": "#/$defs/phone-type" + "$ref": "#/$defs/phone-type", + "description": "Type of the contact phone" } }, "title": "Retail Location Contact", @@ -440,7 +459,8 @@ "description": "Retail Location", "properties": { "address": { - "$ref": "#/$defs/address" + "$ref": "#/$defs/address", + "description": "Physical address of the retail location" }, "alias": { "description": "Alias for the location", @@ -452,10 +472,12 @@ "items": { "properties": { "phone": { - "$ref": "#/$defs/phone" + "$ref": "#/$defs/phone", + "description": "Phone number details" }, "type": { - "$ref": "#/$defs/phone-type" + "$ref": "#/$defs/phone-type", + "description": "Type of the contact phone" } }, "title": "Retail Location Contact", @@ -503,7 +525,8 @@ "type": "string" }, "geoCoordinates": { - "$ref": "#/$defs/geo-coordinates" + "$ref": "#/$defs/geo-coordinates", + "description": "The latitude and longitude of the address. For example, `37.42242` and `-122.08585`." }, "streetName": { "description": "The street name. Just `Drury` in `Drury Lane`.", @@ -565,7 +588,8 @@ "type": "string" }, "countryCode": { - "$ref": "#/$defs/country-code" + "$ref": "#/$defs/country-code", + "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." }, "postalCode": { "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).", diff --git a/rust/schemas/api/chargebacks.json b/rust/schemas/api/chargebacks.json index 5d651dc2..fe798adf 100644 --- a/rust/schemas/api/chargebacks.json +++ b/rust/schemas/api/chargebacks.json @@ -222,7 +222,8 @@ "links": { "description": "An array of error-related HATEOAS links.", "items": { - "$ref": "#/$defs/link-description" + "$ref": "#/$defs/link-description", + "readOnly": true }, "readOnly": true, "type": "array" diff --git a/rust/schemas/api/domains.json b/rust/schemas/api/domains.json index b5bb976f..a338f1fc 100644 --- a/rust/schemas/api/domains.json +++ b/rust/schemas/api/domains.json @@ -398,7 +398,9 @@ "type": "integer" }, "matchingType": { - "$ref": "#/$defs/TLSAMatchingType" + "$ref": "#/$defs/TLSAMatchingType", + "description": "TLSA matching type (RFC 6698; TLSA only). Specifies how the selected certificate material is compared to the association data. Supplying this field for any other record type is ignored.\n", + "example": 1 }, "name": { "description": "The DNS record name (label), relative to the zone apex. Use @ to represent the zone apex itself. Wildcards (*) are supported for A, AAAA, and CNAME records.\n", @@ -436,7 +438,9 @@ "type": "string" }, "selector": { - "$ref": "#/$defs/TLSASelector" + "$ref": "#/$defs/TLSASelector", + "description": "TLSA selector (RFC 6698; TLSA only). Specifies which part of the TLS certificate is matched against the association data. Supplying this field for any other record type is ignored.\n", + "example": 1 }, "service": { "description": "Service name for SRV records, prefixed with an underscore (e.g. `_http`, `_smtp`). Combined with the protocol to form the record name as `_service._proto.name`.\n", @@ -467,7 +471,9 @@ ] }, "usage": { - "$ref": "#/$defs/TLSAUsage" + "$ref": "#/$defs/TLSAUsage", + "description": "TLSA certificate usage (RFC 6698; TLSA only). Determines how certificate association data is interpreted during DANE authentication. Supplying this field for any other record type is ignored.\n", + "example": 3 }, "weight": { "description": "Relative weight for load distribution among SRV records with equal priority. Higher values increase the probability of selection. Use 0 when only one target exists at a given priority.\n", @@ -1634,7 +1640,8 @@ "links": { "description": "An array of error-related HATEOAS links.", "items": { - "$ref": "#/$defs/link-description" + "$ref": "#/$defs/link-description", + "readOnly": true }, "readOnly": true, "type": "array" @@ -1779,7 +1786,8 @@ "type": "string" }, "countryCode": { - "$ref": "#/$defs/country-code" + "$ref": "#/$defs/country-code", + "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." }, "line1": { "description": "The first line of the address. For example, number or street.", diff --git a/rust/schemas/api/email.json b/rust/schemas/api/email.json index c147e84b..b880dc95 100644 --- a/rust/schemas/api/email.json +++ b/rust/schemas/api/email.json @@ -97,7 +97,9 @@ "description": "An account that can be used to provision a mailbox for a given email address, returned by GET /check-mailbox-eligibility. Pass the accountId to POST /mailboxes to provision against this account.\n", "properties": { "accountId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "Account ID to pass to POST /mailboxes when provisioning a mailbox.", + "example": "00000000-0000-0000-0000-000000000001" }, "accountName": { "description": "Human-readable product name for the account.", @@ -110,7 +112,8 @@ "type": "boolean" }, "mailboxType": { - "$ref": "#/$defs/MailboxType" + "$ref": "#/$defs/MailboxType", + "description": "Email platform type backing this account." }, "requirements": { "description": "Agreements that must be submitted in the consents field of POST /mailboxes before a mailbox can be provisioned for this account.\n", @@ -138,7 +141,10 @@ "description": "An email mailbox associated with a domain owned by the authenticated account. On creation (POST /mailboxes), provide emailAddress and optionally firstName, lastName, accountId, and consents. All other fields are server-assigned and returned in responses.\n", "properties": { "accountId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "Account UID from the eligibleAccounts list in GET /check-mailbox-eligibility. Defaults to the account with default: true when omitted.\n", + "example": "00000000-0000-0000-0000-000000000001", + "writeOnly": true }, "consents": { "description": "Agreements the customer has accepted, as required by GET /check-mailbox-eligibility.\n", @@ -154,7 +160,10 @@ "writeOnly": true }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "ISO 8601 timestamp when this mailbox was provisioned. Timezone is UTC.", + "example": "2024-03-15T10:30:00Z", + "readOnly": true }, "displayName": { "description": "Human-readable display name for the mailbox owner, used as the From name in outgoing messages. Server-derived from firstName and lastName.\n", @@ -199,16 +208,27 @@ "type": "array" }, "mailboxId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "Opaque server-assigned identifier for this mailbox. Stable for the lifetime of the mailbox.\n", + "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "readOnly": true }, "mailboxType": { - "$ref": "#/$defs/MailboxType" + "$ref": "#/$defs/MailboxType", + "description": "The email service platform that backs this mailbox.", + "readOnly": true }, "status": { - "$ref": "#/$defs/MailboxStatus" + "$ref": "#/$defs/MailboxStatus", + "description": "Lifecycle status of the mailbox. EXECUTING — initial state; provisioning is actively in progress, keep polling. COMPLETED — terminal success. FAILED — terminal failure. DELETED — mailbox has been deleted.\n", + "example": "COMPLETED", + "readOnly": true }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "ISO 8601 timestamp of the most recent modification to this mailbox.", + "example": "2024-06-01T08:00:00Z", + "readOnly": true } }, "title": "Mailbox", @@ -300,7 +320,8 @@ "links": { "description": "An array of error-related HATEOAS links.", "items": { - "$ref": "#/$defs/link-description" + "$ref": "#/$defs/link-description", + "readOnly": true }, "readOnly": true, "type": "array" diff --git a/rust/schemas/api/fulfillments.json b/rust/schemas/api/fulfillments.json index c93377b3..4ad58a58 100644 --- a/rust/schemas/api/fulfillments.json +++ b/rust/schemas/api/fulfillments.json @@ -70,13 +70,17 @@ "description": "A fulfillment represents a task to fulfill one or more items from a single location for a single fulfillment mode. A Fulfillment can exist in the context of an order or be independent of one.", "properties": { "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the fulfillment was created in our system", + "readOnly": true }, "destination": { - "$ref": "#/$defs/FulfillmentAddress" + "$ref": "#/$defs/FulfillmentAddress", + "description": "Destination address information for the fulfillment" }, "detailedStatus": { - "$ref": "#/$defs/FulfillmentDetailedStatus" + "$ref": "#/$defs/FulfillmentDetailedStatus", + "description": "The detailed status for the fulfillment providing more granular information about the fulfillment state. This field is required for all fulfillment operations. For updates: must be present and be one of the valid detailed statuses. For creates: must be present and valid for the initial status being set (see fulfillment-constraints.json for validation rules)." }, "externalId": { "description": "External identifier for the fulfillment", @@ -89,7 +93,8 @@ "type": "string" }, "fulfillmentWindow": { - "$ref": "#/$defs/FulfillmentWindow" + "$ref": "#/$defs/FulfillmentWindow", + "description": "FulfillmentWindow object specifying the time window for fulfillment (e.g., delivery slot)." }, "history": { "description": "List of history events associated to the fulfillment", @@ -127,7 +132,8 @@ "type": "string" }, "mode": { - "$ref": "#/$defs/Mode" + "$ref": "#/$defs/Mode", + "description": "The mode for the fulfillment" }, "notes": { "description": "List of FulfillmentNote objects, used for internal or customer-facing notes.", @@ -142,10 +148,12 @@ "type": "string" }, "origin": { - "$ref": "#/$defs/FulfillmentAddress" + "$ref": "#/$defs/FulfillmentAddress", + "description": "Origin address information for the fulfillment. Typically this is the address of the warehouse or fulfillment center (e.g. Location)" }, "status": { - "$ref": "#/$defs/FulfillmentStatus" + "$ref": "#/$defs/FulfillmentStatus", + "description": "The current status for the fulfillment" }, "storeId": { "description": "ID of the store that the fulfillment belongs to", @@ -160,7 +168,9 @@ "type": "array" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the fulfillment was last updated in our system", + "readOnly": true } }, "required": [ @@ -181,7 +191,8 @@ "description": "Groups together relevant details about an address for a fulfillment", "properties": { "address": { - "$ref": "#/$defs/address" + "$ref": "#/$defs/address", + "description": "The address details" } }, "required": [ @@ -365,14 +376,18 @@ "type": "string" }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "When the note was created. Used for ordering and audit.", + "readOnly": true }, "id": { "description": "Unique identifier for the note. Used for referencing and editing notes.", "type": "string" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "When the note was last updated. Used for audit and concurrency control.", + "readOnly": true } }, "required": [ @@ -392,10 +407,13 @@ "type": "string" }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the fulfillment plan was created in our system", + "readOnly": true }, "destination": { - "$ref": "#/$defs/FulfillmentAddress" + "$ref": "#/$defs/FulfillmentAddress", + "description": "Destination address information for the fulfillment plan" }, "hasErrors": { "description": "True if any item in the plan encountered an error during inventory sync or fulfillment. This flag is set when errors are detected and is used to block further processing, trigger alerts, and surface issues for operator intervention.", @@ -428,7 +446,8 @@ "type": "string" }, "mode": { - "$ref": "#/$defs/Mode" + "$ref": "#/$defs/Mode", + "description": "The mode for the fulfillment plan" }, "orderId": { "description": "Reference to an order as defined by the Orders Service", @@ -436,10 +455,12 @@ "type": "string" }, "origin": { - "$ref": "#/$defs/FulfillmentAddress" + "$ref": "#/$defs/FulfillmentAddress", + "description": "Origin address information for the fulfillment plan. Typically this is the address of the warehouse or fulfillment center (e.g. Location)" }, "status": { - "$ref": "#/$defs/FulfillmentPlanStatus" + "$ref": "#/$defs/FulfillmentPlanStatus", + "description": "The current workflow status of the plan. Valid values: OPEN, IN_PROGRESS, COMPLETED, CANCELED (OPEN is deprecated). This field drives the fulfillment process, controls which actions are allowed, and is mapped to inventory status for external systems." }, "storeId": { "description": "ID of the store that the fulfillment plan belongs to", @@ -447,7 +468,9 @@ "type": "string" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the fulfillment plan was last updated in our system", + "readOnly": true } }, "required": [ @@ -513,7 +536,8 @@ "type": "string" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "Timestamp of the last update to this item. Used for audit and concurrency control." } }, "required": [ @@ -572,10 +596,12 @@ "description": "Specifies the time window for fulfillment (e.g., delivery slot or pickup time)", "properties": { "endAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "End of the fulfillment window. Used for scheduling and SLA tracking." }, "startAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "Start of the fulfillment window. Used for scheduling and SLA tracking." } }, "required": [ @@ -597,7 +623,9 @@ "description": "Records a event that happened to a fulfillment / fulfillment plan", "properties": { "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the history event was created in our system", + "readOnly": true }, "eventName": { "description": "Name of the history event", @@ -684,7 +712,8 @@ "type": "string" }, "geoCoordinates": { - "$ref": "#/$defs/geo-coordinates" + "$ref": "#/$defs/geo-coordinates", + "description": "The latitude and longitude of the address. For example, `37.42242` and `-122.08585`." }, "streetName": { "description": "The street name. Just `Drury` in `Drury Lane`.", @@ -746,7 +775,8 @@ "type": "string" }, "countryCode": { - "$ref": "#/$defs/country-code" + "$ref": "#/$defs/country-code", + "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." }, "postalCode": { "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).", diff --git a/rust/schemas/api/hosting.json b/rust/schemas/api/hosting.json index 01344eb4..00fb8bae 100644 --- a/rust/schemas/api/hosting.json +++ b/rust/schemas/api/hosting.json @@ -18,7 +18,9 @@ "readOnly": true }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "When the operation was accepted. Optional: the service does not supply it on every operation response, so clients must handle its absence.\n", + "readOnly": true }, "error": { "description": "Populated when `status` is `FAILED`. Describes why the application could not be created.\n", @@ -46,7 +48,8 @@ "type": "string" }, "status": { - "$ref": "#/$defs/OperationStatus" + "$ref": "#/$defs/OperationStatus", + "readOnly": true } }, "required": [ @@ -63,7 +66,8 @@ "description": "The creation-time view of an application, embedded in `AppOperation.app` when the operation reaches `COMPLETED`. It is a deliberate subset of `Application`: only the fields settled at creation are present. Read the full resource with `GET /apps/{appId}` — or follow `links[rel=self]` — once you need `name`, `appType`, `urls` or `updatedAt`.\n", "properties": { "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "readOnly": true }, "id": { "description": "Server-assigned identifier of the created application, in the same form as `Application.id`. Use it for all subsequent calls.\n", @@ -93,7 +97,8 @@ "type": "string" }, "status": { - "$ref": "#/$defs/AppStatus" + "$ref": "#/$defs/AppStatus", + "readOnly": true } }, "required": [ @@ -159,10 +164,12 @@ "description": "A hosted application. After creation, `status` will be `CREATING`. Poll `GET /apps/{appId}` until it reaches `ACTIVE` or `FAILED`.\n", "properties": { "appType": { - "$ref": "#/$defs/AppType" + "$ref": "#/$defs/AppType", + "readOnly": true }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "readOnly": true }, "id": { "description": "Server-assigned identifier. The prefix is the application type in upper case — an upper-case letter followed by any number of upper-case letters, digits, or underscores — then a hyphen, then a product-specific suffix. For `NODEJS`, the suffix is a 10-character nanoid (e.g. `NODEJS-aBcDeFgHiJ`). For `MHWP`, the suffix is a 10-character nanoid of lower-case letters and digits only (e.g. `MHWP-a1b2c3d4e5`).\nThe prefix lets you identify the product type from the id without an extra lookup. Immutable.\n", @@ -198,7 +205,8 @@ "type": "string" }, "source": { - "$ref": "#/$defs/AppSource" + "$ref": "#/$defs/AppSource", + "readOnly": true }, "sourceDetails": { "description": "Present when source is GITHUB. Null when ZIP or no import has been performed.", @@ -213,10 +221,12 @@ "readOnly": true }, "status": { - "$ref": "#/$defs/AppStatus" + "$ref": "#/$defs/AppStatus", + "readOnly": true }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "readOnly": true }, "urls": { "description": "Environment URLs assigned to this application.", @@ -357,7 +367,8 @@ "description": "An asynchronous deployment operation. Poll `GET /apps/{appId}/deployments/{deploymentId}` until `status` reaches `COMPLETED` or `FAILED`.\n", "properties": { "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "readOnly": true }, "deploymentId": { "description": "Server-assigned deployment identifier.", @@ -401,10 +412,12 @@ "type": "array" }, "status": { - "$ref": "#/$defs/OperationStatus" + "$ref": "#/$defs/OperationStatus", + "readOnly": true }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "readOnly": true } }, "required": [ @@ -462,7 +475,9 @@ "type": "string" }, "domainType": { - "$ref": "#/$defs/DomainType" + "$ref": "#/$defs/DomainType", + "description": "How the domain was attached: `CUSTOM` for a customer-owned hostname, or `PREFIX` for a platform-managed subdomain.\n", + "readOnly": true }, "hostname": { "description": "The fully-qualified domain name.", @@ -481,10 +496,14 @@ "type": "array" }, "role": { - "$ref": "#/$defs/DomainRole" + "$ref": "#/$defs/DomainRole", + "description": "Whether this domain is the primary domain for the application or an additional alias.\n", + "readOnly": true }, "verificationStatus": { - "$ref": "#/$defs/DomainVerificationStatus" + "$ref": "#/$defs/DomainVerificationStatus", + "description": "Current DNS verification state. `PENDING` means the domain has not yet been confirmed as pointing to this application. `ACTIVE` means DNS is verified and the domain is live. `DELETING` means removal is in progress. `FAILED` means verification did not complete. Check that the domain's A record points to `anycastIp` and that certificate validation (when required) uses `certificateValidationCname`, then try again.\n", + "readOnly": true } }, "required": [ @@ -571,7 +590,8 @@ "type": "string" }, "variant": { - "$ref": "#/$defs/Environment" + "$ref": "#/$defs/Environment", + "description": "The environment this variant represents." } }, "required": [ @@ -633,7 +653,8 @@ "type": "integer" }, "hostingProduct": { - "$ref": "#/$defs/HostingProduct" + "$ref": "#/$defs/HostingProduct", + "description": "The hosting product associated with this subscription." }, "label": { "description": "Human-readable label for this subscription, suitable for display in a subscription picker.\n", @@ -649,7 +670,12 @@ "type": "array" }, "paidThroughDate": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time through which this subscription is paid, as an RFC 3339 date-time. Omitted when the billing system does not report one.\n", + "examples": [ + "2027-08-06T00:00:00Z" + ], + "readOnly": true }, "slotLimit": { "description": "Total number of application slots available on this subscription.", @@ -736,14 +762,16 @@ "description": "A single normalized log line from an application. The v2 endpoint always returns entries in this shape; entries that cannot be mapped to the normalized level or source values are silently dropped.\n", "properties": { "level": { - "$ref": "#/$defs/LogLevel" + "$ref": "#/$defs/LogLevel", + "description": "Severity level of this log line." }, "message": { "description": "The raw log content.", "type": "string" }, "source": { - "$ref": "#/$defs/LogSource" + "$ref": "#/$defs/LogSource", + "description": "Origin stream of this log line." }, "timestamp": { "$ref": "#/$defs/date-time" @@ -937,7 +965,8 @@ "RestartRequest": { "properties": { "variant": { - "$ref": "#/$defs/Environment" + "$ref": "#/$defs/Environment", + "description": "Which environment to restart." } }, "required": [ @@ -1114,7 +1143,8 @@ "description": "An asynchronous source-code import operation. Use `POST /apps/{appId}/imports` to start an import. Send a ZIP archive as `multipart/form-data`, or send a GitHub repository reference as `application/json`. The `importType` field in the response tells you which kind this is. Poll `GET /apps/{appId}/imports/{importId}` until `status` reaches `COMPLETED` or `FAILED`.\n", "properties": { "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "readOnly": true }, "error": { "description": "Populated when `status` is `FAILED`. Describes why the import did not complete.\n", @@ -1142,7 +1172,8 @@ "type": "string" }, "importType": { - "$ref": "#/$defs/ImportType" + "$ref": "#/$defs/ImportType", + "readOnly": true }, "links": { "description": "HATEOAS navigation links for this resource. When present, `rel=self` is the canonical URL of the source import (`GET /apps/{appId}/imports/{importId}`), suitable as a poll target.\n", @@ -1153,7 +1184,8 @@ "type": "array" }, "status": { - "$ref": "#/$defs/OperationStatus" + "$ref": "#/$defs/OperationStatus", + "readOnly": true } }, "required": [ @@ -1172,13 +1204,16 @@ "description": "The subscription currently attached to an application. Returned by `GET /apps/{appId}/subscription` and `PUT /apps/{appId}/subscription`.\n", "properties": { "appState": { - "$ref": "#/$defs/AppState" + "$ref": "#/$defs/AppState", + "description": "Which environment of the application the subscription currently backs. `PUBLISHED` once the application has been published; `PREVIEW` while only the preview environment is in use.\n" }, "attachState": { - "$ref": "#/$defs/AttachState" + "$ref": "#/$defs/AttachState", + "description": "Current attachment state. The endpoint returns `404` only when no attachment has ever been created for this application; a lapsed attachment is still returned so clients can distinguish that state from a fresh application. `ACTIVE` and `SUSPENDED` are the only values emitted today — `CANCELLED` is reserved, see `AttachState`.\n" }, "hostingProduct": { - "$ref": "#/$defs/HostingProduct" + "$ref": "#/$defs/HostingProduct", + "description": "The hosting product associated with the attached subscription." }, "links": { "description": "HATEOAS navigation links for this resource. When present, `rel=self` is the canonical URL of the attachment (`GET /apps/{appId}/subscription`).\n", @@ -1247,7 +1282,8 @@ "links": { "description": "An array of error-related HATEOAS links.", "items": { - "$ref": "#/$defs/link-description" + "$ref": "#/$defs/link-description", + "readOnly": true }, "readOnly": true, "type": "array" diff --git a/rust/schemas/api/location-addresses.json b/rust/schemas/api/location-addresses.json index 51d54b01..c624b114 100644 --- a/rust/schemas/api/location-addresses.json +++ b/rust/schemas/api/location-addresses.json @@ -24,7 +24,8 @@ "type": "string" }, "geoCoordinates": { - "$ref": "#/$defs/geo-coordinates" + "$ref": "#/$defs/geo-coordinates", + "description": "The latitude and longitude of the address. For example, `37.42242` and `-122.08585`." }, "streetName": { "description": "The street name. Just `Drury` in `Drury Lane`.", @@ -86,7 +87,8 @@ "type": "string" }, "countryCode": { - "$ref": "#/$defs/country-code" + "$ref": "#/$defs/country-code", + "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." }, "postalCode": { "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).", @@ -141,7 +143,8 @@ "links": { "description": "An array of error-related HATEOAS links.", "items": { - "$ref": "#/$defs/link-description" + "$ref": "#/$defs/link-description", + "readOnly": true }, "readOnly": true, "type": "array" diff --git a/rust/schemas/api/manifest.json b/rust/schemas/api/manifest.json index d5e4cc82..245e0640 100644 --- a/rust/schemas/api/manifest.json +++ b/rust/schemas/api/manifest.json @@ -1,5 +1,5 @@ { - "generated": "2026-11-03T21:21:53.466952543+00:00", + "generated": "2026-11-03T22:23:48.433457+00:00", "domains": { "app-registry": { "file": "app-registry.json", diff --git a/rust/schemas/api/metafields.json b/rust/schemas/api/metafields.json index 44b6bb85..1cd7c080 100644 --- a/rust/schemas/api/metafields.json +++ b/rust/schemas/api/metafields.json @@ -41,7 +41,8 @@ "links": { "description": "An array of error-related HATEOAS links.", "items": { - "$ref": "#/$defs/link-description" + "$ref": "#/$defs/link-description", + "readOnly": true }, "readOnly": true, "type": "array" @@ -147,13 +148,16 @@ "description": "A metafield is a custom value that can be associated with a GoDaddy commerce top-level entitiy (e.g. Order).", "properties": { "archivedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the metafield was archived." }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the metafield was created." }, "deletedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the metafield was deleted." }, "id": { "description": "The unique identifier for the metafield.", @@ -183,7 +187,8 @@ "type": "string" }, "storeId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The unique identifier for the store." }, "type": { "description": "The type of the metafield.", @@ -191,7 +196,8 @@ "type": "string" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the metafield was updated." }, "value": { "description": "The value of the metafield.", @@ -305,13 +311,16 @@ "description": "A metafield definition describes the schema/shape of a metafield, including its type, validations, and scope.", "properties": { "archivedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the metafield definition was archived." }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the metafield definition was created." }, "deletedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the metafield definition was deleted." }, "id": { "description": "The unique identifier for the metafield definition.", @@ -338,7 +347,8 @@ "type": "string" }, "storeId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The unique identifier for the store." }, "type": { "description": "The type of the metafield definition. Supported values: boolean, string, stringMultiLine, number, numberDecimal, date, dateTime, json, measurement, url, reference, money, list.string, list.number, list.numberDecimal, list.measurement, list.date, list.url.", @@ -346,7 +356,8 @@ "type": "string" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the metafield definition was updated." }, "validations": { "description": "A list of validations that should be applied to the metafield value when creating or updating a metafield.", diff --git a/rust/schemas/api/onboarding.json b/rust/schemas/api/onboarding.json index d5574525..06325362 100644 --- a/rust/schemas/api/onboarding.json +++ b/rust/schemas/api/onboarding.json @@ -391,7 +391,8 @@ "type": "string" }, "geoCoordinates": { - "$ref": "#/$defs/geo-coordinates" + "$ref": "#/$defs/geo-coordinates", + "description": "The latitude and longitude of the address. For example, `37.42242` and `-122.08585`." }, "streetName": { "description": "The street name. Just `Drury` in `Drury Lane`.", @@ -453,7 +454,8 @@ "type": "string" }, "countryCode": { - "$ref": "#/$defs/country-code" + "$ref": "#/$defs/country-code", + "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." }, "postalCode": { "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).", @@ -517,7 +519,8 @@ "links": { "description": "An array of error-related HATEOAS links.", "items": { - "$ref": "#/$defs/link-description" + "$ref": "#/$defs/link-description", + "readOnly": true }, "readOnly": true, "type": "array" diff --git a/rust/schemas/api/orders.json b/rust/schemas/api/orders.json index 137f70ae..cf9fb9c2 100644 --- a/rust/schemas/api/orders.json +++ b/rust/schemas/api/orders.json @@ -6,7 +6,8 @@ "description": "Groups together relevant billing details about an order", "properties": { "address": { - "$ref": "#/$defs/address" + "$ref": "#/$defs/address", + "description": "The address associated with the billing info" }, "companyName": { "description": "Company name associated with the billing info", @@ -41,7 +42,8 @@ "description": "A discount can be applied at two levels: the broad order level and the individual line item level", "properties": { "amount": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the discount amount" }, "appliedBeforeTax": { "default": false, @@ -79,7 +81,8 @@ "type": "string" }, "ratePercentage": { - "$ref": "#/$defs/percentage" + "$ref": "#/$defs/percentage", + "description": "Rate of the discount when applied. For example, `5.25` would represent a 5.25% discount coupon. An amount based coupon would not set this attribute" }, "referenceId": { "deprecated": true, @@ -188,7 +191,8 @@ "description": "A miscellaneous fee can be applied at two levels: the broad order level (shipping fee or handling cost) and the individual line item level", "properties": { "amount": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the fee amount" }, "appliedBeforeTax": { "default": false, @@ -222,7 +226,8 @@ "type": "string" }, "ratePercentage": { - "$ref": "#/$defs/percentage" + "$ref": "#/$defs/percentage", + "description": "Rate of the fee when applied. For example, `5.25` would represent a 5.25% fee" }, "referenceId": { "deprecated": true, @@ -288,7 +293,9 @@ "description": "Records a event that happened to the order", "properties": { "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the history event was created in our system", + "readOnly": true }, "eventData": { "description": "Data associated with this event", @@ -322,7 +329,9 @@ "description": "A order has to have at least 1 line item which is a representation of what the customer purchased", "properties": { "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the line item was created in our system", + "readOnly": true }, "deprecatedNote": { "deprecated": true, @@ -354,7 +363,9 @@ "description": "An add-on can have multiple values. For example a pizza with a Toppings add-on: `Mushrooms: +$0.00`, `Spinach: +$0.00`, and `Sausage: +$1.00`", "properties": { "amount": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/simple-money", + "deprecated": true, + "description": "Money object with the amount increase/decrease associated with the add-on value" }, "amountIncreased": { "default": true, @@ -363,7 +374,8 @@ "type": "boolean" }, "costAdjustment": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/simple-money", + "description": "Cost increase/decrease associated with the add-on value. The value can be negative, unlike other amount fields across the Order schema" }, "name": { "description": "Name of the add-on value", @@ -445,14 +457,16 @@ "type": "array" }, "fulfilledAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the line item was fulfilled" }, "fulfillmentChannelId": { "description": "ID of the fulfillment channel for the line item", "type": "string" }, "fulfillmentMode": { - "$ref": "#/$defs/FulfillmentMode" + "$ref": "#/$defs/FulfillmentMode", + "description": "Possible fulfillment modes for a line item" }, "id": { "description": "Unique identifier for the line item (LineItem_). Auto-generated by the service on creation", @@ -492,7 +506,8 @@ "type": "number" }, "refundedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the line item was refunded" }, "returnQuantity": { "description": "Sum of all return quantities for the line item", @@ -501,19 +516,25 @@ "type": "number" }, "returnTotals": { - "$ref": "#/$defs/LineItemReturnTotals" + "$ref": "#/$defs/LineItemReturnTotals", + "description": "Grouped return totals for a line item", + "readOnly": true }, "returnedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the line item was returned" }, "serviceEndsAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "Datetime used to mark the end of service for a `STAY` or `SERVICE` line item" }, "serviceStartAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "Datetime used to mark the start of service for a `STAY` or `SERVICE` line item" }, "shipping": { - "$ref": "#/$defs/Shipping" + "$ref": "#/$defs/Shipping", + "description": "Shipping info associated to the line item. If not present, we assume the line item's shipping info is identical to the order's main shipping info" }, "skuGroupId": { "description": "Reference to a SKU Group entity as defined by the V2 Catalog service.", @@ -524,7 +545,8 @@ "type": "string" }, "status": { - "$ref": "#/$defs/FulfillmentStatus" + "$ref": "#/$defs/FulfillmentStatus", + "description": "Possible fulfillment statuses for a line item" }, "tags": { "description": "Tags associated to this line item", @@ -547,22 +569,34 @@ "description": "Grouped totals for a line item", "properties": { "addonsTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/simple-money", + "description": "lineItem.quantity * (Sum of all lineItem.details.selectedAddons[].values[].costAdjustment)", + "readOnly": true }, "discountTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Sum of all lineItem.discounts[].amount", + "readOnly": true }, "feeTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Sum of all lineItem.fees[].amount", + "readOnly": true }, "subTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "lineItem.quantity * lineItem.unitAmount + addonsTotal", + "readOnly": true }, "taxTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Sum of all lineItem.taxes[].amount", + "readOnly": true }, "total": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "subTotal + feeTotal + taxTotal + addonsTotal - discountTotal", + "readOnly": true } }, "required": [ @@ -574,13 +608,17 @@ "type": "object" }, "type": { - "$ref": "#/$defs/LineItemType" + "$ref": "#/$defs/LineItemType", + "description": "Possible types for a line item" }, "unitAmount": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "The base price of the line item including add-ons, but excluding taxes, fees, discounts. Deprecated and will become read-only in the future." }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the line item was last updated in our system", + "readOnly": true } }, "required": [ @@ -601,22 +639,34 @@ "description": "Grouped return totals for a line item.", "properties": { "discountTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the sum of all discount adjustments for a line item", + "readOnly": true }, "feeTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the sum of all fee adjustments for a line item", + "readOnly": true }, "shippingTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the sum of all shipping adjustments for a line item", + "readOnly": true }, "subTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the sum of purchase price adjustments for a line item", + "readOnly": true }, "taxTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the sum of all tax adjustments for a line item", + "readOnly": true }, "total": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the sum of all adjustments for a line item", + "readOnly": true } }, "title": "LineItemReturnTotals", @@ -662,10 +712,12 @@ "type": "string" }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the note was created" }, "deletedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the note was deleted" }, "externalIds": { "description": "A set of externalIds associated with the note", @@ -724,20 +776,24 @@ "type": "boolean" }, "archivedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the order was archived" }, "billing": { - "$ref": "#/$defs/Billing" + "$ref": "#/$defs/Billing", + "description": "Order level billing information" }, "canceledAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the order was canceled" }, "cartId": { "description": "ID associated with a cart. Used to link orders and carts for Inventory tracking purposes", "type": "string" }, "completedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the order was completed" }, "context": { "description": "Context for an order", @@ -776,7 +832,9 @@ "type": "object" }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the order was created in our system", + "readOnly": true }, "customerId": { "description": "Reference to a Customer as defined by the Connections service", @@ -807,7 +865,8 @@ "type": "array" }, "fulfilledAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the order was completely fulfilled" }, "fulfillmentModes": { "description": "Fulfillment modes used across line items for the order", @@ -832,7 +891,9 @@ "type": "string" }, "inventoryAction": { - "$ref": "#/$defs/InventoryAction" + "$ref": "#/$defs/InventoryAction", + "description": "The action to take on inventory when the order is placed. Defaults to `AUTO_ADJUST`.", + "type": "string" }, "lineItems": { "description": "Line items for an order", @@ -871,19 +932,25 @@ "type": "string" }, "paidAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the order was completely paid" }, "processedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the order was processed/placed. If you're importing orders from an app or another platform, then you can set `processedAt` to a datetime in the past to match when the original order was created" }, "refundedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the order was completely refunded" }, "returnTotals": { - "$ref": "#/$defs/OrderReturnTotals" + "$ref": "#/$defs/OrderReturnTotals", + "description": "Grouped totals for returns associated with an order", + "readOnly": true }, "shipping": { - "$ref": "#/$defs/Shipping" + "$ref": "#/$defs/Shipping", + "description": "Order level shipping information" }, "shippingLines": { "description": "Shipping lines for an order", @@ -905,13 +972,16 @@ "description": "Current fulfillment status, payment status, and main status for the order", "properties": { "fulfillmentStatus": { - "$ref": "#/$defs/FulfillmentStatus" + "$ref": "#/$defs/FulfillmentStatus", + "description": "Possible fulfillment statuses for an order" }, "paymentStatus": { - "$ref": "#/$defs/PaymentStatus" + "$ref": "#/$defs/PaymentStatus", + "description": "Possible payment statuses for an order" }, "status": { - "$ref": "#/$defs/OrderStatus" + "$ref": "#/$defs/OrderStatus", + "description": "Possible statuses for an order" } }, "required": [ @@ -944,7 +1014,8 @@ "type": "array" }, "totals": { - "$ref": "#/$defs/Total" + "$ref": "#/$defs/Total", + "description": "Grouped totals for an order" }, "transactionIds": { "description": "List of transactions as defined by the Transaction Service associated with the order", @@ -955,7 +1026,9 @@ "type": "array" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the order was last updated in our system", + "readOnly": true } }, "required": [ @@ -974,7 +1047,8 @@ "description": "Consumers can patch most attributes of an Order, but not all. Notable exceptions include `order.statuses.status` and `order.externalId`", "properties": { "billing": { - "$ref": "#/$defs/Billing" + "$ref": "#/$defs/Billing", + "description": "Order level billing information" }, "canceledAt": { "$ref": "#/$defs/Order_canceledAt" @@ -1054,7 +1128,8 @@ "$ref": "#/$defs/Order_refundedAt" }, "shipping": { - "$ref": "#/$defs/Shipping" + "$ref": "#/$defs/Shipping", + "description": "Order level shipping information" }, "shippingLines": { "description": "Shipping lines for an order", @@ -1109,7 +1184,8 @@ "type": "array" }, "totals": { - "$ref": "#/$defs/Total" + "$ref": "#/$defs/Total", + "description": "Grouped totals for an order" }, "transactionIds": { "description": "List of transactions as defined by the Transaction Service associated with the order", @@ -1132,22 +1208,34 @@ "description": "Grouped return totals for an order. Includes order level and item level adjustments in the totals.", "properties": { "discountTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the sum of all discount adjustments for an order", + "readOnly": true }, "feeTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the sum of all fee adjustments for an order", + "readOnly": true }, "shippingTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the sum of all shipping adjustments for an order", + "readOnly": true }, "subTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the sum of purchase price adjustments for an order", + "readOnly": true }, "taxTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the sum of all tax adjustments for an order", + "readOnly": true }, "total": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the sum of all adjustments for an order", + "readOnly": true } }, "title": "OrderReturnTotals", @@ -1177,7 +1265,8 @@ "type": "boolean" }, "amount": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the tax amount" }, "exempted": { "default": false, @@ -1216,7 +1305,8 @@ "type": "string" }, "ratePercentage": { - "$ref": "#/$defs/percentage" + "$ref": "#/$defs/percentage", + "description": "Rate of the tax when applied to the order. For example, `7.25` would represent a 7.25% tax rate" }, "referenceId": { "deprecated": true, @@ -1233,10 +1323,12 @@ "type": "object" }, "Order_canceledAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the order was canceled" }, "Order_completedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the order was completed" }, "Order_context_businessId": { "description": "ID of the business that the order belongs to", @@ -1263,7 +1355,8 @@ "type": "string" }, "Order_fulfilledAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the order was completely fulfilled" }, "Order_id": { "description": "An identifier unique to the order (Order_). Auto-generated by the service on creation", @@ -1282,19 +1375,24 @@ "type": "string" }, "Order_paidAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the order was completely paid" }, "Order_processedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the order was processed/placed. If you're importing orders from an app or another platform, then you can set `processedAt` to a datetime in the past to match when the original order was created" }, "Order_refundedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the order was completely refunded" }, "Order_statuses_fulfillmentStatus": { - "$ref": "#/$defs/FulfillmentStatus" + "$ref": "#/$defs/FulfillmentStatus", + "description": "Possible fulfillment statuses for an order" }, "Order_statuses_paymentStatus": { - "$ref": "#/$defs/PaymentStatus" + "$ref": "#/$defs/PaymentStatus", + "description": "Possible payment statuses for an order" }, "Order_taxExempted": { "default": false, @@ -1349,7 +1447,9 @@ "type": "object" }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the return was created", + "readOnly": true }, "history": { "description": "The history of events for the return", @@ -1360,7 +1460,8 @@ "type": "string" }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the event was created" }, "eventData": { "description": "Additional data for the event", @@ -1406,10 +1507,14 @@ "type": "string" }, "totalAdjustments": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "The non-negative total sum of adjustments for the return and its items.", + "readOnly": true }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the return was last updated", + "readOnly": true } }, "required": [ @@ -1425,10 +1530,13 @@ "description": "An adjustment for a return. Can be order level or line item level.", "properties": { "amount": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "The non-negative amount of the adjustment. Return adjustments always represent refunded values." }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the adjustment was created", + "readOnly": true }, "id": { "description": "An identifier unique to the adjustment. Auto-generated by the service on creation", @@ -1458,7 +1566,9 @@ "type": "string" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the adjustment was last updated", + "readOnly": true } }, "required": [ @@ -1480,7 +1590,8 @@ "type": "array" }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "readOnly": true }, "id": { "readOnly": true, @@ -1522,10 +1633,13 @@ "type": "string" }, "totalAdjustments": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "The total sum of adjustments for the item", + "readOnly": true }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "readOnly": true } }, "required": [ @@ -1543,7 +1657,8 @@ "description": "Base schema for return preview adjustments", "properties": { "amount": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "The amount of the adjustment" }, "name": { "description": "The name of the adjustment", @@ -1576,7 +1691,8 @@ "description": "Base schema for return preview adjustments", "properties": { "amount": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "The amount of the adjustment" }, "name": { "description": "The name of the adjustment", @@ -1643,7 +1759,8 @@ "description": "Base schema for return preview adjustments", "properties": { "amount": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "The amount of the adjustment" }, "name": { "description": "The name of the adjustment", @@ -1874,7 +1991,8 @@ "description": "Groups together relevant shipping details about an order or a line item", "properties": { "address": { - "$ref": "#/$defs/address" + "$ref": "#/$defs/address", + "description": "The address associated with the shipping info" }, "companyName": { "description": "Company name associated with the shipping info", @@ -1909,7 +2027,8 @@ "description": "A shipping line details a shipping method used for an order", "properties": { "amount": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Shipping cost before taxes" }, "discounts": { "description": "Discounts applied to this shipping line", @@ -1970,19 +2089,29 @@ "description": "Grouped totals for a shipping line", "properties": { "discountTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Total discounts applied to the shipping line", + "readOnly": true }, "feeTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Total fees applied to the shipping line", + "readOnly": true }, "subTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Subtotal (excluding taxes) for a shipping line. Currently the same as amount", + "readOnly": true }, "taxTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Sum of all shippingLine.taxes[].amount", + "readOnly": true }, "total": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Total amount for the shipping line including all taxes, discounts, and fees.\nFormula: totals.subTotal + totals.taxTotal - totals.discountTotal + totals.feeTotal\n", + "readOnly": true } }, "required": [ @@ -2006,7 +2135,8 @@ "description": "An Order Item tax can be applied at the level of an individual line item or shipping line", "properties": { "amount": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the tax amount" }, "exempted": { "default": false, @@ -2045,7 +2175,8 @@ "type": "string" }, "ratePercentage": { - "$ref": "#/$defs/percentage" + "$ref": "#/$defs/percentage", + "description": "Rate of the tax when applied to the order. For example, `7.25` would represent a 7.25% tax rate" }, "referenceId": { "deprecated": true, @@ -2067,31 +2198,49 @@ "description": "Grouped totals for an order", "properties": { "addonsTotal": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/simple-money", + "description": "Sum of all lineItems[].totals.addonsTotal", + "readOnly": true }, "discountTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Non-negative sum of all discounts applied to the order. Subtracted when computing the order total.\nFormula: Sum of all discounts[].amount + Sum of all lineItems[].totals.discountTotal + Sum of all shippingLines[].totals.discountTotal\n", + "readOnly": true }, "feeTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the sum of all fees for an order.\nFormula: Sum of all fees[].amount + Sum of all lineItems[].totals.feeTotal\n", + "readOnly": true }, "productDiscountTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Non-negative sum of all product discounts for an order. Subtracted when computing the order total.\nFormula: Sum of all discounts[].amount + Sum of all lineItems[].totals.discountTotal\n", + "readOnly": true }, "shippingDiscountTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Non-negative sum of all shipping discounts for an order. Subtracted when computing the order total.\nFormula: Sum of all shippingLines[].totals.discountTotal\n", + "readOnly": true }, "shippingTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the sum of all shipping totals for an order.\nFormula: Sum of all shippingLines[].totals.total\n", + "readOnly": true }, "subTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Money object with the sum of item subtotals for an order.\nFormula: Sum of all lineItems[].totals.subTotal\n", + "readOnly": true }, "taxTotal": { - "$ref": "#/$defs/positive-money" + "$ref": "#/$defs/positive-money", + "description": "Sum of all taxes.filter(f => f.additional === true)[].amount + Sum of all lineItems[].totals.taxTotal + Sum of all shippingLines[].totals.taxTotal", + "readOnly": true }, "total": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/simple-money", + "description": "Money object with the sum of all item, shipping, discount, fee, and tax totals.\nFormula: subTotal + shippingTotal + feeTotal + taxTotal - discountTotal\n", + "readOnly": true } }, "required": [ @@ -2129,7 +2278,8 @@ "type": "string" }, "geoCoordinates": { - "$ref": "#/$defs/geo-coordinates" + "$ref": "#/$defs/geo-coordinates", + "description": "The latitude and longitude of the address. For example, `37.42242` and `-122.08585`." }, "streetName": { "description": "The street name. Just `Drury` in `Drury Lane`.", @@ -2191,7 +2341,8 @@ "type": "string" }, "countryCode": { - "$ref": "#/$defs/country-code" + "$ref": "#/$defs/country-code", + "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." }, "postalCode": { "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).", @@ -2396,7 +2547,16 @@ "type": "string" }, "positive-money": { - "$ref": "#/$defs/simple-money" + "$id": "https://godaddy.com/schemas/commerce/orders/positive-money.v1", + "$ref": "#/$defs/simple-money", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "Non-negative currency and amount for a financial transaction. Use for values that must be zero or greater.", + "properties": { + "value": { + "minimum": 0 + } + }, + "title": "Positive Money with Fixed Precision" }, "simple-money": { "$id": "https://godaddy.com/schemas/common/simple-money.v1", diff --git a/rust/schemas/api/payment-requests.json b/rust/schemas/api/payment-requests.json index 30e2b97f..10bb9adb 100644 --- a/rust/schemas/api/payment-requests.json +++ b/rust/schemas/api/payment-requests.json @@ -197,7 +197,8 @@ ], "properties": { "authentication": { - "$ref": "#/$defs/CallbackAuthentication" + "$ref": "#/$defs/CallbackAuthentication", + "description": "Optional authentication configuration for callback requests.\nIf not provided, no authentication headers will be sent.\nHMAC authentication is recommended for production environments.\n" }, "events": { "description": "Array of payment request status values that should trigger callback notifications.\nEvents correspond to PaymentRequestStatus transitions.\n\nAvailable Events (from PaymentRequestStatus):\n- RECEIVED: When payment request is initially received\n- QUEUED: When payment request is queued for processing\n- IN_PROGRESS: When payment request processing begins\n- COMPLETED: When payment request processing is successfully completed\n- FAILED: When payment request processing fails\n", @@ -212,7 +213,8 @@ "type": "array" }, "payloadConfig": { - "$ref": "#/$defs/CallbackPayloadConfiguration" + "$ref": "#/$defs/CallbackPayloadConfiguration", + "description": "Configuration for what data to include in callback payloads" }, "url": { "description": "HTTPS callback URL where notifications will be sent", @@ -337,7 +339,8 @@ "type": "integer" }, "currency": { - "$ref": "#/$defs/Currency" + "$ref": "#/$defs/Currency", + "description": "Amount currency" }, "fees": { "description": "Fees if any", @@ -352,7 +355,9 @@ "type": "integer" }, "tip": { - "$ref": "#/$defs/TipAmount" + "$ref": "#/$defs/TipAmount", + "description": "Tip amount details", + "nullable": true }, "total": { "description": "Total amount", @@ -541,10 +546,12 @@ "type": "array" }, "amount": { - "$ref": "#/$defs/Amount" + "$ref": "#/$defs/Amount", + "description": "Payment amount with currency information" }, "callbackConfig": { - "$ref": "#/$defs/CallbackConfiguration" + "$ref": "#/$defs/CallbackConfiguration", + "description": "Optional configuration for async status notifications" }, "createdAt": { "description": "Created time in RFC 3339 format", @@ -572,13 +579,29 @@ "type": "string" }, "originalTransactionId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "Transaction ID to be refunded. This attribute is used in case the terminal needs to read the card \nwhen issuing referenced refunds. This is not applicable for non-referenced refunds.\n", + "example": "b2c3d4e5-f6a7-8901-bcde-f123456789ab" }, "paymentInstructions": { - "$ref": "#/$defs/Dictionary" + "$ref": "#/$defs/Dictionary", + "description": "Non-sensitive payment instructions passed to the device (e.g. skip signature, force PIN entry)", + "example": { + "enableContactless": true, + "forcePIN": false, + "maxTipAmount": 100.5, + "receiptType": "email", + "skipSignature": true, + "timeoutSeconds": 120, + "tipEnabled": true, + "tipPercentage": 18 + } }, "paymentRequestId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "Server-generated unique identifier for this payment request", + "example": "a1b2c3d4-e5f6-4789-9abc-def123456789", + "readOnly": true }, "references": { "description": "External system references for tracking", @@ -599,10 +622,16 @@ "type": "array" }, "status": { - "$ref": "#/$defs/PaymentRequestStatus" + "$ref": "#/$defs/PaymentRequestStatus", + "description": "Current status of the payment request in its lifecycle", + "example": "RECEIVED", + "readOnly": true }, "storeId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "Store identifier for this payment request", + "example": "12345678-90ab-cdef-1234-567890abcdef", + "readOnly": true }, "transactionIds": { "description": "Transaction IDs created from this payment request (populated after processing)", @@ -700,7 +729,8 @@ "type": "integer" }, "currency": { - "$ref": "#/$defs/Currency" + "$ref": "#/$defs/Currency", + "description": "Transaction currency" } }, "required": [ @@ -821,7 +851,8 @@ "links": { "description": "An array of error-related HATEOAS links.", "items": { - "$ref": "#/$defs/link-description" + "$ref": "#/$defs/link-description", + "readOnly": true }, "readOnly": true, "type": "array" diff --git a/rust/schemas/api/payments.json b/rust/schemas/api/payments.json index 08908730..bd016c9f 100644 --- a/rust/schemas/api/payments.json +++ b/rust/schemas/api/payments.json @@ -54,25 +54,39 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "addressResult": { - "$ref": "#/$defs/AddressVerificationStatus" + "$ref": "#/$defs/AddressVerificationStatus", + "description": "Result of Address verification", + "readOnly": true }, "cardHolderNameResult": { - "$ref": "#/$defs/AddressVerificationStatus" + "$ref": "#/$defs/AddressVerificationStatus", + "description": "Result of Card holder name verification", + "readOnly": true }, "cityResult": { - "$ref": "#/$defs/AddressVerificationStatus" + "$ref": "#/$defs/AddressVerificationStatus", + "description": "Result of City verification", + "readOnly": true }, "countryResult": { - "$ref": "#/$defs/AddressVerificationStatus" + "$ref": "#/$defs/AddressVerificationStatus", + "description": "Result of Country verification", + "readOnly": true }, "phoneResult": { - "$ref": "#/$defs/AddressVerificationStatus" + "$ref": "#/$defs/AddressVerificationStatus", + "description": "Result of Phone verification", + "readOnly": true }, "postalCodeResult": { - "$ref": "#/$defs/AddressVerificationStatus" + "$ref": "#/$defs/AddressVerificationStatus", + "description": "Result of Postal code verification", + "readOnly": true }, "stateResult": { - "$ref": "#/$defs/AddressVerificationStatus" + "$ref": "#/$defs/AddressVerificationStatus", + "description": "Result of State verification", + "readOnly": true } }, "title": "AVS Results", @@ -101,7 +115,8 @@ "description": "Represents Adjustment transaction against a payment", "properties": { "newAmount": { - "$ref": "#/$defs/Amount" + "$ref": "#/$defs/Amount", + "description": "Adjusted transaction amount" } }, "required": [ @@ -177,13 +192,16 @@ "description": "Represents transaction against a payment", "properties": { "amount": { - "$ref": "#/$defs/Amount" + "$ref": "#/$defs/Amount", + "description": "Transaction amount" }, "clientContext": { - "$ref": "#/$defs/Dictionary" + "$ref": "#/$defs/Dictionary", + "description": "non-sensitive context data that can be stored and fetched by client when needed" }, "context": { - "$ref": "#/$defs/TransactionContext" + "$ref": "#/$defs/TransactionContext", + "description": "Transaction context" }, "createdAt": { "description": "Created time in RFC 3339 format", @@ -197,13 +215,16 @@ "type": "string" }, "processorResponse": { - "$ref": "#/$defs/ProcessorResponse" + "$ref": "#/$defs/ProcessorResponse", + "description": "Processor response", + "readOnly": true }, "status": { "$ref": "#/$defs/TransactionStatus" }, "transactionId": { - "$ref": "#/$defs/Id" + "$ref": "#/$defs/Id", + "readOnly": true }, "transactionRefNum": { "$ref": "#/$defs/RefNum" @@ -240,7 +261,9 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "emvTags": { - "$ref": "#/$defs/Dictionary" + "$ref": "#/$defs/Dictionary", + "description": "Card EMV tags", + "writeOnly": true }, "encrypted": { "default": true, @@ -249,7 +272,8 @@ "writeOnly": true }, "entryDetails": { - "$ref": "#/$defs/CardEntryDetails" + "$ref": "#/$defs/CardEntryDetails", + "description": "Card entry details" }, "expMonth": { "maximum": 12, @@ -266,7 +290,9 @@ "type": "string" }, "interacMacDetail": { - "$ref": "#/$defs/InteracMac" + "$ref": "#/$defs/InteracMac", + "description": "Card Interacmac details", + "writeOnly": true }, "keySerialNumber": { "description": "For DUKPT encryption", @@ -387,7 +413,9 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "cardHolderBillingAddress": { - "$ref": "#/$defs/Address" + "$ref": "#/$defs/Address", + "description": "Address for AVS", + "writeOnly": true }, "cardPin": { "description": "Card pin block.", @@ -441,7 +469,9 @@ "type": "integer" }, "avsResult": { - "$ref": "#/$defs/AddressVerificationResult" + "$ref": "#/$defs/AddressVerificationResult", + "description": "Address verifications result", + "readOnly": true }, "cvResult": { "description": "CVV verification result", @@ -454,7 +484,9 @@ "type": "string" }, "emvTags": { - "$ref": "#/$defs/Dictionary" + "$ref": "#/$defs/Dictionary", + "description": "EMV tags obtained from the processor", + "readOnly": true }, "interacMacResult": { "description": "Interac mac result (if interacMac is used)", @@ -508,7 +540,8 @@ "type": "integer" }, "currency": { - "$ref": "#/$defs/Currency" + "$ref": "#/$defs/Currency", + "description": "Amount currency" }, "fees": { "description": "Fees if any", @@ -523,7 +556,9 @@ "type": "integer" }, "tip": { - "$ref": "#/$defs/TipAmount" + "$ref": "#/$defs/TipAmount", + "description": "Tip amount details", + "nullable": true }, "total": { "description": "Total amount", @@ -847,7 +882,9 @@ "description": "A monetary transfer of funds from a funding source to the recipient merchant", "properties": { "additionalProcessingInstruction": { - "$ref": "#/$defs/TransactionProcessingInstruction" + "$ref": "#/$defs/TransactionProcessingInstruction", + "description": "Processing instruction", + "writeOnly": true }, "adjustments": { "description": "Adjustments for the payment", @@ -858,7 +895,8 @@ "type": "array" }, "amount": { - "$ref": "#/$defs/DetailedAmount" + "$ref": "#/$defs/DetailedAmount", + "description": "Payment amount requested" }, "authorizations": { "description": "Authorizations for the payment", @@ -877,7 +915,8 @@ "type": "array" }, "clientContext": { - "$ref": "#/$defs/Dictionary" + "$ref": "#/$defs/Dictionary", + "description": "non-sensitive context data that can be stored and fetched by client when needed" }, "createdAt": { "description": "Created time in RFC 3339 format", @@ -896,7 +935,8 @@ "$ref": "#/$defs/Id" }, "netAmount": { - "$ref": "#/$defs/DetailedAmount" + "$ref": "#/$defs/DetailedAmount", + "description": "Current net payment amount" }, "notes": { "description": "Notes about transaction", @@ -955,13 +995,18 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "cardDetail": { - "$ref": "#/$defs/CardDetail" + "$ref": "#/$defs/CardDetail", + "description": "Card detail" }, "cardVerificationData": { - "$ref": "#/$defs/CardVerificationData" + "$ref": "#/$defs/CardVerificationData", + "description": "Verification data that can be used to verify the customer information", + "writeOnly": true }, "processingInstruction": { - "$ref": "#/$defs/CardProcessingInstruction" + "$ref": "#/$defs/CardProcessingInstruction", + "description": "Processing instruction to use this funding source", + "writeOnly": true } }, "required": [ @@ -1012,7 +1057,9 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "verificationData": { - "$ref": "#/$defs/VerificationData" + "$ref": "#/$defs/VerificationData", + "description": "Verification data", + "writeOnly": true } }, "title": "PaymentTokenFundingSource", @@ -1101,10 +1148,12 @@ "description": "Represents refund transaction against a payment", "properties": { "alternateFundingSource": { - "$ref": "#/$defs/FundingSource" + "$ref": "#/$defs/FundingSource", + "description": "Alternate funding source" }, "parentTransactionId": { - "$ref": "#/$defs/Id" + "$ref": "#/$defs/Id", + "description": "Parent transaction id" } }, "title": "Refund Transaction", @@ -1136,7 +1185,9 @@ "type": "string" }, "id": { - "$ref": "#/$defs/Uuid" + "$ref": "#/$defs/Uuid", + "description": "Id of the signature", + "readOnly": true }, "signature": { "description": "Signature data in Binary format", @@ -1164,7 +1215,8 @@ "type": "integer" }, "currency": { - "$ref": "#/$defs/Currency" + "$ref": "#/$defs/Currency", + "description": "Payment currency" } }, "required": [ @@ -1222,7 +1274,9 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "billingAddress": { - "$ref": "#/$defs/Address" + "$ref": "#/$defs/Address", + "description": "Address for verification", + "writeOnly": true } }, "title": "Token VerificationData", @@ -1920,7 +1974,8 @@ "200": { "description": "Adjustment Signature list", "schema": { - "$ref": "#/$defs/signatureList" + "$ref": "#/$defs/signatureList", + "title": "Adjustment Signatures" } }, "default": { @@ -2392,7 +2447,8 @@ "200": { "description": "Authorization Signature list", "schema": { - "$ref": "#/$defs/signatureList" + "$ref": "#/$defs/signatureList", + "title": "Authorization Signatures" } }, "default": { @@ -3362,7 +3418,8 @@ "200": { "description": "Refund Signature list", "schema": { - "$ref": "#/$defs/signatureList" + "$ref": "#/$defs/signatureList", + "title": "Refund Signatures" } }, "default": { @@ -3834,7 +3891,8 @@ "200": { "description": "Sale Signature list", "schema": { - "$ref": "#/$defs/signatureList" + "$ref": "#/$defs/signatureList", + "title": "Sale Signatures" } }, "default": { diff --git a/rust/schemas/api/price-adjustments.json b/rust/schemas/api/price-adjustments.json index 94a6e19d..8342b9b7 100644 --- a/rust/schemas/api/price-adjustments.json +++ b/rust/schemas/api/price-adjustments.json @@ -57,10 +57,12 @@ "description": "Price Adjustment Entity; contains all the information about a price adjustment", "properties": { "amount": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/simple-money", + "description": "the currency code & amount of currency that makes up the amount discounted or charged for this price adjustment. Present if amountType = AMOUNT, else not present" }, "amountType": { - "$ref": "#/$defs/AmountType" + "$ref": "#/$defs/AmountType", + "type": "string" }, "appliedBeforeTax": { "description": "flag for if the price adjustment should be applied pre- or post- tax", @@ -73,7 +75,9 @@ "type": "string" }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the entity was created", + "readOnly": true }, "description": { "description": "The user friendly description of the price adjustment", @@ -110,7 +114,8 @@ "type": "string" }, "ratePercentage": { - "$ref": "#/$defs/percentage" + "$ref": "#/$defs/percentage", + "description": "the percentage that makes up the amount discounted or charged for this price adjustment. Present id amountType = PERCENTAGE, else not present" }, "storeId": { "description": "The storeId that this price adjustment belongs to", @@ -119,10 +124,14 @@ "type": "string" }, "type": { - "$ref": "#/$defs/PriceAdjustmentType" + "$ref": "#/$defs/PriceAdjustmentType", + "description": "The type of the price adjustment", + "example": "DISCOUNT" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the entity was last updated", + "readOnly": true } }, "title": "PriceAdjustment", @@ -134,7 +143,9 @@ "description": "Price Adjustment Association Entity; contains all the information about a price adjustment association", "properties": { "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the entity was created", + "readOnly": true }, "externalIds": { "items": { @@ -192,7 +203,9 @@ "$ref": "#/$defs/PriceAdjustmentAssociationType" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The datetime when the entity was last updated", + "readOnly": true } }, "title": "PriceAdjustmentAssociation", diff --git a/rust/schemas/api/recommendations.json b/rust/schemas/api/recommendations.json index 2eb034f5..b5734c5e 100644 --- a/rust/schemas/api/recommendations.json +++ b/rust/schemas/api/recommendations.json @@ -124,7 +124,8 @@ "links": { "description": "An array of error-related HATEOAS links.", "items": { - "$ref": "#/$defs/link-description" + "$ref": "#/$defs/link-description", + "readOnly": true }, "readOnly": true, "type": "array" diff --git a/rust/schemas/api/shipping.json b/rust/schemas/api/shipping.json index 2d59878a..d02eeb6f 100644 --- a/rust/schemas/api/shipping.json +++ b/rust/schemas/api/shipping.json @@ -132,7 +132,9 @@ "type": "string" }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the record was created", + "readOnly": true }, "id": { "description": "An identifier unique to the carrier (Carrier_). Auto-generated by the service on creation", @@ -165,7 +167,9 @@ "type": "array" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the record was last updated", + "readOnly": true } }, "required": [ @@ -262,7 +266,9 @@ "type": "string" }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the shipment was created", + "readOnly": true }, "fulfillmentId": { "description": "The unique identifier for the commerce fulfillment.", @@ -368,16 +374,23 @@ "type": "string" }, "shipDate": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The ship date" }, "shipFrom": { - "$ref": "#/$defs/Address" + "$ref": "#/$defs/Address", + "description": "The sender's address", + "type": "object" }, "shipTo": { - "$ref": "#/$defs/Address" + "$ref": "#/$defs/Address", + "description": "The recipient's address", + "type": "object" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The date and time the shipment was last updated", + "readOnly": true } }, "required": [ diff --git a/rust/schemas/api/stores.json b/rust/schemas/api/stores.json index 0a2167e4..ba68a438 100644 --- a/rust/schemas/api/stores.json +++ b/rust/schemas/api/stores.json @@ -13,7 +13,8 @@ "type": "string" }, "featureConfig": { - "$ref": "#/$defs/Dictionary" + "$ref": "#/$defs/Dictionary", + "description": "Optional configs for each feature in the list." }, "featureList": { "description": "List of features the bundle contains.", @@ -24,7 +25,8 @@ "type": "array" }, "id": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The id of the bundle. " }, "name": { "description": "Name of bundle.", @@ -117,10 +119,12 @@ "description": "Contact Phone", "properties": { "details": { - "$ref": "#/$defs/phone" + "$ref": "#/$defs/phone", + "description": "Phone number details" }, "type": { - "$ref": "#/$defs/phone-type" + "$ref": "#/$defs/phone-type", + "description": "Phone type" } }, "required": [ @@ -188,13 +192,16 @@ "description": "Store represent a brand under a business", "properties": { "address": { - "$ref": "#/$defs/address" + "$ref": "#/$defs/address", + "description": "The store's address. This may or may not be different from business address." }, "attributes": { - "$ref": "#/$defs/Dictionary" + "$ref": "#/$defs/Dictionary", + "description": "A name/value pair list that could be persisted and later retrieved." }, "businessId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The business id the store belongs to" }, "createdAt": { "description": "The createdAt of the store. This createdAt is generated internally during create store.", @@ -203,10 +210,12 @@ "type": "string" }, "defaultChannelId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The default channel of the store, where uncategorized transactions are mapped to" }, "defaultRetailChannelId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The default retail channel of the store, where uncategorized transactions from terminals in retail store are mapped to" }, "displayName": { "description": "The store name (used in various displays). It is recommended to pick a different name for each store in the business.", @@ -226,16 +235,21 @@ "type": "array" }, "id": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The id of the store. This id is generated internally during create business." }, "ownerId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The id of the store owner." }, "paymentDetails": { - "$ref": "#/$defs/StorePaymentDetails" + "$ref": "#/$defs/StorePaymentDetails", + "description": "The payment details of the store (if setup)", + "nullable": true }, "phone": { - "$ref": "#/$defs/PhoneWithType" + "$ref": "#/$defs/PhoneWithType", + "description": "The store's phone. This may or may not be different from business phone." }, "status": { "default": "ACTIVE", @@ -286,7 +300,8 @@ "type": "array" }, "links": { - "$ref": "#/$defs/Links" + "$ref": "#/$defs/Links", + "description": "Array of HATEOAS link relations that should be used to navigate across pages of Stores" }, "totalItems": { "description": "Total number of Stores matching the search criteria. Returned only when totalRequired is set to true.", @@ -306,10 +321,12 @@ "description": "Payment details for a store.", "properties": { "acquirer": { - "$ref": "#/$defs/Processor" + "$ref": "#/$defs/Processor", + "description": "The acquirer for this merchant." }, "currency": { - "$ref": "#/$defs/currency-code" + "$ref": "#/$defs/currency-code", + "description": "The primary transaction currency for this store." }, "externalStoreId": { "description": "MID (merchantId) assigned to the store by the acquirer.", @@ -322,7 +339,8 @@ "type": "string" }, "processor": { - "$ref": "#/$defs/Processor" + "$ref": "#/$defs/Processor", + "description": "The processor for this merchant. If this field is left blank it is assumed that the processor is the acquirer itself or CreditCall that happens to be our primary gateway." }, "processorAdapterId": { "deprecated": true, @@ -330,7 +348,8 @@ "type": "string" }, "processorData": { - "$ref": "#/$defs/Dictionary" + "$ref": "#/$defs/Dictionary", + "description": "The processor data for the store." } }, "required": [ @@ -363,7 +382,8 @@ "type": "string" }, "geoCoordinates": { - "$ref": "#/$defs/geo-coordinates" + "$ref": "#/$defs/geo-coordinates", + "description": "The latitude and longitude of the address. For example, `37.42242` and `-122.08585`." }, "streetName": { "description": "The street name. Just `Drury` in `Drury Lane`.", @@ -425,7 +445,8 @@ "type": "string" }, "countryCode": { - "$ref": "#/$defs/country-code" + "$ref": "#/$defs/country-code", + "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." }, "postalCode": { "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).", @@ -504,7 +525,8 @@ "links": { "description": "An array of error-related HATEOAS links.", "items": { - "$ref": "#/$defs/link-description" + "$ref": "#/$defs/link-description", + "readOnly": true }, "readOnly": true, "type": "array" diff --git a/rust/schemas/api/subscriptions.json b/rust/schemas/api/subscriptions.json index 02ffce87..0b361f24 100644 --- a/rust/schemas/api/subscriptions.json +++ b/rust/schemas/api/subscriptions.json @@ -11,7 +11,8 @@ "x-server-pattern": "^(WEEKLY|MONTHLY|YEARLY)$" }, "price": { - "$ref": "#/$defs/simple-money" + "$ref": "#/$defs/simple-money", + "description": "The price for this plan. Value must be > 0." }, "pricingModel": { "const": "FIXED_RECURRING", @@ -55,7 +56,8 @@ "description": "Resource representing a Subscription Plan that can be purchased by a customer. Supports free plans, fixed recurring pricing, and trial periods.\n", "properties": { "applicationId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The ID of the GoDaddy application that owns this subscription plan. Required for application plans.\n" }, "applicationType": { "description": "The type of the application the plan is created for. E.g. GODADDY_APP", @@ -73,10 +75,13 @@ "type": "string" }, "countryCode": { - "$ref": "#/$defs/country-code" + "$ref": "#/$defs/country-code", + "description": "ISO 3166-1 alpha-2 country code where this plan is available. Optional — if omitted, the plan is available in all countries. For country-specific pricing, create separate plans per country.\n" }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The time (ISO-8601) at which the plan was created.", + "readOnly": true }, "description": { "description": "Detailed description of what the subscription plan provides", @@ -89,7 +94,9 @@ "type": "string" }, "id": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The id of the commerce subscription plan", + "readOnly": true }, "marketingData": { "additionalProperties": true, @@ -121,7 +128,8 @@ "type": "string" }, "pricing": { - "$ref": "#/$defs/PricingModel" + "$ref": "#/$defs/PricingModel", + "description": "The pricing configuration for this plan. Uses pricingModel as a discriminator to determine the applicable pricing schema.\n" }, "status": { "default": "ACTIVE", @@ -130,7 +138,9 @@ "x-server-pattern": "^(ACTIVE|DRAFT|DEPRECATED|DISCONTINUED)$" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The time (ISO-8601) at which the plan was last updated.", + "readOnly": true } }, "required": [ @@ -198,29 +208,38 @@ "description": "Resource representing a Subscription that can be applied at Business or Store level", "properties": { "applicationId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The id of the godaddy application the subscription is associated with. Used only for subscription type GODADDY_APP" }, "businessId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The id of the business the subscription is applied at" }, "createdAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The time (in ISO-8601 format) at which the subscription was created. E.g. 2014-09-11T23:14:44Z.", + "readOnly": true }, "customerId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "Customer who purchased the subscription. Required" }, "entitlementId": { "description": "The identifier of the entitlement, if attached to one", "type": "string" }, "expiresAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The time (in ISO-8601 format) at which the subscription expires. E.g. 2014-09-11T23:14:44Z." }, "id": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The id of the commerce subscription", + "readOnly": true }, "planId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The unique identifier of the subscription plan. Optional - if not provided, the system will determine the appropriate plan based on the subscriptionPlanRef and type." }, "status": { "default": "ACTIVE", @@ -229,7 +248,8 @@ "x-server-pattern": "^(PENDING|ACTIVE|SUSPENDED|CANCELLED)$" }, "storeId": { - "$ref": "#/$defs/uuid" + "$ref": "#/$defs/uuid", + "description": "The id of the store if the subscription is applied at store level" }, "subscriptionPlanRef": { "description": "The reference key of the plan or product subscribed to", @@ -241,7 +261,9 @@ "x-server-pattern": "^(GODADDY_ECOMM|POYNT_BUNDLE|CUSTOM|GODADDY_APP)$" }, "updatedAt": { - "$ref": "#/$defs/date-time" + "$ref": "#/$defs/date-time", + "description": "The time (in ISO-8601 format) at which the subscription was updated. E.g. 2014-09-11T23:14:44Z.", + "readOnly": true } }, "required": [ @@ -340,7 +362,8 @@ "links": { "description": "An array of error-related HATEOAS links.", "items": { - "$ref": "#/$defs/link-description" + "$ref": "#/$defs/link-description", + "readOnly": true }, "readOnly": true, "type": "array" diff --git a/rust/schemas/api/transactions.json b/rust/schemas/api/transactions.json index 7fafcf52..be76490f 100644 --- a/rust/schemas/api/transactions.json +++ b/rust/schemas/api/transactions.json @@ -6,25 +6,39 @@ "description": "Address verification result details obtained from processor", "properties": { "addressResult": { - "$ref": "#/$defs/AddressVerificationStatus" + "$ref": "#/$defs/AddressVerificationStatus", + "description": "Result of Address verification", + "readOnly": true }, "cardHolderNameResult": { - "$ref": "#/$defs/AddressVerificationStatus" + "$ref": "#/$defs/AddressVerificationStatus", + "description": "Result of Card holder name verification", + "readOnly": true }, "cityResult": { - "$ref": "#/$defs/AddressVerificationStatus" + "$ref": "#/$defs/AddressVerificationStatus", + "description": "Result of City verification", + "readOnly": true }, "countryResult": { - "$ref": "#/$defs/AddressVerificationStatus" + "$ref": "#/$defs/AddressVerificationStatus", + "description": "Result of Country verification", + "readOnly": true }, "phoneResult": { - "$ref": "#/$defs/AddressVerificationStatus" + "$ref": "#/$defs/AddressVerificationStatus", + "description": "Result of Phone verification", + "readOnly": true }, "postalCodeResult": { - "$ref": "#/$defs/AddressVerificationStatus" + "$ref": "#/$defs/AddressVerificationStatus", + "description": "Result of Postal code verification", + "readOnly": true }, "stateResult": { - "$ref": "#/$defs/AddressVerificationStatus" + "$ref": "#/$defs/AddressVerificationStatus", + "description": "Result of State verification", + "readOnly": true } }, "title": "Address Verification Results", @@ -49,10 +63,12 @@ "description": "Represents Adjustment transaction against a payment", "properties": { "newAmount": { - "$ref": "#/$defs/Amount" + "$ref": "#/$defs/Amount", + "description": "Adjusted transaction amount" }, "parentTransactionId": { - "$ref": "#/$defs/Id" + "$ref": "#/$defs/Id", + "description": "Parent transaction id" } }, "required": [ @@ -103,7 +119,9 @@ "description": "ApplePay Funding source", "properties": { "cardDetail": { - "$ref": "#/$defs/CardDetail" + "$ref": "#/$defs/CardDetail", + "description": "Card that was used with the Apple pay token", + "readOnly": true }, "token": { "description": "Apple pay token", @@ -212,7 +230,8 @@ "description": "Represents a bank account-based financial instrument stored on file", "properties": { "bankAccount": { - "$ref": "#/$defs/BankAccount" + "$ref": "#/$defs/BankAccount", + "description": "Bank account details. Present in responses for BANK_ACCOUNT instruments. On create, supply raw details when `type` is BANK_ACCOUNT. Write-only fields (accountNumber, routingNumber) are never returned in responses.\n" }, "type": { "description": "Discriminator value for this variant. Always BANK_ACCOUNT.", @@ -245,7 +264,8 @@ "description": "Represents capture transaction against a payment", "properties": { "parentTransactionId": { - "$ref": "#/$defs/Id" + "$ref": "#/$defs/Id", + "description": "Parent transaction id" } }, "title": "Capture Transaction", @@ -258,10 +278,13 @@ "description": "Details of the card used for processing transaction", "properties": { "currency": { - "$ref": "#/$defs/Currency" + "$ref": "#/$defs/Currency", + "description": "Card's native currency code, when available." }, "emvTags": { - "$ref": "#/$defs/Dictionary" + "$ref": "#/$defs/Dictionary", + "description": "Card EMV tags", + "writeOnly": true }, "encrypted": { "default": true, @@ -270,7 +293,8 @@ "writeOnly": true }, "entryDetails": { - "$ref": "#/$defs/CardEntryDetails" + "$ref": "#/$defs/CardEntryDetails", + "description": "Card entry details" }, "expMonth": { "maximum": 12, @@ -287,7 +311,9 @@ "type": "string" }, "interacMacDetail": { - "$ref": "#/$defs/InteracMac" + "$ref": "#/$defs/InteracMac", + "description": "Card Interacmac details", + "writeOnly": true }, "keySerialNumber": { "description": "For DUKPT encryption", @@ -299,7 +325,9 @@ "type": "string" }, "legacyData": { - "$ref": "#/$defs/LegacyCardDetailData" + "$ref": "#/$defs/LegacyCardDetailData", + "deprecated": true, + "description": "Contains card details represented by legacy system" }, "number": { "description": "Card number. On create, supply the full PAN. In GET responses, returns a masked representation (e.g. ****9990) — not the full card number.\n", @@ -409,7 +437,8 @@ "description": "Represents a card-based financial instrument stored on file", "properties": { "card": { - "$ref": "#/$defs/PaymentCard" + "$ref": "#/$defs/PaymentCard", + "description": "Card details. Present in responses for CARD instruments. On create, supply raw card details when `type` is CARD. Write-only fields (number, track data, cvData) are never returned in responses.\n" }, "type": { "description": "Discriminator value for this variant. Always CARD.", @@ -449,7 +478,9 @@ "description": "Verification data for the card used as funding source", "properties": { "cardHolderBillingAddress": { - "$ref": "#/$defs/address" + "$ref": "#/$defs/address", + "description": "Address for AVS", + "writeOnly": true }, "cardPin": { "description": "Card pin block.", @@ -512,13 +543,19 @@ "type": "integer" }, "avsResult": { - "$ref": "#/$defs/AddressVerificationResult" + "$ref": "#/$defs/AddressVerificationResult", + "description": "Address verifications result", + "readOnly": true }, "cvResult": { - "$ref": "#/$defs/CVResultStatus" + "$ref": "#/$defs/CVResultStatus", + "description": "CVV verification result", + "readOnly": true }, "emvTags": { - "$ref": "#/$defs/Dictionary" + "$ref": "#/$defs/Dictionary", + "description": "EMV tags obtained from the processor", + "readOnly": true }, "interacMacResult": { "description": "Interac mac result (if interacMac is used)", @@ -526,7 +563,9 @@ "type": "string" }, "legacyProcessorData": { - "$ref": "#/$defs/LegacyProcessorResponseData" + "$ref": "#/$defs/LegacyProcessorResponseData", + "deprecated": true, + "description": "Process response data used by legacy system" }, "scaResult": { "description": "Represents a SCA status if it was triggered. Strong Customer Authentication (SCA) is a European regulatory requirement to reduce fraud and make online payments more secure.", @@ -598,7 +637,9 @@ "description": "Processor response for debit card", "properties": { "legacyProcessorData": { - "$ref": "#/$defs/LegacyProcessorResponseData" + "$ref": "#/$defs/LegacyProcessorResponseData", + "deprecated": true, + "description": "Process response data used by legacy system" }, "remainingBalanceAmount": { "description": "Remaining balance amount", @@ -620,7 +661,8 @@ "type": "integer" }, "currency": { - "$ref": "#/$defs/Currency" + "$ref": "#/$defs/Currency", + "description": "Amount currency" }, "fees": { "description": "Fees if any", @@ -635,7 +677,9 @@ "type": "integer" }, "tip": { - "$ref": "#/$defs/TipAmount" + "$ref": "#/$defs/TipAmount", + "description": "Tip amount details", + "nullable": true }, "total": { "description": "Total amount", @@ -669,7 +713,8 @@ "description": "EBT Card", "properties": { "cardDetail": { - "$ref": "#/$defs/CardDetail" + "$ref": "#/$defs/CardDetail", + "description": "Card detail" }, "cardType": { "description": "Type of EBT card used", @@ -681,7 +726,8 @@ "type": "string" }, "cardVerificationData": { - "$ref": "#/$defs/VerificationData" + "$ref": "#/$defs/VerificationData", + "description": "Card verification data" }, "eVoucherApprovalCode": { "description": "EVoucher Approval code if used with Electronic Voucher", @@ -762,7 +808,9 @@ "type": "string" }, "id": { - "$ref": "#/$defs/Uuid" + "$ref": "#/$defs/Uuid", + "description": "Server-assigned unique identifier for this financial instrument", + "readOnly": true }, "nonce": { "description": "Single-use tokenization nonce from a compliant card-capture SDK — alternative to supplying `card` or `bankAccount` directly (PCI-out-of-scope path). The server resolves this to a card or bank account before persistence; it is not a stored instrument type.\n", @@ -791,7 +839,9 @@ "type": "string" }, "tokenContext": { - "$ref": "#/$defs/TokenContext" + "$ref": "#/$defs/TokenContext", + "description": "Store and application context for minting the first token. Required on create; never returned in responses. Only `storeId` is accepted — application identity is derived from the authorization credential.\n", + "writeOnly": true }, "tokens": { "description": "Per-store charge handles. Populated on create when `tokenContext` is provided, and on list when `includeToken` is true (scoped to the required `storeId`). Each item includes the chargeable JWT in `token`. Use GET /financial-instruments/{id}/tokens to retrieve tokens explicitly.\n", @@ -890,7 +940,9 @@ "description": "GoDaddy Card-on-file Funding source", "properties": { "cardDetail": { - "$ref": "#/$defs/CardDetail" + "$ref": "#/$defs/CardDetail", + "description": "Card that was used with the Godaddy payment token", + "readOnly": true }, "token": { "description": "Godaddy Payment token", @@ -919,7 +971,9 @@ "description": "GooglePay Funding source", "properties": { "cardDetail": { - "$ref": "#/$defs/CardDetail" + "$ref": "#/$defs/CardDetail", + "description": "Card that was used with the Google pay token", + "readOnly": true }, "token": { "description": "Google pay token", @@ -2050,10 +2104,12 @@ "description": "This object shows a summary of the adjustment.", "properties": { "amountChanges": { - "$ref": "#/$defs/Amount" + "$ref": "#/$defs/Amount", + "description": "Total amount change in this adjustment." }, "amounts": { - "$ref": "#/$defs/Amount" + "$ref": "#/$defs/Amount", + "description": "Total amount after this adjustment." }, "createdAt": { "description": "This is a response field. The server time (in ISO-8601 format) at which this transaction was initially created. E.g. 2014-09-11T23:14:44Z.", @@ -2126,7 +2182,8 @@ "type": "object" }, "processorResponse": { - "$ref": "#/$defs/ProcessorResponse" + "$ref": "#/$defs/ProcessorResponse", + "description": "This object includes some important response elements received from the processor." }, "reason": { "description": "Reason for this adjustment.", @@ -2405,10 +2462,12 @@ "description": "This object shows a summary of the adjustment.", "properties": { "amountChanges": { - "$ref": "#/$defs/Amount" + "$ref": "#/$defs/Amount", + "description": "Total amount change in this adjustment." }, "amounts": { - "$ref": "#/$defs/Amount" + "$ref": "#/$defs/Amount", + "description": "Total amount after this adjustment." }, "createdAt": { "description": "This is a response field. The server time (in ISO-8601 format) at which this transaction was initially created. E.g. 2014-09-11T23:14:44Z.", @@ -2481,7 +2540,8 @@ "type": "object" }, "processorResponse": { - "$ref": "#/$defs/ProcessorResponse" + "$ref": "#/$defs/ProcessorResponse", + "description": "This object includes some important response elements received from the processor." }, "reason": { "description": "Reason for this adjustment.", @@ -2561,7 +2621,8 @@ "type": "string" }, "context": { - "$ref": "#/$defs/Dictionary" + "$ref": "#/$defs/Dictionary", + "description": "[Required] Contains context about the transaction. TransmissionAtLocal must be provided. All other fields are optional." }, "customerLanguage": { "description": "The customer's language preference for the transaction.", @@ -2711,7 +2772,8 @@ "type": "object" }, "processorOptions": { - "$ref": "#/$defs/Dictionary" + "$ref": "#/$defs/Dictionary", + "description": "A name/value pair list that could be persisted and later retreived - primarily to store additional payment related data that get passed through to the processor." }, "processorTransactionId": { "description": "The capability to enter a transaction id along with approval code.", @@ -3038,13 +3100,18 @@ "description": "Payment card", "properties": { "cardDetail": { - "$ref": "#/$defs/CardDetail" + "$ref": "#/$defs/CardDetail", + "description": "Card detail" }, "cardVerificationData": { - "$ref": "#/$defs/VerificationData" + "$ref": "#/$defs/VerificationData", + "description": "Verification data that can be used to verify the customer information", + "writeOnly": true }, "processingInstruction": { - "$ref": "#/$defs/CardProcessingInstruction" + "$ref": "#/$defs/CardProcessingInstruction", + "description": "Processing instruction to use this funding source", + "writeOnly": true } }, "required": [ @@ -3059,7 +3126,9 @@ "description": "Payment Token Funding source", "properties": { "verificationData": { - "$ref": "#/$defs/VerificationData" + "$ref": "#/$defs/VerificationData", + "description": "Verification data", + "writeOnly": true } }, "title": "Payment Token Funding Source", @@ -3076,7 +3145,9 @@ "description": "Paze Funding source", "properties": { "cardDetail": { - "$ref": "#/$defs/CardDetail" + "$ref": "#/$defs/CardDetail", + "description": "Card that was used with the Paze payment token", + "readOnly": true }, "token": { "description": "Paze payment token", @@ -3141,7 +3212,8 @@ "description": "Represents refund transaction against a payment", "properties": { "parentTransactionId": { - "$ref": "#/$defs/Id" + "$ref": "#/$defs/Id", + "description": "Parent transaction id" } }, "title": "Refund Transaction", @@ -3176,7 +3248,8 @@ "type": "integer" }, "currency": { - "$ref": "#/$defs/Currency" + "$ref": "#/$defs/Currency", + "description": "Transaction currency" } }, "required": [ @@ -3243,7 +3316,9 @@ "type": "string" }, "id": { - "$ref": "#/$defs/Uuid" + "$ref": "#/$defs/Uuid", + "description": "Unique identifier for this token", + "readOnly": true }, "status": { "description": "Status of this token. Currently accepted values: ACTIVE, INACTIVE.", @@ -3271,7 +3346,8 @@ "description": "Context for minting a per-store token. Used when vaulting a financial instrument (first token) and when associating an existing instrument with a new store. `storeId` is required. Application identity is derived from the authorization credential — clients do not supply `applicationId`.\n", "properties": { "storeId": { - "$ref": "#/$defs/Uuid" + "$ref": "#/$defs/Uuid", + "description": "Store the token is minted for (required)" } }, "required": [ @@ -3286,7 +3362,9 @@ "description": "Verification data for the token used as funding source", "properties": { "billingAddress": { - "$ref": "#/$defs/address" + "$ref": "#/$defs/address", + "description": "Address for verification", + "writeOnly": true } }, "title": "Token Verification Data", @@ -3325,13 +3403,16 @@ ], "properties": { "amount": { - "$ref": "#/$defs/Amount" + "$ref": "#/$defs/Amount", + "description": "Transaction amount" }, "clientContext": { - "$ref": "#/$defs/Dictionary" + "$ref": "#/$defs/Dictionary", + "description": "non-sensitive context data that can be stored and fetched by client when needed" }, "context": { - "$ref": "#/$defs/TransactionContext" + "$ref": "#/$defs/TransactionContext", + "description": "Transaction context" }, "createdAt": { "description": "Created time in RFC 3339 format", @@ -3340,10 +3421,13 @@ "type": "string" }, "fundingSource": { - "$ref": "#/$defs/FundingSource" + "$ref": "#/$defs/FundingSource", + "description": "Funding source" }, "legacyMetadata": { - "$ref": "#/$defs/LegacyTransactionMetadata" + "$ref": "#/$defs/LegacyTransactionMetadata", + "deprecated": true, + "description": "Transaction metadata represented by legacy system" }, "links": { "description": "Links associated with this transaction", @@ -3358,10 +3442,13 @@ "type": "string" }, "processingInstructions": { - "$ref": "#/$defs/TransactionProcessingInstruction" + "$ref": "#/$defs/TransactionProcessingInstruction", + "description": "Processing instructions to be used while processing transaction" }, "processorResponse": { - "$ref": "#/$defs/ProcessorResponse" + "$ref": "#/$defs/ProcessorResponse", + "description": "Processor response", + "readOnly": true }, "references": { "description": "References to the transaction", @@ -3374,10 +3461,14 @@ "$ref": "#/$defs/TransactionStatus" }, "storeId": { - "$ref": "#/$defs/Uuid" + "$ref": "#/$defs/Uuid", + "description": "Store identifier for this transaction", + "readOnly": true }, "transactionId": { - "$ref": "#/$defs/Id" + "$ref": "#/$defs/Id", + "description": "Server generated identifier for this transaction", + "readOnly": true }, "transactionRefNum": { "$ref": "#/$defs/RefNum" @@ -3556,7 +3647,8 @@ "type": "string" }, "geoCoordinates": { - "$ref": "#/$defs/geo-coordinates" + "$ref": "#/$defs/geo-coordinates", + "description": "The latitude and longitude of the address. For example, `37.42242` and `-122.08585`." }, "streetName": { "description": "The street name. Just `Drury` in `Drury Lane`.", @@ -3618,7 +3710,8 @@ "type": "string" }, "countryCode": { - "$ref": "#/$defs/country-code" + "$ref": "#/$defs/country-code", + "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." }, "postalCode": { "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).", @@ -3674,7 +3767,8 @@ "links": { "description": "An array of error-related HATEOAS links.", "items": { - "$ref": "#/$defs/link-description" + "$ref": "#/$defs/link-description", + "readOnly": true }, "readOnly": true, "type": "array" diff --git a/rust/shopping-client/openapi/shopping.oas3.json b/rust/shopping-client/openapi/shopping.oas3.json index 99996372..ea3e1a1f 100644 --- a/rust/shopping-client/openapi/shopping.oas3.json +++ b/rust/shopping-client/openapi/shopping.oas3.json @@ -632,13 +632,24 @@ "name": "dev.ucp.shopping.checkout", "properties": { "attribution": { - "$ref": "#/components/schemas/attribution" + "$ref": "#/components/schemas/attribution", + "ucp_request": "optional" }, "buyer": { - "$ref": "#/components/schemas/buyer" + "$ref": "#/components/schemas/buyer", + "ucp_request": { + "complete": "omit", + "create": "optional", + "update": "optional" + } }, "context": { - "$ref": "#/components/schemas/context" + "$ref": "#/components/schemas/context", + "ucp_request": { + "complete": "omit", + "create": "optional", + "update": "optional" + } }, "continue_url": { "type": "string", @@ -653,7 +664,12 @@ "ucp_request": "omit" }, "fulfillment": { - "$ref": "#/components/schemas/shopping_fulfillment" + "$ref": "#/components/schemas/shopping_fulfillment", + "ucp_request": { + "complete": "omit", + "create": "optional", + "update": "optional" + } }, "id": { "type": "string", @@ -685,13 +701,20 @@ "ucp_request": "omit" }, "order": { - "$ref": "#/components/schemas/order_confirmation" + "$ref": "#/components/schemas/order_confirmation", + "ucp_request": "omit" }, "payment": { - "$ref": "#/components/schemas/payment" + "$ref": "#/components/schemas/payment", + "ucp_request": { + "complete": "required", + "create": "optional", + "update": "optional" + } }, "signals": { - "$ref": "#/components/schemas/signals" + "$ref": "#/components/schemas/signals", + "ucp_request": "optional" }, "status": { "examples": [ @@ -706,10 +729,12 @@ "ucp_request": "omit" }, "totals": { - "$ref": "#/components/schemas/totals" + "$ref": "#/components/schemas/totals", + "ucp_request": "omit" }, "ucp": { - "$ref": "#/components/schemas/ucp_response_checkout_schema" + "$ref": "#/components/schemas/ucp_response_checkout_schema", + "ucp_request": "omit" } }, "title": "Checkout", @@ -725,10 +750,12 @@ "$ref": "#/components/schemas/ucp-refs_schema_attribution" }, "consent": { - "$ref": "#/components/schemas/com_godaddy_shopping_checkout_input_schema_consent_acceptance" + "$ref": "#/components/schemas/com_godaddy_shopping_checkout_input_schema_consent_acceptance", + "x-sensitivity": "confidential" }, "payment": { - "$ref": "#/components/schemas/ucp-refs_schema_payment" + "$ref": "#/components/schemas/ucp-refs_schema_payment", + "x-sensitivity": "restricted" }, "signals": { "$ref": "#/components/schemas/ucp-refs_schema_signals" @@ -746,13 +773,15 @@ "$ref": "#/components/schemas/ucp-refs_schema_attribution" }, "buyer": { - "$ref": "#/components/schemas/ucp-refs_schema_buyer" + "$ref": "#/components/schemas/ucp-refs_schema_buyer", + "x-sensitivity": "confidential" }, "context": { "$ref": "#/components/schemas/ucp-refs_schema_context" }, "fulfillment": { - "$ref": "#/components/schemas/ucp-refs_schema_fulfillment" + "$ref": "#/components/schemas/ucp-refs_schema_fulfillment", + "x-sensitivity": "confidential" }, "line_items": { "items": { @@ -761,7 +790,8 @@ "type": "array" }, "payment": { - "$ref": "#/components/schemas/ucp-refs_schema_payment" + "$ref": "#/components/schemas/ucp-refs_schema_payment", + "x-sensitivity": "restricted" }, "signals": { "$ref": "#/components/schemas/ucp-refs_schema_signals" @@ -1335,7 +1365,8 @@ "ucp_request": "omit" }, "price": { - "$ref": "#/components/schemas/amount" + "$ref": "#/components/schemas/amount", + "ucp_request": "omit" }, "title": { "type": "string", @@ -1599,7 +1630,8 @@ "type": "array" }, "attribution": { - "$ref": "#/components/schemas/attribution" + "$ref": "#/components/schemas/attribution", + "ucp_request": "omit" }, "checkout_id": { "type": "string" @@ -2099,7 +2131,8 @@ "type": "string" }, "plan": { - "$ref": "#/components/schemas/product-plan_schema" + "$ref": "#/components/schemas/product-plan_schema", + "ucp_request": "omit" }, "product_family": { "minLength": 1, @@ -2763,7 +2796,8 @@ ], "properties": { "amount": { - "$ref": "#/components/schemas/signed_amount" + "$ref": "#/components/schemas/signed_amount", + "ucp_request": "omit" }, "display_text": { "type": "string", @@ -3234,7 +3268,8 @@ "ucp_request": "omit" }, "input_schema": { - "$ref": "#/components/schemas/com_godaddy_shopping_input_schema_input_schema" + "$ref": "#/components/schemas/com_godaddy_shopping_input_schema_input_schema", + "ucp_request": "omit" }, "list_price": { "$ref": "#/components/schemas/price" @@ -3262,7 +3297,8 @@ "type": "array" }, "plan": { - "$ref": "#/components/schemas/product-plan_schema" + "$ref": "#/components/schemas/product-plan_schema", + "ucp_request": "omit" }, "price": { "$ref": "#/components/schemas/price" @@ -3271,7 +3307,8 @@ "$ref": "#/components/schemas/rating" }, "renewal_price": { - "$ref": "#/components/schemas/price" + "$ref": "#/components/schemas/price", + "ucp_request": "omit" }, "seller": { "properties": { diff --git a/rust/tools/generate-api-catalog/src/dereference.rs b/rust/tools/generate-api-catalog/src/dereference.rs index e6ab9d2d..c2ca8842 100644 --- a/rust/tools/generate-api-catalog/src/dereference.rs +++ b/rust/tools/generate-api-catalog/src/dereference.rs @@ -128,6 +128,51 @@ fn sanitize_defs_key(s: &str) -> String { sanitized.trim_matches('_').to_owned() } +/// Builds the `{"$ref": "#/$defs/"}` that replaces a lifted `$ref`, +/// keeping the keywords that sat beside it. JSON Schema 2020-12 applies +/// sibling keywords alongside a `$ref`, so dropping them loses constraints +/// (e.g. `positive-money` refines `simple-money` with `value.minimum: 0`) and +/// per-use annotations such as `description` and `readOnly`. +#[expect( + clippy::too_many_arguments, + reason = "threads the same resolution context as `dereference`" +)] +fn lifted_ref_with_siblings( + key: &str, + original: &serde_json::Map, + root: &Value, + spec_dir: &Path, + common_types_dir: Option<&Path>, + qualify_namesakes: bool, + defs: &mut IndexMap, + depth: usize, +) -> Value { + let mut lifted = serde_json::Map::new(); + lifted.insert( + "$ref".to_owned(), + Value::String(format!("#/$defs/{}", json_pointer_escape(key))), + ); + let siblings: serde_json::Map = original + .iter() + .filter(|(name, _)| name.as_str() != "$ref") + .map(|(name, value)| (name.clone(), value.clone())) + .collect(); + if !siblings.is_empty() + && let Value::Object(siblings) = dereference( + root, + Value::Object(siblings), + spec_dir, + common_types_dir, + qualify_namesakes, + defs, + depth + 1, + ) + { + lifted.extend(siblings); + } + Value::Object(lifted) +} + fn dereference( root: &Value, current: Value, @@ -160,7 +205,16 @@ fn dereference( if visibility::ref_targets_private_file(&ref_str, spec_dir) { return Value::Object(map); } - return serde_json::json!({"$ref": format!("#/$defs/{}", json_pointer_escape(&key))}); + return lifted_ref_with_siblings( + &key, + &map, + root, + spec_dir, + common_types_dir, + qualify_namesakes, + defs, + depth, + ); } // Insert null placeholder before resolving (circular ref guard) defs.insert(key.clone(), Value::Null); @@ -191,7 +245,16 @@ fn dereference( }; if let Some(content) = resolved_opt { defs.insert(key.clone(), content); - return serde_json::json!({"$ref": format!("#/$defs/{}", json_pointer_escape(&key))}); + return lifted_ref_with_siblings( + &key, + &map, + root, + spec_dir, + common_types_dir, + qualify_namesakes, + defs, + depth, + ); } // Resolution failed — remove placeholder and preserve original $ref // so collect_unresolved_refs() will catch it. @@ -553,419 +616,5 @@ fn load_and_dereference_with( } #[cfg(test)] -mod tests { - use super::*; - use std::fs; - - #[test] - fn dereference_resolves_relative_file_ref() { - let dir = tempfile::tempdir().expect("tempdir"); - let model_dir = dir.path().join("schemas").join("models"); - fs::create_dir_all(&model_dir).expect("create model dir"); - - fs::write( - model_dir.join("Widget.yaml"), - "type: object\nproperties:\n id:\n type: string\n", - ) - .expect("write model"); - - let spec_path = dir.path().join("schemas").join("openapi.yaml"); - fs::write( - &spec_path, - "openapi: '3.0.0'\ncomponents:\n schemas:\n Widget:\n $ref: './models/Widget.yaml'\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:?}" - ); - } - - #[test] - fn dereference_resolves_ref_in_sibling_of_schemas_dir() { - // Models at {dir}/models/ rather than {dir}/schemas/models/ (sibling layout) - let dir = tempfile::tempdir().expect("tempdir"); - let model_dir = dir.path().join("models"); - fs::create_dir_all(&model_dir).expect("create model dir"); - let schemas_dir = dir.path().join("schemas"); - fs::create_dir_all(&schemas_dir).expect("create schemas dir"); - - fs::write( - model_dir.join("Widget.yaml"), - "type: object\nproperties:\n id:\n type: string\n", - ) - .expect("write model"); - - let spec_path = schemas_dir.join("openapi.yaml"); - fs::write( - &spec_path, - "openapi: '3.0.0'\ncomponents:\n schemas:\n Widget:\n $ref: './models/Widget.yaml'\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 with sibling layout, got: {unresolved:?}" - ); - } - - #[test] - fn collect_unresolved_refs_finds_external_refs() { - let value = serde_json::json!({ - "components": { - "schemas": { - "Foo": { "$ref": "./models/Foo.yaml" }, - "Bar": { "$ref": "#/components/schemas/Baz" }, - "Qux": { "type": "string" } - } - } - }); - let unresolved = collect_unresolved_refs(&value); - assert_eq!(unresolved, vec!["./models/Foo.yaml"]); - } - - #[test] - fn collect_unresolved_refs_finds_external_discriminator_mapping() { - // A discriminator.mapping value pointing outside the document is unresolved, - // even though it is a plain string rather than a `$ref` object. - let value = serde_json::json!({ - "$defs": { - "Channel": { - "discriminator": { - "propertyName": "kind", - "mapping": { - "DEFAULT": "./BasicChannel.yaml", - "LOCAL": "#/$defs/LocalChannel" - } - } - } - } - }); - let unresolved = collect_unresolved_refs(&value); - assert_eq!(unresolved, vec!["./BasicChannel.yaml"]); - } - - #[test] - fn discriminator_mapping_rewritten_to_defs_pointer() { - let dir = tempfile::tempdir().expect("tempdir"); - let schemas_dir = dir.path().join("schemas"); - fs::create_dir_all(&schemas_dir).expect("create schemas dir"); - - fs::write( - schemas_dir.join("BasicChannel.yaml"), - "type: object\nproperties:\n kind:\n type: string\n", - ) - .expect("write model"); - - // The oneOf `$ref` lifts BasicChannel into `$defs`; the discriminator.mapping - // carries the same target as a plain string that dereference() won't touch. - let spec_path = schemas_dir.join("openapi.yaml"); - fs::write( - &spec_path, - concat!( - "openapi: '3.0.0'\n", - "components:\n", - " schemas:\n", - " Channel:\n", - " oneOf:\n", - " - $ref: './BasicChannel.yaml'\n", - " discriminator:\n", - " propertyName: kind\n", - " mapping:\n", - " DEFAULT: './BasicChannel.yaml'\n", - ), - ) - .expect("write spec"); - - let (result, defs) = load_and_dereference(&spec_path, None).expect("dereference"); - - // No external refs remain — the mapping value now points inside the document. - let mut unresolved = collect_unresolved_refs(&result); - for def_val in defs.values() { - unresolved.extend(collect_unresolved_refs(def_val)); - } - assert!( - unresolved.is_empty(), - "expected zero unresolved refs after mapping rewrite, got: {unresolved:?}" - ); - - // The mapping value is rewritten to the lifted def pointer. - let mapping = - result["components"]["schemas"]["Channel"]["discriminator"]["mapping"]["DEFAULT"] - .as_str() - .expect("mapping DEFAULT string"); - assert_eq!(mapping, "#/$defs/BasicChannel"); - assert!(defs.contains_key("BasicChannel")); - } - - #[test] - fn discriminator_mapping_target_not_lifted_stays_external_and_fails_guard() { - // Safety branch: a mapping value whose target is NOT otherwise referenced - // (no oneOf/$ref lifts it into $defs) must be left external — never pointed - // at a missing #/$defs key — so collect_unresolved_refs then flags it and - // the build fails, rather than silently producing a dangling pointer. - let dir = tempfile::tempdir().expect("tempdir"); - let schemas_dir = dir.path().join("schemas"); - fs::create_dir_all(&schemas_dir).expect("create schemas dir"); - - // Note: no BasicChannel.yaml on disk and no oneOf/$ref to it — nothing lifts it. - let spec_path = schemas_dir.join("openapi.yaml"); - fs::write( - &spec_path, - concat!( - "openapi: '3.0.0'\n", - "components:\n", - " schemas:\n", - " Channel:\n", - " type: object\n", - " discriminator:\n", - " propertyName: kind\n", - " mapping:\n", - " DEFAULT: './BasicChannel.yaml'\n", - ), - ) - .expect("write spec"); - - let (result, defs) = load_and_dereference(&spec_path, None).expect("dereference"); - - // The mapping value is left untouched (no matching def to point at)... - let mapping = - result["components"]["schemas"]["Channel"]["discriminator"]["mapping"]["DEFAULT"] - .as_str() - .expect("mapping DEFAULT string"); - assert_eq!(mapping, "./BasicChannel.yaml"); - assert!(!defs.contains_key("BasicChannel")); - - // ...and the unresolved-ref guard flags it, so the build would fail. - let mut unresolved = collect_unresolved_refs(&result); - for def_val in defs.values() { - unresolved.extend(collect_unresolved_refs(def_val)); - } - assert!( - unresolved.contains(&"./BasicChannel.yaml".to_owned()), - "expected the un-liftable mapping to be flagged as unresolved, got: {unresolved:?}" - ); - } - - #[test] - fn dereference_lifts_external_ref_to_defs() { - let dir = tempfile::tempdir().expect("tempdir"); - let model_dir = dir.path().join("schemas").join("models"); - fs::create_dir_all(&model_dir).expect("create model dir"); - - fs::write( - model_dir.join("Widget.yaml"), - "type: object\nproperties:\n id:\n type: string\n", - ) - .expect("write model"); - - let spec_path = dir.path().join("schemas").join("openapi.yaml"); - fs::write( - &spec_path, - "openapi: '3.0.0'\ncomponents:\n schemas:\n Widget:\n $ref: './models/Widget.yaml'\n", - ) - .expect("write spec"); - - let (_result, defs) = load_and_dereference(&spec_path, None).expect("dereference"); - assert!( - defs.contains_key("Widget"), - "Widget should be lifted to $defs" - ); - let widget = &defs["Widget"]; - assert_eq!(widget.get("type").and_then(|v| v.as_str()), Some("object")); - } - - #[test] - fn dereference_deduplicates_same_external_ref() { - let dir = tempfile::tempdir().expect("tempdir"); - let model_dir = dir.path().join("schemas").join("models"); - fs::create_dir_all(&model_dir).expect("create model dir"); - - fs::write( - model_dir.join("Tag.yaml"), - "type: object\nproperties:\n name:\n type: string\n", - ) - .expect("write model"); - - // Spec references Tag from two different endpoints - let spec_path = dir.path().join("schemas").join("openapi.yaml"); - fs::write( - &spec_path, - r#"openapi: '3.0.0' -paths: - /a: - get: - operationId: getA - responses: - '200': - content: - application/json: - schema: - $ref: './models/Tag.yaml' - /b: - get: - operationId: getB - responses: - '200': - content: - application/json: - schema: - $ref: './models/Tag.yaml' -"#, - ) - .expect("write spec"); - - let (result, defs) = load_and_dereference(&spec_path, None).expect("dereference"); - assert!(defs.contains_key("Tag"), "Tag should be in $defs"); - - // Both response schemas should be $ref pointers, not inlined - let paths = result.get("paths").expect("paths"); - let schema_a = - paths["/a"]["get"]["responses"]["200"]["content"]["application/json"]["schema"] - .as_object() - .expect("schema_a object"); - assert_eq!( - schema_a.get("$ref").and_then(|v| v.as_str()), - Some("#/$defs/Tag"), - "schema_a should be a local $defs ref" - ); - let schema_b = - paths["/b"]["get"]["responses"]["200"]["content"]["application/json"]["schema"] - .as_object() - .expect("schema_b object"); - assert_eq!( - schema_b.get("$ref").and_then(|v| v.as_str()), - Some("#/$defs/Tag"), - "schema_b should be a local $defs ref" - ); - } - - #[test] - fn dereference_lifts_component_schema_ref() { - let dir = tempfile::tempdir().expect("tempdir"); - let spec_path = dir.path().join("openapi.yaml"); - fs::write( - &spec_path, - r#"openapi: '3.0.0' -components: - schemas: - Item: - type: object - properties: - id: - type: string -paths: - /items: - get: - operationId: listItems - responses: - '200': - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/Item' -"#, - ) - .expect("write spec"); - - let (result, defs) = load_and_dereference(&spec_path, None).expect("dereference"); - - // Item should be lifted to $defs - assert!(defs.contains_key("Item"), "Item should be in $defs"); - - // The response schema items should be a local $ref - let schema = result["paths"]["/items"]["get"]["responses"]["200"]["content"] - ["application/json"]["schema"] - .as_object() - .expect("schema object"); - let items_ref = schema["items"] - .get("$ref") - .and_then(|v| v.as_str()) - .expect("items.$ref"); - assert_eq!(items_ref, "#/$defs/Item"); - } - - #[test] - fn dereference_circular_ref_guard() { - // Schema A references schema B which references schema A — must not infinite-loop - let dir = tempfile::tempdir().expect("tempdir"); - let spec_path = dir.path().join("openapi.yaml"); - fs::write( - &spec_path, - r#"openapi: '3.0.0' -components: - schemas: - NodeA: - type: object - properties: - child: - $ref: '#/components/schemas/NodeB' - NodeB: - type: object - properties: - parent: - $ref: '#/components/schemas/NodeA' -"#, - ) - .expect("write spec"); - - // Must complete without stack overflow or panic - let (_result, defs) = load_and_dereference(&spec_path, None).expect("dereference"); - assert!(defs.contains_key("NodeA") || defs.contains_key("NodeB")); - } - - #[test] - fn derive_defs_key_for_path_extracts_stem() { - assert_eq!(derive_defs_key_for_path("./models/Order.yaml"), "Order"); - assert_eq!( - derive_defs_key_for_path("../common-types/error.json"), - "error" - ); - assert_eq!( - derive_defs_key_for_path("https://schemas.api.godaddy.com/v1/json/address.json"), - "address" - ); - assert_eq!( - derive_defs_key_for_path("./Bulk_Ingestion.yaml"), - "Bulk_Ingestion" - ); - // Fragment with component name takes precedence over file stem - assert_eq!( - derive_defs_key_for_path("./common.yaml#/components/schemas/Foo"), - "Foo" - ); - assert_eq!( - derive_defs_key_for_path("./shared.yaml#/definitions/Bar"), - "Bar" - ); - // A `#/properties/` fragment picks out one property's schema, not the - // file's root schema — it must be folded into the key so two refs into the - // same file for different properties don't collide (DEVEX-965). - assert_eq!( - derive_defs_key_for_path("./models/FulfillmentPlan.yaml#/properties/storeId"), - "FulfillmentPlan_storeId" - ); - assert_eq!( - derive_defs_key_for_path("./models/FulfillmentPlan.yaml#/properties/orderId"), - "FulfillmentPlan_orderId" - ); - assert_eq!( - derive_defs_key_for_path("./models/Foo.yaml#/properties/a/properties/b"), - "Foo_a_b" - ); - // A literal property named `a_b` must not collide with nested segments `a` - // then `b` — both would sanitize to the same "a_b" suffix without escaping - // the literal underscore first. - assert_ne!( - derive_defs_key_for_path("./models/Foo.yaml#/properties/a_b"), - derive_defs_key_for_path("./models/Foo.yaml#/properties/a/properties/b") - ); - } -} +#[path = "dereference_tests.rs"] +mod tests; diff --git a/rust/tools/generate-api-catalog/src/dereference_tests.rs b/rust/tools/generate-api-catalog/src/dereference_tests.rs new file mode 100644 index 00000000..bbcf1883 --- /dev/null +++ b/rust/tools/generate-api-catalog/src/dereference_tests.rs @@ -0,0 +1,497 @@ +use super::*; +use std::fs; + +#[test] +fn dereference_resolves_relative_file_ref() { + let dir = tempfile::tempdir().expect("tempdir"); + let model_dir = dir.path().join("schemas").join("models"); + fs::create_dir_all(&model_dir).expect("create model dir"); + + fs::write( + model_dir.join("Widget.yaml"), + "type: object\nproperties:\n id:\n type: string\n", + ) + .expect("write model"); + + let spec_path = dir.path().join("schemas").join("openapi.yaml"); + fs::write( + &spec_path, + "openapi: '3.0.0'\ncomponents:\n schemas:\n Widget:\n $ref: './models/Widget.yaml'\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:?}" + ); +} + +#[test] +fn dereference_resolves_ref_in_sibling_of_schemas_dir() { + // Models at {dir}/models/ rather than {dir}/schemas/models/ (sibling layout) + let dir = tempfile::tempdir().expect("tempdir"); + let model_dir = dir.path().join("models"); + fs::create_dir_all(&model_dir).expect("create model dir"); + let schemas_dir = dir.path().join("schemas"); + fs::create_dir_all(&schemas_dir).expect("create schemas dir"); + + fs::write( + model_dir.join("Widget.yaml"), + "type: object\nproperties:\n id:\n type: string\n", + ) + .expect("write model"); + + let spec_path = schemas_dir.join("openapi.yaml"); + fs::write( + &spec_path, + "openapi: '3.0.0'\ncomponents:\n schemas:\n Widget:\n $ref: './models/Widget.yaml'\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 with sibling layout, got: {unresolved:?}" + ); +} + +#[test] +fn collect_unresolved_refs_finds_external_refs() { + let value = serde_json::json!({ + "components": { + "schemas": { + "Foo": { "$ref": "./models/Foo.yaml" }, + "Bar": { "$ref": "#/components/schemas/Baz" }, + "Qux": { "type": "string" } + } + } + }); + let unresolved = collect_unresolved_refs(&value); + assert_eq!(unresolved, vec!["./models/Foo.yaml"]); +} + +#[test] +fn collect_unresolved_refs_finds_external_discriminator_mapping() { + // A discriminator.mapping value pointing outside the document is unresolved, + // even though it is a plain string rather than a `$ref` object. + let value = serde_json::json!({ + "$defs": { + "Channel": { + "discriminator": { + "propertyName": "kind", + "mapping": { + "DEFAULT": "./BasicChannel.yaml", + "LOCAL": "#/$defs/LocalChannel" + } + } + } + } + }); + let unresolved = collect_unresolved_refs(&value); + assert_eq!(unresolved, vec!["./BasicChannel.yaml"]); +} + +#[test] +fn discriminator_mapping_rewritten_to_defs_pointer() { + let dir = tempfile::tempdir().expect("tempdir"); + let schemas_dir = dir.path().join("schemas"); + fs::create_dir_all(&schemas_dir).expect("create schemas dir"); + + fs::write( + schemas_dir.join("BasicChannel.yaml"), + "type: object\nproperties:\n kind:\n type: string\n", + ) + .expect("write model"); + + // The oneOf `$ref` lifts BasicChannel into `$defs`; the discriminator.mapping + // carries the same target as a plain string that dereference() won't touch. + let spec_path = schemas_dir.join("openapi.yaml"); + fs::write( + &spec_path, + concat!( + "openapi: '3.0.0'\n", + "components:\n", + " schemas:\n", + " Channel:\n", + " oneOf:\n", + " - $ref: './BasicChannel.yaml'\n", + " discriminator:\n", + " propertyName: kind\n", + " mapping:\n", + " DEFAULT: './BasicChannel.yaml'\n", + ), + ) + .expect("write spec"); + + let (result, defs) = load_and_dereference(&spec_path, None).expect("dereference"); + + // No external refs remain — the mapping value now points inside the document. + let mut unresolved = collect_unresolved_refs(&result); + for def_val in defs.values() { + unresolved.extend(collect_unresolved_refs(def_val)); + } + assert!( + unresolved.is_empty(), + "expected zero unresolved refs after mapping rewrite, got: {unresolved:?}" + ); + + // The mapping value is rewritten to the lifted def pointer. + let mapping = result["components"]["schemas"]["Channel"]["discriminator"]["mapping"]["DEFAULT"] + .as_str() + .expect("mapping DEFAULT string"); + assert_eq!(mapping, "#/$defs/BasicChannel"); + assert!(defs.contains_key("BasicChannel")); +} + +#[test] +fn discriminator_mapping_target_not_lifted_stays_external_and_fails_guard() { + // Safety branch: a mapping value whose target is NOT otherwise referenced + // (no oneOf/$ref lifts it into $defs) must be left external — never pointed + // at a missing #/$defs key — so collect_unresolved_refs then flags it and + // the build fails, rather than silently producing a dangling pointer. + let dir = tempfile::tempdir().expect("tempdir"); + let schemas_dir = dir.path().join("schemas"); + fs::create_dir_all(&schemas_dir).expect("create schemas dir"); + + // Note: no BasicChannel.yaml on disk and no oneOf/$ref to it — nothing lifts it. + let spec_path = schemas_dir.join("openapi.yaml"); + fs::write( + &spec_path, + concat!( + "openapi: '3.0.0'\n", + "components:\n", + " schemas:\n", + " Channel:\n", + " type: object\n", + " discriminator:\n", + " propertyName: kind\n", + " mapping:\n", + " DEFAULT: './BasicChannel.yaml'\n", + ), + ) + .expect("write spec"); + + let (result, defs) = load_and_dereference(&spec_path, None).expect("dereference"); + + // The mapping value is left untouched (no matching def to point at)... + let mapping = result["components"]["schemas"]["Channel"]["discriminator"]["mapping"]["DEFAULT"] + .as_str() + .expect("mapping DEFAULT string"); + assert_eq!(mapping, "./BasicChannel.yaml"); + assert!(!defs.contains_key("BasicChannel")); + + // ...and the unresolved-ref guard flags it, so the build would fail. + let mut unresolved = collect_unresolved_refs(&result); + for def_val in defs.values() { + unresolved.extend(collect_unresolved_refs(def_val)); + } + assert!( + unresolved.contains(&"./BasicChannel.yaml".to_owned()), + "expected the un-liftable mapping to be flagged as unresolved, got: {unresolved:?}" + ); +} + +#[test] +fn dereference_lifts_external_ref_to_defs() { + let dir = tempfile::tempdir().expect("tempdir"); + let model_dir = dir.path().join("schemas").join("models"); + fs::create_dir_all(&model_dir).expect("create model dir"); + + fs::write( + model_dir.join("Widget.yaml"), + "type: object\nproperties:\n id:\n type: string\n", + ) + .expect("write model"); + + let spec_path = dir.path().join("schemas").join("openapi.yaml"); + fs::write( + &spec_path, + "openapi: '3.0.0'\ncomponents:\n schemas:\n Widget:\n $ref: './models/Widget.yaml'\n", + ) + .expect("write spec"); + + let (_result, defs) = load_and_dereference(&spec_path, None).expect("dereference"); + assert!( + defs.contains_key("Widget"), + "Widget should be lifted to $defs" + ); + let widget = &defs["Widget"]; + assert_eq!(widget.get("type").and_then(|v| v.as_str()), Some("object")); +} + +#[test] +fn dereference_deduplicates_same_external_ref() { + let dir = tempfile::tempdir().expect("tempdir"); + let model_dir = dir.path().join("schemas").join("models"); + fs::create_dir_all(&model_dir).expect("create model dir"); + + fs::write( + model_dir.join("Tag.yaml"), + "type: object\nproperties:\n name:\n type: string\n", + ) + .expect("write model"); + + // Spec references Tag from two different endpoints + let spec_path = dir.path().join("schemas").join("openapi.yaml"); + fs::write( + &spec_path, + r#"openapi: '3.0.0' +paths: + /a: + get: + operationId: getA + responses: + '200': + content: + application/json: + schema: + $ref: './models/Tag.yaml' + /b: + get: + operationId: getB + responses: + '200': + content: + application/json: + schema: + $ref: './models/Tag.yaml' +"#, + ) + .expect("write spec"); + + let (result, defs) = load_and_dereference(&spec_path, None).expect("dereference"); + assert!(defs.contains_key("Tag"), "Tag should be in $defs"); + + // Both response schemas should be $ref pointers, not inlined + let paths = result.get("paths").expect("paths"); + let schema_a = paths["/a"]["get"]["responses"]["200"]["content"]["application/json"]["schema"] + .as_object() + .expect("schema_a object"); + assert_eq!( + schema_a.get("$ref").and_then(|v| v.as_str()), + Some("#/$defs/Tag"), + "schema_a should be a local $defs ref" + ); + let schema_b = paths["/b"]["get"]["responses"]["200"]["content"]["application/json"]["schema"] + .as_object() + .expect("schema_b object"); + assert_eq!( + schema_b.get("$ref").and_then(|v| v.as_str()), + Some("#/$defs/Tag"), + "schema_b should be a local $defs ref" + ); +} + +#[test] +fn dereference_keeps_siblings_next_to_a_lifted_ref() { + let dir = tempfile::tempdir().expect("tempdir"); + let spec_path = dir.path().join("openapi.yaml"); + fs::write( + &spec_path, + r#"openapi: '3.0.0' +components: + schemas: + Item: + type: object + properties: + id: + type: string + Holder: + type: object + properties: + first: + $ref: '#/components/schemas/Item' + description: The first item + readOnly: true + second: + $ref: '#/components/schemas/Item' + description: The second item +"#, + ) + .expect("write spec"); + + let (result, defs) = load_and_dereference(&spec_path, None).expect("dereference"); + let holder = &result["components"]["schemas"]["Holder"]["properties"]; + // First use lifts Item into $defs; second use is the already-registered path. + assert_eq!( + holder["first"], + serde_json::json!({ + "$ref": "#/$defs/Item", + "description": "The first item", + "readOnly": true, + }) + ); + assert_eq!( + holder["second"], + serde_json::json!({ + "$ref": "#/$defs/Item", + "description": "The second item", + }) + ); + assert!( + defs["Item"].get("description").is_none(), + "per-use siblings must not leak into the shared definition" + ); +} + +#[test] +fn dereference_keeps_constraints_a_schema_file_adds_to_its_ref() { + // Mirrors orders' positive-money: a file that `$ref`s a base schema and + // tightens one of its properties. + let dir = tempfile::tempdir().expect("tempdir"); + let model_dir = dir.path().join("schemas").join("models"); + fs::create_dir_all(&model_dir).expect("create model dir"); + fs::write( + model_dir.join("money.json"), + r#"{"type":"object","properties":{"value":{"type":"integer"}}}"#, + ) + .expect("write base"); + fs::write( + model_dir.join("positive-money.json"), + r#"{"$ref":"./money.json","properties":{"value":{"minimum":0}}}"#, + ) + .expect("write refinement"); + let spec_path = dir.path().join("schemas").join("openapi.yaml"); + fs::write( + &spec_path, + "openapi: '3.0.0'\ncomponents:\n schemas:\n Price:\n $ref: './models/positive-money.json'\n", + ) + .expect("write spec"); + + let (_result, defs) = load_and_dereference(&spec_path, None).expect("dereference"); + assert_eq!( + defs["positive-money"], + serde_json::json!({ + "$ref": "#/$defs/money", + "properties": { "value": { "minimum": 0 } }, + }) + ); + assert_eq!(defs["money"]["properties"]["value"]["type"], "integer"); +} + +#[test] +fn dereference_lifts_component_schema_ref() { + let dir = tempfile::tempdir().expect("tempdir"); + let spec_path = dir.path().join("openapi.yaml"); + fs::write( + &spec_path, + r#"openapi: '3.0.0' +components: + schemas: + Item: + type: object + properties: + id: + type: string +paths: + /items: + get: + operationId: listItems + responses: + '200': + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Item' +"#, + ) + .expect("write spec"); + + let (result, defs) = load_and_dereference(&spec_path, None).expect("dereference"); + + // Item should be lifted to $defs + assert!(defs.contains_key("Item"), "Item should be in $defs"); + + // The response schema items should be a local $ref + let schema = result["paths"]["/items"]["get"]["responses"]["200"]["content"] + ["application/json"]["schema"] + .as_object() + .expect("schema object"); + let items_ref = schema["items"] + .get("$ref") + .and_then(|v| v.as_str()) + .expect("items.$ref"); + assert_eq!(items_ref, "#/$defs/Item"); +} + +#[test] +fn dereference_circular_ref_guard() { + // Schema A references schema B which references schema A — must not infinite-loop + let dir = tempfile::tempdir().expect("tempdir"); + let spec_path = dir.path().join("openapi.yaml"); + fs::write( + &spec_path, + r#"openapi: '3.0.0' +components: + schemas: + NodeA: + type: object + properties: + child: + $ref: '#/components/schemas/NodeB' + NodeB: + type: object + properties: + parent: + $ref: '#/components/schemas/NodeA' +"#, + ) + .expect("write spec"); + + // Must complete without stack overflow or panic + let (_result, defs) = load_and_dereference(&spec_path, None).expect("dereference"); + assert!(defs.contains_key("NodeA") || defs.contains_key("NodeB")); +} + +#[test] +fn derive_defs_key_for_path_extracts_stem() { + assert_eq!(derive_defs_key_for_path("./models/Order.yaml"), "Order"); + assert_eq!( + derive_defs_key_for_path("../common-types/error.json"), + "error" + ); + assert_eq!( + derive_defs_key_for_path("https://schemas.api.godaddy.com/v1/json/address.json"), + "address" + ); + assert_eq!( + derive_defs_key_for_path("./Bulk_Ingestion.yaml"), + "Bulk_Ingestion" + ); + // Fragment with component name takes precedence over file stem + assert_eq!( + derive_defs_key_for_path("./common.yaml#/components/schemas/Foo"), + "Foo" + ); + assert_eq!( + derive_defs_key_for_path("./shared.yaml#/definitions/Bar"), + "Bar" + ); + // A `#/properties/` fragment picks out one property's schema, not the + // file's root schema — it must be folded into the key so two refs into the + // same file for different properties don't collide (DEVEX-965). + assert_eq!( + derive_defs_key_for_path("./models/FulfillmentPlan.yaml#/properties/storeId"), + "FulfillmentPlan_storeId" + ); + assert_eq!( + derive_defs_key_for_path("./models/FulfillmentPlan.yaml#/properties/orderId"), + "FulfillmentPlan_orderId" + ); + assert_eq!( + derive_defs_key_for_path("./models/Foo.yaml#/properties/a/properties/b"), + "Foo_a_b" + ); + // A literal property named `a_b` must not collide with nested segments `a` + // then `b` — both would sanitize to the same "a_b" suffix without escaping + // the literal underscore first. + assert_ne!( + derive_defs_key_for_path("./models/Foo.yaml#/properties/a_b"), + derive_defs_key_for_path("./models/Foo.yaml#/properties/a/properties/b") + ); +} From 96e2bfd3e5367cfa5e8e1bb26f082f0c8f34d66e Mon Sep 17 00:00:00 2001 From: Jacob Page Date: Tue, 3 Nov 2026 14:37:50 -0800 Subject: [PATCH 3/4] fix(api-catalog): drop a boolean `required` placed beside a $ref Keeping keywords that sit beside a `$ref` also kept a misplaced `required: true` on one Bulk Operations request body. A schema-level `required` must be an array of property names, so the generator now omits a non-array `required` there; the request body's own `required` flag is unchanged. Co-Authored-By: Claude Sonnet 5.5 --- rust/schemas/api/bulk-operations.json | 3 +- rust/schemas/api/manifest.json | 2 +- .../generate-api-catalog/src/dereference.rs | 6 ++- .../src/dereference_tests.rs | 39 +++++++++++++++++++ 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/rust/schemas/api/bulk-operations.json b/rust/schemas/api/bulk-operations.json index 0faacda8..becbdf4b 100644 --- a/rust/schemas/api/bulk-operations.json +++ b/rust/schemas/api/bulk-operations.json @@ -2322,8 +2322,7 @@ "contentType": "application/json", "required": false, "schema": { - "$ref": "#/$defs/JSONPatch", - "required": true + "$ref": "#/$defs/JSONPatch" } }, "responses": { diff --git a/rust/schemas/api/manifest.json b/rust/schemas/api/manifest.json index 245e0640..283d8ad0 100644 --- a/rust/schemas/api/manifest.json +++ b/rust/schemas/api/manifest.json @@ -1,5 +1,5 @@ { - "generated": "2026-11-03T22:23:48.433457+00:00", + "generated": "2026-11-03T22:36:57.733509956+00:00", "domains": { "app-registry": { "file": "app-registry.json", diff --git a/rust/tools/generate-api-catalog/src/dereference.rs b/rust/tools/generate-api-catalog/src/dereference.rs index c2ca8842..fcfb57d9 100644 --- a/rust/tools/generate-api-catalog/src/dereference.rs +++ b/rust/tools/generate-api-catalog/src/dereference.rs @@ -154,7 +154,11 @@ fn lifted_ref_with_siblings( ); let siblings: serde_json::Map = original .iter() - .filter(|(name, _)| name.as_str() != "$ref") + // A schema-level `required` must be an array of property names; a + // boolean there is the OpenAPI 2 parameter form, misplaced upstream. + .filter(|(name, value)| { + name.as_str() != "$ref" && !(name.as_str() == "required" && !value.is_array()) + }) .map(|(name, value)| (name.clone(), value.clone())) .collect(); if !siblings.is_empty() diff --git a/rust/tools/generate-api-catalog/src/dereference_tests.rs b/rust/tools/generate-api-catalog/src/dereference_tests.rs index bbcf1883..31cadb3f 100644 --- a/rust/tools/generate-api-catalog/src/dereference_tests.rs +++ b/rust/tools/generate-api-catalog/src/dereference_tests.rs @@ -337,6 +337,45 @@ components: ); } +#[test] +fn dereference_drops_a_boolean_required_beside_a_ref_but_keeps_an_array() { + let dir = tempfile::tempdir().expect("tempdir"); + let spec_path = dir.path().join("openapi.yaml"); + fs::write( + &spec_path, + r#"openapi: '3.0.0' +components: + schemas: + Item: + type: object + properties: + id: + type: string + Holder: + type: object + properties: + misplaced: + $ref: '#/components/schemas/Item' + required: true + refined: + $ref: '#/components/schemas/Item' + required: [id] +"#, + ) + .expect("write spec"); + + let (result, _defs) = load_and_dereference(&spec_path, None).expect("dereference"); + let holder = &result["components"]["schemas"]["Holder"]["properties"]; + assert_eq!( + holder["misplaced"], + serde_json::json!({ "$ref": "#/$defs/Item" }) + ); + assert_eq!( + holder["refined"], + serde_json::json!({ "$ref": "#/$defs/Item", "required": ["id"] }) + ); +} + #[test] fn dereference_keeps_constraints_a_schema_file_adds_to_its_ref() { // Mirrors orders' positive-money: a file that `$ref`s a base schema and From 888e9d40da33d2c17bc7e8ace5bf7c3c45acf6d4 Mon Sep 17 00:00:00 2001 From: Jacob Page Date: Tue, 3 Nov 2026 14:43:37 -0800 Subject: [PATCH 4/4] docs: correct which generated specs the drift check covers The maintainers guide said the drift workflow compares every path the generator rewrites. It checks only the catalog and the Domains and Hosting specs; the Email, Shopping and platform app specs are also regenerated and must be committed with them. Co-Authored-By: Claude Sonnet 5.5 --- docs/maintainers.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/maintainers.md b/docs/maintainers.md index 83073a6e..a6c86fec 100644 --- a/docs/maintainers.md +++ b/docs/maintainers.md @@ -60,10 +60,12 @@ The CLI embeds a catalog of upstream API specs (browsable with `gddy api ...`) a 1. Get a token that can read the spec repositories in the `gdcorp-platform` org. `gh auth token` works if your account has access; CI uses a read-only GitHub App instead. 1. From `rust/`, run `GITHUB_TOKEN= cargo run -p generate-api-catalog`. Which specs are pulled is configured in [`api-catalog-sources.json`](../rust/api-catalog-sources.json). -1. Review the diff. The generator rewrites these paths, which are exactly what the workflow compares: +1. Review the diff. The generator rewrites these paths: - [`rust/schemas/api/`](../rust/schemas/api) — the embedded catalog. `manifest.json` carries a generated-at timestamp that changes on every run; the workflow ignores it, so a timestamp-only change is not drift. - - `rust/domains-client/openapi/domains.oas3.json` and `rust/hosting-client/openapi/hosting.oas3.json` — inputs to the generated clients. + - `rust/domains-client/openapi/domains.oas3.json`, `rust/hosting-client/openapi/hosting.oas3.json`, `rust/email-client/openapi/email.oas3.json` and `rust/shopping-client/openapi/shopping.oas3.json` — inputs to the generated clients. - `rust/platform-app-client/graphql/schema.graphql` — input to the platform app client. + + The drift workflow compares only the catalog, the Domains spec and the Hosting spec, so it can pass while the other codegen specs are stale. Commit everything the generator changed, not only what the workflow flagged. 1. Run the checks in [`AGENTS.md`](../AGENTS.md#verification-checklist-required-before-finishing-work). Generated clients are rebuilt from the updated specs, so an upstream breaking change shows up as a compile error or test failure here; fix the affected commands in the same PR. 1. Commit the result as `fix(api-catalog): resync spec drift with ...` and name the APIs that changed (see [#321](https://github.com/godaddy/cli/pull/321)), since the commit title is surfaced in release notes.