# Transfers

Private transfers between airports, ports, hotels and parks. You list the catalog, read a price calendar, book with one lead traveler, and cancel if needed.

This guide explains the flow. Field-by-field detail is in the [Transfer reference](/developers/reference/v1/transfer).

| Step | Endpoint | Gives you |
|---|---|---|
| 1 | `POST /api/v1/transfer/getCatalog` | `id_product` for each transfer you can sell |
| 2 | `POST /api/v1/transfer/getPrice` | Price and availability for each date |
| 3 | `POST /api/v1/transfer/transferConfirm` | `id_order` and the voucher link |
| 4 | `GET /api/v1/transfer/pdf` | The voucher PDF again, at any time |
| 5 | `POST /api/v1/transfer/transferCancelation` | Cancels the order |

All calls need your Bearer credential. See [Authentication](/developers/guides/authentication).

## 1. List the catalog

Send an empty JSON object.

```bash
curl -X POST "https://highstartravel.com/api/v1/transfer/getCatalog" \
  -H "Authorization: Bearer YOUR_CREDENTIAL" \
  -H "Content-Type: application/json" \
  -d '{}'
```

The catalog is grouped as destinations, then services, then products. Only products that can be sold are listed. Titles and descriptions come in Spanish and English (`title_es`, `title_en`).

The `id` of each entry in `service_types` is the `id_product` for the next steps. `max_pax` is the most passengers (adults plus children) the product takes. The limit can depend on the travel date, and `getPrice` and `transferConfirm` check it for the date you ask.

The catalog changes rarely. The response has `Cache-Control: private, max-age=3600`, so you can cache it for an hour.

## 2. Read the price calendar

Ask for one date, or for a range of up to 90 days.

```bash
curl -X POST "https://highstartravel.com/api/v1/transfer/getPrice" \
  -H "Authorization: Bearer YOUR_CREDENTIAL" \
  -H "Content-Type: application/json" \
  -d '{
    "id_product": 301,
    "adults": 2,
    "children": 1,
    "infants": 0,
    "from_date": "2026-11-15",
    "to_date": "2026-11-22"
  }'
```

- Send `date`, or send `from_date` and `to_date`. `to_date` cannot be before `from_date`.
- `adults` and `children` are required, each from 0 to 10. You need at least one of them. Their sum cannot pass 10 or the product's capacity.
- `infants` is optional and does not count towards capacity.

The response has one row per date in `calendar`:

```json
{
  "success": true,
  "code": 200,
  "product": { "id": 301, "title_es": "MCO a zona Disney", "title_en": "MCO to Disney Area", "id_destination": 12, "id_service": 3 },
  "pax": { "adults": 2, "children": 1, "infants": 0, "total_pax": 3 },
  "from_date": "2026-11-15",
  "to_date": "2026-11-22",
  "calendar": [
    { "date": "2026-11-15", "available": true, "price": 95.0 },
    { "date": "2026-11-16", "available": false, "price": null },
    { "date": "2026-11-17", "available": true, "price": 120.0 }
  ],
  "request_id": "3f8a9b7c1d2e4f5a6b7c8d9e0f1a2b3c"
}
```

- `price` is the price of the whole booking for those passengers, not a price per person. It already includes any holiday surcharge.
- `available: false` with `price: null` means you cannot book that date. The date is blocked, or it is closer than the minimum lead time. A transfer must be booked at least 2 days ahead, so the earliest bookable date is today plus 2 days.
- The response has no currency field. Agree the billing currency with your account manager.

If the price cannot be calculated you get `503` with `Pricing unavailable`. Try again in a few minutes.

## 3. Book

Call `getPrice` for the date right before you confirm, and send that date's `price` as `total_amount`. The API calculates the price again and compares it. If it differs by 0.01 or more you get `400 Price mismatch` and nothing is booked. Call `getPrice` again and use the new price.

```bash
curl -X POST "https://highstartravel.com/api/v1/transfer/transferConfirm" \
  -H "Authorization: Bearer YOUR_CREDENTIAL" \
  -H "Content-Type: application/json" \
  -d '{
    "id_product": 301,
    "adults": 2,
    "children": 1,
    "infants": 0,
    "date": "2026-11-17",
    "total_amount": 120.00,
    "external_reference": "MY-SYSTEM-9876",
    "pax": [
      { "name": "John", "surname": "Doe", "phone": "+1 407 555 0100", "nationality": "US" },
      { "name": "Jane", "surname": "Doe", "type": "adult" },
      { "name": "Kid", "surname": "Doe", "type": "child" }
    ],
    "transfer_data": {
      "origin_type": "Airport",
      "destination_type": "Hotel",
      "airport": "MCO",
      "terminal": "A",
      "airline": "AA",
      "hour": "13",
      "minutes": "45",
      "hotel2": "Hotel name",
      "voucher_observations": "Baby seat needed"
    }
  }'
```

### Passengers

The first entry of `pax` is the lead traveler, and it is the only person you must describe. It needs all four fields:

| Field | Rule |
|---|---|
| `name` | Required, up to 200 characters. |
| `surname` | Required, up to 200 characters. |
| `phone` | Required. 6 to 30 characters using digits, spaces, `+`, `-` and parentheses, with at least 6 digits. Include the country prefix. |
| `nationality` | Required. An ISO 3166-1 alpha-2 code such as `AR` or `US`. The alpha-3 code or the country name is converted for you. An unknown country returns `400`. |

The lead traveler is always treated as the holder of the booking, whatever `type` you send.

Other passengers are optional. If you send them, each one needs `name`, `surname` and `type` (`adult`, `child` or `infant`). The list cannot be longer than `adults + children + infants`.

### Trip details

`transfer_data` is optional and every field in it is optional. Send what applies to the trip. The web form uses the values `Airport`, `Port` and `Hotel` for the two ends, so use the same ones.

| Field | Meaning |
|---|---|
| `origin_type`, `destination_type` | The kind of each end: `Airport`, `Port` or `Hotel`. |
| `airport`, `terminal`, `airline`, `hour`, `minutes` | Flight details when the origin is an airport. |
| `port` | The port when the origin is a port. |
| `hotel` | The hotel when the origin is a hotel. |
| `airport2`, `terminal2`, `airline2`, `hour2`, `minutes2`, `port2`, `hotel2` | The same details for the destination. |
| `voucher_observations` | A note printed on the voucher. |
| `cruise_info` | Cruise details, added to the voucher note. |
| `internal_notes` | A note stored with the booking. It is not printed in the voucher. |

### The response

```json
{
  "success": true,
  "code": 200,
  "id_order": 168001,
  "pdf_voucher": "https://highstartravel.com/archivos/api/transfer/pdf/Xa9K2mQ7pR4tY8bW1nZ3cV6h.pdf",
  "request_id": "3f8a9b7c1d2e4f5a6b7c8d9e0f1a2b3c"
}
```

- Keep `id_order`. You need it to cancel and to download the voucher.
- `pdf_voucher` is a link with a random key that nobody can guess. Treat it as private. If the link could not be created, the field is an empty string. Use `GET /transfer/pdf` in that case.

### Checks that can reject a booking

Every one of these returns `400` and creates nothing:

- The date is less than 2 days ahead (`Date not bookable`), or falls in a blocked period (`Date not available`).
- More passengers than the product takes (`Capacity exceeded`).
- A problem in the passenger list (`Invalid pax`, `Pax count mismatch`, `Invalid pax entry`).
- `total_amount` is not the current price (`Price mismatch`).

A product that does not exist or is not for sale returns `404 Product not found`. A paused product returns `503 Provider unavailable`.

### If the request times out

Do not send a new booking with a new reference. Repeat the request with the same `external_reference`. The repeat always returns the original order, with `"idempotent_replay": true`, or `409 ORDER_CONFIRMATION_IN_PROGRESS` if the first request is still running. See [Conventions](/developers/guides/conventions#idempotency).

## 4. Download the voucher

```bash
curl "https://highstartravel.com/api/v1/transfer/pdf?order_id=168001" \
  -H "Authorization: Bearer YOUR_CREDENTIAL" \
  -o voucher.pdf
```

The order must belong to your account. The voucher is regenerated in the language of your credential.

| Status | `error` | Meaning |
|---|---|---|
| 404 | `ORDER_NOT_FOUND` | The order does not exist or is not yours. |
| 410 | `ORDER_CANCELLED` | The order was cancelled. The voucher is not valid. |
| 409 | `VOUCHER_NOT_GENERATED` | The voucher is not available yet. Try again shortly. |

## 5. Cancel

```bash
curl -X POST "https://highstartravel.com/api/v1/transfer/transferCancelation" \
  -H "Authorization: Bearer YOUR_CREDENTIAL" \
  -H "Content-Type: application/json" \
  -d '{ "id_order": 168001 }'
```

```json
{
  "success": true,
  "code": 200,
  "message": "Transfer order cancelled successfully.",
  "cancelled_items": 1,
  "request_id": "3f8a9b7c1d2e4f5a6b7c8d9e0f1a2b3c"
}
```

The cancellation applies to the whole order. The response does not report any cancellation charge. If you need to know the conditions for a product, ask your account manager.

| Status | `error` | Meaning |
|---|---|---|
| 400 | `Cancellation not allowed` | The order is not yours, it does not exist, or it has nothing active left, for example because it is already cancelled. |
| 400 | `Transfer not found` | The order has active items, but none of them is a transfer. |

## What not to do

- Do not reuse a price from an earlier search. Ask for the price right before you confirm.
- Do not retry a timed-out confirmation with a new `external_reference`.
- Do not read the price as a per-person price. It is the total for the booking.
- Do not keep the `pdf_voucher` link as the only copy. You can always ask for the voucher again by `id_order`.

## Next

- [Transfer reference](/developers/reference/v1/transfer) has every field and response.
- [Sandbox](/developers/guides/sandbox) explains how to test this flow without real bookings.
- [Errors](/developers/guides/errors) explains every status code.
