Travel To Discover

Loading documentation…

3. API Reference

Export .md

OrderVoucher

POST /api/trade/orderVoucher

Retrieves the hotel voucher for an order you placed — the travel document your guest presents at the hotel desk.

The voucher is produced by the platform when the supplier confirms the booking, so it is not available the instant Book returns. This endpoint always reports a status; the voucher block is present only when that status is GENERATED. A booking that is genuinely yours but whose voucher has not been issued yet is a 200 with status: NOT_GENERATED, not an error — poll it the same way you poll QueryOrders.

Identifying the order

Supply at least one of customerReferenceNo (your own reference, sent on Book), platformReferenceNo (our order number) or supplierReferenceNo. If a reference matches more than one order the call is refused with 100001008 rather than guessing — supply platformReferenceNo, which is unique.

Getting the bytes

voucher.downloadUrl is a time-limited object URL; voucher.expiresIn is how many seconds it remains valid. Set includeDocument: true to receive the PDF inline as base64 in voucher.content instead of following the link — intended for integrations that cannot reach an object-storage URL from where they run. Documents above 8 MB are never inlined; that request is refused with 100001005.

Checking the document is the one we issued

Every voucher is signed at the moment it is rendered. voucher.signature.digest is the SHA-256 of the exact bytes we issued, in lowercase hex. Hash whatever you received and compare — if the two differ, the file has been altered since issue and must not be given to a traveller. signature.signature is a detached HMAC only we can verify; it is returned so the claim is auditable, not so you can check it yourself. A voucher rendered before document signing was introduced has no signature block at all, rather than a fabricated one.

voucher.verifyUrl is the same public verification page the voucher's QR code opens, which reports whether the document is still valid and whether it is unaltered.

Access

The calling key must be scoped booking:read, and the order must belong to you. An order that is not yours answers 100000404 not found — the same answer as a reference that never existed, so the endpoint cannot be used to probe another seller's order book.

Status values

  • GENERATED — issued and current; voucher is present.
  • NOT_GENERATED — no voucher has been issued for this order yet.
  • PENDING — a voucher number is reserved and the document is being produced.
  • FAILED — generation was attempted and did not complete; contact support.
  • CANCELLED — the booking is cancelled. The document is deliberately withheld: a reissued voucher for a cancelled stay is stamped "not valid for check-in" and must not be handed to a traveller by an automated pipeline.

Request headers

Header Required Description
Client-Request-Timestamp No Client-side send time for this request, expressed as a unix timestamp.
IP No Caller IP address; both IPv4 and IPv6 are accepted.
Language No IETF BCP 47 language tag (see https://masonreview.com/posts/ietf-bcp-47-language-tags/), for example "en" or "en-US". Falls back to "en-US" when omitted.
Market No Point-of-sale market for this call, as an ISO 3166-1 alpha-2 country code. Required only when your account carries a market restriction: an allow-list cannot admit a market you have not stated, so such an account refuses calls that omit it.
Request-Id No Identifier for this individual request; values must not repeat.
Trace-Id No Identifier used to correlate a group of related requests.
User-Ref No Your own identifier for the person on whose behalf this call is made. Required only once named users have been authorised on your account, after which every call must identify one and is authorised against that user's scopes as well as the key's.
Authorization Yes Bearer credential — the value must be prefixed with "Bearer ". Obtain the token from the Ticket response. The Ticket call itself does not require this header.

Request body

Field Type Required Description
customerReferenceNo string No Your own reference, as sent on Book.
platformReferenceNo string No Our order number, as returned by Book and QueryOrders.
supplierReferenceNo string No The supplier's reference, as returned by Book.
includeDocument boolean No Return the PDF inline as base64 in voucher.content as well as the link. Refused with 100001005 for documents above 8 MB.

Example request

json
{
  "customerReferenceNo": "9d1f4b2a-7c60-4f3e-9a58-1b0c2d3e4f50"
}

Response

Successful calls return the standard envelope. code is 0 on success — check it rather than the HTTP status alone, because some business failures are delivered with HTTP 200.

Field Type Required Description
code integer No
msg string No
data hotel.trade.protocol.OrderVoucherResp No
data.customerReferenceNo string No
data.platformReferenceNo string Yes
data.supplierReferenceNo string No
data.status enum Yes GENERATED is the only status that carries a document. CANCELLED withholds it deliberately: a reissued voucher for a cancelled stay is stamped "not valid for check-in". Allowed: GENERATED, NOT_GENERATED, PENDING, FAILED, CANCELLED.
data.voucher OrderVoucherDocument No Present only when status is GENERATED.
data.voucher.voucherNumber string Yes
data.voucher.version integer Yes 1-based. A regenerated voucher supersedes the previous version.
data.voucher.issuedAt string Yes
data.voucher.contentType string Yes
data.voucher.byteSize integer Yes
data.voucher.verifyUrl string Yes The public verification page this voucher's QR code opens.
data.voucher.downloadUrl string Yes Time-limited object URL for the PDF.
data.voucher.expiresIn integer Yes Seconds downloadUrl remains valid.
data.voucher.signature DocumentSignature No Absent for a voucher rendered before document signing was introduced. Omitted rather than fabricated.
data.voucher.signature.alg string Yes
data.voucher.signature.keyId string Yes Which platform key signed it.
data.voucher.signature.digest string Yes Lowercase hex SHA-256 of the document bytes, as issued.
data.voucher.signature.signature string Yes The detached signature over the manifest.
data.voucher.signature.signedAt string Yes
data.voucher.content object No Present only when includeDocument was requested.
data.voucher.content.contentType string Yes
data.voucher.content.byteSize integer Yes
data.voucher.content.base64 string Yes

Example response

json
{
  "code": 0,
  "msg": "string",
  "data": {
    "customerReferenceNo": "string",
    "platformReferenceNo": "string",
    "supplierReferenceNo": "string",
    "status": "GENERATED",
    "voucher": {
      "voucherNumber": "VCH-TTD-2026-000042-01",
      "version": 0,
      "issuedAt": "string",
      "contentType": "application/pdf",
      "byteSize": 0,
      "verifyUrl": "string",
      "downloadUrl": "string",
      "expiresIn": 0,
      "signature": {
        "alg": "HMAC-SHA256",
        "keyId": "ttd-derived-v1",
        "digest": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
        "signature": "string",
        "signedAt": "string"
      },
      "content": {
        "contentType": "string",
        "byteSize": 0,
        "base64": "string"
      }
    }
  }
}

Failure responses

HTTP Meaning
400 Bad Request
401 Unauthorized
403 Forbidden — this key is not scoped for booking:read
404 Order not found, or not yours
429 Too Many Requests

Every failure uses the { code, msg } envelope. See Error handling for the full business-code table.

Code samples

bash
curl -X POST https://api-test.ttdbooking.com/api/trade/orderVoucher \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TICKET" \
  -H "Request-Id: $(uuidgen)" \
  -d '{
    "customerReferenceNo": "9d1f4b2a-7c60-4f3e-9a58-1b0c2d3e4f50"
  }'

Try it

Try it

POST /api/trade/orderVoucher
A ticket will be fetched with ttdbooking_api_demo.