List Experiences
Retrieve a paginated list of experiences (tours, activities, classes).
Endpointโ
GET /v1/experiences
Authenticationโ
Requires an API key with the experiences:read scope.
Query Parametersโ
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
per_page | integer | 15 | Items per page (max 100) |
status | string | - | Filter by status: active, inactive |
category_id | integer | - | Filter by category ID |
include_unlisted | boolean | false | Include marketplace-only experiences (list_as_experience: false), which are excluded by default. |
public | boolean | false | Only what the public booking site shows: leaves out Staff only experiences as well as marketplace-only ones. Staff only experiences are listed by default. |
search | string | - | Search by name |
sort | string | - | Sort field: id, name, created_at, status, sort_order. Prefix with - for descending (e.g. -name). |
lang | string | en | Return translated content fields (name, brief_description, long_description, custom_sections, category names) in the given language, e.g. fr. Only applies when the supplier has that booking widget language enabled โ otherwise, and for any field without a translation yet, the English value is returned. |
Default order
With no sort parameter, experiences are returned in the supplier's manual display order โ the same order shown in the booking widget, POS, and app (category order, then experience order within each category, as set on the Arrange order screen). Pass an explicit sort to override it.
Responseโ
Success (200 OK)โ
{
"data": [
{
"id": 1,
"name": "Sunset Kayak Tour",
"unique_code": "SKT-001",
"status": "active",
"list_as_experience": true,
"staff_only": false,
"shares_places_with_id": null,
"suggest_in_cart": true,
"who_can_book": "everyone",
"booking_mode": "instant",
"brief_description": "2-hour guided kayak tour at sunset",
"long_description": "Experience the beauty of the coast...",
"category": {
"id": 2,
"name": "Water Activities"
},
"duration": {
"value": 2,
"unit": "hours"
},
"multi_day": false,
"pricing": {
"applies": "yearRound",
"structure": "participant"
},
"capacity": 12,
"is_private": false,
"location": "Marina Bay",
"booking_notice": {
"required": true,
"value": 24,
"unit": "hours"
},
"participants_required": true,
"participants_required_override": true,
"availability": [
{
"id": 1,
"day_of_week": "monday",
"start_time": "17:00:00",
"end_time": "19:00:00",
"capacity": 12
},
{
"id": 2,
"day_of_week": "wednesday",
"start_time": "17:00:00",
"end_time": "19:00:00",
"capacity": 12
}
],
"default_image": {
"id": 5,
"url": "https://example.com/images/kayak-tour.jpg"
},
"custom_fields": [
{
"field_id": 3,
"label": "Difficulty Level",
"field_type": "text",
"value": "Intermediate",
"formatted_value": "Intermediate"
}
],
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-15T10:30:00+00:00"
}
],
"meta": {
"current_page": 1,
"per_page": 15,
"total": 18,
"total_pages": 2,
"request_id": "req_abc123",
"timestamp": "2026-01-15T12:00:00+00:00"
}
}
Response Fieldsโ
Experienceโ
| Field | Type | Description |
|---|---|---|
id | integer | Unique experience identifier |
name | string | Experience name |
unique_code | string | Unique identifier code |
status | string | active or inactive |
list_as_experience | boolean | false = sold only on connected marketplaces (e.g. an experience created purely to list a rental fleet there): hidden from the booking widget, POS and the shop's own website, but still active and fully manageable. Such experiences are excluded from this index by default โ pass include_unlisted=1 to include them. GET /experiences/{id} always returns them. |
staff_only | boolean | true = only the shop's team can book it (POS, the app, this API, Dash); hidden from the booking widget, embeds and the shop's website. Listed here by default; public=1 leaves it out. |
suggest_in_cart | boolean | false when the shop left this experience out of cart suggestions. |
who_can_book | string | Read only. everyone, staff_only, or off (marketplaces only for an experience, not bookable on its own for a product). |
shares_places_with_id | integer or null | Another experience whose places this one uses; bookings on either use places on both when their sessions overlap. null = counts only its own places. |
brief_description | string | Short description |
long_description | string | Full description |
category | object|null | Category details |
duration | object | Per-session duration value and unit (not used for multi-day departures) |
multi_day | boolean | true when each departure spans multiple days (one booking covering several days); its schedules carry an explicit end_date |
pricing | object | Pricing configuration |
unit_name | string|null | What one group is sold as when the experience is priced per unit ("canoe"), so a list can read "$160.00 per canoe". null on a per-person or ordinary per-group experience. |
capacity | integer | Default capacity (for private experiences this is the maximum group size) |
is_private | boolean | Private = one group per time slot: the first booking takes the whole departure. false = shared slots where groups fill seats individually until capacity |
location | string | Where the experience takes place |
booking_notice | object|null | Minimum booking notice required: value and unit (the length), minutes (the length in minutes), same_day_cutoff_time ("HH:MM" shop time when online bookings for the same day close, or null) and inherited (true when it comes from the shop default). |
participants_required | boolean | Whether participant details are required โ the per-experience override resolved against the shop-wide default |
participants_required_override | boolean|null | Raw per-experience setting: null = follows the shop-wide default, true/false = explicit override |
availability | array | Weekly availability schedule |
default_image | object|null | Primary experience image |
custom_fields | array | Custom field values for this experience |
created_at | string | ISO 8601 datetime |
updated_at | string | ISO 8601 datetime |
Custom Fieldsโ
| Field | Type | Description |
|---|---|---|
field_id | integer | Custom field definition ID |
label | string | Field display label |
field_type | string | Field type: text, textarea, number, date, datetime |
value | string|null | Raw value |
formatted_value | string|null | Formatted value for display |
Errorsโ
| Status | Code | Description |
|---|---|---|
| 401 | authentication_required | No API key provided |
| 401 | invalid_api_key | Invalid API key |
| 403 | insufficient_scope | API key lacks experiences:read scope |
Example Requestโ
curl -X GET "https://app.equipdash.com/api/v1/experiences?status=active" \
-H "Authorization: Bearer eqd_live_abc123xyz789..."
Translated Contentโ
Request the catalog in another enabled booking widget language with lang:
curl -X GET "https://app.equipdash.com/api/v1/experiences?status=active&lang=fr" \
-H "Authorization: Bearer eqd_live_abc123xyz789..."
Translated fields return the same values the supplier's booking widget shows in that language:
{
"data": [
{
"id": 1,
"name": "Excursion en kayak au coucher du soleil",
"brief_description": "Excursion guidรฉe de 2 heures en kayak au coucher du soleil",
"...": "..."
}
]
}