Integrate Travel Line group flights and bookings directly into your platform. Search published flights, create bookings programmatically, and manage your travel business at scale — all via a simple REST API.
Authenticate every request with a long-lived API key issued by your account manager.
Default 60 requests/minute per key. Headers tell you exactly how many you have left.
Keys carry read and/or write scopes. Only endpoints matching your scope are accessible.
https://api.travellinetour.com/v1/external
Every request must include your API key as a Bearer token in the Authorization header. Contact your Travel Line account manager to obtain a key.
Authorization: Bearer sk_live_<your_32_char_hex_key>
Reset is a Unix timestamp (UTC). Retry after it passes.
/pingUse this endpoint to confirm your API key is valid and the service is reachable. Returns your stakeholder ID. Requires no specific scope.
curl -X GET "https://api.travellinetour.com/v1/external/ping" \ -H "Authorization: Bearer sk_live_<YOUR_KEY>"
{
"message": "pong",
"stakeholderId": "64a1f2e3c4b5d6e7f8a9b0c1"
}/groupsscope: readReturns all published group flights with available seats. Without filters, returns all groups paginated. Use departure/arrival to search specific routes, or category to filter by trip type (e.g. umrah).
| Name | Type | Required | Description |
|---|---|---|---|
| departure | string | optional | Origin airport IATA code (e.g. KHI, ISB, LHE) |
| arrival | string | optional | Destination airport IATA code (e.g. JED, MED, DXB) |
| departureDateFrom | YYYY-MM-DD | optional | Earliest departure date (inclusive) |
| departureDateTo | YYYY-MM-DD | optional | Latest departure date (inclusive) |
| category | string | optional | Trip category — e.g. umrah, hajj, international |
| page | number | optional | Page number (default: 1) |
| limit | number | optional | Results per page (default: 10, max: 50) |
# All published groups (paginated) curl -X GET "https://api.travellinetour.com/v1/external/groups" \ -H "Authorization: Bearer sk_live_<YOUR_KEY>" # Filter by route & date curl -X GET "https://api.travellinetour.com/v1/external/groups?departure=KHI&arrival=JED&departureDateFrom=2026-09-01" \ -H "Authorization: Bearer sk_live_<YOUR_KEY>" # Filter by category curl -X GET "https://api.travellinetour.com/v1/external/groups?category=umrah&page=1&limit=10" \ -H "Authorization: Bearer sk_live_<YOUR_KEY>"
{
"flights": [
{
"_id": "69c76eaab82eac9a5beabb8b",
"availableSeats": 3,
"fares": {
"salePrice": 85500,
"currencyCode": "RS",
"baggage": {
"cabinBag": 0,
"checkedBag": 0,
"maxWeight": "23+7"
},
"discount": 0,
"refundable": "no",
"changeFeeApplicable": "no",
"discountPercentage": null,
"regularPrice": 85500
},
"groupCategory": "K S A Oneway Groups",
"groupPnr": "8ZT29Z",
"itineraries": [
{
"duration": "2h 45mins",
"segments": [
{
"flightNumber": "SV 801",
"airline": {
"carrierCode": "SV",
"carrierName": "Saudia Airline",
"logo": "https://storage.googleapis.com/sub-agents-logo/airline-logos/sv.png"
},
"departure": {
"airport": {
"_id": "679ee25ba43c79b7a887d93e",
"iataCode": "MUX",
"name": "Multan International Airport",
"city": "Multan",
"country": "Pakistan",
"timezone": "Asia/Karachi"
},
"terminal": "",
"gate": "",
"datetime": "2026-04-05T16:45:00"
},
"arrival": {
"airport": {
"_id": "679ee25ba43c79b7a887d946",
"iataCode": "JED",
"name": "King Abdulaziz International Airport",
"city": "Jeddah",
"country": "Saudi Arabia",
"timezone": "Asia/Riyadh"
},
"terminal": "",
"gate": "",
"datetime": "2026-04-05T19:30:00"
},
"aircraft": {
"type": "Airbus",
"registration": ""
},
"duration": "",
"status": "SCHEDULED",
"stops": [],
"meal": "Yes"
}
],
"stops": []
}
],
"spreadSheetId": "",
"status": "published",
"updated_at": "2026-04-02T16:57:04.144Z",
"vendorCode": "C",
"vendorPriceId": 20598
}
],
"pagination": {
"currentPage": null,
"totalPages": null,
"limit": null,
"total": 283
}
}/groups/:idscope: readReturns full details for a single flight group, including live seat availability refreshed from the vendor (TNT, Al-Haider, FSD Millat, NCT, or Google Sheet) when applicable. Private admin-only pricing fields (basePrice, tax, totalBasePrice, discountPercentage, regularPrice, fixedMarkup) and vendor identifiers (vendor, vendorCode, vendorGroupId, vendorId) are stripped from the response.
| Name | Type | Required | Description |
|---|---|---|---|
| id | string (ObjectId) | required | ID of the flight group to fetch (path parameter) |
curl -X GET "https://api.travellinetour.com/v1/external/groups/69c76eaab82eac9a5beabb8b" \ -H "Authorization: Bearer sk_live_<YOUR_KEY>"
{
"_id": "69c76eaab82eac9a5beabb8b",
"availableSeats": 3,
"fares": {
"salePrice": 85500,
"currencyCode": "RS",
"baggage": {
"cabinBag": 0,
"checkedBag": 0,
"maxWeight": "23+7"
},
"discount": 0,
"refundable": "no",
"changeFeeApplicable": "no"
},
"groupCategory": "K S A Oneway Groups",
"groupPnr": "8ZT29Z",
"itineraries": [
{
"duration": "2h 45mins",
"segments": [
{
"flightNumber": "SV 801",
"airline": {
"carrierCode": "SV",
"carrierName": "Saudia Airline",
"logo": "https://storage.googleapis.com/sub-agents-logo/airline-logos/sv.png"
},
"departure": {
"airport": {
"iataCode": "MUX",
"name": "Multan International Airport",
"city": "Multan",
"country": "Pakistan",
"timezone": "Asia/Karachi"
},
"datetime": "2026-04-05T16:45:00"
},
"arrival": {
"airport": {
"iataCode": "JED",
"name": "King Abdulaziz International Airport",
"city": "Jeddah",
"country": "Saudi Arabia",
"timezone": "Asia/Riyadh"
},
"datetime": "2026-04-05T19:30:00"
},
"status": "SCHEDULED"
}
]
}
],
"status": "published"
}/bookingsscope: writeCreate a confirmed booking for a published flight group. All passengers must be provided with complete details. The company (companyId) must be an active stakeholder in the Travel Line system. The total amount is calculated automatically based on the group's fare and number of passengers.
| Name | Type | Required | Description |
|---|---|---|---|
| groupId | string (ObjectId) | required | ID of the published flight group to book. |
| companyId | string (ObjectId) | required | Your company ID as registered with Travel Line. |
| agentContactNumber | string | required | Phone number of the agent making the booking (must match a registered agent on the company). |
| reservedBy | string | required | Full name of the person making the reservation. |
| passengers | Passenger[] | required | List of passengers — see Passenger schema below. Infants do not consume a seat. |
| remarks | string | optional | Optional booking-level notes or special requests. |
curl -X POST "https://api.travellinetour.com/v1/external/bookings" \
-H "Authorization: Bearer sk_live_<YOUR_KEY>" \
-H "Content-Type: application/json" \
-d '{
"groupId": "69c76eaab82eac9a5beabb8b",
"companyId": "64b2e3f4d5c6b7a8f9e0d1e2",
"agentContactNumber": "+923001234567",
"reservedBy": "Ahmed Khan",
"remarks": "Window seat preferred",
"passengers": [
{
"type": "adult",
"title": "MR",
"givenName": "ALI",
"surname": "RAZA",
"passportNo": "AB1234567",
"passportDOE": "2030-06-15",
"dob": "1985-04-15",
"nationality": "PAKISTANI",
"remarks": ""
},
{
"type": "child",
"title": "CHD",
"givenName": "SARA",
"surname": "RAZA",
"passportNo": "AB9876543",
"passportDOE": "2031-03-20",
"dob": "2015-07-20",
"nationality": "PAKISTANI",
"remarks": ""
}
]
}'{
"message": "Booking created successfully",
"_id": "64c3f4a5b6d7c8e9f0a1b2c3",
"orderId": "TXB-2026-00842",
"status": "RESERVED",
"totalAmount": 85500,
"totalSeats": 2,
"adult": 1,
"child": 1,
"infant": 0,
"companyId": "64b2e3f4d5c6b7a8f9e0d1e2",
"companyName": "Acme Travel",
"agentContactNumber": "+923001234567",
"reservedBy": "Ahmed Khan",
"airlinePnr": "8ZT29Z",
"saleFare": 85500,
"currency": "RS",
"reserved_at": "2026-08-08T10:30:00.000Z",
"expired_at": "2026-08-09T10:30:00.000Z",
"remarks": "Window seat preferred",
"itineraries": [
{
"duration": "2h 45mins",
"segments": [
{
"flightNumber": "SV 801",
"airline": { "carrierCode": "SV", "carrierName": "Saudia Airline" },
"departure": { "airport": { "iataCode": "MUX", "city": "Multan" }, "datetime": "2026-04-05T16:45:00" },
"arrival": { "airport": { "iataCode": "JED", "city": "Jeddah" }, "datetime": "2026-04-05T19:30:00" }
}
]
}
],
"passengers": [
{
"type": "adult",
"title": "MR",
"givenName": "ALI",
"surname": "RAZA",
"passportNo": "AB1234567",
"passportDOE": "2030-06-15",
"dob": "1985-04-15",
"nationality": "PAKISTANI",
"status": "RESERVED",
"finalDeal": 85500,
"remarks": ""
},
{
"type": "child",
"title": "CHD",
"givenName": "SARA",
"surname": "RAZA",
"passportNo": "AB9876543",
"passportDOE": "2031-03-20",
"dob": "2015-07-20",
"nationality": "PAKISTANI",
"status": "RESERVED",
"finalDeal": 85500,
"remarks": ""
}
]
}| Field | Type | Required | Values / Notes |
|---|---|---|---|
| type | string | required | adult | child | infant (lowercase) |
| title | string | required | MR | MRS | MS | CHD | INF |
| givenName | string | required | First name as on passport (will be uppercased) |
| surname | string | required | Last name as on passport (will be uppercased) |
| passportNo | string | required | Passport number (will be uppercased) |
| passportDOE | YYYY-MM-DD | required | Passport date of expiry |
| dob | YYYY-MM-DD | required | Date of birth |
| nationality | string | required | e.g. PAKISTANI, SAUDI (will be uppercased) |
| remarks | string | optional | Passenger-level notes or special requests |
/umrah/packagesscope: readReturns all active Umrah packages with public-safe fields. Internal vendor identifiers, markup pricing, and NCT integration details are stripped. Hotel options are included with available seats and pricing per room type.
curl -X GET "https://api.travellinetour.com/v1/external/umrah/packages" \ -H "Authorization: Bearer sk_live_<YOUR_KEY>"
[
{
"_id": "64a1f2e3c4b5d6e7f8a9b0c1",
"id": "umrah-pkg-001",
"slug": "makkah-madinah-15-nights-saudia",
"title": "Makkah & Madinah — 15 Nights (Saudia)",
"shortDescription": "All-inclusive Umrah package with 5-star hotels in Makkah and Madinah.",
"price": 185000,
"currency": "RS",
"durationDays": 17,
"durationNights": 15,
"fromCity": "Karachi",
"toCity": "Jeddah",
"airline": "Saudia",
"airlineLogo": "https://storage.googleapis.com/.../sv.png",
"departureDate": "2026-09-10",
"returnDate": "2026-09-27",
"departureFlightNo": "SV 801",
"makkahNights": 8,
"madinahNights": 7,
"bookingDeadline": "2026-09-05",
"seatsAvailable": 22,
"status": "active",
"hotel": {
"makkahName": "Swissotel Al Maqam",
"makkahDistanceMeters": 50,
"madinahName": "Anwar Al Madinah Mövenpick",
"madinahDistanceMeters": 250,
"rating": 5
},
"pricingOptions": {
"sharing": 185000,
"double": 210000,
"triple": 195000,
"quad": 188000
},
"hotelOptions": [
{
"packageOid": "64a1f2e3c4b5d6e7f8a9b0c1",
"makkahName": "Swissotel Al Maqam",
"makkahDistanceMeters": 50,
"madinahName": "Anwar Al Madinah Mövenpick",
"madinahDistanceMeters": 250,
"rating": 5,
"seatsAvailable": 12,
"pricingOptions": { "sharing": 185000, "double": 210000 }
}
],
"inclusions": ["Visa", "Return flights", "Hotel accommodation", "Daily breakfast & dinner", "Ziyarat transport"],
"exclusions": ["Personal expenses", "Lunch", "Travel insurance"],
"ziyaraa": {
"sites": ["Masjid al-Haram", "Masjid an-Nabawi", "Cave of Hira", "Jabal al-Nour"]
},
"itinerary": [
{ "dayNumber": 1, "title": "Departure from Karachi", "description": "Fly Karachi → Jeddah. Transfer to Makkah hotel." },
{ "dayNumber": 2, "title": "Arrival in Makkah", "description": "Perform Tawaf and Sa'i. Rest." }
]
}
]/umrah/packages/:slug/bookscope: writeCreate a booking for an Umrah package identified by its slug. Your company is resolved automatically from the API key — you do not need to pass companyId. You can pass selectedHotelOptionOid (from hotelOptions[].packageOid) to choose a specific hotel package option and roomSharingType to select the room category. The total price is calculated as unitPrice × numberOfPilgrims.
| Name | Type | Required | Description |
|---|---|---|---|
| fullName | string | required | Full name of the lead pilgrim / contact person. |
| string | required | Contact email address. | |
| phone | string | required | Contact phone number. |
| numberOfPilgrims | number | required | Total number of pilgrims (adults + children). Must not exceed seatsAvailable. |
| selectedHotelOptionOid | string | optional | packageOid of the specific hotel option chosen from hotelOptions[]. Defaults to the first hotel option if omitted. |
| roomSharingType | string | optional | sharing | double | triple | quad | single — specifies room category and determines unit price from pricingOptions of the selected hotel option. |
| reservedBy | string | optional | Name of the agent or user making the reservation. |
| notes | string | optional | Any special requests or notes. |
| passengers | UmrahPassenger[] | optional | Detailed passenger list (see schema below). Can be provided later if not available at booking time. |
curl -X POST "https://api.travellinetour.com/v1/external/umrah/packages/makkah-madinah-15-nights-saudia/book" \
-H "Authorization: Bearer sk_live_<YOUR_KEY>" \
-H "Content-Type: application/json" \
-d '{
"fullName": "Ahmed Khan",
"email": "ahmed@example.com",
"phone": "+923001234567",
"numberOfPilgrims": 2,
"selectedHotelOptionOid": "64a1f2e3c4b5d6e7f8a9b0c1",
"roomSharingType": "double",
"reservedBy": "Ahmed Khan",
"notes": "Window room preferred",
"passengers": [
{
"type": "adult",
"title": "MR",
"givenName": "AHMED",
"surname": "KHAN",
"passportNo": "AB1234567",
"passportDOE": "2030-06-15",
"dob": "1980-04-15",
"nationality": "PAKISTANI"
},
{
"type": "adult",
"title": "MRS",
"givenName": "FATIMA",
"surname": "KHAN",
"passportNo": "CD9876543",
"passportDOE": "2031-03-20",
"dob": "1983-07-20",
"nationality": "PAKISTANI"
}
]
}'{
"success": true,
"message": "Booking created successfully",
"booking": {
"_id": "64c3f4a5b6d7c8e9f0a1b2c3",
"id": "bk_x7k2mn9pq",
"packageId": "umrah-pkg-001",
"packageSlug": "makkah-madinah-15-nights-saudia",
"packageTitle": "Makkah & Madinah — 15 Nights (Saudia)",
"fullName": "Ahmed Khan",
"email": "ahmed@example.com",
"phone": "+923001234567",
"numberOfPilgrims": 2,
"selectedHotelOptionOid": "64a1f2e3c4b5d6e7f8a9b0c1",
"roomSharingType": "double",
"totalPrice": 420000,
"currency": "RS",
"status": "pending",
"companyId": "64b2e3f4d5c6b7a8f9e0d1e2",
"companyName": "Acme Travel",
"reservedBy": "Ahmed Khan",
"notes": "Window room preferred",
"createdAt": "2026-08-08T10:30:00.000Z",
"passengers": [
{
"type": "adult", "title": "MR",
"givenName": "AHMED", "surname": "KHAN",
"passportNo": "AB1234567", "passportDOE": "2030-06-15",
"dob": "1980-04-15", "nationality": "PAKISTANI"
}
]
}
}| Field | Type | Required | Values / Notes |
|---|---|---|---|
| type | string | required | adult | child | infant (lowercase) |
| title | string | required | MR | MRS | MS | CHD | INF |
| givenName | string | required | First name as on passport |
| surname | string | required | Last name as on passport |
| passportNo | string | required | Passport number |
| passportDOE | YYYY-MM-DD | required | Passport date of expiry |
| dob | YYYY-MM-DD | required | Date of birth |
| nationality | string | required | e.g. PAKISTANI, SAUDI |
| remarks | string | optional | Passenger-level notes |
| HTTP Status | Meaning | What to do |
|---|---|---|
| 401 | Unauthorized | No Authorization header or missing Bearer prefix. |
| 403 | Forbidden | Key is invalid, revoked, or missing the required scope (read/write). |
| 429 | Too Many Requests | Per-minute rate limit exceeded. Check X-RateLimit-Remaining header. |
| 400 | Bad Request | Missing or invalid request body/query parameters. |
| 500 | Server Error | Unexpected server error. Contact support. |
Call /ping on startup to verify your key works before making real requests. Catch revoked or expired keys early.
Always use page and limit params. Check pagination.totalPages and loop until all results are fetched.
Read X-RateLimit-Remaining on every response. Back off and retry after X-RateLimit-Reset when it hits 0.
Never expose sk_live_* keys in client-side code. Only use them server-side. Rotate immediately if compromised.
Implement exponential backoff for server errors. Wait 2s, 4s, 8s before retrying failed requests.
Contact your Travel Line account manager or email support. Specify whether you need read, write, or both scopes.
Get your API key from your Travel Line account manager. We'll set you up with the right scopes and rate limits for your use case.
Contact Us →