OpenTravelIndex
Lab test deployment at travel.lab.pinnacledigital.com. Demo hotels are fictional; no payments are taken. The name and namespace are provisional.

OpenTravelIndex Profile v0.1 (draft)

Status: draft, 2026-10-10. Prose: CC-BY-4.0. Schemas: Apache-2.0. Namespace and name are provisional until the project's name and domain are cleared (implementation plan, P0 task K5).

1. What this profile is

The OpenTravelIndex (OTI) Profile lets an independent hotel make itself discoverable and bookable by AI agents from systems it already runs. It defines almost nothing new:

Each extension is drafted to be proposed upstream to UCP. If UCP adopts one, the OTI name becomes an alias.

2. Namespace

OTI capabilities use the reverse-domain namespace of the host that serves their schemas, as UCP's authority binding requires (the reversed schema host must equal or be a label-aligned prefix of the capability name).

CapabilitySchema
<ns>.lodging.search/spec/schemas/search-response.json
<ns>.lodging.availability/spec/schemas/availability-response.json
<ns>.lodging.reservation/spec/schemas/reservation.json

The lab deployment uses <ns> = com.pinnacledigital.lab.travel, with schemas served from https://travel.lab.pinnacledigital.com/spec/schemas/.

3. Conformance levels

LevelA producer servesAn agent can
L0Signed manifest, schema.org JSON-LD, booking linkFind the hotel and link to it
L1L0 + /.well-known/ucp + availability extensionQuote live all-in prices
L2L1 + UCP booking sessionsStart a booking and hand the guest to the hotel's secure page
L3L2 + reservation extensionLook up and cancel a reservation

An index lists a producer at L0 until its domain is verified, whatever it declares.

4. Discovery order for agents

  1. GET https://<hotel>/.well-known/ucp (UCP business profile; REST endpoint and capabilities).
  2. GET https://<hotel>/.well-known/oti.json (the OTI manifest).
  3. An MCP Server Card via the AI Catalog, when the hotel or its platform publishes one.
  4. schema.org JSON-LD on the hotel's pages.

5. The manifest (/.well-known/oti.json)

Schema: manifest.json. It names the publisher (name, domain, contact), the declared conformance level, the UCP profile URL (L1+), the properties (producer-scoped id, slug, name, geo, address, schema.org page URL, booking URL, level), and the public signing keys.

Signature. signature is a detached compact JWS (header..signature, EdDSA/Ed25519) over the RFC 8785 canonical JSON of the manifest without signature. The kid in the JWS header names one of keys. When a domain is verified, an index pins the key's RFC 7638 thumbprint; afterwards it accepts only manifests signed by that key. A key rotation therefore needs re-verification.

Domain. The manifest must be served from the publisher domain or a subdomain of it.

6. Required schema.org subset

A node of type LodgingBusiness or a subtype (Hotel, Motel, Hostel, BedAndBreakfast, Resort, Campground, VacationRental) with: @context schema.org, name, url, address (PostalAddress with addressLocality and addressCountry) and geo (GeoCoordinates). Recommended: amenityFeature, checkinTime, checkoutTime, starRating, image, and containsPlace (HotelRoom).

7. Wire conventions

EndpointRequestResponse
POST {endpoint}/oti/searchsearch-request.jsonsearch-response.json
POST {endpoint}/oti/availabilityavailability-request.jsonavailability-response.json
POST {endpoint}/oti/reservations/lookupreservation-lookup.jsonreservation.json
POST {endpoint}/oti/reservations/cancelreservation-cancel.jsonreservation-cancel-response.json

8. Rules every producer and index follows

  1. No card data. No field of any OTI message carries a card number, CVV or expiry. Every endpoint rejects a request containing a card number with HTTP 400 and does not log it. Payment happens only on a trusted page reached through UCP continue_url: the hotel's own checkout, its payment provider's hosted page, or a page operated for the hotel that embeds no card field.
  2. The hotel is the merchant of record. No OTI component charges the guest.
  3. Room-only. No transport, activity or package items.
  4. All-in prices. Every offer itemizes taxes and mandatory fees (an explicit zero entry when there are none), marks what is collected at the property, and its non-total entries sum to the total. Its payment schedule sums to the total.
  5. Provenance and freshness. Every offer and index record carries source (hotel-published, plugin, edge, crawled, wix-mcp, fallback), fetched_at and expires_at. Consumers discard expired offers.
  6. Organic ranking is not for sale. An index returns paid placement only in a separate, labelled sponsored array.
  7. Read access for agents is free. Search and availability are anonymous and rate-limited, never billed.

9. Conformance

oti-validate <base-url> [--level L0..L3] [--sandbox] checks every layer above. Without --sandbox it creates booking sessions but never completes one, so it is safe against a live hotel; with --sandbox it completes and cancels a test booking (test producers only). Producers must pass the level they declare.