Connecting to us

Build on the product your clients have contracted

The Contracting API lets your booking platform, your agents and third parties sell the product a client has loaded straight into the engine: accommodation, car hire, transfers, attractions, flights, tours, coaches and trains. You build against it. We stay the source of truth for product, price and availability.

  • REST and JSON
  • Bearer keys, server to server
  • Sandbox from day one
cURLYour first call
curl https://contracts.travelify.io/api/v1/properties?property_type=hotel \
  -H "Authorization: Bearer sk_test_demo"
200 OKA page of products your key can sell
The shape of it

Three moves from search to a booking

  1. 01

    Browse

    List and read the product a client has contracted: accommodation, car hire, transfers, attractions, flights, tours, coaches and trains, with full content.

  2. 02

    Price

    Ask for real dates and guests, across many products in one call. Every result is complete: all the bookable options priced with a rate reference, the extras and the full product detail.

  3. 03

    Book

    Quote, hold, then confirm. The confirmed booking lands read-only on the client's calendar.

Request to result

The call on the left. The web page on the right.

Every endpoint returns clean JSON that drops straight into your interface. Here is the same data as your customer would see it.

You send
POST/api/v1/properties/{property_id}/availability
{
  "check_in": "2026-07-10",
  "check_out": "2026-07-17",
  "occupancy": {
    "adults": 2,
    "children": [6]
  }
}
Your customer sees

Vale do Sol Beach Hotel

Twin Garden View · B&B
Early booking 10%
€1,0437 nights · 2 adults, 1 child
Book

Booking more than one room

The same endpoint takes a group two other ways. Tell it who is in each room, or just how many people there are and let it work out what fits. Either way you get back one price and one reference that books the whole group in a single call.

You know the rooms
POST/api/v1/properties/{property_id}/availability
{
  "check_in": "2026-07-10",
  "check_out": "2026-07-17",
  "rooms": [
    { "adults": 2, "children": [6] },
    { "adults": 2, "children": [] }
  ]
}
You only know the group
POST/api/v1/properties/{property_id}/availability
{
  "check_in": "2026-07-10",
  "check_out": "2026-07-17",
  "party": { "adults": 8, "children": [] }
}
You send
POST/api/v1/bookings/{id}/confirm
{
  "payment_reference": "your_pmt_ref_123",
  "payment_status": "paid",
  "amount_paid": { "amount": 1043.00, "currency": "EUR" }
}
Your customer sees
ConfirmedTGC-7F3K9Q

Vale do Sol Beach Hotel

Twin Garden View · B&B
Dates
10–17 Jul 2026 · 7 nights
Lead guest
Sarah Hughes
Total paid
€1,043.00
Status
Live on the calendar
Now a read-only reservation on the client's calendar
Recently added

New on the search surface

Recent additions to how you search and build your booking flow. All live now, and existing calls keep working unchanged.

CoachesSeptember 2026

Ask for the cruise, not the date

POST /api/v1/coaches/availability now takes a sailing_id instead of a date, and answers with exactly two results: that sailing's outbound coach and its inbound coach, each priced on its own with its own rate_reference and labelled leg. No other cruises, no other dates, no other routes. Every departure's sailings now carry a sailing_id, and passing the same one to /bookings/quote takes the coach home from the sailing itself. This matters when one run feeds two cruises that come home on different days: a return_date names a coach, not a cruise, so it could not tell them apart. Add sailing to a normal date search to narrow it to one cruise.

See the reference
TransfersAugust 2026

Point-to-point search

Send an origin and a destination to the transfer availability search to get only the routes that run between a specific pickup and drop-off, instead of everything around one place. Each end is an airport code, e.g. origin: { "airport_code": "GVA" }, or a place with a small radius, e.g. destination: { "near": { "lat": 45.79, "lon": 6.97, "radius_km": 5 } }. Aliases from / pickup and to / dropoff are accepted.

See the reference
CoachesAugust 2026

Destination coordinates

Coach routes now return origin_location and destination_location, resolved by direction, so you can place the drop-off on a map or search by it. On an outbound run destination_location is the terminal (e.g. the airport); on a return it flips. The pick-up towns keep their own coordinates on pick_up_points.

See the reference
CoachesAugust 2026

Sailings on each departure

For a coach that feeds a scheduled service (a cruise-port transfer, say), every departure now carries a sailings array with the sailing name, ship and reference. Build the search box in the natural order: pick the sailing, then its date, then the pick-up. A run can list more than one sailing when two services leave on the same day. A plain point-to-point coach simply omits the field, so the same code handles both.

See the reference
CoachesAugust 2026

List coaches in one call

Add include to GET /v1/coaches to embed the full route detail on every result, so you no longer list and then call Get a coach route per route. Use include=all, or pick from pick_up_points, passenger_types, seasons and departures (departures carry their sailings). Only the current page is expanded, so page through large catalogues.

See the reference
The surface

Every endpoint in v1

Eight product families on one surface, sharing one auth, one error model and one booking flow. Every family has a bulk priced search that returns complete results in one call: all the bookable options with their rate references, the extras and the full product detail, so you never make follow-up calls per result.

Read

  • GET/api/v1/propertiesSearch accommodation (filters, id basket, map radius)
  • POST/api/v1/properties/searchSame search as a JSON body
  • POST/api/v1/properties/availability/searchPriced availability across many properties
  • GET/api/v1/properties/{id}Full property content
  • POST/api/v1/properties/{id}/availabilityPrice a property for dates and guests
  • GET/api/v1/carsSearch car hire (filters, id basket, map radius)
  • GET/api/v1/cars/{id}Full car product content
  • POST/api/v1/cars/{id}/availabilityPrice a vehicle for dates and driver age
  • POST/api/v1/cars/searchPriced availability across many car products
  • GET/api/v1/transfersSearch transfers (filters, id basket, map radius)
  • POST/api/v1/transfers/searchSame search as a JSON body
  • POST/api/v1/transfers/availability/searchPriced availability across many transfers, or point-to-point with origin and destination
  • GET/api/v1/transfers/{id}Full transfer product content
  • POST/api/v1/transfers/{id}/availabilityPrice a transfer for a journey
  • GET/api/v1/ticketsSearch attractions and events (filters, id basket, map radius)
  • POST/api/v1/tickets/searchSame search as a JSON body
  • POST/api/v1/tickets/availability/searchPriced availability across many attractions
  • GET/api/v1/tickets/{id}Full attraction content (options, ticket types, extras)
  • POST/api/v1/tickets/{id}/availabilityPrice an attraction for a visit date
  • GET/api/v1/flightsSearch flight deals (airline, origin, destination)
  • POST/api/v1/flights/searchSame search as a JSON body
  • POST/api/v1/flights/availability/searchPriced availability across many deals for a route
  • GET/api/v1/flights/{id}Full deal content (airports, routes, flights, aircraft, fares)
  • POST/api/v1/flights/{id}/availabilityPrice a route for a date and passengers
  • POST/api/v1/flights/{id}/seatmapSeat map for the seat picker
  • GET/api/v1/toursSearch tours (filters, id basket, map radius)
  • POST/api/v1/tours/searchSame search as a JSON body
  • POST/api/v1/tours/availability/searchPriced departures across many tours for a date window
  • GET/api/v1/tours/{id}Full tour content (itinerary, room bases, departures, spaces)
  • POST/api/v1/tours/{id}/availabilityPrice a departure for a traveller basket
  • GET/api/v1/coachesSearch coach and minibus services (filters, id basket, map radius)
  • POST/api/v1/coaches/searchSame search as a JSON body
  • POST/api/v1/coaches/availabilityPriced availability across routes by pick-up, destination and date
  • GET/api/v1/coaches/{id}Full coach route content (pick-up points, passenger types, departures)
  • POST/api/v1/coaches/{id}/availabilityPrice a departure by pick-up point
  • POST/api/v1/coaches/{id}/seatmapSeat map for the seat picker (when the route has a seat plan)
  • GET/api/v1/trainsSearch train services (filters, id basket, map radius)
  • POST/api/v1/trains/searchSame search as a JSON body
  • POST/api/v1/trains/availabilityPriced availability across services by boarding, destination and date
  • GET/api/v1/trains/{id}Full train service content (stations, passenger types, departures)
  • POST/api/v1/trains/{id}/availabilityPrice a departure by boarding station
  • POST/api/v1/trains/{id}/seatmapSeat map for the seat picker (when the service has a seat plan)

Trains mirror coaches. Booking is identical across products; for search, copy your coach calls, change the path to /v1/trains, and rename a few fields: pick_up_points to stations, pick_up to station (boarding_station on the booking), vehicle to service_class, coach_id to train_id, and the bulk pick_up filter to boarding. A train rate_reference starts with train_.

Booking

  • POST/api/v1/bookings/quoteLock a price from a rate reference
  • POST/api/v1/bookings/holdReserve inventory and attach the guests
  • POST/api/v1/bookings/{id}/confirmCommit once you have taken payment
  • GET/api/v1/bookingsList bookings (filter by reference, external ref or status)
  • GET/api/v1/bookings/{id}Retrieve a booking
  • PATCH/api/v1/bookings/{id}Amend guest details
  • POST/api/v1/bookings/{id}/cancelCancel and apply the policy
  • GET/api/v1/bookings/{id}/voucherBranded PDF voucher for the booking

Ask the API assistant

Stuck on something? Ask in plain English and get a step-by-step answer grounded in these docs.

Build against the sandbox first

Use a sk_test_ key. The surface is identical to live, only the data and the key differ, and nothing you do creates a real booking. The sandbox is seeded with demo product across every family so you can run each path end to end. When you are ready, swap in your live key and the same code runs against real product.

test sk_test_…live sk_live_…
Everything you need

Get the docs

Experienced developers can self-serve from here. If you would rather be walked through it, the written reference reads top to bottom.