Migration

Migration, with a receipt you can file.

Switching vendors is a data problem for about a weekend and a human problem for about six weeks. This page covers both honestly: what the importer does, what it deliberately does not do, and the timeline that makes a cutover survivable.

Last reviewed 2026-08-04 · Kastr is pre-launch; we publish dated status rather than logos.

The seven-file ParentSquare export bundle, and what the importer does with each
FileContentsWhat the importer doesTypical drops
schools.csvSchool and org identifiersBecomes the org hierarchy that row-level security is enforced againstRows with no id or no name
students.csvStudent PII and language preferenceLanguage names mapped to ISO codes; retention class set to student_pii at creationRows missing an id, first name or last name
contacts.csvParents and guardiansPhones normalised to E.164, emails validated, contacts de-duplicated on email plus phone plus family nameJunk first names — mom, dad, parent, guardian, neighbor, grandma, unknown — and duplicate contact points
student_contacts.csvThe many-to-many guardian associationsReferential integrity checked against the parsed students and contactsLinks pointing at a student or contact that is not in the export
staff.csvTeachers and administratorsSame phone and email normalisation; one person row can later carry both a staff role and a guardian roleRows missing an id or names
classes.csvSectionsBound to a school, and to a teacher where the teacher resolvesUnknown school; an unknown teacher drops the binding, not the class
enrollments.csvStudent–class membershipsValidated against parsed classes and studentsUnknown class or unknown student

A missing file is not a silent failure: it is surfaced in the receipt's drops column. The unzip step caps the archive at 200 MB and carries a zip-slip guard, because "upload an archive from a third party" is a category of bug with a long history.

The importer, and exactly what it does

@kastr/importer-parentsquare is MIT-licensed and runs standalone. It takes a folder of CSVs or a ZIP in ParentSquare's documented seven-file export format, parses it, normalises it, and produces a receipt. It does not need a Kastr account and it does not phone home.

$ npx tsx src/cli.ts ./parentsquare-export --out ./receipt.pdf Parsing ./parentsquare-export… Done in 12.4s Record class Source Imported Dropped --------------------------------------------------- schools 14 14 0 students 18,044 18,044 0 contacts 14,217 13,908 309 studentContacts 31,205 30,974 231 staff 1,089 1,089 0 classes 1,412 1,412 0 enrollments 64,880 64,880 0 Receipt PDF: ./receipt.pdf Signed: 4c1f9ab30e77d2a8… SHA-256: 8f3a…21be

The one thing this tool will not do is pretend. Run it without IMPORTER_SIGNING_KEY set and it prints, in red, "no signing key configured" and leaves the signature field empty rather than emitting something that looks signed.

@kastr/importer-parentsquare — migration receipt

Migration receipt — ParentSquare export

Lincoln USD · 7 source files · parsed in 12.4 s
bundle SHA-256 8f3a…21be
Record classIn sourceValidatedDropped
Schools14140
Students18,04418,0440
Contacts (guardians)14,21713,908309
Student–contact links31,20530,974231
Staff1,0891,0890
Classes1,4121,4120
Enrolments64,88064,8800
540 records dropped, every one itemised. 188 guardians whose first name was a junk value — mom, dad, parent, grandma, unknown. 121 duplicate contacts sharing an email or a normalised phone number. 231 student–contact links pointing at a student or contact that is not in the export.

Illustrative receipt, synthetic district. Being exact about what this tool does: it reads, validates and signs. It does not write rows into a live Kastr tenant — that step happens with us during onboarding.

What the receipt proves, and why procurement cares

Most migrations are documented by a screenshot of a success message. A receipt is a different class of artefact, and it is the thing that lets a business official sign off without taking anyone's word for it.

  • A per-source-file SHA-256 manifest. Which exact file, at which exact byte content, was parsed. If the incumbent later sends a different export, the hashes will not match and you will know.
  • An HMAC-SHA256 signature over the bundle hash, computed as HMAC(key, "${generatedAt}:${bundleSha256}"), so the receipt cannot be quietly edited after the fact.
  • Counts in versus counts out, per record class. Not a total. Seven rows, each independently checkable against your own export.
  • A drop ledger. Every single dropped record, with the reason: duplicate email or phone, junk first name, orphaned relationship, missing identifier.
  • A timestamp and source manifest, so the document is dated evidence rather than an assertion.

As far as we can establish, no other vendor in K-12 family communication produces one. It is a weekend of work and it turns "we believe the migration went fine" into a document you can staple to a board agenda.

The honest limit: this validates, it does not load

Read this before you plan around it. The importer parses, validates, normalises and signs. It does not write a single row into a live Kastr database. It is a dry-run validator plus a procurement artefact. The step that loads validated records into your tenant is done with us during onboarding, not self-serve.

We could have described this as "one-click migration" and nobody would have caught it until implementation week. The reason to say it plainly instead is that the receipt's whole value is that it is verifiable, and a tool that overstates one thing has told you what to assume about the rest.

It also means you can run the importer today, against your current export, without any commercial relationship with us at all — and the drop ledger it produces is a genuine data-quality audit of your roster regardless of which vendor you end up choosing.

Six steps, four weeks, one person from your team

  1. Week 0 — request the export. Ask your incumbent for a full export before you sign anything with anyone. FERPA's portability provisions entitle the district to its data; most vendors return a bundle in two to five business days once a formal written request is on file. We will help draft the request language if that is useful.
  2. Week 1 — run the importer in validation mode. Get the PDF receipt. Read the drop ledger properly rather than skimming the totals; it is where the surprises are.
  3. Week 1 — spot-check ten families. Pick them yourself, at random, across schools and languages. Check names, language preference and contact points against what you know to be true. Ten families finds more problems than any automated summary.
  4. Week 2 — connect the roster feed. Classes and enrolments are better re-derived from a live roster sync than carried across a migration. Roster data is POSTed to /api/v1/roster/sync; the diff engine classifies every record and the guardrail aborts a run that would withdraw more than half your active students.
  5. Week 3 — train the front office. Two 45-minute sessions, one for office staff and one for principals. Office managers are the real users; they send twenty messages a week and they decide whether this succeeded.
  6. Week 4 — cut over, and over-communicate first. Announce the change on the old platform, repeatedly, before you turn it off. Families do not care that you changed vendors; they care that the thing which used to tell them about early dismissal has gone quiet.

Timing matters more than any of the six steps. Cut over in June or July: staff get the summer to learn the tool and family re-onboarding rides the back-to-school attention spike. A mid-year cutover asks families to re-enrol in an app when nothing has their attention, and it costs reach. If your renewal date forces the issue, a short bridging extension on the incumbent is a normal procurement conversation.

What does not come across, stated up front

Roster and contact data migrate cleanly. Several other things do not, and every one of them is better handled by planning than by discovering.

  • Message history. Keep your export as the archive. It is a public-records and discovery asset and it should stay in the format the originating system produced.
  • Form responses and signatures. Signed documents should stay with the system that captured the signature.
  • Family app logins and notification preferences. Families re-onboard. This is the actual project. Budget three touches over three weeks, in every language your families read, and expect to chase the last few percent into September.
  • Attachments. Kastr does not support file attachments at all today, so there is nothing on our side to migrate them into. That is a genuine gap and it belongs in your evaluation.

For a vendor-specific walkthrough, see switching from ParentSquare, which covers the same ground with a record-by-record table of what moves.

Questions people actually ask

What if our current vendor drags their feet on the export?

Put the request in writing and cite FERPA's portability provisions; districts are entitled to their data and a formal written request usually produces a bundle in two to five business days. Request it early rather than inside a notice period, and confirm which record classes are included, because message history and form responses are frequently handled separately from roster and contact data.

Does the importer actually load our data into Kastr?

No, and we would rather say so on the page than in implementation week. It parses, validates, normalises and signs a receipt. Loading validated records into a live tenant is done with us during onboarding. The tool is genuinely useful before that point — the drop ledger is a data-quality audit of your roster that you can run today, for free, without talking to us.

What exactly is in the signed migration receipt?

A per-source-file SHA-256 manifest, an HMAC-SHA256 signature over the bundle hash, counts in versus counts out for each of the seven record classes, a ledger of every dropped record with its reason, a timestamp, and the importer version. It renders as a PDF. Without a signing key configured it prints an explicit warning instead of a fabricated signature.

When is the best time to switch platforms?

June or July, without much competition. Staff learn the tool over the summer and family re-onboarding rides the back-to-school attention spike, when messages from school are already being opened. A mid-year cutover is survivable but costs reach, and reach is the entire product.

How long does the whole migration take?

The data is a weekend. Family re-onboarding is three to six weeks of communication and the long tail runs into September. Plan around the second number; every district that has done this badly did the data properly and the humans badly.

Switching is a weekend, and you get a receipt.

Our ParentSquare importer is MIT-licensed and runs without us. It validates your export, normalises phone numbers and languages, drops the junk guardian records, and emits a signed PDF receipt with a per-file SHA-256 manifest — a procurement artefact, not a developer log.