# Create a cart A cart is the starting point for any booking. It holds items, customer information, and optional discount codes until an order is created. ## Recommended flow The recommended flow is to create an empty cart, then add items and other details in separate steps. This approach provides more flexibility and better error handling for each item. 1. **Create an empty cart** (see [basic cart creation](#basic-cart-creation) below) 2. **Add items to the cart** using the [add items endpoint](/api/booking-flow/cart/add-items) 3. **Add customer details** and other information as needed ## Basic cart creation To create an empty cart, make the following request: ```bash curl -X POST '{baseUrl}/carts' \ -H 'X-Musement-Application: {applicationValue}' \ -H 'X-Musement-Version: 3.4.0' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{}' ``` The response returns an empty cart: ```json { "uuid": "cc6fcf36-2ec6-41b8-b715-1072d4e441e4", "items": [], "full_price": { "currency": "EUR", "value": 0, "formatted_value": "€ 0.00" }, "discount": { "currency": "EUR", "value": 0, "formatted_value": "€ 0.00" } } ``` Hold onto the cart's `uuid` property. You'll need it whenever you add products, update customer details, or create an order. ## Alternative: Creating a cart with initial data It is also possible to provide initial data when creating a cart. The sections below show the available options. ### With tickets You can create a cart with products already included by providing a `tickets` array: ```bash curl -X POST '{baseUrl}/carts' \ -H 'X-Musement-Application: {applicationValue}' \ -H 'X-Musement-Version: 3.4.0' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "tickets": [ { "product": { "id": 123456789 }, "quantity": 2 } ] }' ``` The response includes the cart with the requested items and calculated totals: ```json { "uuid": "d83d4e0a-e62b-4c81-b403-4206914cd697", "items": [ { "uuid": "e21aee18-f035-4198-a2f5-2bec63501d1b", "status": "PREBOOK_OK", "quantity": 2, "total_price": { "currency": "EUR", "value": 48, "formatted_value": "€ 48.00" } } ], "full_price": { "currency": "EUR", "value": 48, "formatted_value": "€ 48.00" } } ``` ### With customer information You can include customer details when creating a cart: ```bash curl -X POST '{baseUrl}/carts' \ -H 'X-Musement-Application: {applicationValue}' \ -H 'X-Musement-Version: 3.4.0' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "customer": { "email": "customer@example.com", "firstname": "John", "lastname": "Doe", "country": { "id": 1 }, "mobile": "+1234567890" } }' ``` If a customer with the provided email already exists, their record will be updated with the new information. Otherwise, a new customer record is created. The response includes the customer object: ```json { "uuid": "cc6fcf36-2ec6-41b8-b715-1072d4e441e4", "items": [], "customer": { "email": "customer@example.com", "firstname": "John", "lastname": "Doe" } } ``` ### With discount code You can apply a promo code or gift card when creating a cart using the `discount_code` parameter: ```bash curl -X POST '{baseUrl}/carts' \ -H 'X-Musement-Application: {applicationValue}' \ -H 'X-Musement-Version: 3.4.0' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "discount_code": "PROMO10" }' ``` If the code is a valid promo code, the response includes a `promo_code` object: ```json { "uuid": "bf82a0af-e3b2-48a8-9368-a7417539d5e1", "items": [], "promo_code": { "code": "PROMO10" } } ``` If the code is a valid gift card, the response includes a `gift_card` object instead: ```json { "uuid": "bf82a0af-e3b2-48a8-9368-a7417539d5e1", "items": [], "gift_card": { "code": "GIFTCARD123", "balance": { "currency": "EUR", "value": 50, "formatted_value": "€ 50.00" } } } ``` For more information on promo codes, see the [promo codes page](/api/booking-flow/cart/promo-codes). ## Validating promo codes with customer email Some promo codes have a "once per customer" rule. To validate these codes before adding full customer details, use the `customer_email` parameter: ```bash curl -X POST '{baseUrl}/carts' \ -H 'X-Musement-Application: {applicationValue}' \ -H 'X-Musement-Version: 3.4.0' \ -H 'Authorization: Bearer {accessToken}' \ -H 'Content-Type: application/json' \ --data-raw '{ "discount_code": "ONCE_PER_USER", "customer_email": "customer@example.com" }' ``` This allows the API to check if the customer has already used the code without requiring full customer information upfront. ## Response structure A successful cart creation returns the following properties: | Property | Description | | --- | --- | | `uuid` | Unique identifier for the cart | | `items` | Array of cart items (empty for new carts without tickets) | | `full_price` | Total price before discounts | | `full_price_without_service_fee` | Total price excluding service fees (API v3.4.0+) | | `discount` | Total discount amount | | `retail_price` | Final price after discounts | | `retail_price_without_service_fee` | Final price excluding service fees (API v3.4.0+) | | `service_fee` | Service fee amount | | `customer` | Customer object (if provided) | | `promo_code` | Promo code object (if applied) | | `gift_card` | Gift card object (if applied) | ## Error handling Cart creation can fail for several reasons: ### Invalid product If you include tickets with a non-existent product ID: ```json { "code": "1001", "message": "Product code not valid" } ``` ### Unavailable product If the requested product is no longer available: ```json { "code": "2101", "message": "Failed to add Ticket to Cart. Ticket is not available." } ``` ### Invalid discount code If the provided discount code is invalid or expired: ```json { "code": "3001", "message": "The discount code is invalid" } ``` ### Missing JWT claim If using JWT authentication without the required legacy OAuth2 client claim: ```json { "code": "4001", "message": "claim_legacy_oauth2_client_public_id not found in the JWT payload" } ``` Abandoned carts Carts without an order are automatically removed after three months.