Travel Discovery API · TypeScript + Python SDKs

Add catalogue-aware travel decisioning before inventory search.

Turn open-ended travel intent into ranked destinations, dates and trip lengths before downstream flight, hotel or other inventory shopping. Discovery plans the opportunity set; Verified Search can then check the candidates worth shopping.
From intent to inventory
01
Travel intent
Natural language plus optional structured constraints.
02
Discovery API
Rank destinations, dates and trip lengths before shopping.
03
Verified Search
Optionally check selected opportunities with providers.
04
Your product
Present, enrich or hand off the smaller high-intent result set.
Developer resources

One developer hub. Open contract. Public SDKs.

Start here for the Business API contract and integration model. The public SDK repository supports the documentation; this Business developer hub is the canonical product and API entry point.
SDK

Official TypeScript & Python SDKs

Generated from the Business OpenAPI contract and published in a public MIT-licensed repository.
View SDK on GitHub →
Contract

Machine-readable OpenAPI

Inspect the canonical production Business v1 contract, schemas, operations and authentication requirements.
View OpenAPI →
Product

Travel Discovery API overview

Understand where Discovery sits before inventory search and how provider-backed verification remains a separate step.
Discovery overview →
Demo

See the consumer planning experience

The consumer app is useful for experiencing destination-open planning. Business integrations should use this developer hub and Business API.
Try MyEscapePlan →
SDK quick start

Start from the same contract in TypeScript or Python.

API keys are server-side credentials. Keep them in trusted backend infrastructure, never in public browser or mobile bundles.
TypeScript

@myescapeplan/sdk

git clone https://github.com/myescapeplan/myescapeplan-sdk.git cd myescapeplan-sdk/typescript npm ci npm run build # From your trusted backend project: cd /path/to/your-backend npm install /path/to/myescapeplan-sdk/typescript
import { BusinessTravelAPIApi, Configuration } from "@myescapeplan/sdk"; const api = new BusinessTravelAPIApi( new Configuration({ apiKey: process.env.MYESCAPEPLAN_API_KEY! }), ); const discovery = await api.createDiscovery({ idempotencyKey: crypto.randomUUID(), discoveryRequest: { query: "four nights next month, somewhere warm, under £500", }, }); console.log(discovery.opportunities);
Python

myescapeplan

The Python SDK exposes the same generated Business v1 contract. Full method and model documentation lives in the public repository.
git clone https://github.com/myescapeplan/myescapeplan-sdk.git cd myescapeplan-sdk/python python -m pip install -e .
import asyncio import os import uuid from myescapeplan import ApiClient, BusinessTravelAPIApi, Configuration from myescapeplan.models.discovery_request import DiscoveryRequest async def main(): configuration = Configuration() configuration.api_key["BusinessApiKey"] = os.environ["MYESCAPEPLAN_API_KEY"] async with ApiClient(configuration) as client: api = BusinessTravelAPIApi(client) discovery = await api.create_discovery( idempotency_key=str(uuid.uuid4()), discovery_request=DiscoveryRequest( query="four nights next month, somewhere warm, under 500 GBP" ), ) print(discovery.opportunities) asyncio.run(main())
Built for

Travel decisioning that works before and after the destination is known.

Conversational & AI travel search

Convert open requests into structured destination and date opportunities before inventory fan-out.

Destination recommendation

Return ranked destinations, date options, reasons and qualitative fit instead of a generic list of places.

Flexible-date planning

Preserve hard constraints while finding useful dates, trip lengths and controlled alternatives.

OTA, advisor & platform workflows

Place Discovery upstream of supplier APIs, then use Verified Search only for the opportunities worth checking.
Raw HTTP quick start

Open-destination travel discovery

Discovery accepts natural-language query text and/or structured fields. Origin, party, budget, dates, categories and preferences can constrain the request; exact destination IDs can be supplied for constrained discovery, and trip_anchor can carry a known external commitment.
curl --request POST \ 'https://api.myescapeplan.app/api/v1/business/discovery' \ --header 'Content-Type: application/json' \ --header 'X-API-KEY: YOUR_API_KEY' \ --header 'Idempotency-Key: discovery-example-001' \ --data '{ "query": "4 days next month, under £300pp, somewhere warm with direct flights", "origin": { "query": "London", "airport_iata_codes": ["LHR", "LGW", "STN", "LTN", "LCY"] }, "party": { "adults": 2, "children": 0 }, "budget": { "amount": 300, "currency": "GBP", "scope": "per_person" }, "limit": 10 }'
Trip anchors

Plan around a commitment your application already knows.

Pass a known concert, sporting fixture, conference, cruise, tour, appointment or other external commitment as trip_anchor. MyEscapePlan resolves the destination and plans around its required local dates. The default cover mode includes the full date interval; overlap mode requires at least one shared local date.
The caller supplies the commitment; MyEscapePlan does not discover or verify the event itself. Supported anchor types are event, appointment, cruise, tour and other. Use event for concerts, sporting fixtures and conferences. Neither mode guarantees arrival before a specific event clock time.
{ "query": "4 night trip for a concert", "origin": { "query": "London" }, "trip_anchor": { "type": "event", "title": "Concert", "destination": { "query": "Barcelona, Spain" }, "required_presence": { "start_date": "2026-11-18", "end_date": "2026-11-18" } }, "dates": { "duration_nights": 4 } }
Authentication & reliability

Three integration rules matter first.

Authenticate server-side with X-API-KEY. Test and live keys are isolated Business tenants.
Send an Idempotency-Key on Discovery and Verified Search creation; reuse it only for the same logical retry.
Treat Discovery as planning: opportunities are not provider-verified until the separate Verified Search workflow runs.
Response model

Stable public opportunities, not planner internals.

Downstream products receive ordered opportunities, date options, reasons, airport inputs and qualitative fit. Raw planner scores and internal lanes remain private implementation details.
{ "request_id": "req_…", "idempotency_key": "discovery-example-001", "status": "ok", "discovery_id": "…", "interpreted_request": { "title": "4 days next month, under £300pp, somewhere warm with direct flights", "origin": "London", "duration_nights": 4, "adults": 2, "children": 0, "budget_amount": 300, "budget_currency": "GBP", "budget_scope": "per_person", "categories": ["flights", "accommodation"], "warnings": [] }, "opportunities": [ { "opportunity_id": "…", "destination": { "id": "00000000-0000-0000-0000-000000000000", "name": "Málaga", "display_name": "Málaga, Spain", "country_code": "ES" }, "rank": 1, "date_options": [ { "date_option_id": "date_123", "date_type": "primary", "start_date": "2026-10-08", "end_date": "2026-10-12", "nights": 4 } ], "tags": ["warm"], "reasons": ["Matches the requested warm short-break intent."], "fit": { "label": "strong", "reason": "Strong match to the interpreted request." }, "origin_airport_iata_codes": ["LHR", "LGW", "STN", "LTN", "LCY"], "destination_airport_iata_codes": ["AGP"], "search_inputs_available": { "flights": true, "accommodation": true, "events": false }, "verification_status": "not_verified" } ], "meta": { "contract_version": "travel.discovery.v1", "candidate_count": 1, "usage": { "metering_basis": "request", "discoveries_used": 1, "candidate_count": 1, "plan_period_allowance": 50000 } }, "expires_at": "2026-10-08T12:00:00Z" }
Discovery → Verified Search

Shop only the opportunities worth checking.

Discovery is synchronous planning and makes no supplier calls. When one opportunity needs live flight or accommodation verification, pass its discovery and opportunity IDs into the separately scoped asynchronous Verified Search workflow.
const opportunity = discovery.opportunities?.[0]; if (!opportunity) throw new Error("No discovery opportunities returned"); const job = await api.createSearch({ idempotencyKey: crypto.randomUUID(), businessSearchCreateRequest: { discoveryId: discovery.discoveryId, opportunityId: opportunity.opportunityId, }, }); let search = await api.getSearch({ searchId: job.id }); for (let attempt = 0; attempt < 30; attempt += 1) { if (search.status === "completed" || search.status === "partial") break; if (search.status === "failed" || search.status === "cancelled") { throw new Error("Verified Search ended with status: " + search.status); } await new Promise((resolve) => setTimeout(resolve, 2000)); search = await api.getSearch({ searchId: job.id }); } if (search.status !== "completed" && search.status !== "partial") { throw new Error("Verified Search did not reach a result-ready status in time"); } const results = await api.getSearchResults({ searchId: job.id });
Capability boundary

Discovery decides what is worth shopping. Verified Search shops it.

Provider-backed verification stays separate from synchronous Discovery. Integrations that need live flight or accommodation checks can pass a selected opportunity into the asynchronously executed Verified Search workflow with the appropriate scope.
Discovery
POST /api/v1/business/discovery
travel.discovery · synchronous planning · no supplier calls
Verified Search
POST /api/v1/business/searches
travel.search · asynchronous · provider-backed
Usage
GET /api/v1/business/usage
allowances · consumption · concurrency · scopes
Usage & limits

Read current allowance and concurrency state.

The usage endpoint returns the active billing period, Discovery usage, Verified Search consumption and reservations, concurrency, rate limits and key scopes.
curl --request GET \ 'https://api.myescapeplan.app/api/v1/business/usage' \ --header 'X-API-KEY: YOUR_API_KEY' // 200 BusinessUsageResponse { "environment": "live", "plan_tier": "starter", "period": { "start": "2026-09-01T00:00:00Z", "end": "2026-10-01T00:00:00Z" }, "discovery": { "used": 125, "allowance": 50000, "remaining": 49875 }, "verified_searches": { "consumed": 12, "reserved": 2, "allowance_used": 14, "allowance": 500, "remaining": 486 }, "concurrency": { "active": 2, "limit": 3, "remaining": 1 }, "rate_limits": { "discovery_per_minute": 30 }, "scopes": ["travel.discovery", "travel.search"], "as_of": "2026-09-03T12:00:00Z" }
Current v1 boundaries

Clear contract edges for production integrations.

Open-destination Discovery supports structured fields without query text; explicit destination_ids can constrain discovery.
limit accepts 1–50, while the deployed service may enforce a lower configured candidate cap.
Discovery returns DiscoveryResponse; Verified Search creation returns BusinessJobResource.
Search result collections return BusinessSearchResultsResponse; usage returns BusinessUsageResponse.
Discovery is metered per admitted request, including no-results responses.
fit is qualitative planning suitability, not statistical confidence.
verification_status remains not_verified on Discovery by design.
Verified Search jobs are asynchronous and separately scoped.
BusinessErrorEnvelope is returned for Business API errors.
API keys, quotas and provider-backed verification are provisioned through the Business integration process.
Discovery API overview

MyEscapePlan Business

AI travel decisioning for travel businesses: connect customer intent with your catalogue, supplier policy and commercial rules across digital and advisor workflows.
MYESCAPEPLAN LTD · Company no. 16395758 · Registered in United Kingdom
Discovery API and Advisor are available now. Tour operator and Meetings & Events workflows can be piloted around the same controlled decisioning layer.
Discovery benchmark figures, their formula and their limitations are published in full.
Read the benchmark methodology ↗
Tour operator and Advisor pilots can start with your existing catalogue and supplier policy.