Skip to content

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:

{
  "apiStatus": {
    "errorCode": "OK",
    "errorMessage": "Success"
  },
  "apiData": { ... }
}

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:

{
  "session": "user-session-token",
  "active": true,
  "category": "destinations"
}

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:

{
  "session": "user-session-token",
  "pageId": 1001
}

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:

{
  "session": "user-session-token",
  "pageId": 1003
}

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:

{
  "session": "user-session-token",
  "pageId": 1001,
  "format": "html"
}

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:

{
  "session": "user-session-token",
  "pageId": 1001
}

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:

{
  "session": "user-session-token",
  "snippetId": 2001
}

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:

{
  "session": "user-session-token",
  "snippetId": 2004
}

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:

{
  "session": "user-session-token",
  "active": true
}

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:

{
  "session": "user-session-token",
  "category": "headers"
}

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