---
title: "Quickstart"
description: "Dubai to London, end to end, with curl."
---

> Documentation Index
> Fetch the complete documentation index at: https://agents.wego.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

Get `$TOKEN` per [Authentication](/authentication) first. This needs `jq` (the same threading idiom the CLI uses).

## Flights

```bash
# 0. A departure date ~60 days out, so this block never carries a past date
FROM_DATE=$(date -u -v+60d +%F 2>/dev/null || date -u -d '+60 days' +%F)

# 1. Create a search (IATA airport or city codes; results settle async)
SEARCH_ID=$(curl -s -X POST "https://api.wego.com/v1/flights/searches" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"from":"DXB","to":"LHR","fromDate":"'"$FROM_DATE"'","adults":1}' | jq -r .searchId)

# 2. Read ranked results and take a trip id (empty? rerun: results settle async)
TRIP_ID=$(sleep 3; curl -s -H "Authorization: Bearer $TOKEN" \
  "https://api.wego.com/v1/flights/searches/$SEARCH_ID/results" | jq -r '.results[0].tripId')

# 3. Open the trip (full itinerary, every fare) and take its Wego fare id
# (null? that trip has no Wego fare: try another tripId from step 2)
FARE_ID=$(curl -s -H "Authorization: Bearer $TOKEN" \
  "https://api.wego.com/v1/flights/trips/$TRIP_ID?searchId=$SEARCH_ID" \
  | jq -r '[.fares[] | select(.kind=="wego")][0].fareId')

# 4. Pick a fare option (Saver, Flex and similar). The list is ordered by leg
# first, then by price within a leg - so options[0] is the cheapest option of
# leg 1, not the cheapest of the fare.
# REQUIRED: step 5 rejects a request with no fareOptionId (400 validation_failed).
# This route is one-way, so one id is the whole trip. Read the fare's own
# top-level `price` for the trip total; never add or min() the options.
FARE_OPTION_ID=$(curl -s -H "Authorization: Bearer $TOKEN" \
  "https://api.wego.com/v1/flights/fares/$FARE_ID/options" \
  | jq -r '.options[0].fareOptionId')

# 5. Get the wego.com URL (the booking-link endpoint)
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://api.wego.com/v1/flights/fares/$FARE_ID/booking-link?tripId=$TRIP_ID&fareOptionId=$FARE_OPTION_ID&from=DXB&to=LHR&fromDate=$FROM_DATE"
# -> { "bookingUrl": "https://www.wego.com/...", "expires": true }
```

**Adding a return date?** Then step 4 has a case to check that a one-way does not.
Each option carries `price.covers`: `"trip"` means that one id prices the whole
journey and step 5 takes it alone, exactly as above; `"leg"` means it prices only its
own leg. Send a single `"leg"` id and the booking page still presents the round trip
while pricing half of it, with nothing in the response to say so. So when the options
report `"leg"`, group them by `legId`, take one per entry in `legs[]`, and pass them
to step 5 as a comma-separated `fareOptionId` (at most 8, none twice). `covers` is a
positive witness: absent means the API could not attribute the option, not that it
covers the trip. See [Fares, rates and partners](/api/fares-rates-partners).

Do not know the code? `GET /v1/places?query=dubai` resolves free text to typed places
with codes – cities, airports, states, districts and hotels, so it is also where a
`hotelId` for the hotels funnel comes from. When the response sets
`metadata.hasAmbiguity`, ask the traveler which place they meant before searching.

## Hotels

Nearly the same shape, with one extra step: a city search holds only a sample of any
one hotel's rates, so pricing a hotel's full room list takes a **second** search
created with that `hotelId`. Skip it and the rates read answers `409`
`rates_require_hotel_search`.

```bash
CHECK_IN=$(date -u -v+60d +%F 2>/dev/null || date -u -d '+60 days' +%F)
CHECK_OUT=$(date -u -v+63d +%F 2>/dev/null || date -u -d '+63 days' +%F)

# 1. Create a city search
CITY_SEARCH=$(curl -s -X POST "https://api.wego.com/v1/hotels/searches" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"cityCode":"DXB","checkIn":"'"$CHECK_IN"'","checkOut":"'"$CHECK_OUT"'","adults":2}' | jq -r .searchId)

# 2. Read ranked results and take a hotelId
# (null? rerun: results settle async. Read the top-level searchComplete flag to
# know when to stop - see How search works)
HOTEL_ID=$(sleep 4; curl -s -H "Authorization: Bearer $TOKEN" \
  "https://api.wego.com/v1/hotels/searches/$CITY_SEARCH/results" | jq -r '.results[0].hotelId')

# 3. REQUIRED: a second search, scoped to that hotel
HOTEL_SEARCH=$(curl -s -X POST "https://api.wego.com/v1/hotels/searches" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"hotelId":"'"$HOTEL_ID"'","checkIn":"'"$CHECK_IN"'","checkOut":"'"$CHECK_OUT"'","adults":2}' | jq -r .searchId)

# 4. Rooms and rates, cheapest first (a rate's id is `id`, not `rateId`)
# (null? rerun: rates land over a few seconds too)
RATE_ID=$(sleep 4; curl -s -H "Authorization: Bearer $TOKEN" \
  "https://api.wego.com/v1/hotels/$HOTEL_ID/rates?searchId=$HOTEL_SEARCH" | jq -r '.rates[0].id')

# 5. Get the wego.com checkout URL
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://api.wego.com/v1/hotels/$HOTEL_ID/rates/$RATE_ID/booking-link?searchId=$HOTEL_SEARCH"
# -> { "bookingUrl": "https://www.wego.com/hotels/booking/checkout?...", "expires": true }
```

For endpoint details and parameters, see the [API Reference](/api).

Source: https://agents.wego.com/quickstart/index.mdx
