TripOffer API Specification¶
Overview¶
The TripOffer API provides endpoints for managing trip offer pages, snippets, templates, and page generation for marketing content.
Base Path: /tripoffer
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)
Page Endpoints¶
POST /tripoffer/page/list¶
Lists trip offer pages.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | active | boolean | No | Filter by active status | | category | string | No | Filter by category |
Request Example:
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": [
{
"pageId": 1001,
"pageName": "maldives-summer-2025",
"pageTitle": "Maldives Summer Escape 2025",
"skeletonId": 1,
"skeletonName": "Destination Landing Page",
"category": "destinations",
"active": true,
"createDate": "2025-05-01T10:00:00",
"updateDate": "2025-06-10T14:30:00"
},
{
"pageId": 1002,
"pageName": "dubai-adventure-package",
"pageTitle": "Dubai Adventure Package",
"skeletonId": 2,
"skeletonName": "Package Offer Page",
"category": "packages",
"active": true,
"createDate": "2025-05-15T09:00:00",
"updateDate": "2025-06-12T11:00:00"
}
]
}
POST /tripoffer/page/read¶
Reads a page by ID.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | pageId | integer | Yes | Page ID |
Request Example:
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": {
"pageId": 1001,
"pageName": "maldives-summer-2025",
"pageTitle": "Maldives Summer Escape 2025",
"skeletonId": 1,
"skeletonName": "Destination Landing Page",
"category": "destinations",
"active": true,
"createDate": "2025-05-01T10:00:00",
"updateDate": "2025-06-10T14:30:00",
"snippets": [
{
"snippetId": 2001,
"snippetFileId": 101,
"snippetFileName": "hero-banner",
"slotName": "header",
"displayOrder": 1,
"content": "{\"imageUrl\":\"https://storage.example.com/maldives-hero.jpg\",\"headline\":\"Paradise Awaits\",\"subheadline\":\"Discover the Maldives\"}"
},
{
"snippetId": 2002,
"snippetFileId": 102,
"snippetFileName": "feature-cards",
"slotName": "main",
"displayOrder": 1,
"content": "{\"cards\":[{\"title\":\"Water Villas\",\"description\":\"Luxury overwater accommodation\"},{\"title\":\"Diving\",\"description\":\"World-class diving experiences\"}]}"
},
{
"snippetId": 2003,
"snippetFileId": 103,
"snippetFileName": "price-table",
"slotName": "main",
"displayOrder": 2,
"content": "{\"packages\":[{\"name\":\"Standard\",\"price\":2500},{\"name\":\"Premium\",\"price\":4500}]}"
}
]
}
}
POST /tripoffer/page/write¶
Creates or updates a page.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | pageId | integer | No | Page ID (omit for create) | | pageName | string | Yes | Page name (URL slug) | | pageTitle | string | Yes | Display title | | skeletonId | integer | Yes | Template skeleton ID | | category | string | No | Page category | | active | boolean | No | Active status | | content | object | No | Page content/snippets |
Request Example (Create):
{
"session": "user-session-token",
"pageName": "bali-wellness-retreat",
"pageTitle": "Bali Wellness Retreat 2025",
"skeletonId": 1,
"category": "wellness",
"active": true
}
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": {
"pageId": 1003,
"pageName": "bali-wellness-retreat",
"pageTitle": "Bali Wellness Retreat 2025",
"skeletonId": 1,
"skeletonName": "Destination Landing Page",
"category": "wellness",
"active": true,
"createDate": "2025-06-15T10:30:00",
"updateDate": "2025-06-15T10:30:00",
"snippets": []
}
}
Request Example (Update):
{
"session": "user-session-token",
"pageId": 1003,
"pageTitle": "Bali Ultimate Wellness Retreat 2025",
"active": true
}
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": {
"pageId": 1003,
"pageName": "bali-wellness-retreat",
"pageTitle": "Bali Ultimate Wellness Retreat 2025",
"skeletonId": 1,
"category": "wellness",
"active": true,
"updateDate": "2025-06-15T11:00:00"
}
}
POST /tripoffer/page/delete¶
Deletes a page.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | pageId | integer | Yes | Page ID |
Request Example:
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": {
"pageId": 1003,
"message": "Page deleted successfully"
}
}
POST /tripoffer/page/generate¶
Generates HTML output for a page.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | pageId | integer | Yes | Page ID | | format | string | No | Output format (html, pdf) |
Request Example:
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": {
"pageId": 1001,
"pageName": "maldives-summer-2025",
"format": "html",
"generatedUrl": "https://offers.example.com/maldives-summer-2025",
"previewUrl": "https://offers.example.com/preview/maldives-summer-2025?v=1718447400",
"generatedAt": "2025-06-15T11:30:00",
"fileSize": 45678,
"status": "READY"
}
}
Response for PDF format:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": {
"pageId": 1001,
"pageName": "maldives-summer-2025",
"format": "pdf",
"downloadUrl": "https://storage.example.com/offers/maldives-summer-2025.pdf",
"generatedAt": "2025-06-15T11:30:00",
"fileSize": 1234567,
"status": "READY"
}
}
Snippet Endpoints¶
POST /tripoffer/snippet/list¶
Lists snippets for a page.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | pageId | integer | Yes | Parent page ID |
Request Example:
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": [
{
"snippetId": 2001,
"pageId": 1001,
"snippetFileId": 101,
"snippetFileName": "hero-banner",
"slotName": "header",
"displayOrder": 1,
"content": "{\"imageUrl\":\"https://storage.example.com/maldives-hero.jpg\",\"headline\":\"Paradise Awaits\"}"
},
{
"snippetId": 2002,
"pageId": 1001,
"snippetFileId": 102,
"snippetFileName": "feature-cards",
"slotName": "main",
"displayOrder": 1,
"content": "{\"cards\":[{\"title\":\"Water Villas\"},{\"title\":\"Diving\"}]}"
},
{
"snippetId": 2003,
"pageId": 1001,
"snippetFileId": 103,
"snippetFileName": "price-table",
"slotName": "main",
"displayOrder": 2,
"content": "{\"packages\":[{\"name\":\"Standard\",\"price\":2500}]}"
}
]
}
POST /tripoffer/snippet/read¶
Reads a snippet by ID.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | snippetId | integer | Yes | Snippet ID |
Request Example:
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": {
"snippetId": 2001,
"pageId": 1001,
"snippetFileId": 101,
"snippetFileName": "hero-banner",
"snippetFileDescription": "Full-width hero banner with image, headline, and CTA",
"slotName": "header",
"displayOrder": 1,
"content": "{\"imageUrl\":\"https://storage.example.com/maldives-hero.jpg\",\"headline\":\"Paradise Awaits\",\"subheadline\":\"Discover the Maldives\",\"ctaText\":\"Book Now\",\"ctaUrl\":\"/booking/maldives\"}",
"createdAt": "2025-05-01T10:30:00",
"updatedAt": "2025-06-10T14:00:00"
}
}
POST /tripoffer/snippet/write¶
Creates or updates a snippet.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | snippetId | integer | No | Snippet ID (omit for create) | | pageId | integer | Yes | Parent page ID | | snippetFileId | integer | Yes | Snippet template file ID | | slotName | string | Yes | Slot name in skeleton | | displayOrder | integer | No | Display order | | content | string | No | Snippet content/data (JSON string) |
Request Example (Create):
{
"session": "user-session-token",
"pageId": 1001,
"snippetFileId": 104,
"slotName": "footer",
"displayOrder": 1,
"content": "{\"contactEmail\":\"info@example.com\",\"phone\":\"+971 4 123 4567\"}"
}
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": {
"snippetId": 2004,
"pageId": 1001,
"snippetFileId": 104,
"snippetFileName": "contact-block",
"slotName": "footer",
"displayOrder": 1,
"content": "{\"contactEmail\":\"info@example.com\",\"phone\":\"+971 4 123 4567\"}",
"createdAt": "2025-06-15T11:45:00"
}
}
Request Example (Update):
{
"session": "user-session-token",
"snippetId": 2001,
"content": "{\"imageUrl\":\"https://storage.example.com/maldives-hero-v2.jpg\",\"headline\":\"Your Paradise Awaits\",\"subheadline\":\"Escape to the Maldives\",\"ctaText\":\"Explore Packages\",\"ctaUrl\":\"/packages/maldives\"}"
}
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": {
"snippetId": 2001,
"pageId": 1001,
"content": "{\"imageUrl\":\"https://storage.example.com/maldives-hero-v2.jpg\",\"headline\":\"Your Paradise Awaits\",\"subheadline\":\"Escape to the Maldives\",\"ctaText\":\"Explore Packages\",\"ctaUrl\":\"/packages/maldives\"}",
"updatedAt": "2025-06-15T12:00:00"
}
}
POST /tripoffer/snippet/delete¶
Deletes a snippet.
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | snippetId | integer | Yes | Snippet ID |
Request Example:
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": {
"snippetId": 2004,
"message": "Snippet deleted successfully"
}
}
Template Endpoints¶
POST /tripoffer/skeleton/list¶
Lists available page skeletons (templates).
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | active | boolean | No | Filter by active status |
Request Example:
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": [
{
"skeletonId": 1,
"skeletonName": "Destination Landing Page",
"description": "Full-featured landing page for destination promotions",
"templateFile": "templates/destination-landing.html",
"slots": ["header", "main", "sidebar", "footer"],
"active": true,
"previewUrl": "https://templates.example.com/preview/destination-landing"
},
{
"skeletonId": 2,
"skeletonName": "Package Offer Page",
"description": "Focused page for package deals with pricing",
"templateFile": "templates/package-offer.html",
"slots": ["hero", "details", "pricing", "cta"],
"active": true,
"previewUrl": "https://templates.example.com/preview/package-offer"
},
{
"skeletonId": 3,
"skeletonName": "Simple Promo Page",
"description": "Minimal promotional page with single CTA",
"templateFile": "templates/simple-promo.html",
"slots": ["content", "footer"],
"active": true,
"previewUrl": "https://templates.example.com/preview/simple-promo"
}
]
}
POST /tripoffer/snippetfile/list¶
Lists available snippet files (component templates).
Request Body: | Field | Type | Required | Description | |-------|------|----------|-------------| | session | string | No | User session token | | category | string | No | Filter by category |
Request Example:
Response Structure:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": [
{
"snippetFileId": 101,
"fileName": "hero-banner",
"category": "headers",
"description": "Full-width hero banner with image, headline, and CTA",
"templateContent": "<div class=\"hero-banner\">{{#imageUrl}}...{{/imageUrl}}</div>",
"fields": [
{"name": "imageUrl", "type": "image", "required": true},
{"name": "headline", "type": "text", "required": true},
{"name": "subheadline", "type": "text", "required": false},
{"name": "ctaText", "type": "text", "required": false},
{"name": "ctaUrl", "type": "url", "required": false}
],
"previewUrl": "https://templates.example.com/snippets/hero-banner"
},
{
"snippetFileId": 105,
"fileName": "video-header",
"category": "headers",
"description": "Hero section with background video",
"templateContent": "<div class=\"video-hero\">...</div>",
"fields": [
{"name": "videoUrl", "type": "video", "required": true},
{"name": "headline", "type": "text", "required": true},
{"name": "ctaText", "type": "text", "required": false}
],
"previewUrl": "https://templates.example.com/snippets/video-header"
}
]
}
Response for all categories:
{
"apiStatus": { "errorCode": "OK", "errorMessage": "Success" },
"apiData": [
{
"snippetFileId": 101,
"fileName": "hero-banner",
"category": "headers",
"description": "Full-width hero banner"
},
{
"snippetFileId": 102,
"fileName": "feature-cards",
"category": "content",
"description": "Grid of feature cards with icons"
},
{
"snippetFileId": 103,
"fileName": "price-table",
"category": "pricing",
"description": "Comparison pricing table"
},
{
"snippetFileId": 104,
"fileName": "contact-block",
"category": "footers",
"description": "Contact information block"
},
{
"snippetFileId": 106,
"fileName": "testimonials",
"category": "content",
"description": "Customer testimonials carousel"
},
{
"snippetFileId": 107,
"fileName": "image-gallery",
"category": "content",
"description": "Responsive image gallery"
}
]
}
Data Models¶
CTripOfferPage¶
| Field | Type | Description |
|---|---|---|
| pageId | integer | Page ID |
| pageName | string | Internal name (URL slug) |
| pageTitle | string | Display title |
| skeletonId | integer | Template skeleton ID |
| skeletonName | string | Template skeleton name |
| category | string | Page category |
| active | boolean | Active status |
| createDate | datetime | Creation date |
| updateDate | datetime | Last update date |
| snippets | array | List of snippets |
CTripOfferSnippet¶
| Field | Type | Description |
|---|---|---|
| snippetId | integer | Snippet ID |
| pageId | integer | Parent page ID |
| snippetFileId | integer | Template file ID |
| snippetFileName | string | Template file name |
| snippetFileDescription | string | Template file description |
| slotName | string | Slot name in skeleton |
| displayOrder | integer | Display order within slot |
| content | string | Snippet content/data (JSON string) |
| createdAt | datetime | Creation timestamp |
| updatedAt | datetime | Last update timestamp |
CTripOfferSkeleton¶
| Field | Type | Description |
|---|---|---|
| skeletonId | integer | Skeleton ID |
| skeletonName | string | Skeleton name |
| description | string | Skeleton description |
| templateFile | string | Template file path |
| slots | array | Available slot names |
| active | boolean | Active status |
| previewUrl | string | Preview URL |
CTripOfferSnippetFile¶
| Field | Type | Description |
|---|---|---|
| snippetFileId | integer | Snippet file ID |
| fileName | string | File name |
| category | string | Category (headers, content, pricing, footers) |
| description | string | Description |
| templateContent | string | Template HTML/Mustache |
| fields | array | Available fields for the snippet |
| previewUrl | string | Preview URL |