Column mapping guide
After reading this page you can read the Review column mapping table in Settings → Migration, understand which of your columns Agon matched, correct a wrong match, and deal with columns Agon could not place — for clients, memberships, and classes.
This is a companion to the Migration overview — start there for the full import flow.
How Agon matches your columns
Before uploading, you choose what you're importing — Clients, Memberships, or Classes — under What are you importing?. That choice decides which set of Agon fields your columns can be matched to; each entity has its own field list, covered in its own section below.
When you click Analyse file, Agon looks at each column header in your file and tries to line it up with one of the fields for the entity you picked. Headers that are an obvious match for a field name (for example email, Email, email_address) are matched directly; the rest are matched by interpreting the header text (and, for text-heavy columns, a few of the column's own values, to help tell apart headers like "Type" or "Plan"). The table then shows you what it decided, with the message "We matched each column in your file to an Agon field".
Nothing is imported at this point. The matching is only a starting suggestion that you review and adjust before confirming.
Client fields
Each row in the mapping table has an Agon field dropdown with these choices when importing Clients:
| Choice | What it does |
|---|---|
| Full name | The client's name. If no column is mapped here, the client's email is used as the name. |
| The client's email address. Required — a row with no email is skipped. If the email already belongs to a client in Agon, the row is skipped instead of overwriting that client. | |
| Phone | The client's phone number. Optional. |
| Date of birth | The client's date of birth. Optional. Use YYYY-MM-DD. |
| Notes | Free-text notes about the client. Optional. |
| Billing name | The name to put on this client's invoices going forward, if different from their full name — for example a company name. Optional. |
| Billing address | The address to put on this client's invoices going forward. Optional. |
| Tax ID / VAT Number | The client's tax ID or VAT number, for their invoices going forward. Optional. |
| — don't import — | Ignore this column. Its values are not imported. |
Billing name, billing address, and Tax ID / VAT Number are only used for invoices Agon generates after the client is imported — they don't change how the import itself runs. Agon does not import the client's historical invoices from your old platform; those stay archived in the old system, and migration doesn't attempt to bring them in. If a client needs to appear correctly on future invoices (for example a company being billed, or a client whose country requires a VAT/tax ID on the invoice), fill in these three fields — otherwise leave them out.
Renaming columns in your file instead
| Rename your header to | For |
|---|---|
full_name | The client's name |
email | The client's email address |
phone | The client's phone number |
date_of_birth | The client's date of birth |
notes | Free-text notes about the client |
billing_name | The billing name for this client's future invoices |
billing_address | The billing address for this client's future invoices |
tax_id | The client's tax ID or VAT number for their future invoices |
Put dates of birth in YYYY-MM-DD form, for example 1990-01-15.
Membership fields
Choices offered when importing Memberships:
| Choice | What it does |
|---|---|
| Client email | The email of the client this membership belongs to. Required — the client must already exist in Agon (import your clients first). A row whose email doesn't match any client in Agon is skipped. |
| Membership type | The name of the membership type in Agon (for example "10-Class Pack"). Required — matched to an existing membership type by name (case doesn't matter, spelling does). If nothing matches, the row is skipped — create the membership type in Agon first (Memberships in the left sidebar), then re-import. |
| Starts at | When the membership begins. Required. Use YYYY-MM-DD. |
| Expires at | When the membership ends. Optional. Use YYYY-MM-DD. A date already in the past is still imported — as a membership with expired status, not dropped, so your historical record is kept. |
| Credits remaining | The number of credits left on the membership. Optional, whole numbers only. |
| — don't import — | Ignore this column. |
Renaming columns in your file instead
| Rename your header to | For |
|---|---|
client_email | The client's email address |
membership_type_name | The membership type's name in Agon |
starts_at | The membership start date |
expires_at | The membership expiry date |
credits_remaining | Credits left on the membership |
Class fields
Choices offered when importing Classes:
| Choice | What it does |
|---|---|
| Class name | The name of the class (for example "Yoga Flow"). Required. Matched to an existing class type in Agon by name — unlike membership types, if none matches, Agon creates a new class type automatically using this row's start/end time (for its duration) and capacity as defaults, rather than skipping the row. This is intentional: a first migration is usually the studio's whole class catalogue arriving for the first time. |
| Starts at | When the class starts. Required. Use YYYY-MM-DD HH:MM:SS. A start time that isn't strictly in the future is skipped — only upcoming classes are imported. |
| Ends at | When the class ends. Required. Use YYYY-MM-DD HH:MM:SS. |
| Capacity | Maximum number of clients who can book. Optional, whole numbers only. Defaults to 1 if left blank. |
| Instructor name | The instructor's name. Optional. Matched to an existing instructor in Agon by name. Unlike the fields above, no match does not skip the row — the class still imports without an instructor, and you assign one manually afterwards from the class's own edit screen. |
| — don't import — | Ignore this column. |
Renaming columns in your file instead
| Rename your header to | For |
|---|---|
class_name | The class's name |
starts_at | The class start date and time |
ends_at | The class end date and time |
capacity | Maximum bookings |
instructor_name | The instructor's name |
Columns Agon could not match
A column Agon could not place shows a not mapped badge in the table.
A column left as not mapped is skipped — its data is not imported. That is the right outcome for columns Agon does not have a field for, such as internal record IDs or tags. (When importing Clients, a "Notes" column doesn't need to end up unmapped — map it to the Notes field above if you want it imported.)
If a not mapped column should be imported, open its dropdown and choose the correct field from the list for the entity you're importing.
Correcting a match
- Find the row in the Review column mapping table.
- Open the dropdown in the Agon field column.
- Choose the correct field, or — don't import — to skip the column.
- Repeat for every row that is wrong.
- Click Confirm import when the whole table is right.
Headers that match Agon's own field names (see the renaming tables above, one per entity) are matched directly, so the table comes back correct. After renaming, save the file and run Analyse file again.
What if something goes wrong?
A column was matched to the wrong field Use the Agon field dropdown on that row to pick the right one. The automatic match is only a suggestion, and unusual header names are easy to get wrong.
A column I need shows "not mapped" Open its dropdown and choose the field it belongs to. Unmapped columns are skipped, so nothing from that column is imported until you map it.
Two of my columns hold the same kind of data Only one column can feed each Agon field. Map the better one and set the other to — don't import —, or merge them in your spreadsheet before uploading.
My file has more than one header row, or merged cells Agon expects a single header row followed by one row per record. Flatten merged cells and remove extra header rows in your spreadsheet, then upload again.
My "Membership type" column keeps coming back not mapped, or the type isn't found The Membership type field only matches an existing membership type by name — it never creates one. Check that the name in your file matches a membership type already set up in Agon (Memberships in the left sidebar) exactly, then re-run Analyse file. This is different from Class name below, which creates a new class type automatically when nothing matches.
A class row created a class type I didn't expect This is expected for Class name: if the name doesn't match an existing class type in Agon, a new one is created automatically from that row's start/end time and capacity, rather than skipping the row. Rename or merge duplicate class type names in your source file before importing if you want them to collapse into one class type in Agon.
"Instructor name" doesn't seem to matter It's optional and never causes a class row to be skipped. If it doesn't match an instructor's name in Agon exactly, the class still imports without an instructor — assign one manually afterwards.