# Get the hotel voucher

> Retrieve the confirmation voucher PDF URL of a confirmed hotel booking.

Endpoint: `GET /api/v1/hotels/get_voucher`

Source: https://fx-port.com/docs/hotels/voucher

Get the **voucher PDFs** of a hotel booking: the confirmation to hand to the traveler, with the price for you and without it for the traveler. Only the agency that owns the booking can read its voucher.

**Permission:** Read

## Request

`GET /api/v1/hotels/get_voucher`

| Parameter | Type | Required | Description |
|---|---|---|---|
| `booking_id` | string | Yes | The `bookingId` of [`book_hotel`](https://fx-port.com/docs/hotels/book.md). |


**Request**

```bash
curl 'https://api.fx-port.com/api/v1/hotels/get_voucher?booking_id=HMVXX4ZQ3' \
  -H "Authorization: Bearer fxp_test_YOUR_KEY"
```


### Legacy names

These older spellings still work. The answer carries a `deprecated_field` warning that names the spelling to use (see [Legacy names](https://fx-port.com/docs/legacy-names.md)).

| Older name | Use instead |
|---|---|
| `partner_order_id`, `partnerOrderId`, `bookingId` | `booking_id` |

## Response

A real answer of the sandbox (the links are replaced):

~~~json
{
  "environment": "sandbox",
  "success": true,
  "data": {
    "bookingId": "HMVXX4ZQ3",
    "voucherUrl": "https://files.example.com/hotel-bookings/HMVXX4ZQ3-Jane-Smith.pdf",
    "voucherUrlWithPrice": "https://files.example.com/hotel-bookings/HMVXX4ZQ3-Jane-Smith.pdf",
    "voucherUrlNoPrice": "https://files.example.com/hotel-bookings/HMVXX4ZQ3-Jane-Smith-no-price.pdf",
    "status": "confirmed"
  }
}
~~~

| Field | Description |
|---|---|
| `data.bookingId` | The booking. Also as `booking_id`. |
| `data.voucherUrl`, `data.voucherUrlWithPrice` | **The same link**: the voucher PDF with the price. For your own records. Also as `voucher_url` and `voucher_url_with_price`. |
| `data.voucherUrlNoPrice` | The voucher PDF **without the price**: hand this one to the traveler, so that they do not see what was paid. Also as `voucher_url_no_price`. |
| `data.status` | The status of the booking. |

Both variants are made for every confirmed booking. The same links are in the answer of the [booking detail](https://fx-port.com/docs/hotels/get-booking.md) (`voucherUrl`, `voucherUrlNoPrice`): use whichever call fits your flow, `get_voucher` is the lighter one when you only need the link.

## When the voucher exists

The voucher is made **after the booking is `confirmed`**: at the same moment, or up to about 10 seconds later. Before that the call answers `404` with the code `pdf_not_found`. So:

1. Poll [the booking](https://fx-port.com/docs/hotels/get-booking.md) until it is `confirmed`.
2. Ask for the voucher; on `404 pdf_not_found`, wait 2 seconds and ask again, up to about 10 times.

- A booking that is still `pending` has no voucher.
- **The links stay after a cancellation**: the voucher of a cancelled booking is still returned, so do not hand it out again.

## The links are public

The links are **permanent public addresses with no signature and no expiry**: anyone who has one can open the voucher, without a key. The file name is `<booking id>-<first name>-<last name>.pdf`, so it **contains the name of the first guest**.

- Do not log them, post them in a ticket or send them to anybody who is not the traveler or your own staff.
- Give the traveler `voucherUrlNoPrice`; keep `voucherUrl` for your agency.
- Fetch the link again from this call when you need it rather than storing it in many places.

## Errors

| HTTP | Code | Cause |
|---|---|---|
| `404` | `booking_not_found` | No booking has this id. |
| `404` | `pdf_not_found` | The booking exists and its voucher is not made yet (`The voucher is not available yet ...`). Try again in 2 seconds. |
| `403` | `forbidden` | The booking belongs to another agency. |
| `400` | `invalid_booking_id` | `booking_id` is not 1 to 256 characters: letters, digits and `_ . : -`. |
| `422` | `validation_error` | `booking_id` is missing. |
| `503` | `service_overloaded` | The service is overloaded for a moment (the database pool is full). Nothing was read: retry after the seconds in `Retry-After`. |
| `401`, `403` | | The key is missing, wrong or not allowed: [Authentication](https://fx-port.com/docs/authentication.md). |
| `429` | `rate_limit_exceeded` | Too many calls: [Rate limits](https://fx-port.com/docs/rate-limits.md). |

## Related


- [Get a hotel booking](https://fx-port.com/docs/hotels/get-booking.md): The status, the price and the same links.
- [Book a hotel](https://fx-port.com/docs/hotels/book.md): How a booking becomes `confirmed`.
- [API reference: Get the voucher PDF links of a booking](https://fx-port.com/docs/api/get-hotel-voucher.md): Every field and error.
