Skip to content

Trip page and calendar

GET /v1/public/products/{product} takes the trip’s slug or id and answers everything its page shows: text, photos in order (the first is the cover), highlights, the itinerary, inclusions, places, the seller, the options with their units and policies, and the extras.

A trip's page, by its slug
Terminal window
curl "https://api.stg.vacationpackagesoman.com/v1/public/products/desert-safari-with-bbq-dinner?locale=en" \
-H "Tp-Publishable-Key: $TP_KEY"
Answer: 200 OK (shortened)
{
"id": "5b1f0c3e-8d2a-4f6b-9c41-2e7a9d0b6f13",
"slug": "desert-safari-with-bbq-dinner",
"content_locale": "en",
"locales": [
"en",
"ar"
],
"title": "Desert safari with BBQ dinner",
"timezone": "Asia/Dubai",
"sales_paused": false,
"options": [
{
"id": "9e4c2a71-3b5d-4e8f-a1c6-7d20f5b93e48",
"name": "Shared 4WD, afternoon",
"is_default": true,
"private": false,
"vehicle": "Shared 4WD",
"sales_paused": false,
"min_units": null,
"max_units": null,
"availability_type": "start_time",
"capacity_mode": "limited",
"confirmation": "instant",
"units": [
{
"id": "1c7e9b42-6a3f-4d85-b0e2-58f4a1c9d736",
"type": "adult",
"label": "Adult",
"min_age": 12,
"max_age": null,
"min_qty": null,
"max_qty": null,
"takes_seat": true,
"free": false
},
{
"id": "2d8fac53-7b40-4e96-81f3-69a5b2dae847",
"type": "child",
"label": "Child (3-11)",
"min_age": 3,
"max_age": 11,
"min_qty": null,
"max_qty": null,
"takes_seat": true,
"free": false
}
],
"policy": {
"name": "Flexible",
"tiers": [
{
"from_days": 1,
"to_days": null,
"refund_pct": 100
},
{
"from_days": 0,
"to_days": 0,
"refund_pct": 0
}
]
},
"traveller_details": {
"scope": "lead",
"fields": [],
"collect": "checkout",
"due_hours_before": null
},
"pickup": null,
"pickup_rules": []
}
],
"city": {
"slug": "dubai",
"name": "Dubai"
},
"region": {
"slug": "dubai-emirate",
"name": "Dubai"
},
"country": {
"slug": "ae",
"name": "United Arab Emirates"
},
"seller": {
"slug": "demo",
"name": "tourpingo demo",
"base": "Nowhere: a demo for developers",
"blurb": "Invented trips in the UAE, Oman and Zanzibar for trying tourpingo's API. Never on the marketplace; bookings are deleted after a day."
},
"extras": [
{
"id": "3e90bd64-8c51-4fa7-92a4-7ab6c3ebf958",
"name": "Quad bike, 30 minutes",
"description": null,
"per": "item",
"who": "choose",
"included": false,
"option_ids": [],
"min_age": 16,
"max_age": null,
"unit_types": [],
"max_per_booking": null,
"pay": "upfront",
"price": {
"amount": 4000,
"currency": "USD"
},
"unit_prices": {},
"local_price": null
}
],
"from_price": {
"amount": 6500,
"currency": "USD",
"group_size": 1
}
}
  • Ask with locale for the page’s language and currency for its prices. content_locale says which language the text is in (languages).
  • On a marketplace, add seller to open a trip by its slug.
  • A trip the site doesn’t sell, or doesn’t have, is 404 NotFound.
  • sales_paused on the trip or an option: show it, but don’t offer to book.

When a trip has several options, show each with what sets it apart: its name, whether it is private, its vehicle, its policy and its units. Start with the one marked is_default.

Each option has its own calendar. Ask for a month at a time:

An option's month
Terminal window
curl "https://api.stg.vacationpackagesoman.com/v1/public/options/9e4c2a71-3b5d-4e8f-a1c6-7d20f5b93e48/calendar?month=2026-11" \
-H "Tp-Publishable-Key: $TP_KEY"
Answer: 200 OK (shortened)
[
{
"date": "2026-11-13",
"status": "sold_out",
"starts": [
{
"time": "15:00",
"status": "sold_out",
"remaining": 0
}
]
},
{
"date": "2026-11-14",
"status": "open",
"starts": [
{
"time": "15:00",
"status": "open",
"remaining": 14
}
]
},
{
"date": "2026-11-15",
"status": "closed",
"starts": []
}
]

Show open days as bookable, and for each start its time and, when counted, the places left. sold_out, closed and past_cutoff days aren’t bookable. The calendar has no prices: once the traveller picks a day, ask for a quote.

An option with pickup collects travellers where they stay. Its pickup_rules list the areas it covers and their prices, for the page. For one traveller’s address, search the places library as they type with GET /v1/public/places/search, then ask the option with GET /v1/public/options/{optionId}/pickup/resolve, which says whether pickup is offered there, when and at what price. Send the chosen place with the quote as pickup.

The trip’s seller has its name, where it is based and what it does. Put it on the page, near the price.