Skip to content

Data migration

SettingsMay 13, 2026·13 min read·Updated May 26, 2026

Data migration brings your existing business data into Off The Couch from a previous system. Each migration type has its own CSV schema with required and optional columns. Prepare the files according to the schemas in this article, then send them to your Off The Couch migration administrator.

Getting started

Navigate to Settings > Data migration from the sidebar.

How it works

Migrations are performed by Off The Couch administrators only. The page shows a notice at the top of the Migration upload tab:

Currently Migrations can only be performed by Off The Couch Administrators. Please contact Nick at nick@offthecouch.io or on Discord to schedule your migration. In preparation please look at Migration Advice to the right and the Migration Types below to prepare reports in advance.

The CSV upload control is hidden for non-OTC accounts. Your job is to prepare CSV files using the schemas below and send them along; Nick (or another Off The Couch admin) runs the actual import on your behalf and the results show up in the migration log on this page.

The page has two tabs:

TabPurpose
Migration uploadThe migration type picker, schema panel, and (for OTC admins) the upload control. The right side shows the Migration Advice panel
Migration logOne row per past migration run, with success / failure / duplicate counts and per-run actions (view records, view duplicates, download error records, purge records)

Migration Advice

The page surfaces four pieces of generic advice on the right side of the Migration upload tab. They apply to every migration:

  1. Recommended order of file uploads: 1. Customers (Global), 2. Transactions (By Group / Location), 3. Bookings (By Group / Location, needs to be associated to a transaction by an ID), 4. Waivers (By Group / Location), 5. Gift cards, 6. Customer credit (Global), 7. Promo codes (By Group / Location).
  2. Make sure your headers match the ones provided. Use the copy tool on the page (or the schemas in this article) to avoid typos.
  3. Headers marked with * are required. Every other column is optional.
  4. Make sure you have corresponding events created before uploading bookings or waivers and that the names match.

Headers are case-sensitive. "Email" works; "email" or "EMAIL" doesn't. Match the casing exactly as shown in this article.

Step-by-step guide

Prepare your files

  1. Look at the Migration Advice above and follow the recommended order
  2. Pick the migration type you're starting with from the schemas below
  3. Build a CSV with the headers from the schema. Use the copy icon on the Settings > Data migration page to copy the field list and avoid typos
  4. Make sure required fields (marked with *) have a value in every row
  5. Confirm your event names in Events > Event settings match the names in Booking name and waiver columns (corresponding events must exist before bookings or waivers can be migrated)

Send your files for migration

  1. Once your CSVs are ready, contact Nick at nick@offthecouch.io or on Discord (per the notice on the page)
  2. Share your prepared CSV files with him
  3. Off The Couch administrators run the import on your behalf
  4. The result lands in the Migration log tab on this page

Review the migration log

Open the Migration log tab on Settings > Data migration. Each previous migration run is one row with these columns:

ColumnWhat it shows
Upload typeMigration type as a badge
Uploaded byTeam member who started the run, plus the timestamp
Records importedSuccessful rows imported (e.g., "150 / 200") with a progress bar while the import is in flight. Shows a purged badge once the run is purged
Failed recordsRows that didn't import due to validation errors
DuplicatesRows skipped because they matched existing records
ActionsThree-dot menu with View records, View duplicates, Download error records, Purge records

Use the per-page selector at the top right (5, 10, 25, or 50) to change rows per page. The empty state ("No data has been uploaded yet.") appears when no migrations have been run.

Inspect a previous run

  1. In the migration log, open the three-dot menu on the run
  2. Pick the action you need:
ActionWhen
View recordsSee the records imported by the run
View duplicatesSee the rows that were skipped because they matched existing records (only present when duplicates were found)
Download error recordsGet a CSV of the failed rows with their error reason. Fix and resend (only present when there were failures)
Purge recordsPermanently remove every record imported by this specific run. Requires the Delete migrations permission

Purge a migration run

  1. In the migration log, open the three-dot menu on the run you want to remove
  2. Click Purge records
  3. Confirm the Are you sure? prompt
  4. Every record imported by that specific run is deleted

Purging is permanent. Records that already existed before the run are not affected.

Schemas

Customers (Global)

Customer records. Migrated once per account, not per group.

FieldRequiredDescription
First nameNoCustomer's first name
Last nameNoCustomer's last name
EmailYesUsed as the unique customer identifier
BirthdayNoDate of birth in YYYY-MM-DD format
PhoneNoPhone number
Address line 1NoStreet address
Address line 2NoApartment, suite, or unit
CityNoCity
StateNoState or province
ZipNoZIP or postal code
CountryNoTwo-letter ISO 3166-1 alpha-2 code (US, CA, GB, AU, DE, NZ). The page has a Download reference link for the full country code list
Email opt outNoWhether the customer has opted out of marketing emails. Boolean: 1 / 0 or true / false
Photo opt outNoWhether the customer has opted out of photo sharing. Boolean: 1 / 0 or true / false
Date joinedNoWhen the customer first interacted with your business, in YYYY-MM-DD. Defaults to the import date if omitted
Date last visitedNoDate of the customer's most recent visit, in YYYY-MM-DD. Defaults to the import date if omitted
NotesNoFree-text internal notes about the customer

Transactions (By Group / Location)

Order-level records. Scoped to the company group you're migrating into.

FieldRequiredDescription
First nameNoCustomer's first name on the transaction
Last nameNoCustomer's last name
EmailYesCustomer email used to link the transaction to a customer record
PhoneNoCustomer phone
Transaction dateNoWhen the transaction was created. Format YYYY-MM-DD HH:MM:SS or YYYY-MM-DD (omit time if not known)
Transaction statusNoOne of active or cancelled
Order numberYesYour existing order/invoice number. Used as the unique identifier and to link bookings to this transaction
PriceNoSubtotal before taxes, fees, or discounts
TotalNoTotal amount on the transaction
PaidNoAmount already paid
DueNoOutstanding balance
TaxesNoTax amount
FeesNoFee amount
DiscountNoDiscount amount applied
RefundedNoAmount refunded
NotesNoFree-text internal notes

Bookings (By Group / Location)

Booking slots and reservations. Migrate after Transactions so each booking can be linked to its transaction by Order number.

FieldRequiredDescription
Booking nameYesName of the event corresponding to this booking. Must match an existing event in Events > Event settings
Booking start dateYesDate the booking starts, in YYYY-MM-DD
Booking end dateNoDate the booking ends, in YYYY-MM-DD
Booking start timeYesBooking start time in HH:MM:SS
Booking end timeYesBooking end time in HH:MM:SS
Group sizeNoNumber of participants in the booking
PriceNoPrice for the booking
StatusYesSlot status. One of available, booked, cancelled, blocked, call_to_book
Order numberNoThe corresponding transaction's Order number, when applicable. Links the booking to a transaction in your data
NotesNoFree-text booking notes
Reservation typeNopublic for public bookings (multiple groups can book the same slot, no duplicate check applied) or private for private bookings

Waivers (By Group / Location)

Signed waivers tied to a customer and an event. Migrate after Bookings so the corresponding events exist.

FieldRequiredDescription
First nameNoSigner's first name
Last nameNoSigner's last name
EmailYesSigner's email used to link to the customer record
BirthdayNoSigner's date of birth in YYYY-MM-DD
PhoneNoSigner's phone
Date signedNoWhen the waiver was signed. Format YYYY-MM-DD HH:MM:SS or YYYY-MM-DD (omit time if unknown)
Booking nameYesName of the event the waiver is for. Must match an existing event in Events > Event settings
Booking start dateYesBooking date in YYYY-MM-DD
Booking end dateNoBooking end date in YYYY-MM-DD
Booking start timeYesBooking start time in HH:MM:SS
Booking end timeYesBooking end time in HH:MM:SS

Gift cards

Gift card records.

FieldRequiredDescription
Gift card codeYesThe unique gift card code your customers redeem
Personal messageNoPersonal message attached to the gift card
Date purchasedNoPurchase date in YYYY-MM-DD
Delivery dateNoScheduled delivery date in YYYY-MM-DD
Expiration dateNoExpiration date in YYYY-MM-DD
StatusNoactive or deactivated. Defaults to active when omitted
Total valueYesTotal amount loaded on the gift card
SpentYesAmount already spent (0 for unused cards)
Order numberNoLinks the gift card as a purchase under an existing transaction with this Order number
Customer first nameNoPurchaser first name
Customer last nameNoPurchaser last name
Customer emailYesPurchaser email used to link to the customer record
Recipient emailYesEmail of the gift card recipient
Recipient first nameNoRecipient first name
Recipient last nameNoRecipient last name

Customer credit (Global)

Store-credit balances on customer accounts. Migrated once per account.

FieldRequiredDescription
First nameNoCustomer's first name
Last nameNoCustomer's last name
EmailYesCustomer email used to link the credit to the customer record
Total valueYesTotal credit issued
RemainingNoRemaining credit balance
SpentNoAmount of credit already spent

Promo codes (By Group / Location)

Promo and discount codes.

FieldRequiredDescription
Promo nameYesThe promo code itself (the string customers redeem)
DescriptionNoInternal description of the promo
Redemption typeYesvalue for fixed-amount discounts (e.g., $10 off) or percentage for percent-based discounts (e.g., 10% off)
Value amountYesThe numeric discount value (e.g., 10 for $10 off or 10%)
QuantityNoTotal redemptions allowed. Set to -1 for unlimited
Number of times usedNoExisting usage count to carry over
Applicable to gift cards and merchandiseNoWhether the promo can apply to gift cards and merchandise. Boolean: 1 / 0 or true / false
Promo code groupNoOptional. Links promo codes to an existing promo code template by name

Reference

Date and time formats

Field typeFormat
Date-only fields (Birthday, Booking start date, Date purchased, etc.)YYYY-MM-DD
Date-time fields (Date signed, Transaction date)YYYY-MM-DD HH:MM:SS or YYYY-MM-DD if you want to omit the exact time
Time-only fields (Booking start time, Booking end time)HH:MM:SS

Boolean values

Boolean columns accept 1 / 0 or true / false.

Enum values

FieldAllowed values
Status (Bookings)available, booked, cancelled, blocked, call_to_book
Reservation type (Bookings)public, private
Transaction statusactive, cancelled
Redemption type (Promo codes)value, percentage
Status (Gift cards)active, deactivated
Country (Customers)Two-letter ISO 3166-1 alpha-2 code

Migration log row actions

ActionShown when
View recordsAlways
View duplicatesThe run had duplicate records skipped
Download error recordsThe run had failed records
Purge recordsThe user has the Delete migrations permission

Migration log statuses and counts

ElementDescription
Records importedSuccessful row count over the total uploaded, with a progress bar during the import
Failed recordsCount of rows that didn't import
DuplicatesCount of rows skipped because they already existed
Purged badgeAppears in place of the count when the run has been purged

Empty state

If no migrations have been run yet, the migration log table shows the warning triangle icon and "No data has been uploaded yet."

Good to know

  • Migrations are performed by Off The Couch administrators only. The upload control on the page is hidden for non-OTC accounts. Send your prepared files to nick@offthecouch.io or on Discord to schedule a run.
  • Headers are case-sensitive. "Email" works; "email" or "EMAIL" doesn't. Use the copy icon on the page (or the schemas in this article) to grab the exact header text and avoid typos.
  • The recommended file order in Migration Advice is the safe path: Customers, Transactions, Bookings, Waivers, Gift cards, Customer credit, Promo codes. Following the order means each migration has the data it needs to link records correctly (e.g., bookings link to transactions by Order number, waivers link to bookings by event name).
  • Customers and Customer credit are global. The other migration types are scoped to the company group you're migrating into. Switch groups before sending the data if you have multiple locations.
  • Bookings and Waivers require corresponding events in Events > Event settings. Create the events first; they're matched by exact name in the Booking name column.
  • Country for the Customers schema must be a two-letter ISO 3166-1 alpha-2 code, not the full country name. Examples: US, CA, GB, AU, DE, NZ. The page has a Download reference link for the full code list.
  • Order number in the Bookings schema is what links a booking to its transaction. Make sure the Transactions migration ran first and that the same Order number is used in the Bookings file.
  • Public bookings (Reservation type = public) are not checked for duplicates because the same slot can host multiple parties.
  • Promo codes: set Quantity to -1 to allow unlimited redemptions. Existing usage counts can be carried over via Number of times used.
  • Failed rows are downloadable as CSV via Download error records in the migration log's three-dot menu. Each failed row has its error reason in a column. Fix the issues and re-send only the corrected rows.
  • Purging removes only records imported by that specific run. It doesn't affect records that already existed before the run.

FAQ

Q: Can I upload migrations myself?

A: No, not yet. The page restricts uploads to Off The Couch administrators. Prepare your files using the schemas in this article and send them to nick@offthecouch.io or contact Nick on Discord. He'll run the imports for you.

Q: I got the email wrong but the rest of my CSV is fine. What now?

A: Once a migration has run, the imported records can be purged via the Purge records action in the migration log. After purging, fix the email column and resend the corrected file.

Q: My file failed to upload entirely. What do I do?

A: Confirm the file is .csv (not .xlsx), the headers match exactly (case-sensitive), and the date and time formats match the Date and time formats reference. Re-export from your spreadsheet and resend.

Q: Some rows imported but others failed. Where are the failures?

A: In the Migration log tab, open the three-dot menu on the run and click Download error records. The downloaded CSV includes a column explaining why each row failed. Fix and resend only the failed rows.

Q: Can I undo a migration?

A: Yes. Use Purge records in the migration log's three-dot menu. This deletes every record imported by that specific run. Records that already existed before the run are untouched.

Q: Why do my booking imports fail with an "event not found" error?

A: The Booking name column must exactly match an event in your account. Create the events first under Events > Event settings, then resend the bookings file.

Q: Why do my waiver imports fail?

A: Waivers require both the customer (matched by Email) and the event (matched by Booking name) to exist. Run the Customers migration first, then create matching events, then send the waivers.

Q: Why is the Purge records option missing from a row's menu?

A: It requires the Delete migrations permission. Ask an admin to grant it in Settings > User management.

Q: What does "By Group / Location" mean in the migration order?

A: That migration type is scoped to a single company group. If you have multiple locations, you'll need a separate file per group, with the right group selected in the group picker before sending each one.

Q: My country names are full names like "United States". Will the migration accept them?

A: No. The Country column must be a two-letter ISO 3166-1 alpha-2 code (e.g., US). Convert before sending. The page has a Download reference link with the full country-to-code mapping.