Reservation Handoff with Signed Tokens
Enable your travelers to seamlessly transfer their booked flights, hotels, tours, and activities into Trips52’s AI itinerary builder using secure, cryptographically signed URL tokens.
Integrated partners can also be credited as affiliates, earning commission whenever your imported travelers purchase AI itinerary credits or upgrades.
Zero Server-to-Server Sync
No complex webhooks or polling APIs needed at click time. Everything is packed in a tamper-proof URL.
Cryptographic Security
HMAC-SHA256 signatures ensure reservation details cannot be forged or altered in transit.
Replay Protected
Each unique token ID (jti) is strictly single-use and guarded by short TTL expiry windows.
Auto Google Places AI
Trips52 enriches hotel addresses, coordinates, and attraction details automatically upon import.
How the Integration Works
Customer Books
Traveler completes flight, hotel, or tour booking on your platform.
Sign Payload
Your backend creates a JSON payload and signs it using your private secret.
Redirect Traveler
Send traveler to trips52.com/import?token=<JWT> in a single click.
Instant Itinerary
Trips52 validates the token, enriches locations, and builds their personalized trip.
Partner Registration & Credentials
Before issuing import tokens, your organization must be registered in the Trips52 Partner Registry.
Contact our partnerships team at partners@trips52.com with your company name, technical lead email, and expected traffic volume.
Our team will review your application and create your partner record.
You will receive two configuration values securely:
- Partner ID (slug): e.g.
expedia_main - Secret Key: A 256-bit cryptographically secure hexadecimal string
By default, links have a maximum lifespan of 15 minutes. If your handoff flow requires longer windows (up to 60 minutes), inform our team during setup.
Payload Parameters & Specification
All data is encapsulated in the JWT claims and the structured reservation payload.
1. Top-Level JWT Claims
| Field | Type | Requirement | Description |
|---|---|---|---|
| alg | string | Mandatory | Must be "HS256" in JWT header. |
| partnerId | string | Mandatory | Your unique slug issued upon registration (e.g. "expedia_main"). |
| jti | string | Mandatory | Unique token ID (UUID v4) for single-use replay protection. |
| iat | number | Mandatory | Issued-at Unix timestamp in seconds (e.g. Math.floor(Date.now() / 1000)). |
| exp | number | Mandatory | Expiration Unix timestamp in seconds. Must be <= maxTokenTtlMinutes. |
| reservation | object | Mandatory | The structured trip and bookings object. |
2. Reservation Object (`payload.reservation`)
| Field | Type | Requirement | Description |
|---|---|---|---|
| tripTitle | string | Optional | Custom title for the imported trip (e.g. "Family Vacation in Rome"). |
| destinationCity | string | Optional | Primary destination city (e.g. "Rome"). |
| destinationCountry | string | Optional | Destination country (e.g. "Italy"). |
| startDate | string | Optional | Trip start date formatted as YYYY-MM-DD (e.g. "2026-09-10"). |
| endDate | string | Optional | Trip end date formatted as YYYY-MM-DD (e.g. "2026-09-16"). |
| destinationPlaceId | string | Optional | Google Place ID if known for auto-location resolution. |
| flights | array | Optional | List of flight objects (defaults to []). |
| hotels | array | Optional | List of hotel objects (defaults to []). |
| activities | array | Optional | List of tour/activity objects (defaults to []). |
| transportation | array | Optional | List of car rental or transit objects (defaults to []). |
3. Hotels Array (`reservation.hotels[]`)
| Field | Type | Requirement | Description |
|---|---|---|---|
| hotelName | string | Mandatory | Name of the accommodation (e.g. "Hotel Artemide"). |
| destination | string | Optional | City / locality (e.g. "Rome"). |
| address | string | Optional | Physical street address. Auto-enriched by Google Places AI if omitted. |
| checkInDate | string | Optional | Check-in date formatted as YYYY-MM-DD. |
| checkOutDate | string | Optional | Check-out date formatted as YYYY-MM-DD. |
| confirmationCode | string | Optional | Hotel booking reference code. |
| bookingUrl | string | Optional | URL where user can manage their booking on your platform. |
4. Flights Array (`reservation.flights[]`)
| Field | Type | Requirement | Description |
|---|---|---|---|
| airline | string | Optional | Carrier name (e.g. "ITA Airways", "Delta"). |
| flightNumber | string | Optional | Flight code (e.g. "AZ609"). |
| departureAirport | string | Optional | 3-letter IATA departure airport code (e.g. "JFK"). |
| arrivalAirport | string | Optional | 3-letter IATA arrival airport code (e.g. "FCO"). |
| departureTime | string | Optional | ISO 8601 timestamp (e.g. "2026-09-10T17:30:00Z"). |
| arrivalTime | string | Optional | ISO 8601 timestamp (e.g. "2026-09-11T07:45:00Z"). |
| confirmationCode | string | Optional | Flight PNR or booking code. |
5. Activities Array (`reservation.activities[]`)
| Field | Type | Requirement | Description |
|---|---|---|---|
| title | string | Mandatory | Name of the activity (e.g. "Colosseum Guided Tour"). |
| type | string | Optional | "tour" | "attraction" | "restaurant" | "event" (default: "attraction"). |
| dateTime | string | Optional | ISO 8601 datetime for the activity. |
| durationMinutes | number | Optional | Expected duration in minutes (e.g. 180). |
| placeName | string | Optional | Venue or meeting point name. |
| confirmationCode | string | Optional | Activity voucher reference. |
Example Payload & Token Generation
Ready-to-use code snippets in the most popular backend languages to generate and sign your reservation URLs.
npm i jsonwebtokenimport jwt from 'jsonwebtoken';
import { randomUUID } from 'crypto';
// 1. Your partner credentials provided by Trips52
const PARTNER_ID = 'your_partner_slug';
const PARTNER_SECRET = 'your_256_bit_secret_hex';
// 2. Build the reservation payload
const nowInSeconds = Math.floor(Date.now() / 1000);
const payload = {
partnerId: PARTNER_ID,
jti: randomUUID(), // Unique token ID for replay protection
iat: nowInSeconds,
exp: nowInSeconds + 15 * 60, // 15 minutes lifetime (max 60m)
reservation: {
tripTitle: 'Trip to Rome & Florence',
destinationCity: 'Rome',
destinationCountry: 'Italy',
startDate: '2026-09-10',
endDate: '2026-09-16',
flights: [
{
airline: 'ITA Airways',
flightNumber: 'AZ609',
departureAirport: 'JFK',
arrivalAirport: 'FCO',
departureTime: '2026-09-10T17:30:00Z',
arrivalTime: '2026-09-11T07:45:00Z',
confirmationCode: 'ITA-98721',
},
],
hotels: [
{
hotelName: 'Hotel Artemide',
destination: 'Rome',
checkInDate: '2026-09-11',
checkOutDate: '2026-09-16',
confirmationCode: 'HTL-88231',
bookingUrl: 'https://partner.com/bookings/HTL-88231',
},
],
activities: [
{
title: 'Colosseum & Ancient Rome VIP Tour',
type: 'tour',
dateTime: '2026-09-12T09:30:00Z',
durationMinutes: 180,
confirmationCode: 'ACT-55412',
},
],
},
};
// 3. Sign the JWT with HMAC-SHA256 (HS256)
const token = jwt.sign(payload, PARTNER_SECRET, { algorithm: 'HS256' });
// 4. Redirect traveler to Trips52
const redirectUrl = `https://trips52.com/import?token=${token}`;
console.log('Redirect user to:', redirectUrl);Testing & Error Reference
How to test your generated tokens and handle all possible response states gracefully.
1. Admin Sandbox Tester
Trips52 administrators can test your integration via the Admin Portal at /admin/partners:
- Click "Sandbox Tester" next to your partner record.
- Generates a signed URL with your actual secret key.
- Opens the live import UI to verify end-to-end trip hydration.
2. Direct API Verification
Your backend can test raw tokens by sending a POST request directly to:
Body: {"token":"<SIGNED_JWT>"}
Error Codes Reference
When verification fails, the endpoint returns HTTP 400 or 429 with { success: false, code: "...", message: "..." }.
| Error Code | Status | Reason & Resolution |
|---|---|---|
| MISSING_TOKEN | 400 | No token found in query parameter or request body. |
| INVALID_HEADER | 400 | Unsupported algorithm (only HS256 is accepted). |
| INVALID_SIGNATURE | 400 | Signature check failed. Secret key mismatch or tampered payload. |
| PARTNER_NOT_FOUND | 400 | The partnerId claim does not match any registered partner. |
| PARTNER_SUSPENDED | 400 | Partner account is currently disabled or suspended. |
| TOKEN_EXPIRED | 400 | The "exp" timestamp has passed. |
| TOKEN_LIFESPAN_TOO_LONG | 400 | exp - iat exceeds the partner's max allowed TTL (default 15m). |
| TOKEN_ALREADY_USED | 400 | Replay protection caught a reused "jti" token ID. |
| INVALID_PAYLOAD | 400 | Missing mandatory fields (e.g. jti, iat, hotelName, activity title). |
| RATE_LIMIT_EXCEEDED | 429 | Exceeded 20 verification requests per minute per IP. |
| SERVER_ERROR | 500 | Internal error processing the token. |
Frequently Asked Questions
Common architectural and implementation questions from our integration partners.
Yes! All sub-arrays (flights, hotels, activities, transportation) are completely optional. You can send a single flight booking, a 3-night hotel reservation, or a full multi-city vacation package.
Trips52 verifies the token immediately upon landing. If the traveler is not logged in, the app securely holds the verified reservation in session and presents an authentication prompt. Once authenticated, the trip is saved directly to their account.
If you only provide the hotelName and destination (e.g. "Hotel Artemide", "Rome"), Trips52's Google Places AI automatically enriches the precise street address, placeId, and latitude/longitude coordinates.
Trips52 caches verified tokens in the active browser session during the import handoff. However, opening the raw signed link in a brand-new tab after it was already consumed will trigger TOKEN_ALREADY_USED for security.
Yes. Since tokens are signed on demand by your backend, you can generate a fresh token with a new "jti" and updated "iat"/"exp" whenever a customer requests their itinerary handoff link.
No. For privacy and compliance reasons, do not include credit card details, passport numbers, billing addresses, or traveler identification. Only send trip dates, destination names, confirmation codes, and booking URLs.
We strongly recommend 15 minutes. This provides plenty of time for the traveler to complete the redirect while ensuring leaked or shared URLs cannot be exploited long after the booking.
Contact support@trips52.com or your dedicated account manager. We can rotate your secret key seamlessly without interrupting active user traffic.
Need Technical Assistance?
Our developer partnerships team is here to assist with payload schema customization, secret provisioning, and sandbox testing.