Logo
    API v1 — Production Ready

    Travel Line API Integration

    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.

    🔑

    API Key Auth

    Authenticate every request with a long-lived API key issued by your account manager.

    Rate Limited

    Default 60 requests/minute per key. Headers tell you exactly how many you have left.

    🔒

    Scope-based

    Keys carry read and/or write scopes. Only endpoints matching your scope are accessible.

    #Base URL

    url
    https://api.travellinetour.com/v1/external

    #Authentication

    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 Header
    Authorization: Bearer sk_live_<your_32_char_hex_key>

    Scopes

    readBrowse and search published flight groups.
    writeCreate bookings on behalf of your company.

    Rate Limit Headers

    X-RateLimit-Limit: 60
    X-RateLimit-Remaining: 45
    X-RateLimit-Reset: 1723110060

    Reset is a Unix timestamp (UTC). Retry after it passes.

    #Endpoints

    1. Health Check

    GET/ping

    Use this endpoint to confirm your API key is valid and the service is reachable. Returns your stakeholder ID. Requires no specific scope.

    bash
    curl -X GET "https://api.travellinetour.com/v1/external/ping" \
      -H "Authorization: Bearer sk_live_<YOUR_KEY>"

    Example Response

    json
    {
      "message": "pong",
      "stakeholderId": "64a1f2e3c4b5d6e7f8a9b0c1"
    }

    2. Flight Groups

    GET/groupsscope: read

    Returns 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).

    Query Parameters

    NameTypeRequiredDescription
    departurestringoptionalOrigin airport IATA code (e.g. KHI, ISB, LHE)
    arrivalstringoptionalDestination airport IATA code (e.g. JED, MED, DXB)
    departureDateFromYYYY-MM-DDoptionalEarliest departure date (inclusive)
    departureDateToYYYY-MM-DDoptionalLatest departure date (inclusive)
    categorystringoptionalTrip category — e.g. umrah, hajj, international
    pagenumberoptionalPage number (default: 1)
    limitnumberoptionalResults per page (default: 10, max: 50)
    bash
    # 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>"

    Example Response

    json
    {
      "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
      }
    }

    3. Get Group by ID

    GET/groups/:idscope: read

    Returns 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.

    Query Parameters

    NameTypeRequiredDescription
    idstring (ObjectId)requiredID of the flight group to fetch (path parameter)
    bash
    curl -X GET "https://api.travellinetour.com/v1/external/groups/69c76eaab82eac9a5beabb8b" \
      -H "Authorization: Bearer sk_live_<YOUR_KEY>"

    Example Response

    json
    {
      "_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"
    }

    4. Create Booking

    POST/bookingsscope: write

    Create 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.

    Request Body (JSON)

    NameTypeRequiredDescription
    groupIdstring (ObjectId)requiredID of the published flight group to book.
    companyIdstring (ObjectId)requiredYour company ID as registered with Travel Line.
    agentContactNumberstringrequiredPhone number of the agent making the booking (must match a registered agent on the company).
    reservedBystringrequiredFull name of the person making the reservation.
    passengersPassenger[]requiredList of passengers — see Passenger schema below. Infants do not consume a seat.
    remarksstringoptionalOptional booking-level notes or special requests.
    bash
    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": ""
          }
        ]
      }'

    Example Response

    json
    {
      "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": ""
        }
      ]
    }
    Passenger Object Schema
    FieldTypeRequiredValues / Notes
    typestringrequiredadult | child | infant (lowercase)
    titlestringrequiredMR | MRS | MS | CHD | INF
    givenNamestringrequiredFirst name as on passport (will be uppercased)
    surnamestringrequiredLast name as on passport (will be uppercased)
    passportNostringrequiredPassport number (will be uppercased)
    passportDOEYYYY-MM-DDrequiredPassport date of expiry
    dobYYYY-MM-DDrequiredDate of birth
    nationalitystringrequirede.g. PAKISTANI, SAUDI (will be uppercased)
    remarksstringoptionalPassenger-level notes or special requests

    #Umrah Packages

    5. List Umrah Packages

    GET/umrah/packagesscope: read

    Returns 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.

    bash
    curl -X GET "https://api.travellinetour.com/v1/external/umrah/packages" \
      -H "Authorization: Bearer sk_live_<YOUR_KEY>"

    Example Response

    json
    [
      {
        "_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." }
        ]
      }
    ]

    6. Book Umrah Package

    POST/umrah/packages/:slug/bookscope: write

    Create 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.

    Request Body (JSON)

    NameTypeRequiredDescription
    fullNamestringrequiredFull name of the lead pilgrim / contact person.
    emailstringrequiredContact email address.
    phonestringrequiredContact phone number.
    numberOfPilgrimsnumberrequiredTotal number of pilgrims (adults + children). Must not exceed seatsAvailable.
    selectedHotelOptionOidstringoptionalpackageOid of the specific hotel option chosen from hotelOptions[]. Defaults to the first hotel option if omitted.
    roomSharingTypestringoptionalsharing | double | triple | quad | single — specifies room category and determines unit price from pricingOptions of the selected hotel option.
    reservedBystringoptionalName of the agent or user making the reservation.
    notesstringoptionalAny special requests or notes.
    passengersUmrahPassenger[]optionalDetailed passenger list (see schema below). Can be provided later if not available at booking time.
    bash
    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"
          }
        ]
      }'

    Example Response

    json
    {
      "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"
          }
        ]
      }
    }
    UmrahPassenger Object Schema
    FieldTypeRequiredValues / Notes
    typestringrequiredadult | child | infant (lowercase)
    titlestringrequiredMR | MRS | MS | CHD | INF
    givenNamestringrequiredFirst name as on passport
    surnamestringrequiredLast name as on passport
    passportNostringrequiredPassport number
    passportDOEYYYY-MM-DDrequiredPassport date of expiry
    dobYYYY-MM-DDrequiredDate of birth
    nationalitystringrequirede.g. PAKISTANI, SAUDI
    remarksstringoptionalPassenger-level notes

    #Error Codes

    HTTP StatusMeaningWhat to do
    401UnauthorizedNo Authorization header or missing Bearer prefix.
    403ForbiddenKey is invalid, revoked, or missing the required scope (read/write).
    429Too Many RequestsPer-minute rate limit exceeded. Check X-RateLimit-Remaining header.
    400Bad RequestMissing or invalid request body/query parameters.
    500Server ErrorUnexpected server error. Contact support.

    #Integration Tips

    🔍

    Always ping first

    Call /ping on startup to verify your key works before making real requests. Catch revoked or expired keys early.

    📄

    Paginate properly

    Always use page and limit params. Check pagination.totalPages and loop until all results are fetched.

    ⏱️

    Respect rate limits

    Read X-RateLimit-Remaining on every response. Back off and retry after X-RateLimit-Reset when it hits 0.

    🛡️

    Keep your key secret

    Never expose sk_live_* keys in client-side code. Only use them server-side. Rotate immediately if compromised.

    🔄

    Handle 503 gracefully

    Implement exponential backoff for server errors. Wait 2s, 4s, 8s before retrying failed requests.

    📞

    Need a key?

    Contact your Travel Line account manager or email support. Specify whether you need read, write, or both scopes.

    Ready to integrate?

    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 →
    Home
    Explore
    Home
    Explore