Product API Specification¶
Overview¶
The Product API provides endpoints for product catalog management including categories, products, variants, attributes, availability, and timeslots.
Base Path: /product
Content Types:
- Request: application/json
- Response: application/json
Response Format¶
All endpoints return a TlinqApiResponse object:
Date Format: All dates are returned in ISO 8601 format (yyyy-MM-dd'T'HH:mm:ss)
Category Endpoints¶
GET /product/getCategories¶
Lists all product categories.
Query Parameters: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token |
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": [
{
"categoryId": 1,
"categoryName": "Tours & Activities",
"parentCategoryId": null,
"categoryPath": "Tours & Activities",
"categorySeq": 1,
"childCategories": [
{
"categoryId": 10,
"categoryName": "Desert Safari",
"parentCategoryId": 1,
"categoryPath": "Tours & Activities/Desert Safari",
"categorySeq": 1,
"childCategories": null
},
{
"categoryId": 11,
"categoryName": "City Tours",
"parentCategoryId": 1,
"categoryPath": "Tours & Activities/City Tours",
"categorySeq": 2,
"childCategories": null
}
]
},
{
"categoryId": 2,
"categoryName": "Theme Parks",
"parentCategoryId": null,
"categoryPath": "Theme Parks",
"categorySeq": 2,
"childCategories": [
{
"categoryId": 20,
"categoryName": "Dubai Parks",
"parentCategoryId": 2,
"categoryPath": "Theme Parks/Dubai Parks",
"categorySeq": 1,
"childCategories": null
}
]
}
]
}
POST /product/getCategories¶
Lists all product categories (POST version).
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token |
Request Example:
Response: Same as GET version.
POST /product/findCategory¶
Finds a category by name.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | catName | string | Yes | Category name to search |
Request Example:
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": {
"categoryId": 10,
"categoryName": "Desert Safari",
"parentCategoryId": 1,
"categoryPath": "Tours & Activities/Desert Safari",
"categorySeq": 1,
"childCategories": null
}
}
Product Endpoints¶
GET /product/getCategoryProducts¶
Gets products for a category.
Query Parameters: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | category | integer | Yes | Category ID |
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": [
{
"productId": 1001,
"prodCode": "DSF-PREM",
"prodName": "Desert Safari Premium",
"prodDisplayName": "Premium Desert Safari Experience",
"productDescription": "Experience the ultimate desert adventure...",
"productPrice": 299.00,
"childPrice": 199.00,
"currency": "AED",
"publicCategoryId": 10,
"publicCategoryName": "Desert Safari",
"prodImgSmall": "/images/products/dsf-small.jpg",
"prodImgMed": "/images/products/dsf-med.jpg",
"prodImgLarge": "/images/products/dsf-large.jpg",
"webDescription": "<p>Premium desert safari with BBQ dinner...</p>",
"availableOnWeb": true,
"availableFrom": "2025-01-01T00:00:00",
"availableTo": "2025-12-31T23:59:59",
"bookingType": "TICKET",
"pricingType": "PERPAX",
"hasDateRange": false,
"hasTime": true,
"hasTimeSlot": true,
"hasPaxInfo": true,
"hasVendorBooking": true,
"hasOnlinePayment": true,
"minQuantity": 1,
"maxQuantity": 20,
"unitId": 5001,
"unitName": "Adult",
"childUnitId": 5002,
"childUnitName": "Child (3-11 years)",
"maxAdults": 20,
"maxChildren": 10,
"maxChildAge": 11,
"maxInfantAge": 2,
"variantCount": 3
}
]
}
POST /product/getCategoryProducts¶
Gets products for a category (POST version).
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | catId | integer | Yes | Category ID |
Request Example:
Response: Same as GET version.
POST /product/getProduct¶
Gets a product by ID or code.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | productId | integer | No | Product ID | | productCode | string | No | Product code |
*Either productId or productCode must be provided.
Request Example:
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": {
"productId": 1001,
"prodCode": "DSF-PREM",
"prodName": "Desert Safari Premium",
"prodDisplayName": "Premium Desert Safari Experience",
"productDescription": "Experience the ultimate desert adventure with dune bashing, camel riding, and a BBQ dinner under the stars.",
"productPrice": 299.00,
"childPrice": 199.00,
"currency": "AED",
"publicCategoryId": 10,
"publicCategoryName": "Desert Safari",
"prodImgSmall": "/images/products/dsf-small.jpg",
"prodImgMed": "/images/products/dsf-med.jpg",
"prodImgLarge": "/images/products/dsf-large.jpg",
"webDescription": "<p>Premium desert safari with BBQ dinner...</p>",
"availableOnWeb": true,
"availableFrom": "2025-01-01T00:00:00",
"availableTo": "2025-12-31T23:59:59",
"bookingType": "TICKET",
"pricingType": "PERPAX",
"hasDateRange": false,
"hasTime": true,
"hasTimeSlot": true,
"hasPaxInfo": true,
"hasVendorBooking": true,
"splitAges": true,
"hasOnlinePayment": true,
"minQuantity": 1,
"maxQuantity": 20,
"qtyType": "PAX",
"unitId": 5001,
"unitName": "Adult",
"childUnitId": 5002,
"childUnitName": "Child (3-11 years)",
"infantUnitId": 5003,
"infantUnitName": "Infant (0-2 years)",
"maxAdults": 20,
"maxChildren": 10,
"maxChildAge": 11,
"maxInfantAge": 2,
"variantCount": 3,
"productInfo": "Pick-up from hotel included. Vegetarian options available.",
"productTerms": "Subject to weather conditions.",
"productInclusions": "Hotel pickup, Dune bashing, Camel ride, BBQ dinner, Entertainment",
"productExclusions": "Alcoholic beverages, Personal expenses",
"cancelPolicy": "Free cancellation up to 24 hours before. 50% charge within 24 hours.",
"childPolicy": "Children under 3 years free. Children 3-11 years at child rate.",
"transfers": [
{
"transferId": 100,
"transferName": "Shared Transfer",
"transferType": "SIC",
"price": 0.00
},
{
"transferId": 101,
"transferName": "Private Transfer",
"transferType": "PVT",
"price": 150.00
}
]
}
}
Error Codes:
- MISSING_PARAMETER - Product ID or code required
POST /product/searchProduct¶
Searches for products by criteria.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | method | string | No | "partial" for partial matching | | prodName | string | No | Product name filter | | publicCategoryId | integer | No | Category ID filter | | availableOnWeb | boolean | No | Web availability filter |
Request Example:
{
"session": "user-session-token",
"method": "partial",
"prodName": "safari",
"availableOnWeb": true
}
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": [
{
"productId": 1001,
"prodCode": "DSF-PREM",
"prodName": "Desert Safari Premium",
"productPrice": 299.00,
"currency": "AED",
"publicCategoryId": 10,
"availableOnWeb": true
},
{
"productId": 1002,
"prodCode": "DSF-STD",
"prodName": "Desert Safari Standard",
"productPrice": 199.00,
"currency": "AED",
"publicCategoryId": 10,
"availableOnWeb": true
}
]
}
POST /product/productLookup¶
Product name lookup for autocomplete.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | namepart | string | No | Partial product name |
Request Example:
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": [
["Desert Safari Premium", 1001],
["Desert Safari Standard", 1002],
["Desert Overnight Camp", 1003]
]
}
Attribute Endpoints¶
POST /product/getProductAttributes¶
Gets attributes for a product.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | productId | integer | Yes | Product ID |
Request Example:
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": [
{
"attributeId": 1,
"name": "Transfer Type",
"sequence": 1,
"values": [
{
"attributeValueId": 10,
"attributeValue": "SIC",
"attributeDescription": "Shared Transfer",
"sequence": 1,
"priceAdjustment": 0.00
},
{
"attributeValueId": 11,
"attributeValue": "PVT",
"attributeDescription": "Private Transfer",
"sequence": 2,
"priceAdjustment": 150.00
}
]
},
{
"attributeId": 2,
"name": "Meal Option",
"sequence": 2,
"values": [
{
"attributeValueId": 20,
"attributeValue": "STD",
"attributeDescription": "Standard BBQ",
"sequence": 1,
"priceAdjustment": 0.00
},
{
"attributeValueId": 21,
"attributeValue": "VIP",
"attributeDescription": "VIP Dining",
"sequence": 2,
"priceAdjustment": 100.00
}
]
}
]
}
Variant Endpoints¶
POST /product/getProductVariants¶
Gets all variants for a product.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | productId | integer | Yes | Product ID | | bookInfo | object | No | Booking information for filtering |
Request Example:
{
"session": "user-session-token",
"productId": 1001,
"bookInfo": {
"date": "2025-07-15",
"adults": 2,
"children": 1
}
}
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": [
{
"servid": 2001,
"servcode": "DSF-PREM-SIC-STD",
"servname": "Premium Safari - Shared Transfer - Standard BBQ",
"servfullname": "Desert Safari Premium with Shared Transfer and Standard BBQ",
"servdesc": "Premium desert safari experience",
"cprice": 299.00,
"bprice": 299.00,
"child_price": 199.00,
"currency": "AED",
"templateid": 1001,
"attributeIds": [1, 2],
"attributeVals": [10, 20],
"maxOccupancy": 20,
"maxAdults": 20,
"maxChildren": 10,
"hasTimeSlots": true,
"timeSlots": "15:00,16:00",
"available": true,
"needsLocation": true,
"transfers": [
{
"transferId": 100,
"transferName": "Shared",
"price": 0.00
}
]
},
{
"servid": 2002,
"servcode": "DSF-PREM-PVT-STD",
"servname": "Premium Safari - Private Transfer - Standard BBQ",
"servfullname": "Desert Safari Premium with Private Transfer and Standard BBQ",
"cprice": 449.00,
"bprice": 449.00,
"child_price": 349.00,
"currency": "AED",
"templateid": 1001,
"attributeIds": [1, 2],
"attributeVals": [11, 20],
"available": true
}
]
}
POST /product/getVariant¶
Gets a specific variant based on attribute values.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | productId | integer | Yes | Product ID | | attrValues | array | Yes | Array of attribute value IDs | | bookInfo | object | No | Booking information |
Request Example:
{
"session": "user-session-token",
"productId": 1001,
"attrValues": [10, 20],
"bookInfo": {
"date": "2025-07-15"
}
}
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": {
"servid": 2001,
"servcode": "DSF-PREM-SIC-STD",
"servname": "Premium Safari - Shared Transfer - Standard BBQ",
"cprice": 299.00,
"child_price": 199.00,
"currency": "AED",
"attributeIds": [1, 2],
"attributeVals": [10, 20],
"available": true,
"hasTimeSlots": true,
"timeSlots": "15:00,16:00"
}
}
POST /product/getDefaultVariant¶
Gets the default variant for a product.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | productId | integer | Yes | Product ID |
Request Example:
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": {
"servid": 2001,
"servcode": "DSF-PREM-SIC-STD",
"servname": "Premium Safari - Shared Transfer - Standard BBQ",
"cprice": 299.00,
"child_price": 199.00,
"currency": "AED",
"available": true
}
}
Availability & Pricing Endpoints¶
POST /product/getAvailability¶
Checks product availability and gets pricing.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | bookingRequest | object | Yes | Booking request details |
Booking Request Object: | Field | Type | Description | |-------|------|-------------| | productId | integer | Product ID | | variantId | integer | Variant ID | | date | string | Booking date (yyyy-MM-dd) | | quantity | integer | Total quantity | | adultCount | integer | Number of adults | | childCount | integer | Number of children | | infantCount | integer | Number of infants | | timeSlotId | integer | Selected timeslot ID | | attributes | object | Attribute key-value map |
Request Example:
{
"session": "user-session-token",
"bookingRequest": {
"productId": 1001,
"variantId": 2001,
"date": "2025-07-15",
"adultCount": 2,
"childCount": 1,
"infantCount": 0,
"timeSlotId": 100,
"attributes": {
"Transfer Type": "SIC",
"Meal Option": "STD"
}
}
}
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": {
"priceInfoId": "PRC-20250715-001",
"apc": 299.00,
"cpc": 199.00,
"sttl": 797.00,
"available": true,
"statusReason": null,
"startTime": "15:00",
"needsLocation": true,
"vpc": [200.00, 133.00]
}
}
Response Fields: | Field | JSON Key | Description | |-------|----------|-------------| | adultPrice | apc | Price per adult | | childPrice | cpc | Price per child | | totalCost | sttl | Total cost | | available | available | Availability status | | statusReason | statusReason | Reason if unavailable | | startTime | startTime | Service start time | | needsLocation | needsLocation | Whether pickup location required | | vpc | vpc | Vendor purchase cost array |
Error Codes:
- MISSING_PARAMETER - Booking request not initialized
POST /product/getTerms¶
Gets terms and conditions for a product.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | productId | integer | Yes | Product ID |
Request Example:
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": {
"productId": 1001,
"productTerms": "Subject to weather conditions. Safari may be cancelled in case of sandstorm.",
"cancelPolicy": "Free cancellation up to 24 hours before the activity. 50% charge for cancellations within 24 hours. No refund for no-shows.",
"childPolicy": "Infants (0-2 years) are free. Children (3-11 years) are charged at child rate. Children 12+ are charged as adults."
}
}
POST /product/getTimeslots¶
Gets available timeslots for a variant.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | variant | object | Yes | CProductVariant object | | bookInfo | object | Yes | Booking information |
Request Example:
{
"session": "user-session-token",
"variant": {
"servid": 2001,
"templateid": 1001
},
"bookInfo": {
"date": "2025-07-15",
"adults": 2,
"children": 1
}
}
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": [
{
"slotId": 100,
"startTime": "2025-07-15T15:00:00",
"endTime": "2025-07-15T21:00:00",
"slotName": "Afternoon Safari (3:00 PM)",
"available": 15,
"price": 299.00
},
{
"slotId": 101,
"startTime": "2025-07-15T16:00:00",
"endTime": "2025-07-15T22:00:00",
"slotName": "Evening Safari (4:00 PM)",
"available": 8,
"price": 299.00
}
]
}
Data Models¶
CProductCategory¶
| Field | Type | Description |
|---|---|---|
| categoryId | integer | Category ID |
| categoryName | string | Category name |
| parentCategoryId | integer | Parent category ID (null for root) |
| categoryPath | string | Full category path |
| categorySeq | integer | Display sequence |
| childCategories | array | Nested child categories |
CProduct¶
| Field | Type | Description |
|---|---|---|
| productId | integer | Product ID |
| prodCode | string | Product code |
| prodName | string | Product name |
| prodDisplayName | string | Display name |
| productDescription | string | Full description |
| productPrice | number | Base adult price |
| childPrice | number | Child price |
| currency | string | Currency code |
| publicCategoryId | integer | Category ID |
| publicCategoryName | string | Category name |
| prodImgSmall | string | Small image URL |
| prodImgMed | string | Medium image URL |
| prodImgLarge | string | Large image URL |
| webDescription | string | HTML description for web |
| availableOnWeb | boolean | Web availability |
| availableFrom | datetime | Availability start |
| availableTo | datetime | Availability end |
| bookingType | string | TICKET, HOTEL, etc. |
| pricingType | string | PERPAX, PERUNIT |
| hasDateRange | boolean | Requires date range |
| hasTime | boolean | Has time selection |
| hasTimeSlot | boolean | Has timeslots |
| hasPaxInfo | boolean | Requires passenger info |
| hasVendorBooking | boolean | Has vendor integration |
| hasOnlinePayment | boolean | Online payment enabled |
| minQuantity | integer | Minimum quantity |
| maxQuantity | integer | Maximum quantity |
| unitId | integer | Adult unit ID |
| unitName | string | Adult unit name |
| childUnitId | integer | Child unit ID |
| childUnitName | string | Child unit name |
| infantUnitId | integer | Infant unit ID |
| infantUnitName | string | Infant unit name |
| maxAdults | integer | Max adults |
| maxChildren | integer | Max children |
| maxChildAge | integer | Max child age |
| maxInfantAge | integer | Max infant age |
| variantCount | integer | Number of variants |
CProductAttribute¶
| Field | Type | Description |
|---|---|---|
| attributeId | integer | Attribute ID |
| name | string | Attribute name |
| sequence | integer | Display order |
| values | array | Array of CProductAttributeValue |
CProductAttributeValue¶
| Field | Type | Description |
|---|---|---|
| attributeValueId | integer | Value ID |
| attributeValue | string | Value code |
| attributeDescription | string | Display description |
| sequence | integer | Display order |
| priceAdjustment | number | Price adjustment |
CProductVariant¶
| Field | Type | Description |
|---|---|---|
| servid | integer | Variant ID |
| servcode | string | Variant code |
| servname | string | Variant name |
| servfullname | string | Full name |
| servdesc | string | Description |
| cprice | number | Current price |
| bprice | number | Base price |
| child_price | number | Child price |
| currency | string | Currency code |
| templateid | integer | Product template ID |
| attributeIds | array | Attribute ID array |
| attributeVals | array | Attribute value array |
| maxOccupancy | integer | Max occupancy |
| maxAdults | integer | Max adults |
| maxChildren | integer | Max children |
| hasTimeSlots | boolean | Has timeslots |
| timeSlots | string | Available timeslots |
| available | boolean | Availability |
| needsLocation | boolean | Requires location |
| transfers | array | Transfer options |
CItemPriceInfo¶
| Field | Type | Description |
|---|---|---|
| priceInfoId | string | Price info ID |
| apc (adultPrice) | number | Adult price |
| cpc (childPrice) | number | Child price |
| sttl (totalCost) | number | Total cost |
| available | boolean | Is available |
| statusReason | string | Unavailability reason |
| startTime | string | Service start time |
| needsLocation | boolean | Location required |
| vpc | array | Vendor purchase costs |
CTimeslot¶
| Field | Type | Description |
|---|---|---|
| slotId | integer | Timeslot ID |
| slotName | string | Slot display name |
| startTime | datetime | Start time |
| endTime | datetime | End time |
| available | integer | Available capacity |
| price | number | Slot price |