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.
- Exportcustomers, appointments
- Add servicesand staff
- Import clientsdry run, then Import
- Import bookingsclashes named first
Square’s words, and ours
Section titled “Square’s words, and ours”| In Square | In Tuppence | Comes over? |
|---|---|---|
| Customer | Client | Yes |
| Appointment | Booking | Upcoming only (not repeating) |
| Service (service library) | Service | No, add first |
| Team member | Staff member | No, add first with hours |
| Gift cards, packages, memberships | Gift vouchers, session packages, memberships | No, set up again |
What Square exports
Section titled “What Square exports”| File | Contents | Import as |
|---|---|---|
| Customers (CSV) | Name, email, phone, address, birthday, memo, visits, spend, email subscription | Clients |
| Appointment history (CSV) | Every appointment, past and upcoming: date and time, customer, service, team member, status | Upcoming 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.
Export from Square
Section titled “Export from Square”- Customers: in Square Dashboard, go to Customers › Customer directory › Import/Export › Export customers, choose all customers and select Download.
- Appointments: go to Appointments › Settings › History › Export. Only upcoming appointments import. Repeating appointments aren’t in the file; add those by hand.
Import into Tuppence
Section titled “Import into Tuppence”- 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.
- Select Import. You can undo it for 24 hours.
- 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 osfrom 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 exportprint(upload["date_order"]) # mdy: 7/23/1988 can only be month-firstprint(upload["dry_run"]["created"], "clients to import") # 2 clients to importimport osfrom 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 exportprint(upload["date_order"]) # mdy: 7/23/1988 can only be month-firstprint(upload["dry_run"]["created"], "clients to import") # 2 clients to importimport osfrom 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 exportprint(upload["date_order"]) # mdy: 7/23/1988 can only be month-firstprint(upload["dry_run"]["created"], "clients to import") # 2 clients to importWhat comes over
Section titled “What comes over”| Square’s column | In Tuppence |
|---|---|
| First Name, Last Name | Name |
| Email Address | Email (matches existing clients before phone) |
| Phone Number | Phone, in E.164 (+44…, +1…), without Excel’s leading ' |
| Street Address 1 and 2, City, State, Postal Code | Address |
| Birthday | Date of birth |
| Memo | Notes |
| Start Date, Start Time, Customer Name, Customer Email, Customer Phone | Booking, and who it’s for |
| Service, Team Member | Service and staff member, matched by name |
| Note | The booking’s internal note |
| Status | Cancelled, declined and no-show appointments skipped |
Dates are read month-first or day-first, as the file’s dates show.
What doesn’t come over
Section titled “What doesn’t come over”- 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.
If Square changes its export
Section titled “If Square changes its export”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.