# Overview

API v2 sells every product through one flow. You read the catalog, ask for availability, and book with an `offer_id`. Reading, cancelling and the voucher work the same way for every product.

This page is a map. The reference has every field: [Transfers reference](/developers/reference/v2/transfers), [Tickets reference](/developers/reference/v2/tickets), [Hotels reference](/developers/reference/v2/hotels) and [Booking flow reference](/developers/reference/v2/bookings). v2 is stable since 2026-10-02 and covers transfers, tickets and hotels today.

## The flow

1. `GET /api/v2/{product}/products` lists what your credential can sell, with the data you must collect for each product. `{product}` is `transfers` or `tickets`. Tickets also have `GET /api/v2/tickets/brands`, with what each brand needs from travelers. Hotels have `GET /api/v2/hotels/destinations` instead.
2. `POST /api/v2/{product}/availability` returns a price and an `offer_id` for each product and day. For hotels it starts an asynchronous search, and `GET /api/v2/hotels/availability/{search_id}` reads it.
3. `POST /api/v2/offers/check` is optional. It re-quotes the offer live and returns the cancellation policy.
4. `POST /api/v2/bookings` books the offer. You send an `Idempotency-Key` header, one new value for each booking.
5. `GET /api/v2/bookings/{booking_id}`, `POST /api/v2/bookings/{booking_id}/cancel` and `GET /api/v2/bookings/{booking_id}/voucher` cover everything after the sale.

A minimal integration is three calls for each sale: the catalog once (it changes rarely), then availability, then the booking. The booking call needs the `Idempotency-Key` header and the traveler data that the catalog lists. Once you hold the `booking_id`, the read, the cancel and the voucher are one call each. The steps from the offer on are the same for every product and are described once, in the [Booking flow](/developers/guides/v2-booking-flow). Only how you get the catalog and the availability changes, and each product guide covers that: [Transfers](/developers/guides/v2-transfers), [Tickets](/developers/guides/v2-tickets) and [Hotels](/developers/guides/v2-hotels).

## What is different from v1

- **One booking resource.** `POST /bookings` books any product type. A booking item is shaped by its product type, so your client ignores item shapes it does not know.
- **Signed offers.** Each price comes with an `offer_id`. The offer carries the price, the date and the passenger counts. You do not send them again when you book. `expires_at` is `null` unless the source gives a real expiry. The price is validated again at booking time.
- **Requirements come from the catalog.** Each product lists its `booking_requirements` (tickets list them once per brand, in `GET /tickets/brands`): the traveler fields and the trip details to collect. They are the same data the website asks for, so build your form from them instead of hard-coding fields.
- **One error envelope with closed codes.** Every error is `{"error": {"code", "message", "request_id", "details"}}`. You match on `code`. See [v2 errors](/developers/guides/v2-errors).
- **`Idempotency-Key` is required** on `POST /bookings`. It makes the request safe to repeat. `external_reference` is only your own number for the booking: it is optional, up to 50 characters, and you can use the same one on several bookings.
- **An unknown result is a `202`, not an error.** When the source does not answer and we cannot know whether it booked, `POST /bookings` answers `202` with `booking.status: "pending"`. You read `GET /bookings/{booking_id}` until it is `confirmed` or `failed`.
- **Quantities are called `pax`.** Availability, offers and booking items carry `pax` (`adult`, `child`, `infant`). Hotels use `occupancy`. In a booking, `travelers[]` are the people.
- **The API asks only for what the product needs.** The traveler fields come from the catalog, per product or brand.
- **Hotels book one offer per room.** A hotel booking has one item per room, and the offers of one rate are booked together. See [Hotels](/developers/guides/v2-hotels).

## Conventions

- Base path is `https://api.avantetravel.com/api/v2`. JSON uses `snake_case`.
- Dates are `YYYY-MM-DD`, timestamps are ISO 8601 in UTC, countries are ISO 3166-1 alpha-2 and currencies are ISO 4217.
- Authenticate with `Authorization: Bearer <credential>`. It is the same credential as in v1. See [Authentication](/developers/guides/authentication).
- A successful response is the resource plus `request_id`. The same id is in the `X-Request-Id` header.
- Responses carry `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`. A `429` adds `Retry-After`. Each version has its own limit per credential: what you send to v1 does not count against v2.
- Adding fields to a response is not a breaking change. Ignore fields you do not know.
- If a response is not 2xx, nothing was booked. A `202` means the booking is pending: read it until it settles.

## Products

| Product | Status |
|---|---|
| Transfers | Available in v2 |
| Tickets (Universal and Disney) | Available in v2 |
| Hotels, including Disney resort hotels | Available in v2 |
| Other products | Will be added in later releases without breaking this contract |

Products that are not in v2 yet stay on v1, and v1 stays available for transfers, tickets and hotels too. See [Migrating from v1](/developers/guides/v2-migrating-from-v1).

## Test credentials

A test credential runs every validation for real and books nothing real. The booking answers `test_mode: true`, and read, cancel and voucher work on it. What is stored depends on the product: see [Sandbox](/developers/guides/sandbox).
