Skip to content

Switching from Square Appointments

Export your customers and appointment history from Square and import the CSVs unchanged. Tuppence recognises Square’s columns and previews every row before importing.

  1. Exportcustomers, appointments
  2. Add servicesand staff
  3. Import clientsdry run, then Import
  4. Import bookingsclashes named first
In SquareIn TuppenceComes over?
CustomerClientYes
AppointmentBookingUpcoming only (not repeating)
Service (service library)ServiceNo, add first
Team memberStaff memberNo, add first with hours
Gift cards, packages, membershipsGift vouchers, session packages, membershipsNo, set up again
FileContentsImport as
Customers (CSV)Name, email, phone, address, birthday, memo, visits, spend, email subscriptionClients
Appointment history (CSV)Every appointment, past and upcoming: date and time, customer, service, team member, statusUpcoming bookings

Square doesn’t export its service library, and its item library export (Items › Actions › Export library) lists items you sell, not service lengths. Add services first under Bookings › Services, or add a Duration column to the item library and import it as a services spreadsheet. Use Square’s service and staff names so appointments match.

  1. Customers: in Square Dashboard, go to Customers › Customer directory › Import/Export › Export customers, choose all customers and select Download.
  2. Appointments: go to Appointments › Settings › History › Export. Only upcoming appointments import. Repeating appointments aren’t in the file; add those by hand.
  1. Go to Imports › Clients and choose the customers file. You see Read as a Square customer export, the column feeding each field (and why any are left out), and a dry run: new clients, existing ones (same email or phone), and unreadable rows.
  2. Select Import. You can undo it for 24 hours.
  3. Go to Imports › Upcoming bookings and choose the appointment history. Calendar clashes are named before anything is created. Bookings import as confirmed and nobody is messaged: Square already told your clients, so their first message from you is the reminder.

With the API, upload the file unchanged to POST /v1/imports; source and format show how it was read:

import os
from tuppence import Tuppence
tuppence = Tuppence(os.environ["TUPPENCE_SECRET_KEY"])
export = """Reference ID,First Name,Last Name,Email Address,Phone Number,Nickname,Company Name,Street Address 1,Street Address 2,City,State,Postal Code,Birthday,Memo,Square Customer ID,Creation Source,First Visit,Last Visit,Transaction Count,Lifetime Spend,Email Subscription Status,Instant Profile
,Ruby,Ashworth,ruby.ashworth@example.com,'+447700900301,,,8 Mill Lane,,Bath,,BA1 2QS,7/23/1988,Nervous of the dryer,Q7K2M9P4R8T1V6X3Z5B0N2D4FJ,Appointments,3/14/2025,9/2/2026,6,£310.00 ,subscribed,No
,Tom,Whitaker,tom.whitaker@example.com,+44 7700 900302,Tommy,,,,,,,,,H3J8L1N6Q9S2U5W7Y0A4C6E8GK,Directory,,,0,£0.00 ,unknown,No
"""
upload = tuppence.request("POST", "/v1/imports", body={"kind": "clients", "file": export})
print(upload["source"], "·", upload["format"]["name"]) # square · Square customer export
print(upload["date_order"]) # mdy: 7/23/1988 can only be month-first
print(upload["dry_run"]["created"], "clients to import") # 2 clients to import
import os
from tuppence import Tuppence
tuppence = Tuppence(os.environ["TUPPENCE_SECRET_KEY"])
export = """Reference ID,First Name,Last Name,Email Address,Phone Number,Nickname,Company Name,Street Address 1,Street Address 2,City,State,Postal Code,Birthday,Memo,Square Customer ID,Creation Source,First Visit,Last Visit,Transaction Count,Lifetime Spend,Email Subscription Status,Instant Profile
,Ruby,Ashworth,ruby.ashworth@example.com,'+447700900301,,,8 Mill Lane,,Bath,,BA1 2QS,7/23/1988,Nervous of the dryer,Q7K2M9P4R8T1V6X3Z5B0N2D4FJ,Appointments,3/14/2025,9/2/2026,6,$310.00 ,subscribed,No
,Tom,Whitaker,tom.whitaker@example.com,+44 7700 900302,Tommy,,,,,,,,,H3J8L1N6Q9S2U5W7Y0A4C6E8GK,Directory,,,0,$0.00 ,unknown,No
"""
upload = tuppence.request("POST", "/v1/imports", body={"kind": "clients", "file": export})
print(upload["source"], "·", upload["format"]["name"]) # square · Square customer export
print(upload["date_order"]) # mdy: 7/23/1988 can only be month-first
print(upload["dry_run"]["created"], "clients to import") # 2 clients to import
import os
from tuppence import Tuppence
tuppence = Tuppence(os.environ["TUPPENCE_SECRET_KEY"])
export = """Reference ID,First Name,Last Name,Email Address,Phone Number,Nickname,Company Name,Street Address 1,Street Address 2,City,State,Postal Code,Birthday,Memo,Square Customer ID,Creation Source,First Visit,Last Visit,Transaction Count,Lifetime Spend,Email Subscription Status,Instant Profile
,Ruby,Ashworth,ruby.ashworth@example.com,'+447700900301,,,8 Mill Lane,,Bath,,BA1 2QS,7/23/1988,Nervous of the dryer,Q7K2M9P4R8T1V6X3Z5B0N2D4FJ,Appointments,3/14/2025,9/2/2026,6,€310.00 ,subscribed,No
,Tom,Whitaker,tom.whitaker@example.com,+44 7700 900302,Tommy,,,,,,,,,H3J8L1N6Q9S2U5W7Y0A4C6E8GK,Directory,,,0,€0.00 ,unknown,No
"""
upload = tuppence.request("POST", "/v1/imports", body={"kind": "clients", "file": export})
print(upload["source"], "·", upload["format"]["name"]) # square · Square customer export
print(upload["date_order"]) # mdy: 7/23/1988 can only be month-first
print(upload["dry_run"]["created"], "clients to import") # 2 clients to import
Square’s columnIn Tuppence
First Name, Last NameName
Email AddressEmail (matches existing clients before phone)
Phone NumberPhone, in E.164 (+44…, +1…), without Excel’s leading '
Street Address 1 and 2, City, State, Postal CodeAddress
BirthdayDate of birth
MemoNotes
Start Date, Start Time, Customer Name, Customer Email, Customer PhoneBooking, and who it’s for
Service, Team MemberService and staff member, matched by name
NoteThe booking’s internal note
StatusCancelled, declined and no-show appointments skipped

Dates are read month-first or day-first, as the file’s dates show.

  • Email subscription status: consent doesn’t transfer. Ask clients again before sending anything but booking messages.
  • Cards, payments, prices: cards and payments stay with Square. Bookings use the service’s price here.
  • Visit and spend history (First Visit, Last Visit, Transaction Count, Lifetime Spend).
  • Gift cards, packages, memberships, loyalty: set them up again.
  • Nickname, company name, creation source and Square’s IDs.
  • Past and repeating appointments.

A file is recognised when most of Square’s columns are present. Missing or renamed columns are matched by header or content (a column of email addresses becomes the email) and flagged. Fix any wrong match, then select Check with these columns. In the API, format.missing lists each with its field and the column matched instead. An unrecognisable file is read as a plain spreadsheet; send source: "square" to force the Square format.

Docs assistant

Open as a page
Loading the assistant…