Event Packages API
The Event Packages API provides endpoints for managing pre-built multi-activity packages (admin) and browsing available packages (public).
Overview
Event packages combine multiple activities into a single bookable unit. For example, a "Corporate Redi Experience" package might include 1 hour of Hohtogolf and 1 hour of Laserareena.
Packages support:
- Per-person bundle pricing (e.g., €55/person for all activities)
- Fixed pricing (e.g., €1,000 flat rate)
- Party size constraints (min/max)
- Public/private visibility control
Public Endpoints
These endpoints are available without authentication, requiring only a tenant context via x-tenant-id header.
List Public Packages
GET /api/v1/event-packages
Returns all active, public event packages for the tenant.
Response:
[
{
"id": "pkg_abc123",
"name": "Corporate Redi Experience",
"description": "Hohtogolf + Laserareena for your team event",
"slug": "corporate-redi-experience",
"minPartySize": 10,
"maxPartySize": 40,
"bundlePricePerPerson": 55.0,
"fixedPrice": null,
"imageUrl": "https://cdn.example.com/packages/redi.jpg",
"isActive": true,
"isPublic": true,
"items": [
{
"id": "item_1",
"productId": "p_hohtogolf",
"siteId": "s_redi",
"sortOrder": 0,
"durationOverride": null,
"isRequired": true
},
{
"id": "item_2",
"productId": "p_laser",
"siteId": "s_redi",
"sortOrder": 1,
"durationOverride": null,
"isRequired": true
}
]
}
]
Get Package by Slug
GET /api/v1/event-packages/:slug
Returns a single package by its URL-friendly slug.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
slug | string | URL-friendly package slug |
Admin Endpoints
All admin endpoints require Bearer token authentication and manage_catalog permission.
List All Packages
GET /api/v1/admin/event-packages
Returns all non-deleted packages (including inactive and private ones).
Create Package
POST /api/v1/admin/event-packages
Request Body:
{
"name": "Corporate Redi Experience",
"description": "Hohtogolf + Laserareena for your team event",
"minPartySize": 10,
"maxPartySize": 40,
"bundlePricePerPerson": 55.0,
"isActive": true,
"isPublic": false,
"holdTtlMinutes": 30,
"items": [
{
"productId": "p_hohtogolf",
"siteId": "s_redi",
"sortOrder": 0
},
{
"productId": "p_laser",
"siteId": "s_redi",
"sortOrder": 1
}
]
}
Request Fields:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Package display name |
description | string | No | Marketing description |
minPartySize | number | Yes | Minimum group size (at least 1) |
maxPartySize | number | Yes | Maximum group size (up to 500) |
bundlePricePerPerson | number | No | Per-person bundle price (overrides individual pricing) |
fixedPrice | number | No | Fixed total price (overrides per-person pricing) |
imageUrl | string | No | URL for package image |
isActive | boolean | No | Active status (default: true) |
isPublic | boolean | No | Visible to customers (default: false) |
holdTtlMinutes | number | No | Custom hold duration for this package (5-120 min) |
items | array | No | Activities to include (can be added later) |
A URL-friendly slug is auto-generated from the name (e.g., "Corporate Redi Experience" becomes "corporate-redi-experience"). Slugs must be unique per tenant.
Update Package
PATCH /api/v1/admin/event-packages/:id
Accepts partial updates. If the name changes, the slug is regenerated.
Delete Package
DELETE /api/v1/admin/event-packages/:id
Soft deletes the package. Existing booking groups referencing this package are not affected.
Add Activity to Package
POST /api/v1/admin/event-packages/:id/items
Request Body:
{
"productId": "p_hohtogolf",
"siteId": "s_redi",
"sortOrder": 0,
"durationOverride": 60
}
The product must belong to the specified site. Returns 400 if the product-site relationship is invalid.
Remove Activity from Package
DELETE /api/v1/admin/event-packages/:id/items/:itemId
Update Activity in Package
PATCH /api/v1/admin/event-packages/:id/items/:itemId
Update sort order, duration override, or required status.
Pricing Logic
When a booking group is created from a package, pricing is determined by priority:
- Fixed price (
fixedPrice) — used as the group total regardless of party size - Per-person bundle (
bundlePricePerPerson) — multiplied by party size - Individual sum — if neither is set, sums each activity's individual product price
The total is allocated proportionally across child bookings based on each product's individual price ratio. This allocation is used for partial refund calculations.