Skip to content
Last updated

Create an order

After a cart has been filled with products and customer data, you can create an order with the following request:

curl -X POST '{baseUrl}/orders' \
-H 'X-Musement-Application: {applicationValue}' \
-H 'X-Musement-Version: 3.4.0' \
-H 'Authorization: Bearer {accessToken}' \
-H 'Content-Type: application/json' \
--data-raw '{
	"cart_uuid": "{cartUuid}",
	"email_notification": "NONE"
}'

A successful request returns a new order:

{
	"identifier": "MUS0738876",
	"uuid": "8bd6f4a4-ece7-4cf6-a1c4-2455b6f5f514",
	"date": "2018-08-17T15:59:43+0000",
	"status": "PENDING",
	"market": "us",
	"source": "frontend",
	"isAgency": false,
	"isPaid": false,
	"extraData": null,
	"trustpilot_url": "https://us.trustpilot.com/evaluate/embed/www.musement.com?a=MUS0738876&b=Zm9vQHN0YXlvbG9neS5jb20=&c=Test+3.3.0+One+&e=bac16bfbee8271a62fa90988dd70065a0af93164&stars=5",
	"customer": {
		"email": "example@musement.com",
		"firstname": "John",
		"lastname": "Smith"
	},
	"items": [
		{
			"uuid": "8b742505-38c7-4bed-9bf5-468a3e7cc731",
			"transaction_code": "19c8af5f-2a1c-487d-be27-cfdc20c03c83",
			"product": {
				"type": "musement",
				"max_confirmation_time": "P0D",
				"price_tag": {
					"price_feature": "Tour",
					"ticket_holder": "Adult",
					"price_feature_code": "tour",
					"ticket_holder_code": "adult"
				},
				"date": "2018-09-01 15:30",
				"id": "434696106",
				"title": "Exclusive skip-the-line guided visit of Leonardo da Vinci's vineyard",
				"api_url": "https://sandbox.musement.com/api/v3/activities/11eeb25c-2046-11e7-9cc9-06a7e332783f",
				"url": "https://sandbox.musement.com/us/milan/exclusive-skip-the-line-guided-visit-of-leonardo-da-vinci-s-vineyard-3936/",
				"cover_image_url": "https://images.musement.com/cover/0002/50/thumb_149030_cover_header.jpeg",
				"original_retail_price": {
					"currency": "USD",
					"value": 21,
					"formatted_value": "$ 21.00"
				},
				"retail_price": {
					"currency": "USD",
					"value": 21,
					"formatted_value": "$ 21.00"
				},
				"discount_amount": {
					"currency": "USD",
					"value": 0,
					"formatted_value": "$ 0.00"
				},
				"service_fee": {
					"currency": "USD",
					"value": 0,
					"formatted_value": "$ 0.00"
				}
			},
			"quantity": 2,
			"status": "PENDING",
			"vouchers": []
		}
	],
	"total_price": {
		"currency": "USD",
		"value": 42,
		"formatted_value": "$ 42.00"
	},
	"discount_amount": {
		"currency": "USD",
		"value": 0,
		"formatted_value": "$ 0.00"
	}
}

For subsequent requests in the API involving the order, use its uuid property. The same property can also be used when contacting us about questions or issues, but you are also free to use the more human-friendly identifier property.

Pay for the order

We strongly recommend creating orders only when payment is guaranteed. This reduces the number of unnecessary API calls. Additionally, creating too many unpaid orders can lead to misleading sales reports for the Strategic partnerships team.

Abandoned carts

Carts without an order are automatically removed after three months.

Request parameters

The following table describes all available request parameters:

ParameterTypeRequiredDescription
cart_uuidstring (UUID)Yes*The UUID of the cart to create an order from.
cart_idintegerYes*Legacy cart identifier. Use cart_uuid instead.
email_notificationstringNoControls email notifications. See Email notifications. Default: ALL.
sms_notification_tostringNoPhone number in E.164 format for SMS notifications (e.g., +39123456789).
affiliatestringNoAffiliate identifier for tracking partner sales.
affiliate_channelstringNoAffiliate channel name. Requires affiliate to be set.
extra_datastringNoSerialized JSON object with custom key-value pairs. See Extra data.
refundablebooleanNoWhether the order should be refundable. Default: true.
sourcestringNoOrder source identifier (e.g., frontend, app). Available from API version 3.4.0.

*You must provide either cart_uuid or cart_id, but not both.

Request validation

The API validates requests according to the following rules:

  • Either cart_uuid or cart_id must be provided, but not both
  • If affiliate_channel is provided, affiliate must also be provided
  • The sms_notification_to must be a valid phone number in E.164 format
  • The extra_data must be a valid serialized JSON object

Cart requirements

Before creating an order, ensure the cart meets these requirements:

  • The cart must have a customer with a valid email address
  • The cart must contain at least one available item
  • The cart must not be locked by a previously paid order

If the cart has a previous unpaid order (in created or authorization_failed state), that order will be automatically cancelled and a new order will be created.

Email notifications

Note the email_notification property in the example request above. This property affects email notifications which are sent to the lead booker and activity providers. It accepts the following values:

  • ALL: Emails are sent to both the lead booker and the activity providers.
  • NONE: No emails are sent.
  • TO-CUSTOMER: Emails are sent to the lead booker only.

Partners who opt to send no email notifications assume responsibility of managing all communication with their customers regarding the order. This includes issuing vouchers and communicating status changes.

In the sandbox environment, this property has no effect. For more information, refer to the test purchases guide.

Extra data

When creating an order, partners can add the extra_data property to the request body to include additional information which might be relevant for their own booking systems. The exact values to save are the partner's choice. However, be aware that this property only accepts a serialized JSON object with key-value pairs:

curl -X POST '{baseUrl}/orders' \
-H 'X-Musement-Application: {applicationValue}' \
-H 'X-Musement-Version: 3.4.0' \
-H 'Authorization: Bearer {accessToken}' \
-H 'Content-Type: application/json' \
--data-raw '{
	"cart_uuid": "{cartUuid}",
	"email_notification": "NONE",
	"extra_data": "{\"clientReferenceId\":\"12345678\",\"firstName\":\"John\",\"lastName\":\"Smith\",\"reservationId\":\"3E5B7445-00E6-4ED6-9321-19E30D73A128\",\"utm_campaign\":\"example-it\",\"utm_content\":\"it-native\",\"utm_medium\":\"example-App it\",\"utm_source\":\"channel-abc\"}"
}'

In the example request above, the partner is saving the following object to extra_data:

{
	"clientReferenceId": "12345678",
	"firstName": "John",
	"lastName": "Smith",
	"reservationId": "3E5B7445-00E6-4ED6-9321-19E30D73A128",
	"utm_campaign": "example-it",
	"utm_content": "it-native",
	"utm_medium": "example-App it",
	"utm_source": "channel-abc"
}

Affiliate tracking

To track orders for affiliate partners, include the affiliate and optionally affiliate_channel parameters:

curl -X POST '{baseUrl}/orders' \
-H 'X-Musement-Application: {applicationValue}' \
-H 'X-Musement-Version: 3.4.0' \
-H 'Authorization: Bearer {accessToken}' \
-H 'Content-Type: application/json' \
--data-raw '{
	"cart_uuid": "{cartUuid}",
	"affiliate": "affiliate_123",
	"affiliate_channel": "web"
}'
Affiliate channel requirement

You cannot specify affiliate_channel without also specifying affiliate.

SMS notifications

To enable SMS notifications for the customer, provide a phone number in E.164 format:

curl -X POST '{baseUrl}/orders' \
-H 'X-Musement-Application: {applicationValue}' \
-H 'X-Musement-Version: 3.4.0' \
-H 'Authorization: Bearer {accessToken}' \
-H 'Content-Type: application/json' \
--data-raw '{
	"cart_uuid": "{cartUuid}",
	"sms_notification_to": "+39123456789"
}'

Source field

The source field allows you to track where orders originate from (e.g., frontend, app, agency). This field is available from API version 3.4.0.

From API version 3.5.0, only the explicit source field is used. In earlier versions, the source could also be extracted from the extra_data field.

curl -X POST '{baseUrl}/orders' \
-H 'X-Musement-Application: {applicationValue}' \
-H 'X-Musement-Version: 3.5.0' \
-H 'Authorization: Bearer {accessToken}' \
-H 'Content-Type: application/json' \
--data-raw '{
	"cart_uuid": "{cartUuid}",
	"source": "frontend"
}'

Response structure

A successful order creation returns the following fields:

FieldTypeDescription
identifierstringHuman-readable order identifier (e.g., MUS0738876).
uuidstringUnique order UUID for API operations.
datedatetimeOrder creation timestamp in ISO 8601 format.
statusstringOrder status. Available until API version 3.5.99. See order statuses.
customerobjectCustomer information with firstname, lastname, and email.
itemsarrayArray of order items with product details, quantity, status, and vouchers.
total_priceobjectTotal order price with currency, value, and formatted_value.
discount_amountobjectTotal discount amount with currency, value, and formatted_value.
extraDatastringCustom data stored with the order (JSON string).
marketstringMarket code assigned to the order.
sourcestringOrder source identifier. Available from API version 3.4.0.
isAgencybooleanWhether the order is from an agency.
isPaidbooleanWhether the order has been paid.

Error handling

The API returns appropriate error responses for various failure scenarios:

Cart identifier errors

Missing cart identifier (HTTP 400)

{
	"code": 400,
	"message": "You must specify the id or the uuid"
}

Both identifiers provided (HTTP 400)

{
	"code": 400,
	"message": "You can specify the id or the uuid. Not both"
}

Cart validation errors

No customer set (HTTP 400)

{
	"code": 400,
	"message": "No customer set for the Cart. In order to set the customer please call PUT {{api_base_url}}/carts/{{cart_uuid}}/customer"
}

Customer without email (HTTP 400)

{
	"code": 400,
	"message": "No valid customer associated with the cart"
}

Empty cart (HTTP 400)

{
	"code": 400,
	"message": "You are trying to create and order from an empty cart. Please add at least one item to the cart before."
}

Unavailable items (HTTP 400)

{
	"code": 400,
	"message": "We are really sorry. There was an error while creating the order because the items you had in the cart are not available anymore. Please add new items and try again."
}

Parameter validation errors

Invalid phone number (HTTP 400)

{
	"code": 400,
	"message": "Invalid phone number. Required format E164"
}

Affiliate channel without affiliate (HTTP 400)

{
	"code": 400,
	"message": "You can not specify the affiliate channel without specify the affiliate."
}

Invalid extra_data format (HTTP 400)

{
	"code": 400,
	"message": "Extra data must be a serialized JSON object of key-value pairs"
}

Promo code errors

If the cart has an invalid or expired promo code, the order creation will fail with a discount code error.

Full request example

Here's a complete example with all optional parameters:

curl -X POST '{baseUrl}/orders' \
-H 'X-Musement-Application: {applicationValue}' \
-H 'X-Musement-Version: 3.5.0' \
-H 'Authorization: Bearer {accessToken}' \
-H 'Content-Type: application/json' \
--data-raw '{
	"cart_uuid": "550e8400-e29b-41d4-a716-446655440000",
	"affiliate": "affiliate_123",
	"affiliate_channel": "web",
	"email_notification": "TO-CUSTOMER",
	"sms_notification_to": "+39123456789",
	"extra_data": "{\"clientReferenceId\":\"12345678\",\"reservationId\":\"3E5B7445-00E6-4ED6-9321-19E30D73A128\"}",
	"refundable": true,
	"source": "frontend"
}'