Skip to content
Developers

Save to Mobile Itinerary

Link reference

What the button's link carries. One Base64url-encoded parameter holds your referral ID and one booking, a flight or a hotel stay.

The link

The link has a single query parameter, t. Its value is your JSON note encoded in Base64url, and everything travels in it, including your referral ID.

Link
https://app.voyani.com/ota/open?t={BASE64_PAYLOAD}
ParameterValueMeaning
t{BASE64_PAYLOAD}Your referral ID and the booking, as one JSON note encoded in Base64url.

How you build t

t is Base64url-encoded JSON. You produce its value in three steps.

  1. Write the booking note. For each booking, build the JSON on this page: the schema version, your referral ID, the booking reference and type, the time of the tap, and the booking itself.
  2. Base64url-encode it. Encode the note's UTF-8 bytes as Base64, then make it URL-safe: + becomes -, / becomes _, and trailing = signs are dropped. Standard Base64 with = padding is accepted too.
  3. Pass the result as t. Put the encoded value in the link as the single query parameter t. The button and the email both use that one value.

Worked example

The minimum hotel payload, from note to link.

1. Note, on one line
{"v":1,"partnerReferralId":"OTA-7K3QZ9M2XA","bookingReference":"HX88213","bookingType":"hotel","referredAt":"2026-11-06T09:00:00Z","destination":{"city":"Lisbon","countryCode":"PT"},"hotel":{"name":"Example Lisbon Hotel","checkInLocal":"2026-12-11T15:00:00","checkOutLocal":"2026-12-17T11:00:00"}}
2. t, the note in Base64url
eyJ2IjoxLCJwYXJ0bmVyUmVmZXJyYWxJZCI6Ik9UQS03SzNRWjlNMlhBIiwiYm9va2luZ1JlZmVyZW5jZSI6IkhYODgyMTMiLCJib29raW5nVHlwZSI6ImhvdGVsIiwicmVmZXJyZWRBdCI6IjIwMjYtMTEtMDZUMDk6MDA6MDBaIiwiZGVzdGluYXRpb24iOnsiY2l0eSI6Ikxpc2JvbiIsImNvdW50cnlDb2RlIjoiUFQifSwiaG90ZWwiOnsibmFtZSI6IkV4YW1wbGUgTGlzYm9uIEhvdGVsIiwiY2hlY2tJbkxvY2FsIjoiMjAyNi0xMi0xMVQxNTowMDowMCIsImNoZWNrT3V0TG9jYWwiOiIyMDI2LTEyLTE3VDExOjAwOjAwIn19
3. Link
https://app.voyani.com/ota/open?t=eyJ2IjoxLCJwYXJ0bmVyUmVmZXJyYWxJZCI6Ik9UQS03SzNRWjlNMlhBIiwiYm9va2luZ1JlZmVyZW5jZSI6IkhYODgyMTMiLCJib29raW5nVHlwZSI6ImhvdGVsIiwicmVmZXJyZWRBdCI6IjIwMjYtMTEtMDZUMDk6MDA6MDBaIiwiZGVzdGluYXRpb24iOnsiY2l0eSI6Ikxpc2JvbiIsImNvdW50cnlDb2RlIjoiUFQifSwiaG90ZWwiOnsibmFtZSI6IkV4YW1wbGUgTGlzYm9uIEhvdGVsIiwiY2hlY2tJbkxvY2FsIjoiMjAyNi0xMi0xMVQxNTowMDowMCIsImNoZWNrT3V0TG9jYWwiOiIyMDI2LTEyLTE3VDExOjAwOjAwIn19

Booking types

bookingType tells Voyani what you booked: flight with flightSegments, or hotel with hotel. One link carries one booking, and both types share the same required fields and rules.

Flight payload

Draft spec

One flight booking and its segments, with bookingType set to flight.

Flight payload, before encoding
{
  "v": 1,
  "partnerReferralId": "OTA-7K3QZ9M2XA",
  "bookingReference": "AB12CD",
  "bookingType": "flight",
  "referredAt": "2026-10-24T14:22:10Z",
  "destination": {
    "city": "Lisbon",
    "countryCode": "PT",
    "airportCode": "LIS"
  },
  "flightSegments": [
    {
      "carrier": "TP",
      "flightNumber": "204",
      "originIata": "JFK",
      "destinationIata": "LIS",
      "departsAtLocal": "2026-12-10T19:05:00",
      "arrivesAtLocal": "2026-12-11T07:00:00",
      "isReturn": false
    },
    {
      "carrier": "TP",
      "flightNumber": "209",
      "originIata": "LIS",
      "destinationIata": "JFK",
      "departsAtLocal": "2026-12-17T11:30:00",
      "arrivesAtLocal": "2026-12-17T14:45:00",
      "isReturn": true
    }
  ]
}
FieldFormatRequiredPurpose
vInteger, 1YesSchema version, so later changes don't break live links.
partnerReferralIdOTA- + 10 charactersYesYour OTA Partner Referral ID. Voyani resolves the partner from it.
bookingReferenceTextYesYour confirmation reference. With partnerReferralId it is the dedupe key, and the app shows it on the booking.
bookingTypeflight or hotelYesWhich booking this link carries, and so which of flightSegments or hotel Voyani reads.
referredAtISO-8601 with offset, e.g. ZYesWhen the traveler tapped the button. Voyani keeps it as the record of their consent.
totalAmount, currencyDecimal; ISO 4217 codeOptionalWhat the traveler paid you. Without currency Voyani uses your partner payment currency, and a missing amount is shown as incomplete.
destination.city, countryCode, airportCodeText; country code; IATA codeRecommendedThe trip destination. The city is the only booking detail shown before the traveler signs in.
traveler.firstName, lastName, email, phoneTextOptionalOnly as your consent and integration allow. The email lets Voyani prepare the traveler's account before they sign in.
support.displayName, phone, email, urlTextOptionalYour traveler support for this booking. Your OTA Partner Profile's support details take priority.
flightSegments[]ArrayRecommended, 1 or moreEach segment becomes part of the trip, its Timeline and its Wallet item.
flightSegments[].carrierIATA, 2 charactersRecommendedThe airline that sold the flight.
flightSegments[].flightNumberTextRecommendedFlight number. With the carrier it titles the booking, for example TP 204 JFK-LIS.
flightSegments[].originIata, destinationIataIATA airport codeOptionalWhere the segment departs and lands.
flightSegments[].departsAtLocal, arrivesAtLocalLocal ISO-8601, no offsetRecommendedLocal time at each airport, as you sold it. Voyani does not convert it.
flightSegments[].isReturntrue or falseOptionaltrue for a leg of the return journey. Defaults to false.
flightSegments[].operatingCarrierIATA, 2 charactersOptionalThe airline operating a codeshare sold under carrier.
flightSegments[].seat, cabinClassTextOptionalShown on the Timeline entry.
  • Recommended fields never block the link. When the outbound segment lacks one, the booking is created and shown as incomplete.
  • One-way trips are valid: send only the outbound segments.

Hotel payload

Draft spec

One hotel stay, with bookingType set to hotel.

Hotel payload, before encoding
{
  "v": 1,
  "partnerReferralId": "OTA-7K3QZ9M2XA",
  "bookingReference": "HX88213",
  "bookingType": "hotel",
  "referredAt": "2026-11-06T09:00:00Z",
  "destination": {
    "city": "Lisbon",
    "countryCode": "PT"
  },
  "hotel": {
    "name": "Example Lisbon Hotel",
    "checkInLocal": "2026-12-11T15:00:00",
    "checkOutLocal": "2026-12-17T11:00:00"
  }
}
Hotel payload with optional details
{
  "v": 1,
  "partnerReferralId": "OTA-7K3QZ9M2XA",
  "bookingReference": "HX88213",
  "bookingType": "hotel",
  "referredAt": "2026-11-06T09:00:00Z",
  "destination": {
    "city": "Lisbon",
    "countryCode": "PT"
  },
  "hotel": {
    "name": "Example Lisbon Hotel",
    "checkInLocal": "2026-12-11T15:00:00",
    "checkOutLocal": "2026-12-17T11:00:00",
    "address": "10 Example Street, Lisbon",
    "roomDescription": "Double room, city view"
  },
  "totalAmount": 1240.5,
  "currency": "EUR",
  "traveler": {
    "firstName": "Ana",
    "lastName": "Silva",
    "email": "ana.silva@example.com",
    "phone": "+351910000000"
  },
  "support": {
    "displayName": "Example Travel support",
    "phone": "+18005550100",
    "email": "help@example-travel.com",
    "url": "https://example-travel.com/help"
  }
}
FieldFormatRequiredPurpose
vInteger, 1YesSchema version, so later changes don't break live links.
partnerReferralIdOTA- + 10 charactersYesYour OTA Partner Referral ID. Voyani resolves the partner from it.
bookingReferenceTextYesYour confirmation reference. With partnerReferralId it is the dedupe key, and the app shows it on the booking.
bookingTypeflight or hotelYesWhich booking this link carries, and so which of flightSegments or hotel Voyani reads.
referredAtISO-8601 with offset, e.g. ZYesWhen the traveler tapped the button. Voyani keeps it as the record of their consent.
totalAmount, currencyDecimal; ISO 4217 codeOptionalWhat the traveler paid you. Without currency Voyani uses your partner payment currency, and a missing amount is shown as incomplete.
destination.city, countryCode, airportCodeText; country code; IATA codeRecommendedThe trip destination. The city is the only booking detail shown before the traveler signs in.
traveler.firstName, lastName, email, phoneTextOptionalOnly as your consent and integration allow. The email lets Voyani prepare the traveler's account before they sign in.
support.displayName, phone, email, urlTextOptionalYour traveler support for this booking. Your OTA Partner Profile's support details take priority.
hotelObject, one per linkRecommendedThe stay. It becomes a Timeline entry and a Wallet item.
hotel.nameTextRecommendedProperty name. It titles the booking on the Timeline and in the Wallet.
hotel.checkInLocal, checkOutLocalLocal ISO-8601, no offsetRecommendedStart and end of the stay, in the hotel's local time. The last check-out ends the trip.
hotel.addressTextOptionalA precise location for the map.
hotel.roomDescriptionTextOptionalRoom type, shown on the booking.
  • Recommended fields never block the link. A missing name or date creates the booking and shows it as incomplete. Voyani fills nothing in.
  • One link carries one hotel. Send a separate link for each stay.

Not in the link

The payload has no field for these. Don't add them.

ItemWhere Voyani gets it
Rate plan, loyalty numbers, payment detailsNot carried. The payload has no field for them.
Special requests and free-text notesNot carried. Free text can contain personal details.
Partner UUIDResolved by Voyani from partnerReferralId.
Consent flagVoyani records the tap from referredAt.

How Voyani handles the link

  • Known fields only. Fields outside this specification are ignored.
  • One booking per reference. partnerReferralId plus bookingReference is the dedupe key. Reopening the link, or opening it on another device, never creates a second account, trip or booking.
  • Missing or malformed data. Without one of the five required fields the link is refused. Anything else missing still creates the records it can, shown as incomplete. Voyani never invents a value.
  • Before login. The traveler sees the destination city only. Booking details appear after they sign in and the booking is bound to their account.
  • Binding. The first verified account binds the booking. A different account cannot claim it afterward.

Before you go live

  • HTTPS only. It is a universal link, so the app, mobile web and desktop all keep your referral.
  • Keep t at 1,500 characters or fewer. Longer values are refused.
  • The link stays valid until 10 days after the trip ends, meaning the last flight arrival or the hotel check-out, unless Voyani revokes it.
  • Build t as the Base64url-encoded JSON note, one booking per link.