Hermeseus

Tours and activities API

Browse the catalogue of tours, attractions, and experiences, then open a product and read its bookable variants.

All activity endpoints live under Activity/v2/. Send SessionId as a query parameter on these GET requests. Responses are wrapped as { "data": ..., "timestamp": ... }, and lists add meta.pagination. Prices are USD.

List products

GET/Activity/v2/products

Access requires the permission activity_products_list

A paginated, filterable list served from the local catalogue cache, so it is fast. For the whole catalogue in one call use /Activity/v2/products/all. For a country and city tree use the public /Activity/v2/products/by-location.

Query parameters

NameTypeRequiredDefaultDescription
qstringNo-Name search in any stored language. Matched rows carry matchedLanguage.
typestringNo-Product-type name substring or type UUID.
categorystringNo-Category name or UUID. A parent UUID expands to its descendants.
countrystringNo-Filter by country name.
citystringNo-Filter by city name.
tagstringNo-Filter by tag.
languagestringNo-Localize titles, for example KO or AR.
min_price / max_pricenumberNo-Price band in USD.
sortstringNocatalogue orderOne of price, -price, date, -date, bestselling, sold, -sold.
pageintegerNo11-based page number.
per_pageintegerNo50Results per page.
curl "https://api.hermeseus.com/api/Activity/v2/products?city=Singapore&sort=bestselling&per_page=20&SessionId=8f3c81d2-4a5b-4c6d-9e0f-1a2b3c4d5e6f"
const params = new URLSearchParams({
  city: "Singapore",
  sort: "bestselling",
  per_page: "20",
  SessionId: "8f3c81d2-4a5b-4c6d-9e0f-1a2b3c4d5e6f"
});

const res = await fetch("https://api.hermeseus.com/api/Activity/v2/products?" + params);
const data = await res.json();
import requests

res = requests.get(
    "https://api.hermeseus.com/api/Activity/v2/products",
    params={
        "city": "Singapore",
        "sort": "bestselling",
        "per_page": 20,
        "SessionId": "8f3c81d2-4a5b-4c6d-9e0f-1a2b3c4d5e6f",
    },
)

data = res.json()

Response

FieldTypeDescription
dataarray of objectProducts. See below.
meta.paginationobjecttotal, count, per_page, current_page, total_pages.
data[] object
FieldTypeDescription
uuidstringProduct id. Open it for details.
titlestringProduct title.
basePricenumberLead-in price. USD.
cityNamestringCity of the product.
image_urlstringMain image.
imagesarray of stringFull gallery.
{
  "data": [
    {
      "uuid": "97475b54-3378-4eb2-8f19-85c8b76255d8",
      "title": "Gardens by the Bay Admission",
      "basePrice": 22.00,
      "currency": "USD",
      "cityName": "Singapore",
      "image_url": "https://cdn.example.com/products/97475b54/main.jpg",
      "images": ["https://cdn.example.com/products/97475b54/1.jpg"]
    }
  ],
  "meta": { "pagination": { "total": 812, "count": 20, "per_page": 20, "current_page": 1, "total_pages": 41 } },
  "timestamp": "2026-10-15T16:24:49.648+08:00"
}

Open a product

GET/Activity/v2/products/{uuid}

Access requires the permission activity_products_details

Fetch the full product live: description, images, itinerary, and policies. Read age and pax rules from /Activity/v2/products/{uuid}/restrictions.

Path parameters

NameTypeRequiredDescription
uuidstringYesProduct id from the list.

List bookable variants

GET/Activity/v2/products/{uuid}/product-types

Access requires the permission activity_product_types_list

A product has one or more product-types: ticket tiers, durations, or packages. Each has its own uuid, the productTypeUuid you book. Carry it into availability and bookings.

Read the restrictions

GET/Activity/v2/products/{uuid}/restrictions

Access requires the permission activity_products_restrictions

The age, pax, and eligibility rules for a product. Read them before you collect traveller details, so you can validate the pax mix up front.

The whole catalogue

GET/Activity/v2/products/all

Access requires the permission activity_products_list

Every product in one call, for a full local sync. Takes the same filters as the list, plus full (boolean) to return the full object per row instead of a summary. With no per_page it returns everything. The response is { success, count, total, data }.

Countries and cities

GET/Activity/v2/products/by-location

Access public, no session

A tree of countries and their cities with product counts, for building a location picker. It takes no parameters.

{
  "success": true,
  "countries": 42,
  "products": 8130,
  "data": [
    {
      "country": "Singapore",
      "countryUuid": "c1a2...",
      "cities": [ { "city": "Singapore", "cityUuid": "d3f4...", "count": 812 } ],
      "total": 812
    }
  ]
}
Next step. Check the dates, timeslots, and prices for a variant with the availability API.