// AUTOGENERATED — DO NOT EDIT. // // Generated by scripts/codegen-schemas.ts from UCP spec at: // url https://ucp.dev/2026-04-08/schemas/discovery/profile.json // version 2026-04-08 // // Transforms applied: // - T2 injectObjectType // - T4 openAdditionalProperties // // To regenerate: pnpm gen:schemas // CI drift gate: any uncommitted change here fails the build. import { z } from "zod" export const businessProfileSchema = z.intersection(z.object({ "ucp": z.object({ "version": z.string().regex(new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("UCP version in YYYY-MM-DD format."), "status": z.enum(["success","error"]).describe("Application-level status of the UCP operation.").default("success"), "services": z.record(z.string(), z.array(z.intersection(z.object({ "version": z.string().regex(new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("Entity version in YYYY-MM-DD format."), "spec": z.string().url().describe("URL to human-readable specification document.").optional(), "schema": z.string().url().describe("URL to JSON Schema defining this entity's structure and payloads.").optional(), "id": z.string().describe("Unique identifier for this entity instance. Used to disambiguate when multiple instances exist.").optional(), "config": z.record(z.string(), z.any()).describe("Entity-specific configuration. Structure defined by each entity's schema.").optional() }).catchall(z.any()).describe("Shared foundation for all UCP entities."), z.object({ "transport": z.enum(["rest","mcp","a2a","embedded"]).describe("Transport protocol for this service binding."), "endpoint": z.string().url().describe("Endpoint URL for this transport binding.").optional() }).catchall(z.any())))).describe("Service registry keyed by reverse-domain name.").optional(), "capabilities": z.record(z.string(), z.array(z.intersection(z.object({ "version": z.string().regex(new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("Entity version in YYYY-MM-DD format."), "spec": z.string().url().describe("URL to human-readable specification document.").optional(), "schema": z.string().url().describe("URL to JSON Schema defining this entity's structure and payloads.").optional(), "id": z.string().describe("Unique identifier for this entity instance. Used to disambiguate when multiple instances exist.").optional(), "config": z.record(z.string(), z.any()).describe("Entity-specific configuration. Structure defined by each entity's schema.").optional() }).catchall(z.any()).describe("Shared foundation for all UCP entities."), z.object({ "extends": z.any().superRefine((x, ctx) => { const schemas = [z.string().regex(new RegExp("^[a-z][a-z0-9]*(?:\\.[a-z][a-z0-9_]*)+$")), z.array(z.string().regex(new RegExp("^[a-z][a-z0-9]*(?:\\.[a-z][a-z0-9_]*)+$"))).min(1)]; const { errors, failed } = schemas.reduce<{ errors: z.core.$ZodIssue[]; failed: number; }>( ({ errors, failed }, schema) => ((result) => result.error ? { errors: [...errors, ...result.error.issues], failed: failed + 1, } : { errors, failed })( schema.safeParse(x), ), { errors: [], failed: 0 }, ); const passed = schemas.length - failed; if (passed !== 1) { ctx.addIssue(errors.length ? { path: [], code: "invalid_union", errors: [errors], message: "Invalid input: Should pass single schema. Passed " + passed, } : { path: [], code: "custom", errors: [errors], message: "Invalid input: Should pass single schema. Passed " + passed, }); } }).describe("Parent capability(s) this extends. Present for extensions, absent for root capabilities. Use array for multi-parent extensions.").optional() }).catchall(z.any())))).describe("Capability registry keyed by reverse-domain name.").optional(), "payment_handlers": z.record(z.string(), z.array(z.intersection(z.object({ "version": z.string().regex(new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("Entity version in YYYY-MM-DD format."), "spec": z.string().url().describe("URL to human-readable specification document.").optional(), "schema": z.string().url().describe("URL to JSON Schema defining this entity's structure and payloads.").optional(), "id": z.string().describe("Unique identifier for this entity instance. Used to disambiguate when multiple instances exist.").optional(), "config": z.record(z.string(), z.any()).describe("Entity-specific configuration. Structure defined by each entity's schema.").optional() }).catchall(z.any()).describe("Shared foundation for all UCP entities."), z.intersection(z.record(z.string(), z.any()), z.object({ "available_instruments": z.array(z.object({ "type": z.string().describe("The instrument type identifier (e.g., 'card', 'gift_card'). References an instrument schema's type constant."), "constraints": z.record(z.string(), z.any()).describe("Constraints on this instrument type. Structure depends on instrument type and active capabilities.").optional() }).catchall(z.any()).describe("An instrument type available from a payment handler with optional constraints.")).min(1).describe("Instrument types this handler supports, with optional constraints. When absent, every instrument should be considered available.").optional() }).catchall(z.any()))))).describe("Payment handler registry keyed by reverse-domain name.").optional() }).catchall(z.any()).describe("Base UCP metadata with shared properties for all schema types."), "signing_keys": z.array(z.object({ "kid": z.string().describe("Key identifier referenced by Signature-Input keyid. For keys used in dual-audience (Web Bot Auth) signatures, the kid MUST be the key's JWK SHA-256 Thumbprint (RFC 7638) so UCP-Agent and Signature-Agent lookups resolve the same key; otherwise the kid MAY be any stable string."), "kty": z.string().describe("JWK key type. Well-known values: EC for ECDSA (P-256, P-384); OKP for EdDSA (Ed25519). Open vocabulary; verifiers tolerate unrecognized types and select keys by kid."), "crv": z.string().describe("Curve name. Well-known values: P-256, P-384 (EC); Ed25519 (OKP). Open vocabulary.").optional(), "x": z.string().describe("Public key value, base64url-encoded. For EC, the x coordinate (RFC 7518 §6.2); for OKP, the public key (RFC 8037 §2).").optional(), "y": z.string().describe("EC public key y coordinate, base64url-encoded (RFC 7518 §6.2). Not used by OKP keys.").optional(), "n": z.string().describe("Modulus for RSA public keys (base64url encoded).").optional(), "e": z.string().describe("Exponent for RSA public keys (base64url encoded).").optional(), "use": z.enum(["sig","enc"]).describe("Key usage. Should be 'sig' for signing keys.").optional(), "alg": z.string().describe("JWA algorithm associated with this public key. Optional; verifiers derive the algorithm from crv when alg is omitted. When present for a well-known curve it MUST match: ES256 with P-256, ES384 with P-384, EdDSA with Ed25519.").optional() }).catchall(z.any()).and(z.intersection(z.intersection(z.any(), z.any()), z.intersection(z.any(), z.intersection(z.any(), z.any())))).describe("Public JSON Web Key used for HTTP Message Signatures and signed webhook verification. UCP profiles publish public keys only; private key material MUST NOT appear in a profile. Well-known key types: EC (ECDSA P-256, P-384) and OKP (EdDSA Ed25519); OKP keys are RECOMMENDED for signers opting into Web Bot Auth (WBA) interop on HTTP transport. A single profile MAY publish keys of either or both types; consumers select keys by kid. The kty, crv, and alg vocabularies are OPEN: verifiers MUST tolerate key types, curves, and algorithms they do not recognize, selecting keys by kid at verification time. An unsupported key affects only the signature that references it (algorithm_unsupported) and MUST NOT cause whole-profile rejection. Additional public JWK members are permitted; consumers ignore unknown members.")).describe("Canonical UCP profile field for publishing signing keys. When a profile publishes signing keys, they MUST appear here; this is where every UCP verifier reads them. A future UCP version will promote keys[] to canonical and deprecate signing_keys[]; profiles wanting WBA interop today MAY publish both arrays as mirrors.").optional(), "keys": z.array(z.object({ "kid": z.string().describe("Key identifier referenced by Signature-Input keyid. For keys used in dual-audience (Web Bot Auth) signatures, the kid MUST be the key's JWK SHA-256 Thumbprint (RFC 7638) so UCP-Agent and Signature-Agent lookups resolve the same key; otherwise the kid MAY be any stable string."), "kty": z.string().describe("JWK key type. Well-known values: EC for ECDSA (P-256, P-384); OKP for EdDSA (Ed25519). Open vocabulary; verifiers tolerate unrecognized types and select keys by kid."), "crv": z.string().describe("Curve name. Well-known values: P-256, P-384 (EC); Ed25519 (OKP). Open vocabulary.").optional(), "x": z.string().describe("Public key value, base64url-encoded. For EC, the x coordinate (RFC 7518 §6.2); for OKP, the public key (RFC 8037 §2).").optional(), "y": z.string().describe("EC public key y coordinate, base64url-encoded (RFC 7518 §6.2). Not used by OKP keys.").optional(), "n": z.string().describe("Modulus for RSA public keys (base64url encoded).").optional(), "e": z.string().describe("Exponent for RSA public keys (base64url encoded).").optional(), "use": z.enum(["sig","enc"]).describe("Key usage. Should be 'sig' for signing keys.").optional(), "alg": z.string().describe("JWA algorithm associated with this public key. Optional; verifiers derive the algorithm from crv when alg is omitted. When present for a well-known curve it MUST match: ES256 with P-256, ES384 with P-384, EdDSA with Ed25519.").optional() }).catchall(z.any()).and(z.intersection(z.intersection(z.any(), z.any()), z.intersection(z.any(), z.intersection(z.any(), z.any())))).describe("Public JSON Web Key used for HTTP Message Signatures and signed webhook verification. UCP profiles publish public keys only; private key material MUST NOT appear in a profile. Well-known key types: EC (ECDSA P-256, P-384) and OKP (EdDSA Ed25519); OKP keys are RECOMMENDED for signers opting into Web Bot Auth (WBA) interop on HTTP transport. A single profile MAY publish keys of either or both types; consumers select keys by kid. The kty, crv, and alg vocabularies are OPEN: verifiers MUST tolerate key types, curves, and algorithms they do not recognize, selecting keys by kid at verification time. An unsupported key affects only the signature that references it (algorithm_unsupported) and MUST NOT cause whole-profile rejection. Additional public JWK members are permitted; consumers ignore unknown members.")).describe("Optional top-level JWK Set per RFC 7517, mirroring signing_keys[]. When present, makes the UCP profile a valid JWK Set that a signer can reuse as its Web Bot Auth key source. A WBA-shape verifier resolving via Signature-Agent type=jwks_uri pointed at this profile reads these keys; UCP-default verifiers read signing_keys[]; the cimd and directory variants reach keys through their own documents. When both arrays are published, they MUST list the same set of kid values, and entries sharing a kid MUST be semantically equivalent — identical RFC 7638 base64url JWK SHA-256 Thumbprints (serialization differences such as member order are not significant). See the Deployment Patterns for WBA Interop section in the overview for hosting patterns.").optional() }).catchall(z.any()).describe("Base discovery profile with shared properties for all profile types."), z.object({ "ucp": z.intersection(z.object({ "version": z.string().regex(new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("UCP version in YYYY-MM-DD format."), "status": z.enum(["success","error"]).describe("Application-level status of the UCP operation.").default("success"), "services": z.record(z.string(), z.array(z.intersection(z.object({ "version": z.string().regex(new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("Entity version in YYYY-MM-DD format."), "spec": z.string().url().describe("URL to human-readable specification document.").optional(), "schema": z.string().url().describe("URL to JSON Schema defining this entity's structure and payloads.").optional(), "id": z.string().describe("Unique identifier for this entity instance. Used to disambiguate when multiple instances exist.").optional(), "config": z.record(z.string(), z.any()).describe("Entity-specific configuration. Structure defined by each entity's schema.").optional() }).catchall(z.any()).describe("Shared foundation for all UCP entities."), z.object({ "transport": z.enum(["rest","mcp","a2a","embedded"]).describe("Transport protocol for this service binding."), "endpoint": z.string().url().describe("Endpoint URL for this transport binding.").optional() }).catchall(z.any())))).describe("Service registry keyed by reverse-domain name.").optional(), "capabilities": z.record(z.string(), z.array(z.intersection(z.object({ "version": z.string().regex(new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("Entity version in YYYY-MM-DD format."), "spec": z.string().url().describe("URL to human-readable specification document.").optional(), "schema": z.string().url().describe("URL to JSON Schema defining this entity's structure and payloads.").optional(), "id": z.string().describe("Unique identifier for this entity instance. Used to disambiguate when multiple instances exist.").optional(), "config": z.record(z.string(), z.any()).describe("Entity-specific configuration. Structure defined by each entity's schema.").optional() }).catchall(z.any()).describe("Shared foundation for all UCP entities."), z.object({ "extends": z.any().superRefine((x, ctx) => { const schemas = [z.string().regex(new RegExp("^[a-z][a-z0-9]*(?:\\.[a-z][a-z0-9_]*)+$")), z.array(z.string().regex(new RegExp("^[a-z][a-z0-9]*(?:\\.[a-z][a-z0-9_]*)+$"))).min(1)]; const { errors, failed } = schemas.reduce<{ errors: z.core.$ZodIssue[]; failed: number; }>( ({ errors, failed }, schema) => ((result) => result.error ? { errors: [...errors, ...result.error.issues], failed: failed + 1, } : { errors, failed })( schema.safeParse(x), ), { errors: [], failed: 0 }, ); const passed = schemas.length - failed; if (passed !== 1) { ctx.addIssue(errors.length ? { path: [], code: "invalid_union", errors: [errors], message: "Invalid input: Should pass single schema. Passed " + passed, } : { path: [], code: "custom", errors: [errors], message: "Invalid input: Should pass single schema. Passed " + passed, }); } }).describe("Parent capability(s) this extends. Present for extensions, absent for root capabilities. Use array for multi-parent extensions.").optional() }).catchall(z.any())))).describe("Capability registry keyed by reverse-domain name.").optional(), "payment_handlers": z.record(z.string(), z.array(z.intersection(z.object({ "version": z.string().regex(new RegExp("^\\d{4}-\\d{2}-\\d{2}$")).describe("Entity version in YYYY-MM-DD format."), "spec": z.string().url().describe("URL to human-readable specification document.").optional(), "schema": z.string().url().describe("URL to JSON Schema defining this entity's structure and payloads.").optional(), "id": z.string().describe("Unique identifier for this entity instance. Used to disambiguate when multiple instances exist.").optional(), "config": z.record(z.string(), z.any()).describe("Entity-specific configuration. Structure defined by each entity's schema.").optional() }).catchall(z.any()).describe("Shared foundation for all UCP entities."), z.intersection(z.record(z.string(), z.any()), z.object({ "available_instruments": z.array(z.object({ "type": z.string().describe("The instrument type identifier (e.g., 'card', 'gift_card'). References an instrument schema's type constant."), "constraints": z.record(z.string(), z.any()).describe("Constraints on this instrument type. Structure depends on instrument type and active capabilities.").optional() }).catchall(z.any()).describe("An instrument type available from a payment handler with optional constraints.")).min(1).describe("Instrument types this handler supports, with optional constraints. When absent, every instrument should be considered available.").optional() }).catchall(z.any()))))).describe("Payment handler registry keyed by reverse-domain name.").optional() }).catchall(z.any()).describe("Base UCP metadata with shared properties for all schema types."), z.object({ "supported_versions": z.record(z.string(), z.string().url()).describe("Previous protocol versions this business supports, mapped to profile URIs. Businesses that support older protocol versions SHOULD advertise each version and link to its profile. Each URI points to a complete, self-contained profile for that version. When omitted, only `version` is supported.").optional(), "services": z.any(), "capabilities": z.any().optional(), "payment_handlers": z.any() }).catchall(z.any())).describe("UCP metadata for business/merchant-level configuration. Subset of platform schema with business-specific settings.").optional() }).catchall(z.any())).describe("Discovery profile for businesses/merchants. Subset of platform profile with business-specific configuration.") export type BusinessProfile = z.infer