Get Product
Retrieve a single product by its ID.
Endpointโ
GET /v1/products/{id}
Authenticationโ
Requires an API key with the products:read scope.
Parametersโ
| Parameter | Type | Location | Description |
|---|---|---|---|
id | integer | path | The product ID |
lang | string | query | Return translated content fields (name, brief_description, long_description, custom_sections, category name) 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. Defaults to en. |
Responseโ
Success (200 OK)โ
{
"data": {
"id": 1,
"name": "Mountain Bike",
"sku": "MTB-001",
"status": "active",
"brief_description": "High-quality mountain bike for trail riding",
"long_description": "Full suspension mountain bike perfect for beginners and intermediate riders...",
"category": {
"id": 5,
"name": "Bikes"
},
"from_price": 50.00,
"from_price_unit": "day",
"pricing": {
"applies": "yearRound",
"structure": "flat",
"rate_mode": "total",
"uses_template": false,
"rules": [
{
"id": 1,
"season_id": null,
"price_structure": "flat",
"price": 50.00,
"interval": 1,
"label": null,
"interval_units": "Days",
"display_on_widget": true
}
]
},
"rental_constraints": {
"min": { "value": 1, "unit": "Days" },
"max": { "value": 7, "unit": "Days" }
},
"min_booking_notice": {
"value": 2,
"unit": "Hours",
"minutes": 120,
"same_day_cutoff_time": null,
"inherited": false
},
"buffer_time": {
"enabled": true,
"before": { "value": 30, "unit": "minutes" },
"after": { "value": 30, "unit": "minutes" }
},
"inventory": true,
"inventory_tracking": "group",
"booking_mode": "instant",
"allow_shortage": true,
"max_shortage": 2,
"has_variations": true,
"bundle_only": false,
"require_participants": false,
"require_participants_override": null,
"participants_per_unit": 1,
"variations": [
{
"id": 10,
"sku": "MTB-001-S",
"values": [
{ "property": "Size", "value": "Small" }
],
"image": null
},
{
"id": 11,
"sku": "MTB-001-L",
"values": [
{ "property": "Size", "value": "Large" }
],
"image": "https://example.com/images/mtb-large.jpg"
}
],
"images": [
{
"id": 1,
"url": "https://example.com/images/mtb-1.jpg",
"is_default": true,
"position": 0
},
{
"id": 2,
"url": "https://example.com/images/mtb-2.jpg",
"is_default": false,
"position": 1
}
],
"default_image": {
"id": 1,
"url": "https://example.com/images/mtb-1.jpg"
},
"custom_fields": [
{
"field_id": 2,
"label": "Serial Number",
"field_type": "text",
"value": "SN-12345-ABC",
"formatted_value": "SN-12345-ABC"
}
],
"content_blocks": {
"whats_included": [{"label": "Paddle", "description": null}],
"does_not_include": [{"label": "Wetsuit hire", "description": null}],
"itinerary": null,
"highlights": ["Self-drain hull"],
"check_in_details": "<p>Pick up from the kiosk on <strong>Pier 4</strong>.</p>",
"what_to_bring": ["Sunscreen"],
"restrictions": "<p>Minimum age 12.</p>",
"health_and_safety": "<p>Life vest included.</p>",
"cancellation_notes": "<p>Free cancellation up to 24 hours before.</p>",
"custom_sections": [
{ "heading": "Parking", "body": "<p>Free lot next to the pier.</p>" }
]
},
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-15T10:30:00+00:00"
},
"meta": {
"request_id": "req_abc123",
"timestamp": "2026-01-15T12:00:00+00:00"
}
}
Response Fieldsโ
See List Products for complete field descriptions.
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 |
Content Blocksโ
The content_blocks object contains the eight supplier-authored sections rendered on the booking widget (what's included, itinerary, highlights, check-in details, what to bring, restrictions, health & safety, cancellation notes), plus custom_sections โ an ordered list of free-form { heading, body } blocks, plus location (where the item happens, used for the map under the check-in / pickup section). The four prose fields and each custom-section body are allowlisted rich-text HTML. Shape is identical for products and experiences โ see Content Blocks for the full field reference.
Custom field definitions can be retrieved via GET /v1/settings/custom-fields.
Errorsโ
| Status | Code | Description |
|---|---|---|
| 401 | authentication_required | No API key provided |
| 401 | invalid_api_key | Invalid API key |
| 403 | insufficient_scope | API key lacks products:read scope |
| 403 | forbidden | Product belongs to different supplier |
| 404 | resource_not_found | Product does not exist |
Example Requestโ
curl -X GET "https://app.equipdash.com/api/v1/products/1" \
-H "Authorization: Bearer eqd_live_abc123xyz789..."
With translated content (the supplier must have that booking widget language enabled):
curl -X GET "https://app.equipdash.com/api/v1/products/1?lang=fr" \
-H "Authorization: Bearer eqd_live_abc123xyz789..."