Every published version of the contract, as of v1.64.0. Internal references are left out.
One entry per distribution label. tools/version-check.sh fails a PR whose VERSION has no heading here. The wire contract's own version stays date-based (info.version); info.x-contract-version is the minor each label is a cut of.
info.x-contract-version 1.63.0 → 1.64.0; info.version stays 2026-09-30. Source sha256 9be218acd85aa9fd17efa68e430d800385eb286fbe5ac99a9fec70fce9f8a439 (a74937c6… as first drafted, amended in place 2026-10-29 by the review fixes)./admin/v1/agent-registry (list, register, get, update, :verify-domain, versions with :drain, :revoke, :request-certificate, keys with :retire) and /ops/v1/agent-registry (list, :set-tier, :suspend, :unsuspend); agent traffic listAgentTraffic / getAgentRequestTrace and opsListAgentTraffic; public discovery resolveAgent (GET /v1/agents:resolve) and searchAgentDirectory (GET /v1/agents:search). /admin/v1/agents is untouched.agent.registered, agent.version_registered, agent.version_revoked, agent.key_rotated, agent.tier_changed, agent.suspended), added to the subscribable events of WebhookSubscription. Twenty-eight new schemas, three response components, seven parameter components (Signature, Signature-Input, Signature-Agent, Agent-Version headers; path ids).ApiErrorResponse.code enum does not grow: six agent identity refusals ride as details.reason under stable codes (UNAUTHENTICATED AGENT_SIGNATURE_INVALID and AGENT_VERSION_REVOKED; PERMISSION_DENIED AGENT_TIER_INSUFFICIENT; CONFLICT HANDLE_TAKEN and DOMAIN_NOT_VERIFIED; VALIDATION HANDLE_RESERVED); verify_agent joins the nextAction x-extensible-enum.agent: AgentStamp on McpGrantRequest (plus agentConsent), McpGrant, ConsoleAgentProposal, ConsoleAuditRecord.spec/mcp-names.baseline and spec/baseline/ are unchanged.info.x-contract-version 1.61.0 → 1.63.0; info.version stays 2026-09-30. Source sha256 c4ae299c88f131ea8b1a0fe6ce41fe96be2cca165cb28dc0af11325cb804dbf0. Drafted and amended as v1.58.0 (1.57.0 → 1.58.0) on 2026-10-28 and 2026-10-29; renumbered to v1.62.0 at the merge of main on 2026-10-29: main published its own v1.58.0 and v1.59.0 (the Usage tab), release/connect-v1-1.60.0-apiq-public-text held v1.60.0 (merged to main later that day) and release/connect-v1-1.61.0-mcp-descriptions held v1.61.0 (merged to main the same day; this entry took both text rebases). Renumbered to v1.63.0 on 2026-10-30: feat/ops-tenant-lifecycle-v1.62 (abhinavk, operator tenant lifecycle; MR!99) opened with v1.62.0 before this proposal's MR (!100); v1.63.0 is the next number no branch or MR head holds. Source sha256 history, recorded under the unpublished number v1.58.0: 257a0121… (after the 2026-10-29 in-place amendments, round 3, the owners' details and the go-live review with the owner's answers; 4ef527df… after the first pass of the go-live review; bad220ef… before the go-live review; be8c5d08… after round 3 alone; 882a8dd7… after the 2026-10-28 amendments, the per-country live switch and the click-wrap terms; f4e64cd1… after the first of those, 2c3ebb15… before them).405 MethodNotAllowed and 414 UriTooLong on the seven new /v1 operations, 415 UnsupportedMediaType on the six that take a body (not getBusinessPeople), and 413 PayloadTooLarge on goLiveCapped (optional body); the proposal's public text names no supplier or brand (the card and UPI providers, the hosted onboarding provider and their browser libraries by role; AIKONIC → Apiq; the 502 example's details.psp EXAMPLEPAY). Kept as v1.60.0 keeps them: the wire values (PaymentMethodSetup.provider STRIPE | HARNESS, provider keys stripe, razorpay, stripe_connect, the pm_/seti_/pk_ shapes) and the example keys stripeCard and stripe. Additive; spec/mcp-names.baseline unchanged.lookUpBusinessRegistrationByNumber (POST /v1/activation/business-registrations:look-up; IN, GB, AE, US, CA), getBusinessPeople / putBusinessPeople (/v1/activation/business-people), sendWorkEmailCode / confirmWorkEmail (/v1/activation/work-email:send-code, :confirm), goLiveCapped; console getContactEmails / putContactEmails (/admin/v1/contact-emails).MonthlyVolume, BusinessRegistrationLookup, BusinessPeople, BusinessRepresentative, BusinessOwner, WorkEmailSendCodeRequest, WorkEmailCodeSent, WorkEmailConfirmRequest, WorkEmail, ActivationWorkEmail, ContactEmails) and four superset responses (BusinessRegistrationValidation, BusinessRegistrationNotFound, BusinessRegisterUnavailable, BusinessRegisterUnreachable; each keeps every example key of the GST component it extends).businessStructure, industry, industryOther, noWebsite, productDescription, phone, monthlyVolume; BusinessProfile.registrationScheme, registrationNumber), BusinessRegistration scheme, number, jurisdiction, the confirm's scheme, number, legalName, the signatory method and dateOfBirth, SignatoryCheck.method, ActivationState.workEmail, MoneyModelElectionRequest.accreditationNumber / contractReference, MoneyModelElection.reviewState, InviteRequest.role, Invited.role, details.open; x-extensible values on registration status, signatory result and OpsApproval.kind (MONEY_MODEL_REVIEW). Relaxed request requirements (exactly one of the alternatives): BusinessRegistrationConfirmRequest.gstin, SignatoryCheckRequest.pan / nameOnPan, InviteRequest.permissions. Relaxed response requirements on two v1.51.0 proposal schemas only (BusinessRegistration, SignatoryCheck.panLast4); generated clients type those members optional. New details.reason values on existing codes only.response-property-became-optional, all on PROPOSAL, flag-gated responses read only by the AIKONIC console: GET /v1/activation/business-registrations/{gstin} 200 address, constitution, gstin, pan, registeredOn (round 2 shares BusinessRegistration across register countries that lack those fields) and POST /v1/activation/signatory-checks 200 panLast4 (a NAME_DOB check has no PAN). The schema-diff gate against the published baseline (1.7.0) passes with breaking 0.spec/mcp-names.baseline unchanged.acceptActivationTerms takes termsVersion with no proof (no stepUpCode, stepUpAssertion or emailCode; the Owner's human session is the proof); NINE_STEP keeps the step-up; new request example cappedClickWrap; sendActivationTermsCode kept for compatibility.createPaymentMethodSetup. New schemas VerificationRequirement, ActivationBusinessVerification (optional ActivationState.businessVerification: status, provider, submittedAt, decidedAt, outstanding[], rejectionReason) and response PaymentMethodProviderUnreachable (502). putBusinessPeople opens or resumes the provider's case: 409 REGISTRATION_NOT_CONFIRMED, SIGNATORY_NOT_MATCHED, VERIFICATION_IN_REVIEW, ALREADY_VERIFIED, VERIFICATION_REJECTED, 501 inline (cappedFlowUnavailable kept, kybUnavailable), new 502; write-only BusinessRepresentative.idNumber; BusinessOwner optional dateOfBirth, address (BusinessAddress), write-only idNumber, read-only idNumberLast4 (asked on needs_more as owners[i].*; request example resubmitWithOwnerDetails); goLiveCapped keeps PREREQUISITES_OPEN until verified (example verificationNotVerified); addPaymentMethod takes a Stripe pm_… token, 400 VPA_INVALID (Razorpay), new 502; Notification.kind gains verification.needs_more, verification.verified, verification.rejected. Additive; every existing example key kept; spec/mcp-names.baseline unchanged.goLiveCapped takes an optional body GoLiveRequest (products, canonical product codes; absent = every product of the tenant's sandbox capabilities) and answers 202 ActivationState (example inReview) instead of 200: it opens a go-live review and an operator approval GO_LIVE_REVIEW; the tenant turns LIVE, LIVE_CAPPED, only when an operator approves. New schemas GoLiveRequest, GoLiveReview (id, status in_review | approved | partly_approved | changes_requested | rejected, submittedAt, decidedAt, expectedBy, note, products[]), GoLiveProductReview (product, status queued | in_review | approved | rejected | changes_requested, decidedAt, note, checks[]), GoLiveCheck (key business_details | test_calls, status todo | in_progress | passed | failed, by operator | agent | system, at, detail, verbsSeen), every enum x-extensible; optional ActivationState.goLiveReview; 409 GO_LIVE_IN_REVIEW (example goLiveInReview), 400 VALIDATION PRODUCT_NOT_AVAILABLE (example productNotAvailable); getActivation examples cappedGoLiveChangesRequested, cappedGoLiveApproved; OpsApproval.kind documents GO_LIVE_REVIEW; Notification.kind gains golive.in_review, golive.approved, golive.changes_requested, golive.rejected. The 200→202 change is inside the unpublished 1.63.0, then numbered 1.58.0 (schema-diff baseline 1.7.0 has no goLiveCapped): NON-breaking against every published contract.opsApprove of a GO_LIVE_REVIEW answers 409 CONFLICT GO_LIVE_TEST_CALLS_MISSING with the new typed details.missingTestCalls (new schema GoLiveMissingTestCalls {product, verbs}) until every requested product's sandbox test calls (search, reprice, orders, cancel) are seen, and 409 PREREQUISITES_OPEN when a prerequisite no longer holds (examples goLiveTestCallsMissing, goLivePrerequisitesOpen); sandbox_booking is required: true on CAPPED (never in go-live's details.open; CAPPED examples updated); GoLiveCheck.verbsSeen value book renamed orders (the CapabilityProduct.verbs name, inside the unpublished 1.63.0, then numbered 1.58.0); decisions e-mailed to the Owner and the operations contact (descriptions).info.x-contract-version 1.60.0 → 1.61.0; info.version stays 2026-09-30. Source sha256 5b7aff2f75a8a0ee4ed00b1040603065efa9ecde1f8507a4087fbd93f44cf7f0.description keys (204 added, 3 rewritten without internal citations) on 96 inline operation parameters, 9 component schemas and 102 schema properties the customer MCP reference prints.make generate): doc comments and the version only.pc/customer-webhooks-status. Renumbered at the merge if another release takes 1.60.0 first.info.x-contract-version 1.59.0 → 1.60.0; info.version stays 2026-09-30. Source sha256 183d633884a6bef43269a5bf5450bc8b8b3d53d9a3d6711088af968555f55dde.info.title "Apiq — Unified Travel API", info.contact.name "Apiq API support". servers[]: sandbox https://apiq-sandbox.tripproagencysites.com; production https://api.apiq.example, a placeholder until the host is issued at go-live. Global security lists apiKeyAuth first; its description is the self-serve key from the console, sent as X-Api-Key.oauthClientCredentials lists the 27 key-grantable scopes (lookups:personal added; finance:read/finance:write no longer ""); issueOAuthToken loses "". releaseHold, endSession and the login 202 lose x-status: planned (served).RateLimited: the real limits (per key and per tenant 50 rps, burst 100; every travel verb but poll also 10 rps, burst 20 on the supplier budget), details.scope/budget/reason/tier/retryAfterMs, and the RateLimit-Limit, -Remaining, -Reset, -Policy headers (new components/headers).MethodNotAllowed (405), UriTooLong (414), UnsupportedMediaType (415), the public edge's own VALIDATION refusals: 405 and 414 on every /v1 operation, 415 on every /v1 operation that takes a body except the upload content route.*.mondee.io hosts → the apiq-sandbox host or *.example; the brand is Apiq; supplier names and supplier codes → neutral placeholders. Tag, error, and search-intent descriptions in plain words. Wire identifiers unchanged (MondeeContext, x-aikonic-*, X-Mondee-Signature, MONDEE, package names).tools/sync-contract.sh); the Postman collections send X-Api-Key: {{apiKey}} by default and Bearer {{accessToken}} only on operations that take no key (tools/postman.mjs); the Swift pod's version is the release label (generators/swift.yaml podVersion, checked by tools/version-check.sh); the TypeScript package description is current. The five clients are regenerated (their default base path is now the production placeholder).spec/mcp-names.baseline unchanged.info.x-contract-version 1.58.0 → 1.59.0; info.version stays 2026-09-30.GET /admin/v1/usage/detail (getUsageDetail): one endpoint, key, class or status code over the window — summary, previous, series (ConsoleUsageDetailPoint), breakdowns (ConsoleUsageDetailEndpoint, ConsoleUsageClassCount), 429 bursts.GET /admin/v1/usage/rows (listUsageRows): every endpoint, key or 429 burst, with q, class, sort, cursor, limit (ConsoleUsageRows, ConsoleUsageRow).spec/mcp-names.baseline unchanged (it is promoted on its own).info.x-contract-version 1.57.0 → 1.58.0; info.version stays 2026-09-30.ConsoleUsage gains optional summary and previous (new schema ConsoleUsageSummary), latencySeries (ConsoleUsageLatencyPoint), statuses (ConsoleUsageStatus), endpoints (ConsoleUsageEndpoint, max 10), keys (ConsoleUsageKey, max 10), rateLimitEvents (ConsoleRateLimitEvent, max 25), weekHours (ConsoleUsagePoint) and funnel (ConsoleUsageFunnel). ConsoleUsageClass gains optional peakRps. Response-only.pc/customer-webhooks-status holds 1.56.0. Renumbered again at the merge if another release takes 1.57.0 first.info.x-contract-version 1.52.0 → 1.57.0; info.version stays 2026-09-30. Source sha256 520c1a7bb18fb4c655abcae10db381b2410bc1b8e173bca7cd8c70dd8d4b1f3a (after the merge of main and the renumbering; 75cba5e8…, e6925380…, e0167e82…, 2183ec2e… as 1.53.0).startDeviceSignup, pollDeviceSignup (RFC 8628 OAuthError while pending), getDeviceSignupRequest, approveDeviceSignup, denyDeviceSignup, getOnboard, updateApiKeyScope (PATCH /v1/keys/{keyPrefix}), pauseApiKey, resumeApiKey, getApiKeyUsage. Discovery: getAgentManifest (/.well-known/aikonic.json, JWS-signed) and getAgentManifestKeys (/.well-known/aikonic-jwks.json). Seven webhooks key.minted, key.paused, key.resumed, key.revoked, key.rotated, key.expiring, signup.device.approved.MintApiKeyRequest and ApiKeyMetadata (kind, writes, products, spend per day, look-to-book, rates, expiry, principal, agent, mintedBy, state, usage); rotateApiKey keeps the scope and gains 409 ROTATION_TOO_EARLY; Attribution on orders, holds, wallet transactions, console usage points and certification evidence; CertificationState.advisory; ApiErrorResponse.nextAction and docs (optional). New responses KeyPaused (423) and VelocityLimited (429).spec/mcp-names.baseline unchanged.info.x-contract-version 1.54.0 → 1.55.0; info.version stays 2026-09-30.ParkingSearchIntent (new): location (iata or portCode), entryAt and exitAt (local at the location, or with an offset), filters (parkingClasses, covered, shuttle). PARK in the typed-intent lists; one parking example on POST /v1/search.ParkingExtension (new) as ItemExtension.parking: the lot, the product, the priced interval (and whether the price includes taxes), access and cancellation text; detail facts; confirmationNumber on the order line.BARCODE document, format PNG (both already in OrderDocument's open vocabulary).info.x-contract-version 1.50.0 → 1.54.0; info.version stays 2026-09-30.MondeeContext.selection (new, optional, SelectionPreferences: view, objective, preferSuppliers[], excludeSuppliers[]); GET /v1/search/{searchRef} gains the optional query parameter view (SELECTED | ALL).Offer.selection (new, optional, OfferSelection: itemRef, matchTier, role, reason, comparisonTotal, alternativesCount, final) and Offer.alternatives[] (new, optional, recursive Offer, on a SELECTED winner only).MondeeResponseContext.selection (new, optional, SelectionStamp: view, policyRefs[], final).info.x-contract-version 1.51.0 → 1.52.0; info.version stays 2026-09-30. Source sha256 67a9fe638a98baf2c2a048bcd6d49cb9e51a3be366516f8ae09b4e0260973c9a (merged source, re-synced at the merge of main's 1.49.0 and 1.50.0).sendActivationTermsCode (POST /v1/activation/terms:send-code) — human session, Owner only, Idempotency-Key, no body; 202 TermsCodeSent (sentTo masked, expiresAt, resendAfter); CAPPED flow only (409 CONFLICT FLOW_NOT_CAPPED on NINE_STEP); 429 RATE_LIMITED SUBJECT_RATE_LIMITED (action terms-code-send, Retry-After); 501 CAPPED_FLOW_UNAVAILABLE / NO_VERIFICATION_SENDER.TermsCodeSent; optional TermsAcceptRequest.emailCode (^[0-9]{6}$): exactly one of stepUpCode, stepUpAssertion, emailCode; wrong or expired 403 STEP_UP_FAILED, the 5th wrong attempt STEP_UP_LOCKED; on NINE_STEP 400 VALIDATION emailCode FLOW_NOT_CAPPED. acceptActivationTerms gains the emailCode request example and an inline 400 that keeps every BadRequest example key (+ emailCodeNotCapped, emailCodeFormat); EnrollmentForbidden gains stepUpUnavailableCapped and stepUpLocked. New details.reason values on existing codes only.spec/mcp-names.baseline unchanged.info.x-contract-version 1.50.0 → 1.51.0; info.version stays 2026-09-30. Source sha256 67a9fe638a98baf2c2a048bcd6d49cb9e51a3be366516f8ae09b4e0260973c9a. Every new route is served only behind flags that are off by default; with the flags off it answers 501 NOT_IMPLEMENTED.lookUpBusinessRegistration (GET /v1/activation/business-registrations/{gstin}), confirmBusinessRegistration (POST /v1/activation/business-registration:confirm), checkSignatory (POST /v1/activation/signatory-checks), getActivationLimits (GET /v1/activation/limits), createLimitRequest and listLimitRequests (/v1/activation/limit-requests); payment methods listPaymentMethods, addPaymentMethod (/v1/payments/methods), removePaymentMethod (DELETE /v1/payments/methods/{methodId}), setDefaultPaymentMethod (POST /v1/payments/methods/{methodId}:make-default); console listInvoices, getInvoice, getInvoiceDocument (/admin/v1/invoices, text/html document), listNotifications, markNotificationsRead (/admin/v1/notifications).BusinessAddress, BusinessRegistration, BusinessRegistrationConfirmRequest, SignatoryCheckRequest, SignatoryCheck, TierLimits, LimitRequestCreate, LimitRequest, LimitRequestPage, SavedPaymentMethod, PaymentMethodCreate, SavedPaymentMethodList, Invoice, InvoicePage, Notification, NotificationPage, NotificationsMarkRead, NotificationsMarkReadResult; new parameters PaymentMethodIdPath, InvoiceIdPath; new responses GstinValidation, GstinNotFound, GstRegisterUnreachable, GstRegisterUnavailable, CappedFlowUnavailable, PaymentMethodsUnavailable, InvoicesUnavailable, NotificationsUnavailable.SignupVerifyRequest.givenName/.familyName/.country (and the existing password); for a BUSINESS tenant country also reads back as ActivationState.country. The SignupRequest.country, SignupVerifyRequest.firstName/.lastName and AccessContext.firstName/.lastName drafted under 1.47.0 were withdrawn at the merge. The CAPPED flow applies to BUSINESS tenants only; INDIVIDUAL keeps the 1.47.0 rail.BusinessProfileUpdate.buildingIntent, BusinessProfile.legalName/.address/ .gstinConfirmedAt, ActivationStep.required, ActivationState.flow/.limits/.country/.registrationGstin/.registrationConfirmedAt, OrderCreateRequest payment.methodId (payment.mode documents SAVED_METHOD), ApiErrorResponse.details.cap/.usedToday/.resetAt. The MoneyModelElectionRequest.model request enum gains CARD (x-extensible-enum on the responses). TIER_CAP_REACHED is un-reserved; new details.reason values sit on existing codes.spec/mcp-names.baseline is unchanged: it is promoted only with spec/baseline/ in its own MR (CI contract:baseline-protected).TIER_CAP_REACHED (details.cap, .usedToday, .resetAt), OWNER_ONLY on the Owner-only routes; 402 CARD_DECLINED; 409 GSTIN_NOT_ACTIVE, GSTIN_ALREADY_CLAIMED, REGISTRATION_LOCKED, REGISTRATION_NOT_CONFIRMED, LIMIT_REQUEST_OPEN, TENANT_NOT_CAPPED, LAST_METHOD_IN_USE; 404 GSTIN_NOT_FOUND; 400 SIGNATORY_NOT_SIGNED_IN_USER and, on POST /v1/orders with SAVED_METHOD, PAYMENT_MODE_CONFLICT; 429 SIGNATORY_ATTEMPTS_EXCEEDED; 500 FX_SNAPSHOT_UNAVAILABLE (the cap currency conversion); 501 CAPPED_FLOW_UNAVAILABLE, GST_REGISTER_UNAVAILABLE, PAYMENT_METHODS_UNAVAILABLE, INVOICES_UNAVAILABLE, NOTIFICATIONS_UNAVAILABLE.POST /v1/orders 501 is inline (same ApiErrorResponse) with the paymentMethodsUnavailable example beside notImplemented and noOrderReader; PaymentMethodCreate no longer takes brand/last4 (the server derives them from the PSP token; SavedPaymentMethod still returns them); Invoice.number has the pattern ^AIK/[0-9]{4}/[0-9]{7}$; getActivationLimits and listLimitRequests moved from MCP resources to excluded; ActivationStep.required false documented for business_profile and go_live; the daily cap's currency, window and reset spelled out.info.x-contract-version 1.49.0 → 1.50.0; info.version stays 2026-09-30.ConsoleCredentialSecret.webhookSecret (new, optional, write-only, format: password, maxLength 512): the signing secret of the webhook endpoint the tenant registered at the supplier for this set — for a payment source, Stripe's endpoint secret for POST /v1/payments/psp-webhook/{provider}/{sourceRef}. With any kind.info.x-contract-version 1.47.0 → 1.49.0; info.version stays 2026-09-30.ExperiencesExtension.priceBasis. Additive.PaymentIntentRequest gains optional amount (Money) and paymentSource (new schema PaymentSource: supplier, credentialSet?) and no longer schema-requires repriceRef (a relaxed request requirement: not breaking). repriceRef stays required on the platform's account; with a source it is refused and the caller states the amount.PaymentIntentResponse.paymentSource (new schema PaymentSourceView: kind TENANT_OWN, credentialSet); fork is absent then.createPaymentIntent declares a new 404 (PAYMENT_SOURCE_NOT_FOUND); new details.reason values under existing codes only.POST /v1/payments/psp-webhook/{provider}/{sourceRef} (receivePspSourceWebhook): the provider's notification about one tenant's own account, verified with that account's own signing secret.spec/mcp-names.baseline is unchanged.info.x-contract-version 1.46.0 → 1.47.0; info.version stays 2026-09-30. Source sha256 6abfae320d1e8f1bf3e8546d9e9bec0e1b9c02472e2a625fd5600229f2538642. Drafted as v1.45.0 on 2026-10-24, renumbered to 1.46.0 at the merge of main on 2026-10-26 (main had taken 1.45.0, the MCP grant webhooks) and again to 1.47.0 at the merge of main later the same day (main had taken 1.46.0, the supplier allowlist below).AccountType (x-extensible-enum BUSINESS, INDIVIDUAL; absent reads BUSINESS). Optional SignupVerifyRequest.accountType, givenName, familyName, country (INDIVIDUAL needs both names: 400 VALIDATION NAME_REQUIRED); optional SignupResult.accountType; optional AccessContext.accountType, givenName, familyName; optional ActivationState.accountType and identityCheck; ActivationStep.key gains identity_verification (the INDIVIDUAL rail has five steps).POST /v1/activation/identity-checks (startIdentityCheck): IdentityCheckRequest (taxId TaxIdentifier {scheme IN_PAN, value (writeOnly)}, fullName) → IdentityCheck (masked value only). New details.reason values on existing codes: TAX_ID_FORMAT, PERSONAL_PAN_REQUIRED, UNSUPPORTED_SCHEME (400), ALREADY_VERIFIED (409 CONFLICT), IDENTITY_CHECK_UNAVAILABLE (501 NOT_IMPLEMENTED).GoLiveState.requiredSignoffs 1).spec/mcp-names.baseline is unchanged: it is promoted only with spec/baseline/ in its own MR (CI contract:baseline-protected). No new error code, no new required field.info.x-contract-version 1.45.0 → 1.46.0; info.version stays 2026-09-30. Source sha256 6eeb3b92c518574214e61387dcffe56a848a5fc33eac07f8de765578a6fb0c7e. Drafted here as 1.41.0 by hand and rendered as 1.45.0 on 2026-10-26; renumbered to 1.46.0 at the merge of main the same day, which had taken 1.45.0 first (the MCP grant webhooks below). That label already published claude's 1.41.0 to 1.44.0, so this one carries the allowlist alone.MintApiKeyRequest and ApiKeyMetadata gain optional suppliers (supplier registry codes, at most 64). Absent or empty keeps today's meaning: every supplier the scopes reach, which is how every key minted before 1.46.0 reads. New 400 VALIDATION reasons UNKNOWN_SUPPLIER, SUPPLIER_OUTSIDE_SCOPES, SCOPE_WITHOUT_SUPPLIER; new 403 PERMISSION_DENIED reason SUPPLIER_NOT_ALLOWED_FOR_KEY (example on Forbidden, ForbiddenOrSuspended, OrderForbiddenOrSuspended, PostBookingForbidden).info.x-contract-version 1.40.0 → 1.45.0; info.version stays 2026-09-30. Source sha256 6971bdb8bde7aeeade5bae1074b04f1e20843c9f3abed879109a255780a80a22. Drafted as v1.31.0 on 2026-10-20, renumbered to 1.41.0 at the merge of main on 2026-10-22 and to 1.45.0 at the merge of main on 2026-10-24: claude main had taken 1.41.0 to 1.44.0 (contracts main at 1.40.0). Contracts main lags claude, so this label also carries claude's 1.41.0 to 1.44.0, which no contracts distribution had published yet:HotelExtension.roomRateOptions, HotelRoomRateOption, rate policies, review-score word); change note CHANGE-NOTE-connect-v1-2026-10-23-v1.41.0.md.AirExtension.brandOptions), segment time zones, the booking's confirmation, the flight on reprice; change note CHANGE-NOTE-connect-v1-2026-10-23-v1.42.0.md.GET /v1/orders/{orderRef}/fare-rules (getOrderFareRules, orders:read), the booked fare's rule text read live; change note CHANGE-NOTE-connect-v1-2026-10-23-v1.43.0.md.CruiseExtension vendor configuration, rate facts, category content, the booked line's identity, payment options; change note CHANGE-NOTE-connect-v1-2026-10-23-v1.44.0.md.get_order_fare_rules (getOrderFareRules; public, read, L0). No other carried version adds, renames or removes an MCP tool or resource; nothing money-related is reachable through MCP.agent.proposal.*: mcp.grant.approved (onMcpGrantApproved), mcp.grant.denied (onMcpGrantDenied), mcp.grant.revoked (onMcpGrantRevoked), mcp.grant.expired (onMcpGrantExpired), mcp.settings.changed (onMcpSettingsChanged), each a WebhookEnvelope plus typed data. New schemas McpGrantEventData and McpSettingsEventData; the payloads never carry a token, code, hash, session id or address. Tenant-realm (console) grants only.WebhookSubscriptionRequest.events enum gains the five types (a request enum widened: not breaking). WebhookSubscription.events is an untyped string, unchanged.spec/mcp-names.baseline is unchanged: it is promoted only with spec/baseline/ in its own MR (CI contract:baseline-protected).info.x-contract-version 1.39.0 → 1.40.0; info.version stays 2026-09-30. Proposed as 1.35.0 and renumbered to 1.38.0, then 1.40.0 when main took 1.39.0 first. A PROPOSAL: PN-1 to PN-5 wait on the platform owner.GET /v1/enrichment/flight-track (getFlightTrack), keyed like getFlightStatus (carrier, flightNumber, date, optional origin); new schemas FlightTrackResponse, FlightTrack, FlightTrackPoint (on GeoPoint); EnrichmentProvenance.kind documents FLIGHT_TRACK.info.x-contract-version 1.37.0 → 1.39.0; info.version stays 2026-09-30. Numbered after the open 1.38.0 flight-track change; renumber at the merge if this lands first.AicontSearchIntent: operation (required, the Aarna experience-scraping service's operation name) and arguments (open, that operation's own arguments). The typed-intent lists of POST /v1/search and SearchRequest.message.intent and MondeeContext.domain name AICONT; one aicont search request example.info.x-contract-version 1.36.0 → 1.37.0; info.version stays 2026-09-30.FlightSearchIntent gains optional carriers (IATA include list, 1–20), alliance (STAR_ALLIANCE | SKYTEAM | ONEWORLD, x-extensible-enum), refundableOnly, changeableOnly, excludeBasicEconomy and slices[].cabin; fareTypes documents the new open value COMMISSIONABLE and the whole-list rule. New warning code text SEARCH_FILTER_UNSUPPORTED; one flightFiltered search request example.info.x-contract-version 1.35.0 → 1.36.0; info.version stays 2026-09-30. Renumbered from 1.35.0 at the merge of main: main took 1.35.0 for the cruise and package intents.GET /v1/payments/card-key (getCardEnvelopeKey): the RSA public key (JWK) a card is sealed to; new optional payment.encryptedCard (EncryptedCardEnvelope {kid, jwe}) for payment.mode ENCRYPTED_CARD on POST /v1/orders; new schemas EncryptedCardEnvelope, CardEnvelopeKey. SANDBOX/UAT only: production answers 501 CARD_PAYMENT_NOT_ENABLED.info.x-contract-version 1.34.0 → 1.35.0; info.version stays 2026-09-30.CruiseSearchIntent, PackageSearchIntent, PackageExtension (ItemExtension.package), CruiseNamedRef, PackageLeg; named properties inside the open CruiseExtension; DetailRequest.message.intent.offerRef and .selection documented; optional filter.packageType, filter.origin, filter.destination on GET /v1/lookup/{type}.info.x-contract-version 1.33.0 → 1.34.0; info.version stays 2026-09-30.POST /v1/orders/{orderRef}/visa-assistance (createOrderVisaAssistance: sends 1–20 travellers' trip to the visa provider, which e-mails each traveller and answers a prepared application link; Idempotency-Key, orders:write) and GET on the same path (listOrderVisaAssistance, orders:read); new schemas OrderVisaAssistanceRequest, OrderVisaAssistanceTraveller, OrderVisaAssistanceResponse, OrderVisaAssistanceSend.info.x-contract-version 1.31.0 → 1.33.0; info.version stays 2026-09-30. The ESIM intent was proposed as v1.32.0 and renumbered at the merge: claude main took 1.32.0 for the experience fields, which no contracts distribution had published yet, so this label carries both.ExperiencesExtension.EsimSearchIntent (destination, dates, party, resultShape: OFFERS, and the plan filter esim: country, region, type GLOBAL, minDays, minDataGb, quantity); the ESIM sentence on MondeeContext.domain; EsimSearchIntent in the typed-intent lists; one esim search request example.info.x-contract-version 1.30.0 → 1.31.0; info.version stays 2026-09-30.GiftSearchIntent and GiftExtension; ItemExtension.gift; the GIFT registration sentence on MondeeContext.domain; GiftSearchIntent in the typed-intent lists; one gift search request example.info.x-contract-version 1.29.0 → 1.30.0; info.version stays 2026-09-30.info.x-contract-version 1.28.0 → 1.29.0; info.version stays 2026-09-30. Source sha256 b7dfd9a50908f5a3e0c3aaca9d63233b8244e1b74b84fc435645e18dfa5836ad. Drafted as v1.20.0 on a v1.19.1 base (2026-10-15); renumbered v1.29.0 at the merge of main on 2026-10-17, after main's v1.20.0 to v1.28.0.AccessContext.passwordSet (optional boolean) on GET /v1/me for a human session.MintApiKeyRequest.scopes description: "At least one and at most 32 (ApiKeyService.MAX_SCOPES; more is 400 VALIDATION details.field scopes)". The cap is documented in the description only, with no schema maxItems, to keep gate 1 green without a baseline promotion. Gate 1 schema-diff: no breaking change against the baseline; baseline not promoted.getActivation / getCertification need tenant:read alone, carried by the Owner and Admin bundles, the users:manage fallback retired; signup's sender is SMTP (Mailgun) on every rung, 501 NO_VERIFICATION_SENDER only where the SMTP credential is not deployed.info.x-contract-version 1.27.0 → 1.28.0; info.version stays 2026-09-30. Optional MondeeContext.includeUpstream (default false). New schemas UpstreamPassThrough {supplier, calls[]} and UpstreamCall {operation, sector?, context?, response}. Optional upstream on Offer, AirReturnOption, RepriceResponse.message and OrderItem: the supplier's JSON exactly as answered, present only when the request asked on a deployment that serves it; else 400 VALIDATION details.reason UPSTREAM_PASS_THROUGH_DISABLED.info.x-contract-version 1.26.0 → 1.27.0; info.version stays 2026-09-30. Optional FlightSearchIntent.journeyMode (COMPLETE default | OUTBOUND_FIRST, x-extensible-enum); optional AirExtension.journey (new schema AirJourneyState: mode, complete, selectedSlices, nextSliceIndex). Reprice and orders refuse an incomplete journey as 409 CONFLICT details.reason JOURNEY_INCOMPLETE. New examples on search (flightOutboundFirst), the new route, reprice and orders (journeyIncomplete). Clients regenerated.info.x-contract-version 1.25.0 → 1.26.0; info.version stays 2026-09-30. Source sha256 8bead7105410b2f17830b74d9b4c9e1956d72db2c143078ddcd606731ec9d6d1. Gate 1 schema-diff: no breaking change against the baseline (baseline not promoted).identity tag): getOAuthServerMetadata (GET /.well-known/oauth-authorization-server, RFC 8414), oauthAuthorize (GET /v1/oauth/authorize), registerOAuthClient (POST /v1/oauth/register, RFC 7591, deprecated by MCP 2026-07-28), startDeviceAuthorization (POST /v1/oauth/device_authorization, RFC 8628), revokeOAuthToken (POST /v1/oauth/revoke, RFC 7009), getMcpGrantRequest, lookupMcpGrantRequest, approveMcpGrantRequest, denyMcpGrantRequest (/v1/mcp/grant-requests/{requestId}, :lookup, :approve, :deny);supplierGetMcpGrantRequest, supplierLookupMcpGrantRequest, supplierApproveMcpGrantRequest, supplierDenyMcpGrantRequest (/supplier/v1/mcp/grant-requests/…), supplierListMcpGrants, supplierGetMcpGrant, supplierRevokeMcpGrant (/supplier/v1/mcp/grants/…);admin tag): listMcpGrants, getMcpGrant, revokeMcpGrant, revokeAllMcpGrants (/admin/v1/mcp/grants…), getMcpSettings, updateMcpSettings (/admin/v1/mcp/settings);opsGetMcpGrantRequest, opsApproveMcpGrantRequest (step-up), opsDenyMcpGrantRequest (/ops/v1/mcp/grant-requests/{requestId}, :approve, :deny), opsListMcpGrants, opsGetMcpGrant, opsRevokeMcpGrant (/ops/v1/mcp/grants…; OPS_SECURITY sees and revokes grants in every realm).McpSettings gains writesEnabled (the 10 console commit-lite tools, ON|OFF, absent means OFF); updateMcpSettings takes the new McpSettingsUpdate (toolsets, writesEnabled, write-only stepUpCode / stepUpAssertion) with 403 examples OWNER_REQUIRED, STEP_UP_REQUIRED, STEP_UP_FAILED; McpGrantRequest, McpGrantRequestApproval, McpGrant and aikonic_grant gain writeOperations; scope mcp:console:write.mcp:operator:read; realm OPERATOR and toolset operator on the grant schemas; McpGrantRequest gains state AWAITING_SECOND_APPROVAL, crossTenantReads, stepUpRequired, secondApprovalRequired, approvalId, redirectTo (the code once approved, error=access_denied once denied or expired); McpGrantRequestDecision gains awaitingSecondApproval and approvalId; McpGrant gains crossTenantReads and approvedBy; OpsApproval.kind and the opsApprove / opsReject descriptions add MCP_OPERATOR_GRANT. OAuthError.reason adds OPERATOR_MFA_NOT_ENFORCED, OPERATOR_GRANTS_DISABLED, WRITES_DISABLED and EXCHANGE_RATE_LIMITED; issueOAuthToken gains a 429 example for the per-grant exchange limit.issueOAuthToken (POST /v1/oauth/token) accepts authorization_code, refresh_token, urn:ietf:params:oauth:grant-type:device_code and urn:ietf:params:oauth:grant-type:token-exchange beside client_credentials; OAuthTokenRequest gains code, redirect_uri, code_verifier, refresh_token, device_code, resource, subject_token, subject_token_type; OAuthTokenResponse gains refresh_token, issued_token_type, aikonic_grant; the 400 gains invalid_target, authorization_pending, slow_down, expired_token, access_denied. The human-session-only refusals document that a grant-derived token is 403 SESSION_REQUIRED.OAuthError.error becomes an open list (x-extensible-enum), so the generated enum type for it goes away (Python models/o_auth_error_error.py deleted; Java, Kotlin and Swift type the field as a string).mcp-check MCP_DECISION_ROUTE_EXPOSED: the grant consent decision is a human decision route like proposal approve/reject. approveMcpGrantRequest, denyMcpGrantRequest, supplierApproveMcpGrantRequest and supplierDenyMcpGrantRequest join DECISION_OPERATIONS, and DECISION_PATH also matches any /mcp/grant-requests/{id}:approve|:deny, so exposing one goes red whatever its class or operationId. Phase 4 adds opsApproveMcpGrantRequest and opsDenyMcpGrantRequest (the /ops/v1 path was already matched by shape).mcp-check rule MCP_CREDENTIAL_ROUTE_EXPOSED: the OAuth authorization server and the MCP grant surface are never a tool or resource, whatever their class: by operationId (issueOAuthToken, getOAuthServerMetadata, oauthAuthorize, registerOAuthClient, startDeviceAuthorization, revokeOAuthToken, the four grant-request reads and lookups, revokeMcpGrant, revokeAllMcpGrants, supplierRevokeMcpGrant, updateMcpSettings) and by shape (any route under an /oauth/ segment or /.well-known/oauth-*, any route under mcp/grant-requests, any non-GET under mcp/grants or mcp/settings). The GET reads of mcp/grants and mcp/settings stay reclassable. Every new operation is already excluded, so the contract passes unchanged; the rule stops a later edit from exposing one. Phase 4 names all six operator MCP routes, the opsListMcpGrants and opsGetMcpGrant GETs included: operator grant metadata spans every realm and is never an agent read, so /ops/v1/mcp/grants… is also matched by shape for every method, GET included.:approve (console) and :deny (supplier) fail by path, and the console approve and supplier deny moved to another path fail by name; eleven credential-route fixtures fail (by name, and a renamed supplier :lookup and mcp/settings PUT by shape); exposing the listMcpGrants GET passes. Phase 4 adds ten: the operator approve and deny exposed fail, the approve moved to another path fails by name, a renamed operator :deny fails by path, opsGetMcpGrantRequest, opsListMcpGrants, opsGetMcpGrant and opsRevokeMcpGrant exposed fail, and the two operator GETs renamed and exposed fail by shape. MCP_REASON_RULE_MISMATCH adds seven: a commit-lite reason citing "rule 6", "Rule 6", "rule-6", "rules 6 and 8" or "rules 4, 6 and 8" fails; the same reason on a commit-money operation passes, and a commit-lite reason citing rule 16 or 60 passes.spec/mcp-names.baseline is NOT regenerated in this release: contract:baseline-protected refuses a registry modification in the same change as spec/connect-v1.yaml, so the 28 new (excluded) names (make mcp-check: 407 operations, registry 373) join the registry at the next baseline promotion (tools/promote-baseline.sh --force, its own MR)./v1 and /.well-known operations, the approve in three example variants, and four new issueOAuthToken grant examples, all with fabricated values; the Phase 3 fold adds the withWrite approve variant (160 → 161). The operator routes are not in the public collection. The partner collection's 38 requests are unchanged (only its version label and spec sha move).info.x-contract-version 1.24.0 → 1.25.0; info.version stays 2026-09-30. Hotels, response-side optional properties only: new schemas HotelImage (url required, caption, isPrimary) and HotelAmenity (name required, code, top); extension.hotel.property gains type, stars, address, geo, chain, guestRating, images, amenities, check-in and check-out times, phone, description, timeZone, policies, nearby, distanceKm; HotelRoom gains images, amenities, inclusions, maxOccupancy, bedCount, size, view, indicative unitsAvailable, petsAllowed and the order-line-only confirmationNumber; HotelExtension.confirmationNumber (order lines) and rate.ratePlanName; CancellationPolicy.policyText (the ladder stays authoritative); PriceBreakdownLine.currency (a disclosed line in another currency only). New POST /v1/search 200 example hotelRich.info.x-contract-version 1.23.0 → 1.24.0; info.version stays 2026-09-30. Response-side optional properties only: new schemas AirPenaltyRule (allowed, amount Money, percentBasisPoints 0..10000, description) and AirFareRules (refund and change, before and after departure); new AirExtension.fareRules (whole itinerary), AirSlice.fareRules (that journey only) and AirSlice.meals[]; AirSegment gains connecting, operatedByText and, on order lines only, airlineLocator and status; the open AirExtension.fare documents validatingCarrierName, eight fare-flag booleans, milesEarned, an informational cardFee and brandFares[] tier / meals. The flightRoundTrip example is updated. Clients regenerated.info.x-contract-version 1.22.0 → 1.23.0; info.version stays 2026-09-30. Response-side optional properties only: AirSegment gains durationMinutes, airport/city/carrier names, fareBasis, brandName, layoverMinutes, intermediateStops[], redEye, selfTransfer, bagsRecheckRequired, longLayover, seatsRemaining; new schemas AirSlice, AirBaggageAllowance, AirBaggageItem, AirIntermediateStop; new AirExtension.slices[]; the open AirExtension.fare documents fareType, basicEconomy, nonRefundable, gdsType and an informational brandFares[]. One new POST /v1/search 200 example flightRoundTrip. Clients regenerated.info.x-contract-version 1.21.0 → 1.22.0; info.version stays 2026-09-30. The check-in domain's canonical code is CHK; CHECKIN, ONLINE_CHECKIN, OLCI stay accepted aliases (resolved by the domain registry).CheckinSearchIntent for the new CHECKIN domain, named in the POST /v1/search typed-intent lists, with one request example. Clients regenerated.info.x-contract-version 1.19.1 → 1.20.0; info.version stays 2026-09-30. Source sha256 0ede7c310cf2662dbcae1dee20c1a2d4e49e52622690fc8ee7ee4f4bfc54be26. Gate 1 schema-diff: no breaking change against the baseline; baseline not promoted.GET /ops/v1/platform-suppliers/{supplierCode}/account-profile (opsGetPlatformSupplierAccountProfile, ops:read, 200 Cache-Control: no-store, 404 SUPPLIER_NOT_DEPLOYED | ACCOUNT_PROFILE_NOT_SET) and PUT (opsSetPlatformSupplierAccountProfile, ops:suppliers:credentials, Idempotency-Key, step-up; 400 PROFILE_TOO_LARGE | PROFILE_SHAPE | REASON_INVALID; audit ops.platform_supplier.account_profile.set; no approval parking). New schemas PlatformSupplierAccountProfile and PlatformSupplierAccountProfileUpdate. The profile is the non-secret customer and user block the Mondee One suppliers read from each request body; it holds contact PII and is never logged.info.x-contract-version 1.19.0 → 1.19.1; info.version stays 2026-09-30. Source sha256 9f0e5c05c9be2ccd3b11010c3f971f50aab3da027f84c3fc03dd41c35c18187c.ajv 8.20.0, ajv-formats 2.1.1, versions already in the lock). Where _entry would refuse the shape (non-JSON body, unsupported or dangling $ref, duplicate argument, a parameter named body, a required unknown header, a cookie parameter) the gate fails the example with that refusal. Self-test 46 → 53: a wrapped example, a body field at the top level, a non-UUID key, a missing required argument and a refused shape must fail; flat valid examples and a hand-written name must pass.info.x-contract-version 1.18.1 → 1.19.0; info.version stays 2026-09-30. Source sha256 89e895230c568ef646f8ef09f80e60f3dd9301d107a43df36a6f11e7516bac7e. Gate 1 schema-diff: no breaking change against the baseline (vendor extension only; baseline not promoted).createOrder (book_offer) and cancelOrder (cancel_with_quote) are commit-money tools, and both only file POST /v1/agent-proposals; the 7 x-status: planned operations and all 35 webhooks are excluded; the 19 hand-written MCP tool names are kept. No path, schema, parameter, example or response changes.mondee_connect_client/connect-v1.yaml, so the AI plane generates its MCP catalog from the client it pins instead of a sibling checkout.### Unreleased — MCP gate hardening (Lane MCP-ALL phase 3 review); tooling only, the contract is unchanged
mcp-check new rules: MCP_DECISION_ROUTE_EXPOSED and MCP_WEBHOOK_EXPOSED. MCP_TENANT_SELECTOR now matches any parameter name containing "tenant" and walks request bodies; MCP_TASKS_INVALID checks tasks against the four task tools and one primary operation per task. Self-test 36 → 46 (incl. toolset-changed and autonomy-changed diff classifications).contract:baseline-protected fetches its base (GIT_DEPTH: "0"), fails closed when the base commit is missing or git diff errors (it used to print OK on an unreachable base), and refuses a modification of spec/mcp-names.baseline outside a baseline promotion merge request.### Unreleased — the MCP gate (Lane MCP-ALL phase 2, package A); tooling only, the contract is unchanged
tools/mcp-check.mjs (node + js-yaml).tools/promote-baseline.sh --force regenerates it with the baseline; contract:baseline-protected refuses a merge request that modifies or deletes it together with spec/connect-v1.yaml or VERSION.--changelog appends the MCP section. CI contract:schema-diff and contract:gate-selftest now install nodejs/npm and run npm ci.info.x-contract-version 1.18.0 → 1.18.1; info.version stays 2026-09-30. Source sha256 4ee6d2eb0270ca4282139e89badeb355632a08828d380f1a7eb0a224d8ec82d8. Gate 1 schema-diff: no breaking change against the baseline (additive only; no shape changes).404, 501 WALLET_TOPUP_UNAVAILABLE, and a payment.mode WALLET order 402 WALLET_INSUFFICIENT. Test: wallet_insufficient is served. TIER_CAP_REACHED stays reserved.info.x-contract-version 1.17.0 → 1.18.0; info.version stays 2026-09-30. Additive only; no backend serves the new operations yet.x-status: planned.ActivationState, ActivationStep, ActivationTerms, BusinessProfileUpdate, BusinessProfile, VerificationSessionRequest, VerificationSession, MoneyModelElectionRequest, MoneyModelElection, TermsAcceptRequest, TermsAcceptance, CertificationState, CertificationCheck, CertificationRun, WalletEnvironment, Wallet, WalletFundingInstructions, WalletList, WalletTransaction, WalletTransactionPage, WalletAlertsRequest, WalletTopUpRequest, WalletTopUp; parameters WalletCurrencyPath, WalletEnvironmentQuery; response EnrollmentForbidden; OAuth scopes tenant:read, finance:read, finance:write.POST /v1/orders: WALLET joins the open payment.mode list (description only; the field stays an open string); 402 PAYMENT_FAILED gains the walletInsufficient example (details.reason WALLET_INSUFFICIENT, details.required, details.available); the Test header documents the planned wallet_insufficient scenario. No new ApiErrorResponse.code.requestSignup / verifySignup: SignupRequest.required [email, organization] → [email] (organisation prefilled from the e-mail domain); SignupVerifyRequest.required [email, code, password, organization] → [email, code] (password keeps 12–1024 when sent); new optional SignupVerifyRequest.buildingIntent (new schema BuildingIntent, API_INTEGRATION | AI_AGENT | BOOKING_SITE); new optional SignupResult.session (SessionResponse, as /v1/auth/login) — the console session starts on code verification. New examples emailOnly, codeOnly, withBuildingIntent, createdWithSession. Non-breaking under gate 1 (request required relaxed, optional response property added).Bus*, OrderTicket*, OpsSupplierCancellation*) and the v1.17.0 PlatformSupplier* shapes that the v1.15.0, v1.16.0 and v1.17.0 cuts did not regenerate./ops/v1/platform-suppliers; additiveinfo.x-contract-version 1.16.0 → 1.17.0; info.version stays 2026-09-30. Additive only.opsListPlatformSuppliers, opsGetPlatformSupplier, opsLandPlatformCredentials (PUT /ops/v1/platform-suppliers/{supplierCode}/credentials) and opsSetPlatformSupplierStatus (PUT …/status, 202 PlatformSupplierPending on PROD). Schemas PlatformSupplier, PlatformSupplierList, PlatformMaterialField, PlatformMaterialState, PlatformCredentialsLanding, PlatformSupplierStatusChange, PlatformSupplierPending; parameter PlatformSupplierCode. New approval kind PLATFORM_SUPPLIER_ACTIVATE.GET /v1/orders/{orderRef}/tickets, the operator's supplier cancellations report; additiveinfo.x-contract-version 1.15.0 → 1.16.0; info.version stays 2026-09-30. Additive only.getOrderTickets (GET /v1/orders/{orderRef}/tickets): OrderTicketsResponse {orderRef, tickets[OrderTicket]}, read live from the supplier and never stored (passenger, seat, ISSUED | CANCELLED, price, the ticket's PDF). 409 ORDER_NOT_TICKETED / TICKETS_NOT_READABLE.opsListSupplierCancellations (GET /ops/v1/suppliers/{supplierCode}/cancellations?offset&limit): OpsSupplierCancellationsPage, each row joined to the AIKONIC order holding the booking. ops:read.BusSearchIntent, ItemExtension.bus; additiveinfo.x-contract-version 1.14.0 → 1.15.0; info.version stays 2026-09-30. Additive only.BusSearchIntent (origin, destination PlaceRefs, departureDate, party), BusPartySpec (adults, childAges, seniorAges) and BusExtension (bookingReference, ticketBundlePdf, tickets[{ticketId, reference}]); ItemExtension.bus.search operation and SearchRequest.message.intent name BusSearchIntent for BUS, with one example. No route changes: the BUS verb book rides search, reprice, orders, order read, cancel-quote and cancel.POST /v1/auth/sign-in; additiveinfo.x-contract-version 1.13.0 → 1.14.0; info.version stays 2026-09-30. Gate 1 schema-diff: no breaking change against the baseline (additive only).signIn (POST /v1/auth/sign-in): {username, password, siteId?} → 200 SignInResult (realm TENANT | OPERATOR | SUPPLIER and exactly one of tenantSession, operatorSession, supplierSession, the realms' existing session shapes) or 202 SignInNextStep (step MFA with challenge, completed at the realm's own mfa/verify; or SITE_CHOICE with sites). One 401 LOGIN_FAILED for every refusal.SignInRequest, SignInResult, SignInNextStep, SignInSite. The realm login routes are unchanged.ForgotPasswordRequest.siteId and ResetPasswordRequest.siteId become optional (a relaxed request requirement); omitted, the customer account is found by its email./ops/v1/supplier-data/* for PLATFORM credential sets; additiveinfo.x-contract-version 1.12.0 → 1.13.0; info.version stays 2026-09-30. Gate 1 schema-diff: no breaking change against the baseline (additive only).x-audience: operator operations, the operator-realm twins of /admin/v1/supplier-data/*: opsListSupplierDatasets, opsGetSupplierDataProfile, opsUpdateSupplierDataProfile, opsListSupplierDataRuns, opsStartSupplierDataRun, opsGetSupplierDataRun, opsCancelSupplierDataRun, opsPauseSupplierDataRun, opsResumeSupplierDataRun, opsListSupplierDataSnapshots, opsDiffSupplierDataSnapshots, opsRollbackSupplierDataSnapshot, opsPurgeSupplierData. PLATFORM credential sets only; a tenant token is 401 TOKEN_WRONG_REALM.supplier_data:read every OPS_* role; supplier_data:manage|run|purge|rollback OPS_ENGINEER and OPS_ADMIN.OpsSupplierDataRollbackRequest and OpsSupplierDataPurgeRequest. Rollback and purge answer 202 OpsApprovalRequested on PROD (a PROD_ROLLBACK / PROD_PURGE approval a different operator with ops:approvals:money approves); 200 below PROD. No X-Approval-Token in this realm.OpsApproval and OpsApprovalRequested widen. No existing shape changes.info.x-contract-version 1.11.0 → 1.12.0.GET /ops/v1/operators, PUT /ops/v1/operators/{operatorId}/roles, POST …:disable, POST …/sessions:revoke, GET /ops/v1/finance/summary, GET/PUT /ops/v1/suppliers/{supplierCode}/contract, GET/POST …/statements, GET /ops/v1/content/feeds, GET /ops/v1/developer/overview; 16 schemas (OpsOperator*, OpsFinanceSummary, SupplierContractRecord, OpsSupplierStatement*, OpsContentFeeds, OpsDeveloperOverview, …).POST /ops/v1/auth/login may answer 200 OperatorSessionResponse (deployment requires no operator second factor) besides 202 MfaChallenge; OperatorAccessContext.mfaRequired says which. Operator clients must accept both.info.x-contract-version 1.10.0 → 1.11.0; info.version stays 2026-09-30. Gate 1 schema-diff: no breaking change against v1.10.0.x-status: planned (served): /supplier/v1/feeds, /contract, /sla/scorecard, /sla/breaker-events, /integration/{health,cert,sandbox}, /settlements, /settlements/{statementId}/reconcile, /disputes (GET, POST), /disputes/{disputeId}/messages, /notifications (GET, PUT), /compliance/documents (GET, POST).GET /supplier/v1/contract and GET /supplier/v1/integration/sandbox gain 404 (NO_CONTRACT_ON_FILE / SANDBOX_NOT_PROVISIONED); POST /supplier/v1/disputes/{disputeId}/messages gains 409 (VERSION_MOVED). No schema changes.info.x-contract-version 1.9.0 → 1.10.0; info.version stays 2026-09-30. Source sha256 96fa28a9a59aa780449a15f53b98a8521d41ef38e020accd9d96fb9c997362d1. Gate 1 schema-diff: no breaking change against the baseline (additive only).getGoLive: one of tenant:activate, users:manage or audit:read.signOffGoLive / promoteGoLive: tenant:activate or users:manage, and the caller is an Owner (OWNER or CUSTOMER_ADMIN); a non-owner is 403 PERMISSION_DENIED details.reason OWNER_ONLY.promoteGoLive: X-Approval-Token required on PROD, minted for scope users:manage, action go-live.promote, resource <tenantId>; the minter must not be the promoter (403 SECOND_APPROVER_REQUIRED); missing is 403 PERMISSION_DENIED APPROVAL_REQUIRED with details {scope, action, resourceRef}.GoLivePromotion: optional activationApprovalId (string); the 200 example and the schema example are tenantStatus: TRIAL with activationApprovalId.info.x-contract-version 1.8.0 → 1.9.0; info.version stays 2026-09-30. Gate 1 schema-diff: no breaking change against v1.8.0 (additive only).x-audience: operator, ops:read): GET /ops/v1/insights/environments (opsInsightsEnvironments: tenants per side of the sandbox/production pairing with status, region, features), GET /ops/v1/insights/summary (opsInsightsSummary), /calls (opsInsightsCalls), /orders (opsInsightsOrders); filters environment (InsightsEnvironment), tenant, supplier, operation, outcome (SupplierCallOutcome), state, from, to, limit.x-audience: console, analytics:read): GET /admin/v1/insights/summary (getConsoleInsightsSummary), /calls (listConsoleInsightsCalls), /orders (listConsoleInsightsOrders), walled to the caller's own tenant pair./supplier/v1/analytics/{volume,conversion,response-times,errors,cancellations,l2b} lose x-status: planned (served) and gain optional from/to; new GET /supplier/v1/analytics/api-calls (supplierAnalyticsApiCalls).InsightsSummary (+ InsightsTotals, InsightsSupplierRow, InsightsOperationRow, InsightsTenantRow, InsightsFaultRow, InsightsDayRow, InsightsCount), InsightsCall, InsightsOrder, OpsInsights*, ConsoleInsights*, SupplierAnalyticsApi*.info.x-contract-version 1.7.0 → 1.8.0; info.version stays 2026-09-30. Gate 1 schema-diff: no breaking change against v1.7.0 (additive only).GET /admin/v1/suppliers: the read-only, tenant-filtered supplier directory read from the adapter registry. ConsoleSupplierDirectory / ConsoleSupplier (supplierId, domains, adapterVersion, status AVAILABLE|DEGRADED|NO_CREDENTIAL, open-string verbs and flags, pricingCurrencies, credentialSets) / ConsoleSupplierCredentialSet (credentialSetId, owner PLATFORM|TENANT, environment, FSM status, certification). Optional ?domain= filter. Never a secret.FareSourceConfig, FareSourceConfigUpdate (full replace, mandatory reason, optimistic expectedVersion; Idempotency-Key required), FareSourceRule (perSupplier override), FareSourceStrategy (PREFER_OWN|OWN_ONLY|MONDEE_ONLY|BLEND), FareSourceFallback (MONDEE|NONE), FareSourceBlendDedupe (CHEAPEST_WINS|TAG_BOTH), parameter FareSourceDomainPath. Unsaved = platform default at version 0; 409 CONFLICT details.reason VERSION_MOVED.x-audience: console (in no Postman collection). Both were the console's CONTRACT ASKs.tools/mock-smoke.sh gains six fixtures for the three operations (both directory examples, both config reads, the PUT 200 and 409).info.x-contract-version 1.6.8 → 1.7.0; info.version stays 2026-09-30. Gate 1 schema-diff: no breaking change against v1.6.8.FNB (aliases REST, DINING, RESTAURANT, RESTAURANTS); DiningSearchIntent with three /v1/search examples (diningByDestination, diningByRestaurantIds, diningWithExperiences); ItemExtension.dining (DiningExtension: restaurant, slot, policies, experience(s), menus, reviews, payment); venue-paid EXPERIENCE / GRATUITY lines on OfferPricing.payAtProperty.AmendRequest.message.intent typed (mode, amendType, amendRef, itemIds, changes = AmendChanges; FNB DATE_SHIFT).OrderCreateRequest…payment.paymentMethod = PaymentMethodToken (provider SPREEDLY, token, last4, brand). No card-number, expiry or security-code field exists anywhere in the contract. 400 example paymentMethodRequired.POST /v1/enquiries (createEnquiry), GET /v1/enquiries/{enquiryRef} (getEnquiry); webhook order.supplier_event with supplierLifecycle; VERIFY case action; the OPENTABLE_* warning and refusal codes; scopes search:dining, dining:partner./v1/dining/partner/... (CRM, POS, Sync, menus, profile, reviews, directory, private-dining leads, onboarding), all x-audience: partner: left out of the default Postman collection, emitted as a second collection.PaymentMethodToken.threeDs (PaymentThreeDs: redirectUrl, mpiData with a sensitive cavv, setupIntent, paymentIntent) and the orders 400 SCA_REQUIRED refusal (subCode, intent, paymentMethod, retryWith); amend payment.paymentMethod with 400 PAYMENT_METHOD_REQUIRED / 409 CARD_SECURED_SLOT_NOT_AMENDABLE; cardCapture OPENTABLE_SMS_LINK; DiningGuarantee and order-line cardProvider / cardBrand / cardLast4; 409 OPENTABLE_CANCEL_CUTOFF_PASSED with details.forfeit on cancel-quote and cancel.DiningExperienceSelection (experienceSelection) on DiningSearchIntent and the reprice, hold and order intents; DiningExtension.confirmationNumber; FNB diner answers stated in requiredInfoAnswers; GET /v1/enquiries (listEnquiries, cursor-paged; EnquiryListResponse); onboarding OAuth state stated (OpenTable's echoed, the platform's own verified on the callback, 400 ONBOARDING_STATE_INVALID), optional PKCE code_challenge / code_challenge_method on authorize.diningPartnerListLocations (GET /v1/dining/partner/locations), diningPartnerPutLocation / diningPartnerDeleteLocation (/v1/dining/partner/onboarding/locations/{restaurantId}); the supplier-facing media edge diningPartnerMediaFetch GET /ingest/dining/opentable/media/{token} (x-audience supplier; in no Postman collection); DiningDirectoryPage.warnings; warnings OPENTABLE_FIELD_NOT_PUBLISHED, FREE_OFFER_PRICED; POS currency rules and DiningPosTicketRead; enquiry.submitted|unconfirmed|failed webhooks (EnquiryEventData) and order.supplier_event subscribable; amend COMMIT definite refusal 409 SUPPLIER_REFUSED.AmendResponse.message.targetSlot (AmendTargetSlot: dateTime, partySize, creditCardRequired, guarantee) on an FNB amend QUOTE; example diningQuoteCardSecuredTarget.OPENTABLE_CARD_TOKEN_UNUSED); the COMMIT to a card-secured target must carry message.intent.payment.paymentMethod (example diningCommitCardSecured).info.x-contract-version 1.6.7 → 1.6.8; info.version stays 2026-09-30.ConsoleAuditRecord gains optional ipPrefix (IPv4 /24 a.b.c.0/24, IPv6 /48 x:y:z:/48, never a full address) and optional userAgentFamily (a described string: the backend's closed UserAgentFamily list is a Java set of constants, not an enum). Additive.ConsoleAuditRecord.outcome (CLOSED) gains UNKNOWN_OUTCOME: the write-ahead PENDING row was never closed and the audit-pending-sweep resolved it after its threshold (default 5 minutes); such a row has no outcomeCode. Breaking for an exhaustive client; the console is the only consumer and is updated in the same release.PayloadTooLarge example shows details.maxBodyBytes (the backend's answer); POST /ops/v1/operators:invite declares 409 OPERATOR_EXISTS (checked after a successful step-up); POST /ops/v1/auth/invites/accept says the operator becomes ACTIVE; OperatorAccessContext.permissions lists ops:operators:invite and ops:approvals:operator.info.x-contract-version 1.6.6 → 1.6.7; info.version stays 2026-09-30. Stacked on v1.6.6 (not yet merged).POST /ops/v1/auth/mfa/step-up/webauthn-options.SupplierOnBehalf.ticketRef (optional).info.x-contract-version 1.6.5 → 1.6.6; info.version stays 2026-09-30. Stacked on v1.6.5.ConsoleReconcileOutcome.outcome gains FOUND_UNSETTLED: the supplier holds the booking but has not settled it (held, pending, a state that is not CONFIRMED); the order stays as it is and the reconcile can be retried. NOT_FOUND now means only a booking the supplier does not have. The only consumer is the operator console (web), updated in the same release.POST /admin/v1/orders/{orderRef}/reconcile:adopt on such a locator is 409 CONFLICT details.reason SUPPLIER_UNSETTLED (was LOCATOR_NOT_FOUND). ConsoleConflict lists the reason; :retry gains a foundUnsettled example.opsActivateTenant description: a ticketRef over 100 characters is 400 VALIDATION (served so since backend!126; description only).:activate and supplier invite accept published (additive; not breaking)info.x-contract-version 1.6.4 → 1.6.5; info.version stays 2026-09-30. Stacked on v1.6.4./ops/v1, 19 /v1/auth and /supplier/v1/auth MFA and session) drop x-status: planned and the "PLANNED — no backend serves this route yet" description lead-in. Matched by method and path against Spring mappings on backend origin/main fdd8fc2. Nothing else on those operations changes; 32 operations stay planned.POST /ops/v1/tenants/{tenantId}:activate (opsActivateTenant, request OpsReasonRequest, 202 new OpsApprovalRequested) and POST /supplier/v1/auth/invites/accept (supplierAcceptInvite, request InviteAcceptRequest, 201 new SupplierInviteAccepted).OpsRollbackRequest; breaking for callers of one operation)info.x-contract-version 1.6.3 → 1.6.4; info.version stays 2026-09-30.OpsRollbackRequest {reason, ticketRef?, stepUpCode (required)} is the request body of POST /ops/v1/tenants/{tenantId}/entitlements/versions/{version}:rollback (was OpsReasonRequest). The only caller is the ops console (web). The backend enforces it: a missing or wrong code is 403 STEP_UP_FAILED.OpsReasonRequest gains an optional ticketRef (additive; the backend already binds it on :reject).domain descriptions (doc patch; additive, gate 1 green)info.x-contract-version 1.6.2 → 1.6.3; info.version stays 2026-09-30. Builds on v1.6.2 (PARTIALLY_REFUNDED). Documentation only. First cut as a second "v1.6.2" (pc/v162); renumbered after the PARTIALLY_REFUNDED v1.6.2 landed.SupplierAnalyticsVolume.byProduct[].domain and SupplierContract.commissionSchedule[].domain: the description was a bare pipe list of HTL/ACT/TRF/CAR, which the backend conformance checker read as the vocabulary of every domain field. Now "Canonical product code per the domain registry; for supplier-portal suppliers this is typically HTL, ACT, TRF or CAR. Open string." Still {type: string}, no enum.info.x-contract-version 1.6.1 → 1.6.2; info.version stays 2026-09-30. Builds on v1.6.1.PaymentIntentResponse.state and OrderPayment.state (open strings, no enum) gain the documented value PARTIALLY_REFUNDED: 0 < refundedAmount < capturedAmount on a payment with nothing left to capture; further refunds allowed; cumulative refunds reaching capturedAmount moves it to REFUNDED. Description-only change: no schema shape change, so the generated clients differ only in version labels and doc comments. Clients must treat an unknown state as non-terminal.info.x-contract-version 1.6.0 → 1.6.1; info.version stays 2026-09-30. Builds on v1.6.0.x-status: POST /admin/v1/ai/search-intent, /admin/v1/ai/autofill-validation, /admin/v1/ai/error-explain (tag admin, x-audience: console, session only, permission ai:assist, no Idempotency-Key). The backend forwards each body as-is to the AI plane's POST /ai/v1/p0/<same>; request and 200 schemas are the plane's own.ConsoleAiAssist* (SearchIntentRequest, SearchIntent, SearchIntentResponse, RequiredInfoItem, AutofillDraft, AutofillRequest, AutofillFinding, AutofillSuggestion, AutofillResponse, ErrorExplainRequest, ErrorExplainResponse) and responses ConsoleAiAssist{BadRequest,Forbidden,RateLimited,UpstreamUnavailable,Unavailable}: 403 SESSION_REQUIRED | MISSING_PERMISSION, 429 RATE_LIMITED with Retry-After and details.retryAfterSeconds, 502 UPSTREAM_UNAVAILABLE, 503 PROVIDER_DOWN (AI_FEATURE_DISABLED | AI_PLANE_UNAVAILABLE | plane down).tools/mock-smoke.sh: fixtures for the three routes. Clients regenerated with the pinned generators.info.x-contract-version 1.5.0 → 1.6.0; info.version stays 2026-09-30. Builds on v1.5.0 (merge after!27).x-status:Traceparent / CorrelationId parameters, X-Correlation-Id response header, ApiErrorResponse.traceId documented.x-status: planned, no backend serves them): /ops/v1 operator realm; MFA families /v1|/ops/v1|/supplier/v1/auth/mfa*, /v1/auth/mfa/verify, 202 on POST /v1/auth/login, POST /v1/auth/sso/discover; sessions for all three realms; the /supplier/v1 console (analytics, feeds, contract, sla, integration, settlements, disputes, notifications, compliance); /admin/v1/go-live*, /admin/v1/tickets, /admin/v1/orders/manual, /admin/v1/supplier-data/alerts/*; POST /v1/hold/{holdRef}/release; enrichment fields (timeZone, holiday cells, typed entry profiles and alert previous/current, CO2 / flight status beyond extension.air).tools/mock-smoke.sh: fixtures for every new shape. Clients regenerated with the pinned generators.info.x-contract-version 1.4.1 → 1.5.0; info.version stays 2026-09-30.FlightSearchIntent, StaySearchIntent, GroundSearchIntent, ExperienceSearchIntent, InsuranceSearchIntent, AirportServiceSearchIntent, LoungeSearchIntent, VisaSearchIntent) with one POST /v1/search request example each; SupplierProgress.detail[].ItemExtension on Offer and OrderItem with the typed blocks AirExtension, HotelExtension, GroundExtension, ExperiencesExtension, CruiseExtension, InsuranceExtension, AirportServicesExtension, LoungeExtension, VisaExtension, EnrichmentBlock; domain APTSVC.RequiredInfo rows, POST /v1/uploads + GET /v1/uploads/{uploadId}, Consent[], Traveler / PostalAddress / TravelerDocument, OrderCreateRequest.message.intent typed.OfferPricing, PricedAddOn, PricingBasis, SecurityDeposit, TaxCode, PriceBreakdownLine tax components; reprice firmness PLATFORM_EMULATED / FRESH_READ_NO_GUARANTEE with firmnessBasis; paymentRelevant.fork.priceAdjustments[], CancelQuoteResponse.message.lines[] and handledBy, CancellationPenalty.fromDateTime / hoursBefore, POST /v1/hold/{holdRef}/extend, OrderDocument.delivery / scope / format and new kinds.PaymentAttempt[], winningAttemptId, CheckoutSignature, method EMI, state REFUNDED, fork.order.dispatch_updated, order.flight_status_changed, order.flight_disrupted, order.ticket_revoked, order.ticket_expired, order.price_adjusted, order.supplier_price_mismatch./v1/enrichment/*, GET /v1/orders/{orderRef}/enrichment, GET /v1/sustainability/summary) and its objects; MondeeContext.enrich[]; CapabilityDataProduct.CapabilitySupplierFlags retrieveMode / supportsRetrieve / paymentFork / searchMode / sellFloorImposed / passengerEmailPolicy / bookingModel / syncedDatasets[]; CapabilityVerb.amendTypes[]./admin/v1/supplier-data/* (11 routes), POST /admin/v1/agents/{agentId}:resume, GET /admin/v1/agent-proposals/{proposalId}, GET /admin/v1/jobs/{jobId}/download, queues OFFLINE_SUPPLIER_ACTION / REQUEST_TO_BOOK / VOUCHER_REISSUE (ConsoleQueueName and ConsoleQueueAction become x-extensible-enum strings), ConsoleQueueItem.watching./supplier/v1/*./v1/keys session-only; AccessContext.siteId null for key callers documented; ConsoleApprovalRequest.resourceRef, ConsoleApprovalToken.approvalToken / binding as-built aliases; OrderItem.state / OrderResponse.message.state as-built values documented.