# Importing data

> Bring bookings, customers, vouchers and bundles across from Acuity, Bookwhen, Periode and others.

Who can do this: admins only.

Import from any tool that exports a spreadsheet, in four types: **Bookings** (past and future; every attendee becomes a customer), **Gift vouchers** and **Bundles** (existing codes with their remaining balance or sessions), and **Customers** (a mailing list with marketing consent). For the whole switch in order, see [switch to Session](/docs/switching-to-session).

Customers claim their account at `bookasession.org/your-link/welcome` with the **same email address** you had on file. Credits and codes work whether or not they claim it.

## Members

**We move member lists for you** - send us a message. Members arrive inactive, so nobody is charged twice. On reactivating, a member pays nothing that day (their first payment falls on their old renewal date) and their credits apply automatically. Tell us who cancels the old subscriptions: you, or each member.

Track them under **Imported members** on [Customers](/go/admin/users); they move into **Members** as they re-subscribe. Until someone completes the reactivation prompt, they pay standard prices.

## Before you start

<Callout variant="warning">
**Import on the day you switch over, once your old system has stopped selling.** Anything sold in between is missed, and a second import skips existing codes instead of refreshing balances.
</Callout>

**Create first:** your **sessions** (required, so bookings link up), **membership tiers** if members are coming across, and optionally **bundle products** (without one, packs arrive as unrestricted credits).

**Export** as CSV, TSV or XLSX, with headers in the first row and **an email on every row**, up to 25 MB and 50,000 rows. From **Periode**, [send us your exports](/docs/switching-to-session#from-periode) instead.

## Exporting from Acuity

### Appointments (bookings and customers)

<Steps>
<Step>In Acuity, **Export** your appointments from **Reports**, covering the history you want plus everything upcoming.</Step>
<Step>Include **Email**, **Type**, **Start time**, **Price**, **Amount paid**, **Appointment ID**, **Scheduled by** and the **status** column (sometimes called Canceled), and import it as **Bookings**.</Step>
</Steps>

<Callout variant="tip" title="Cancelled appointments">
Map **status** and mark which values mean cancelled: those appointments are skipped, their customers still added.
</Callout>

### Clients (a mailing list on its own)

For contacts who never booked, export from **Clients** → **Import / Export** → **Export** and import it as **Customers**.

<Callout variant="warning">
Session never assumes consent. If your intake form asked about marketing, map that column as consent. Otherwise add one or import everyone as **Not asked**.
</Callout>

### Gift certificates and packages (fill these by hand)

Acuity can't export these balances, so either:

- **Send us** a screenshot of Acuity's **Gift Certificates** and **Packages** screens and we'll build the file, or
- **Build a spreadsheet** with one row each: **code**, customer **email**, and **remaining value** or **remaining sessions**. Import it as **Gift vouchers** or **Bundles**, mapping the **Code** column so existing codes keep working.

## Exporting from Wix

<Steps>
<Step>**Bookings:** export Wix's **Booking List** as a CSV - scroll to the end first so every booking loads. Import it below, or send it to us if its columns don't map.</Step>
<Step>**Contacts:** export Wix **Contacts** as a CSV (up to 50,000 at a time).</Step>
<Step>**Pricing Plans** members re-subscribe on Session - see [members](#members). Package balances and gift cards come across from a spreadsheet, like [Acuity's](#gift-certificates-and-packages-fill-these-by-hand).</Step>
</Steps>

## Exporting from Bookwhen

Export **Attendances** (not Bookings, which has no session times) as a CSV. Each booking goes to the person who booked, with guests as extra spaces and Bookwhen's fee in the amount paid. Give private tickets your **private** price.

## Running an import

<Steps>
<Step>**Upload** your file under [Settings → Data](/go/admin/settings/data) and confirm the type Session detected.</Step>
<Step>**Map your columns**, and pick your file's date format and a fallback timezone.</Step>
<Step>**Review what was found** - link upcoming session times to your sessions, choose sessions for past appointment types and a price for each type, and optionally link bundles to a product.</Step>
<Step>**Confirm and run**, optionally emailing booking customers from a chosen date forward. Results list failed rows to fix and re-upload, and the welcome link.</Step>
</Steps>

## Column guide

Email is required on every type. Prices (£15.00, 15,00 €, 1,234.56) and phone numbers are understood in any common format.

- **Bookings** - Type, Start time, Appointment price and **Amount Paid Online** (not the yes/no Paid? column). **External ID** and **Status** are recommended. Rows with the same email, type and start time merge into one booking with that many spaces. Pick each type's price; a **private** price books the whole session. Staff-made appointments (an email in **Scheduled by**) show as **Added by staff**. Refund imported money in your old system - cancelling here only records it. A booking paid with an imported gift certificate or package is linked to that code once both are imported, so cancelling it puts the value back. That needs the booking's **Appointment price** for a gift certificate; without it, add the value back by hand on the code.
- **Gift vouchers** - Products, which gives the session count ("Gift Voucher - 5 Sessions"). Add **Remaining balance** and **Status** if any are used (used and expired rows are left out), or every row imports at full value. A missing Code is generated; an Order date sets a 12-month expiry.
- **Bundles** - one row per order (Products) or per package (Package name + Sessions total), optionally with Sessions remaining and dates.
- **Customers** - optional names, Phone and Marketing consent (each value mapped to opted in, opted out, not asked or undeliverable). Unmapped, every contact imports as **Not asked** - the confirm step shows each count first.

**Re-uploading is safe**: existing bookings, codes and External IDs are skipped and customers match by email. If one **code is on two rows**, the others get a generated code.

## Troubleshooting

1. **"File has no recognisable header row".** The first row must be column names, not data.

2. **"Row N: no email address".** The row had no email or External ID.

3. **"Could not parse start time".** Re-check the date format on the mapping step.

4. **The Continue button is disabled.** A required field is unmapped.

5. **A customer can't see their bookings.** They probably used a different email from your export - message us and we'll merge the accounts.

6. **A booking I'd already cancelled came across as live.** Its status column wasn't mapped. Switch the **Booking cancelled** email off under [Email → Notifications](/go/admin/email/automated), cancel it with a refund amount of 0, then switch the email back on.
