metadata.externalAdapter.baseUrl at the public Voyant sandbox connector Worker and use HMAC as below — the sandbox implements the same operation paths.
Register the provider
CLI (recommended)
signingSecret from the register response in the adapter’s secret manager.
HTTP API
Register the provider withPOST /connect/v1/connector-providers. The request body is the connector manifest. Private connectors must include metadata.externalAdapter; hostedWorker and externalAdapter are mutually exclusive.
Registration validates the manifest, enforces public HTTPS URL policy on metadata.externalAdapter.baseUrl, and probes the adapter endpoint (well-known manifest preferred; otherwise /health must respond as reachable, including 401/403 when signature is required).
For stays and packages, the well-known manifest’s operation list is recorded at registration. Declare quoteStay/quotePackage and lockStay/lockPackage only when those operations are implemented. A declared quote that returns null or fails stops the hold; an adapter without a declared quote can hold an unexpired search offer. Legacy adapters registered through the health fallback retain the quote dispatch path until they publish an operation list.
After creation, PUT /connect/v1/connector-providers/{key}/manifest re-registers the manifest for the same provider — use it to update capabilities, credential forms, or the adapter target as the integration evolves. This PUT probes the new target again and replaces its admitted operation list. Connect also discovers operation lists through its pinned egress relay for providers registered before operation lists were recorded. Only the owning organization can touch an owned key, and platform-managed metadata (managedByOrganizationId, website, applicationForm, iconObjectKey) is ignored if a manifest tries to set it. Adapters may also self-describe by serving their manifest at /.well-known/voyant-connect/manifest, which is how hosted connectors publish theirs; for private connectors it is optional but useful for voyant-side validation tooling.
data.provider and data.signingSecret. The signing secret is revealed once. Store it in the adapter service secret manager; later reads do not return it.
URL constraints
metadata.externalAdapter.baseUrl must be a public HTTPS URL. The control plane rejects URLs with credentials, query strings, or fragments, and rejects hosts that are local, internal, loopback, private, link-local, carrier-grade NAT, documentation-only, benchmark, multicast, reserved, or otherwise non-public after DNS resolution.
Voyant repeats this policy at connect time in its connector egress relay. The relay resolves the complete DNS answer set, rejects the request if any answer is non-public, selects one accepted address, and pins that address into the TLS connection. It keeps the original hostname for certificate validation and SNI. DNS failure and mixed public/private answers fail closed. The relay does not follow redirects.
The configuration-time check remains defense in depth. It is not the check that authorizes the connection, so changing DNS after registration cannot redirect a connector request to a private service.
Valid:
Request contract
Connect dispatches each operation withPOST to:
baseUrl is https://adapter.example.com/connect, searchStays is sent to https://adapter.example.com/connect/stays/search.
The request body is JSON:
operatorId, marketContext, and now as absent-able: catalog-wide operations dispatch without an operator, and only per-call operations carry the tracing fields. Code the adapter against this exact shape rather than assuming every field is present.
The adapter must return one of these JSON envelopes:
Headers and signing
Every external adapter request includes:
The egress relay authentication header is platform-internal and is never sent to the adapter. The adapter-facing method, URL path, body, headers, timeout envelope, and response handling are unchanged by relaying.
The signature is HMAC-SHA256 over this canonical string:
url.pathname includes any path prefix from baseUrl plus the operation path. It does not include scheme, host, query, or fragment. bodyText is the exact raw request body bytes decoded as text.
Operation paths
The platform dispatches only the operations it needs for a connection and the provider capabilities in use. Stay and package search offers carry__offerProof, which binds the exact offer snapshot, connection, and viewer to the hold request. Clients must preserve this field when posting offerId and offer to the lock route. Altered or expired offers require a new search.
When releasing this hold validation, deploy the connector egress relay with restricted manifest GET support before deploying Connect API. Existing external adapters without recorded operations depend on that relay read to distinguish an absent optional quote from a failed configured quote.
Before Connect API deployment, inventory active Stay and Package external registrations. Each must have an admitted operation list from registration or manifest update, or serve a valid well-known manifest through the relay. A health-only legacy registration without either source has unknown quote capability: update and probe its provider manifest with PUT /connect/v1/connector-providers/{key}/manifest before release. Do not treat a quote endpoint’s 404 as proof that quoting is optional; a failed declared or unknown quote must stop the hold.
Rotate the signing secret
UsePOST /connect/v1/connector-providers/:key/signing-secret/rotate to rotate the per-provider external adapter signing secret. The response includes the new data.signingSecret once, alongside the provider row.
Deploy the adapter with the new secret before using it exclusively. The current dispatch code signs with the single encrypted secret stored on the provider row.
Grants and sharing
Creating a private provider automatically creates an active owner self-grant. The owning organization can share the provider with another organization using:expiresAt.
Lifecycle
Disable a private provider with:409 with the active connection count. To tear down active references, revoke grants, remove provider registrations and stored provider secret material, and hard-delete the provider row, call:
Reference implementation
The TUI connector is the reference implementation for the hosted connector protocol. It is registered as an internal provider withmetadata.hostedWorker.type = "hosted_worker_target" and protocol version 2026-05-28, and the Connect API dispatches TUI stays and packages operations through the same operation envelope and response envelope described here.