---
title: "Duplicate a package"
method: POST
path: "/shop/packages/{packageId}/copy"
tags: ["Packages"]
---

# Duplicate a package

`POST /shop/packages/{packageId}/copy`

Creates a copy of an existing `Package` with new fields applied from
the request body. Useful when seeding a new offering off an existing
one rather than building from scratch. The new package is created
under the same site and organisation as the original; fields not
listed in the body are inherited from the source unchanged.

Requires the `SETTINGS_MANAGE` permission on the original package's
site. As with create/update, `separate_couples_package_choices` is
forced to `false` unless both `min_guests` and `max_guests` equal
`2`, and `overnight_package_config.enabled=true` requires `rate_id`
and `num_nights`.

## Request body

- object
  - `name` string — Display name for the new copy. Strongly recommended so the copy is distinguishable from the source.
  - `description` string — Override the customer-facing long-form description on the copy. Defaults to the source's description when omitted. Markdown rendered.
  - `external_id` string, nullable — Override external identifier on the copy. Defaults to `null` so integrations don't accidentally see two offerings with the same external id.
  - `price` integer — Flat base price (in the smallest currency unit, e.g. pence/cents) to set on the copy. Most packages prefer `price_rules`; this field is a convenience for the simple case.
  - `standard_price` integer, nullable — Override the standard price on the copy, in the smallest currency unit (e.g. pence). Defaults to the source's standard price when omitted.
  - `currency` string — The ISO-4217 currency code.
  - `availability_rules` AvailabilityRule[] — Override the per-day availability rules on the copy.
    - `id` string, object-id, required — The ID of the availability rule.
    - `date_from` string, date, required — The start of the rule period.
    - `date_to` string, date, required — The end of the rule period.
    - `is_available` boolean, required — Whether the resource is available during this period. Any `false` rules will override `true` rules.
    - `max_duration` integer — Maximum number of minutes.
    - `min_duration` integer — Minimum number of minutes.
    - `time_from` string, required — The daily start time of the time period, in 24 hour format.
    - `time_to` string, required — The daily end time of the time period, in 24 hour format.
    - `weekdays` string[] — The weekdays this rule applies to.
  - `offered_online` boolean — Whether the copy is bookable via the public shopfront. Defaults to the source's value.
  - `private` boolean — When true, only customers with the direct link can book the copy.
  - `visibility` 'public' | 'link_only' | 'private' — Visibility override on the copy. Same semantics as on the source.
  - `customers_only` boolean — When true, only registered customers (not guests) can book the copy.
  - `members_only` boolean — When true, only members of permitted membership types can book the copy.
  - `permitted_membership_type_ids` string[], nullable — Membership types whose members can book the copy when `members_only=true`.
  - `membership_booking_windows_enabled` boolean — Whether to apply per-membership-type advance-booking windows on the copy.
  - `membership_booking_windows` MembershipBookingWindow[] — Per-membership-type advance-window overrides on the copy.
    - `membership_type_id` string, uuid, required — The ID of the membership type this booking window applies to.
    - `max_advance_bookings_interval` string, required — The maximum time before a booking's start time that it may be booked, as an ISO8601 string. See https://en.wikipedia.org/wiki/ISO_8601#Durations
    - `min_advance_bookings_interval` string, required — The minimum time before a booking's start time that it may be booked, as an ISO8601 string. See https://en.wikipedia.org/wiki/ISO_8601#Durations
  - `upsell_offerings` OfferingIdentifier[] — Override the upsell candidates surfaced at booking confirmation on the copy.
    - `offering_id` string, mongo-id, required — The ID of the offering.
    - `offering_name` string, required — The name of the offering.
    - `offering_type` 'appointment' | 'appointment_enquiry' | 'area_booking' | 'course' | 'hotel_room_reservation' | 'membership' | 'package' | 'product' | 'session' | 'table_reservation' | 'voucher', required — Discriminator describing what kind of sellable item an `Offering` represents. The value determines which downstream schema (`Appointment`, `Session`, `Package`, etc.) the offering's `offering_id` resolves against, and which checkout/booking flow applies.
  - `cross_sell_offerings` OfferingIdentifier[] — Override the cross-sell candidates surfaced during the booking flow on the copy.
    - `offering_id` string, mongo-id, required — The ID of the offering.
    - `offering_name` string, required — The name of the offering.
    - `offering_type` 'appointment' | 'appointment_enquiry' | 'area_booking' | 'course' | 'hotel_room_reservation' | 'membership' | 'package' | 'product' | 'session' | 'table_reservation' | 'voucher', required — Discriminator describing what kind of sellable item an `Offering` represents. The value determines which downstream schema (`Appointment`, `Session`, `Package`, etc.) the offering's `offering_id` resolves against, and which checkout/booking flow applies.
  - `related_retail_offerings` OfferingIdentifier[] — Override the related retail products on the copy's shopfront page.
    - `offering_id` string, mongo-id, required — The ID of the offering.
    - `offering_name` string, required — The name of the offering.
    - `offering_type` 'appointment' | 'appointment_enquiry' | 'area_booking' | 'course' | 'hotel_room_reservation' | 'membership' | 'package' | 'product' | 'session' | 'table_reservation' | 'voucher', required — Discriminator describing what kind of sellable item an `Offering` represents. The value determines which downstream schema (`Appointment`, `Session`, `Package`, etc.) the offering's `offering_id` resolves against, and which checkout/booking flow applies.
  - `meta` object — SEO metadata for the copy's shopfront page.
    - `title` string, nullable
    - `description` string, nullable
  - `customer_cancellation_permitted` 'allowed' | 'if_unpaid' | 'disallowed', nullable — Customer self-cancellation policy on the copy. `allowed` = always; `if_unpaid` = only if no payment has been taken; `disallowed` = never.
  - `customer_cancellation_min_duration` string, nullable — ISO 8601 duration before the package start during which cancellation is no longer permitted on the copy.
  - `customer_reschedule_permitted` 'allowed' | 'disallowed' | 'unpaid', nullable — Whether and when customers can reschedule a booking of this type themselves. `allowed` = always. `unpaid` = only if no payment has been taken against the order. `disallowed` = never (admin only).
  - `customer_reschedule_min_duration` string, nullable — ISO 8601 duration before the package start during which rescheduling is no longer permitted on the copy.
  - `max_daily_duration` integer — Maximum minutes between first-item start and last-item end on each day for the copy.
  - `max_advance_bookings_interval` string, nullable — ISO 8601 duration limiting how far in advance customers can book the copy.
  - `min_advance_bookings_interval` string, nullable — ISO 8601 duration limiting how soon before the package start a customer can book the copy.
  - `min_guests` integer, nullable — Minimum guests per booking of the copy.
  - `max_guests` integer, nullable — Maximum guests per booking of the copy.
  - `prevent_choice_overlaps` boolean — Whether to prevent booking choices in the copy from overlapping times.
  - `separate_couples_package_choices` boolean, nullable — For couples packages, whether each guest can independently pick choices on the copy. Forced to `false` for any other guest configuration.
  - `email_options` object — Email-rendering options for the copy.
    - `hide_prices` boolean — Hide prices on customer emails for the copy.
  - `overnight_package_config` object — Overnight-package configuration on the copy. When `enabled=true`, both `rate_id` and `num_nights` are required.
    - `enabled` boolean — Whether the copy is an overnight package.
    - `rate_id` string, nullable — PMS rate code ID. Required when `enabled=true`.
    - `num_nights` integer, nullable — Number of nights. Required when `enabled=true`.
  - `include_pricing_on_calendar` boolean — Whether to surface the price alongside the copy in calendar views.
  - `max_per_basket` integer, nullable — Maximum number of the copy per basket.
  - `max_per_guest` integer, nullable — Maximum number of the copy per individual guest per basket.

## Response `201`

A single `Package`.

- object — Single-item envelope mixin. `allOf` this into any show response that wraps its `data` payload in an outer object; the concrete schema (e.g. `ShowUser`) adds its own `data` property with the appropriate `$ref` and keeps its own title so the SDK surface is unchanged.
  - `data` SchemasPackage, required — A bundled set of offerings sold as a single product (e.g. a "Spa Day" combining treatments, lunch and pool access). Packages declare their allocations — which offering types they include and in what quantities — and how the inner items are scheduled, priced and discounted at checkout.
    - `id` string, required — The ID of the package.
    - `allocations` object, required
    - `categories` SchemasCategory2[], required — The category associated with this package type
      - `id` string, object-id, required — The ID of the category.
      - `name` string, required — The name of the category.
    - `category_ids` string[], required — The category IDs associated with this package type
    - `cross_sell_offerings` OfferingIdentifier[], required
      - `offering_id` string, mongo-id, required — The ID of the offering.
      - `offering_name` string, required — The name of the offering.
      - `offering_type` 'appointment' | 'appointment_enquiry' | 'area_booking' | 'course' | 'hotel_room_reservation' | 'membership' | 'package' | 'product' | 'session' | 'table_reservation' | 'voucher', required — Discriminator describing what kind of sellable item an `Offering` represents. The value determines which downstream schema (`Appointment`, `Session`, `Package`, etc.) the offering's `offering_id` resolves against, and which checkout/booking flow applies.
    - `currency` string, required — The ISO-4217 currency code in lower case
    - `customer_cancellation_min_duration` string, nullable, required — The minimum duration that must be left before the booking in order for the customer to cancel, as an ISO8601 string. See https://en.wikipedia.org/wiki/ISO_8601#Durations
    - `customer_cancellation_permitted` 'allowed' | 'disallowed' | 'unpaid', required
    - `customer_reschedule_min_duration` string, nullable, required — The minimum duration that must be left before the booking in order for the customer to reschedule, as an ISO8601 string. See https://en.wikipedia.org/wiki/ISO_8601#Durations
    - `customer_reschedule_permitted` 'allowed' | 'disallowed' | 'unpaid', nullable, required — Whether and when customers can reschedule a booking of this type themselves. `allowed` = always. `unpaid` = only if no payment has been taken against the order. `disallowed` = never (admin only).
    - `customers_only` boolean, required
    - `default_revenue_centre` string, nullable, required — The default revenue centre to fall back to to balance allocations
    - `description` string, required — A description of the package
    - `email_options` PackageOfferingEmailOptions, required
      - `hide_prices` boolean, required — Enable to hide prices from customer emails, in cases where the customer didn't purchase the item directly.
    - `external_id` string, nullable, required — An external identifier for this offering.
    - `image` Media
      - `id` string, uuid, required — Unique identifier of the uploaded media item, returned from `createMedia`. Pass this ID into any field that accepts a media reference (logos, hero images, product images, etc.).
      - `file_name` string, required — Original filename of the uploaded asset, preserved as provided at upload time. Used for display in the media library and as a hint when serving downloads.
      - `mime_type` string, required — The mime type of the media item.
      - `original_url` string, required — The url of the media resource.
      - `size` integer, required — The size of the media item in bytes.
      - `url` string, required — The url of the converted media resource.
    - `include_pricing_on_calendar` boolean, required — Whether the booking engine calendar should display pricing under each date
    - `item_choices` PackageItemChoice[], required — An array of choices for items which may be included in this package.
      - `id` string, required — The ID of this choice.
      - `allocation` object, required
        - `amount` integer, required
        - `revenue_centre` string, required
      - `allow_overlaps` boolean, required — Allow this choice to overlap with other items when `prevent_choice_overlaps` is enabled on the package.
      - `auto_select_timeslot` boolean, required — Whether a timeslot should be automatically selected for this choice
      - `choice_configuration` object, required — Any additional configuration for this choice.
      - `description` string, required — A description of this choice.
      - `hide_times` boolean, required — Whether to hide times for this choice from customers
      - `name` string, required — A name for this choice.
      - `max_options` integer, nullable, required — The maximum number of options that may be chosen.
      - `min_options` integer, nullable, required — The minimum number of options that must be chosen.
      - `offering_type` 'appointment' | 'product' | 'session', required — The type of offerings included in this choice.
      - `option_budget` integer, required — The budget that this package allows for options in this choice. Each option will use its standalone price, and the overall package price will be increased if the total exceeds the budget.
      - `optional` boolean, required — Whether this item choice should be optional.
      - `options` PackageItemChoiceOption[], required — An array of options to make up this choice.
        - `id` string, required — Identifier of the offering this option points at — an `AppointmentType`, `SessionType` or retail `Product`, depending on `item_type`. The guest sees the offering's name and image when picking this option in the storefront.
        - `item_type` string, required — The type of item this option represents.
        - `offering` PackageShopOffering, required
          - `id` string, required — The ID of the offering
          - `categories` object[]
            - `id` string, required — The ID of the category
            - `name` string, required — The name of the category
          - `currency` string, required — The currency code for the price
          - `description` string, required — The name of the offering
          - `discounted_price_from` integer — If set, a discounted 'price from' that applies to the current customer
          - `duration` integer — The duration of the offering in minutes
          - `durations` integer[]
          - `external_id` string, nullable, required — An external identifier for this offering.
          - `has_availability` boolean — Whether there is availability for the offering on the requested date.
          - `image` Media
            - `id` string, uuid, required — Unique identifier of the uploaded media item, returned from `createMedia`. Pass this ID into any field that accepts a media reference (logos, hero images, product images, etc.).
            - `file_name` string, required — Original filename of the uploaded asset, preserved as provided at upload time. Used for display in the media library and as a hint when serving downloads.
            - `mime_type` string, required — The mime type of the media item.
            - `original_url` string, required — The url of the media resource.
            - `size` integer, required — The size of the media item in bytes.
            - `url` string, required — The url of the converted media resource.
          - `max_guests` integer — The maximum guests this offering is for
          - `min_guests` integer — The minimum guests this offering is for
          - `name` string, required — The name of the offering
          - `next_available_date` string, date — The next available date if there is no availability on the given date
          - `price_from` integer — The minimum price of the offering on the given date
          - `price_to` integer — The maximum price of the offering on the given date
          - `type` string — Identifies the type of this model
        - `price_change` integer, nullable, required — A currency amount that this option would increase the package price by.
      - `start_time_rules` PackageChoiceStartTimeRule[], required — An array of rules determining the start times that should be allowed for this choice.
        - `absolute_time_from` string, nullable, required — The earliest allowed start time.
        - `absolute_time_to` string, nullable, required — The latest allowed start time.
        - `relative_mins_from` integer, nullable, required — The minimum number of minutes from the relative base point that should be allowed.
        - `relative_mins_to` integer, nullable, required — The maximum number of minutes from the relative base point that should be allowed.
        - `relative_to` 'first_item_start', nullable, required — The base time that a relative start time should be calculated from.
        - `type` 'relative' | 'absolute', required — The type of the rule.
      - `visible` boolean, required — Whether this item choice should be visible to the customer.
    - `max_advance_bookings_interval` string, nullable, required — The maximum time before the package's start time that it may be booked, as an ISO8601 string. See https://en.wikipedia.org/wiki/ISO_8601#Durations
    - `max_daily_duration` integer, nullable, required — The maximum amount of time between the start of the first and end of the last item on each day of a package, in minutes.
    - `max_guests` integer, required — The maximum guests this package is for
    - `max_per_basket` integer, nullable, required — The maximum number of bookings that may be made in a single basket for this package.
    - `max_per_guest` integer, nullable, required — The maximum number of bookings that may be made by a single guest for this package.
    - `members_only` boolean, required — Whether this package requires an active membership in order to book.
    - `membership_booking_windows` MembershipBookingWindow[], required
      - `membership_type_id` string, uuid, required — The ID of the membership type this booking window applies to.
      - `max_advance_bookings_interval` string, required — The maximum time before a booking's start time that it may be booked, as an ISO8601 string. See https://en.wikipedia.org/wiki/ISO_8601#Durations
      - `min_advance_bookings_interval` string, required — The minimum time before a booking's start time that it may be booked, as an ISO8601 string. See https://en.wikipedia.org/wiki/ISO_8601#Durations
    - `membership_booking_windows_enabled` boolean, required — Whether membership-specific booking windows should be enabled for this package.
    - `meta` object, required
      - `description` string, nullable, required — The meta description of this offering. If not specified, it falls back to the description of the offering.
      - `title` string, nullable, required — The meta title of this offering. If not specified, it falls back to the name of the offering.
    - `min_advance_bookings_interval` string, nullable, required — The minimum time before the package's start time that it may be booked, as an ISO8601 string. See https://en.wikipedia.org/wiki/ISO_8601#Durations
    - `min_guests` integer, required — The minimum guests this package is for
    - `name` string, required — The name of this package
    - `offered_online` boolean, required — Whether this session type is bookable online
    - `overnight_package_config` object, required
      - `enabled` boolean — Whether this package is an overnight package.
      - `rate_id` string — The ID of the rate this package is associated with.
      - `num_nights` integer — The number of nights this package is associated with.
    - `permitted_membership_type_ids` string[] — If this package is for members only, this property may be used to restrict the offering further so it may only be purchased by active members with of one of the given membership types.
    - `prevent_choice_overlaps` boolean, required — Whether to prevent booking choices in this package from overlapping times.
    - `price_rules` PackagePriceRule[], required — The rules defining prices for this package
      - `id` string, required — The ID of the price rule.
      - `package_id` string, required — The ID of the package the price rule relates to.
      - `date_from` string, date, nullable, required — The rule should apply to packages starting on or after this date.
      - `date_to` string, date, nullable, required — The rule should not apply to packages starting after this date.
      - `time_from` string, nullable, required — The rule will apply to packages that have bookings starting on or after this time.
      - `time_to` string, nullable, required — The rule will apply to packages that have bookings starting before this time.
      - `weekdays` string[], required — The rule should apply to packages starting on any of these weekdays.
      - `price` integer, required — The price of the package.
    - `private` boolean, required — Whether this is private. When private, it is accessible from the URL but doesn't appear on category pages and isn't indexed on search engines.
    - `product_code` string, nullable, required — A custom product code for the package.
    - `related_retail_offerings` OfferingIdentifier[], required
      - `offering_id` string, mongo-id, required — The ID of the offering.
      - `offering_name` string, required — The name of the offering.
      - `offering_type` 'appointment' | 'appointment_enquiry' | 'area_booking' | 'course' | 'hotel_room_reservation' | 'membership' | 'package' | 'product' | 'session' | 'table_reservation' | 'voucher', required — Discriminator describing what kind of sellable item an `Offering` represents. The value determines which downstream schema (`Appointment`, `Session`, `Package`, etc.) the offering's `offering_id` resolves against, and which checkout/booking flow applies.
    - `separate_couples_package_choices` boolean, required — If this is a couples package, defines whether each person should be able to make different choices.
    - `site_id` string, required — The ID of the site the package belongs to.
    - `standard_price` integer, nullable, required — The standard price for this package, in the smallest currency unit (e.g. pence). `null` if a standard price hasn't been configured — this is distinct from a price of zero.
    - `upsell_offerings` OfferingIdentifier[], required
      - `offering_id` string, mongo-id, required — The ID of the offering.
      - `offering_name` string, required — The name of the offering.
      - `offering_type` 'appointment' | 'appointment_enquiry' | 'area_booking' | 'course' | 'hotel_room_reservation' | 'membership' | 'package' | 'product' | 'session' | 'table_reservation' | 'voucher', required — Discriminator describing what kind of sellable item an `Offering` represents. The value determines which downstream schema (`Appointment`, `Session`, `Package`, etc.) the offering's `offering_id` resolves against, and which checkout/booking flow applies.
    - `visibility` 'public' | 'link_only' | 'private' — The visibility status of the product.
    - `deleted_at` string, date-time, nullable, required — When then resource was deleted.
    - `updated_at` string, date-time, required — When then resource was last updated.

## Other responses

- `401` — The user is unauthenticated
- `403` — The authenticated user does not have permission.
- `404` — The resource couldn't be found
- `422` — The request didn't pass validation

---

[API](https://skmtc.dev/try/apis/trybe-api.md) · [All operations](https://skmtc.dev/try/apis/trybe-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/try/trybe-api/revisions/f37f92702da5/schema)
