# Conventions

These rules apply to every product.

## Requests

- Use HTTPS and UTF-8.
- `POST` endpoints take a JSON body and need `Content-Type: application/json`. `GET` endpoints take query parameters.
- Using the wrong method returns `405`.
- Field names are in English. JSON keys are case sensitive, and a few use camelCase (for example `childrenAges` and `DeliveryMethod`), so copy them from the reference.

## Formats

- Dates are `YYYY-MM-DD`, for example `2026-11-17`. Other forms are rejected.
- Countries are ISO 3166-1 alpha-2 codes, for example `AR`, `BR`, `US`. Transfers and Disney also accept the alpha-3 code or the country name and convert it.
- Send amounts, such as `total_amount`, as JSON numbers, for example `120.00`. Do not send them as strings.
- Hotel and Disney responses carry the currency next to each price. Transfer responses have no currency field. Agree the billing currency with your account manager.
- Responses are UTF-8 JSON, with two exceptions: voucher endpoints return `application/pdf`, and some catalog endpoints return a bare JSON array (Disney and Universal `getTickets`).

## Success and error responses

A successful response is the data itself, with no wrapper such as `{"data": ...}`. Most object responses include a `request_id`. A few endpoints add `"success": true` and `"code": 200` as plain fields.

An error has an HTTP status of 400 or higher and this body:

```json
{
  "error": "Price mismatch",
  "message": "The total_amount does not match the current price. Please call getPrice again.",
  "code": 400,
  "request_id": "3f8a9b7c1d2e4f5a6b7c8d9e0f1a2b3c"
}
```

See [Errors](/developers/guides/errors) for the full list.

## Request ID

Most object responses and most error responses carry a `request_id` inside the JSON. It is not a response header. Log it on every call. It is the fastest way for support to find your request.

Some responses have no `request_id`: the catalog arrays of Disney and Universal, PDFs, the `429` response, the success bodies of Universal `ticketConfirm` and `ticketCancelation`, and a few older error shapes. When there is none, log your own `external_reference` and the order id.

## Rate limits

The default limit is 500 requests per minute per credential. Past it you receive `429` with a `Retry-After: 60` header:

```json
{
  "error": "rate_limited",
  "message": "Too many requests for this company. Try again in 60 seconds.",
  "code": 429,
  "limit": 500,
  "window": "60s"
}
```

Wait the number of seconds in `Retry-After` and repeat the same request. There are no `X-RateLimit` headers. If your volume needs a higher limit, ask your account manager.

Quote calls are the ones that tend to add up. Cache catalogs on your side and avoid asking for prices you do not show.

## Timeouts and retries

Set client timeouts that fit the call. As a starting point, use 30 seconds for reads, 60 seconds for bookings and cancellations, and 90 seconds for a hotel search in `full` mode.

| Situation | What to do |
|---|---|
| `429` | Wait `Retry-After` and repeat the request. |
| `500`, `502`, `503`, network error, timeout on a read | Retry with backoff, for example after 1, 3, 10 and 30 seconds, then stop. |
| Timeout or network error on a confirmation | Repeat it with the same `external_reference`. Never use a new one. On Hotels, see the exception in [Idempotency](#idempotency). |
| `400`, `401`, `403`, `404`, `405`, `410` | Do not retry. Fix the request or ask support. |
| `409` with `ORDER_CONFIRMATION_IN_PROGRESS` | Wait a few seconds and repeat the same reference. |

## Idempotency

Every confirmation endpoint accepts your own reference:

| Product | Endpoint |
|---|---|
| Transfers | `transferConfirm` |
| Hotels | `bookingConfirm` |
| Universal | `ticketConfirm` |
| Disney | `ticketConfirm` |

Send it in the body as `external_reference`, or in the `X-Idempotency-Key` header. If you send both, the body wins. Use a value that is unique per booking in your system, such as your order id, and keep it under 50 characters: the API stores it on the order cut to 50.

How it behaves:

- First request: the booking is created and the reference is tied to the new order.
- Same reference again, after the first one finished: you get `200` with the same order and `"idempotent_replay": true`. Nothing is booked again.
- Same reference while the first request is still running: you get `409` with `ORDER_CONFIRMATION_IN_PROGRESS`. Wait a few seconds and repeat the same reference.
- If the booking fails, for example because the supplier rejected it, the reference is released and you can repeat it.
- The reference is unique per account and per product. The same value on a transfer and on a hotel creates two separate bookings.

```json
{
  "success": true,
  "code": 200,
  "id_order": 168001,
  "pdf_voucher": "https://example.com/voucher.pdf",
  "idempotent_replay": true
}
```

Hotels: `bookingConfirm` looks up the reference before it checks the rates again. A repeat of a booking that exists returns it with `200` and `"idempotent_replay": true`, in the same shape as the first answer, even if the `rate_key` has expired since. A credential in test mode does not get this shortcut. Never repeat with another reference.

Replay details: on Universal the replayed `id_order` is a string, like on a new booking. On Disney and Hotels the replay carries the same fields as the first answer.

If you send no reference, a repeated confirmation is not protected and can create a second booking. There is no endpoint to look an order up by your reference, so send one every time.

The body field `reference` is different. It is stored with the order for your own tracking and never prevents a duplicate.

Sandbox note: transfers in sandbox ignore `external_reference`, so you can repeat the same request as many times as you need.

## Caching

Some responses are safe to cache on your side and say so with `Cache-Control: private, max-age=3600`: the transfer catalog and the hotel content endpoints. Cache them for up to one hour.

## Compression

Hotel search responses can be several megabytes. Send `Accept-Encoding: gzip` to receive them compressed. Most HTTP clients decompress automatically.

## Document language

Transfer and hotel voucher PDFs are generated in the language set on your credential: `es`, `en` or `pt`. Ask your account manager to change it. The language is stored on each booking when you confirm it, so a voucher downloaded later keeps the same language. Universal and Disney vouchers use the supplier's own format and language.

## Next

- [Errors](/developers/guides/errors) lists every error and how to react to it.
- [Sandbox](/developers/guides/sandbox) explains test credentials.
