How do I import students in bulk and refresh the roster each year?
Senior Admins only. Instead of adding students one at a time, click Import CSV from the roster page (or go to /students/import) — Junior Admins won't see this button.
Last updated 2026-11-04
From the School Administrator manual, "Bulk Importing Students (and the Annual Roster Refresh)".
Senior Admins only. Instead of adding students one at a time, click Import CSV from the
roster page (or go to /students/import) — Junior Admins won't see this button.
- Click Download template (.csv) for a starter file with the right columns.
- Required columns:
first_name,last_name. - Optional student columns:
graduation_year(4-digit year, e.g.2027),street,city,state,zip. The oldergradecolumn (9–12) still works too. - Optional guardian columns (up to 2 per student row):
guardian1_title,guardian1_first_name,guardian1_last_name,guardian1_email,guardian1_phone, and the same forguardian2_*.titleis the relationship (e.g. "Mom", "Dad"). Guardian emails are automatically added to the registration allowlist. - Choose your filled-in CSV file. Save it as CSV UTF-8 (Comma delimited): a file saved by Windows
Excel as plain "CSV (Comma delimited)" is refused with a message saying so, because accented
letters (é, ñ) in it would otherwise be garbled. A ZIP that Excel shortened by dropping its
leading zero (
07030saved as7030) is read back as07030. If you re-upload the Students download from Data Export, rows markedis_archived=true(graduated or departed students) are skipped, so they stay archived; change the cell tofalseto bring one back. One file can hold your whole school: several thousand rows is fine, and you do not need to split it. The only limit is a file size of 4 MB (the hosting service accepts 4.5 MB per upload); a plain CSV is roughly 200 bytes per student, so that is on the order of 20,000 rows. A larger file shows a message naming the limit - remove blank rows and unused columns, and make sure it is saved as CSV rather than Excel. Instead of just inserting everyone as new, the importer compares the file to your current roster (including archived/former students, so a returning student is recognized rather than duplicated) and sorts every row into:- New — not on your roster yet, will be added.
- Returning, no changes — already matches your roster exactly; collapsed by default. Any guardian listed on that row who isn't on the student's allowlist yet (say, a step-parent added to this year's export) is still added when you Apply. A street address that's only written differently (e.g. "Street" vs "St", "132 East 35th St" vs "132 E 35 St") isn't treated as a change at all. Gaining an apartment/unit number, or gaining a ZIP+4 extension, also lands here (not in "Returning, changed") since it's more precise, not a real change — expand the section and you'll see a pre-checked (but overridable) checkbox for it, the same as any other accepted field.
- Returning, changed — matched an existing student, but a field genuinely differs. Each changed field shows the old value crossed out next to the new one (addresses are shown in a normalized form so the real difference is easy to spot at a glance), with its own checkbox — uncheck any you don't want applied (e.g. keep the address you already have on file). A student who was previously archived and reappears in the file is tagged Re-enrolling.
- Graduating — an existing student not in the file whose class has already graduated; expected, checkbox pre-checked to archive them.
- No longer listed — an existing active student not in the file at all; also pre-checked to archive, since this usually means they've left the school. Archiving never deletes their record — it hides them from the active roster while preserving their history (notes, stars, lists, other parents' data), and can be undone from their student page any time.
- Needs your decision — an ambiguous match the importer can't resolve on its own: two students who share a name and graduation year, or a student whose name matches an existing one but whose graduation year doesn't (shows both years so you can tell if it's really the same student, e.g. a grade correction, before deciding). There's no way to resolve this from within the importer itself — Skip this entry just excludes the row from this Apply run so the rest of your import can proceed; it doesn't create or update anything for that student, and doesn't fix the underlying mismatch. To actually resolve it, correct the source file and re-upload, or edit the student's record directly. Apply is disabled until every row here is either skipped or no longer ambiguous.
- If the importer reports that nothing in the file matched your current roster on a school that
already has students, stop and double-check before proceeding — this almost always means a date
mismatch (e.g. a
grade-column file uploaded on the other side of the July 1 school-year changeover from when it was made), not that every student actually left. You'll need to explicitly check "I've checked this is correct" before Apply unlocks in this case. - Review the running summary at the bottom of the page, then click Apply. A large import can take a minute or two. Students and parents are saved first, so they are in your roster even if the page is closed or the connection drops partway; if that happens, upload the same file again - students already added are recognized, not duplicated. Map locations are looked up after everything is saved. If there was not time to place every address, the result says how many are not on the map yet; open School Settings and click Re-geocode missing addresses (repeat if it says more remain). If any newly-linked guardian's email already has staff/admin access at your school, the result after Apply lists them and their existing role — this is informational only, linking them as a guardian never changes that role.
