All articles

Family accounts

A kids program has two people on every booking. The parent pays, gets the email and holds the card. The child is the one who walks in. Family accounts keep the parent as your contact and hang each child under it as a student, so the roster, the door tile and the subject line say the child's name while every message still reaches the parent.

What is built today

Milestone 1. A student record under a guardian contact, a “Who is this for?” picker on the booking page, a Family card on the contact page, the child's name on the roster, and per-child visit counts. Recurring series, standby and tuition rows can each carry a student id, but nothing reads those columns yet. The parts that are not built are listed further down, and they are not small.

Turning it on

Whether an event type books for a student is one setting, student_mode, with three values:

  • off — the default on every event type, including every one that already exists. No picker is rendered and the booking endpoint refuses a student id outright, so an event type that never opted in cannot acquire a student through a hand-written request.
  • optional — the picker offers Me alongside the family's children. A dance school that also teaches adults.
  • required — the picker has no Me, and a booking that names no student is refused. A children's class.

There is no control for this in the dashboard yet. Nothing on the event type page, the admin API or the public API writes student_mode, so today the value can only be set directly in the database. Until that control ships, family accounts are set up for you rather than by you.

What a student record holds

Four fields you maintain, and four counters the product maintains:

  • Name — required, up to 120 characters, and editable by you at any time.
  • Notes — free text for staff, up to 2,000 characters. Allergies, an injury, a reading level.
  • Pickup — one line saying who collects them, up to 200 characters. It is a note for the instructor, not a gate at the door; nothing checks it.
  • Tags — the same free-form tags your contacts use.
  • Visits — a count, a first-visit date and a last-visit date, maintained by check-in and reversed by an undo.

There is no email, phone, date of birth, address, photo, government identifier, login or payment identity on a student, and those columns do not exist to be filled in. A student is never a Stripe customer. The phone number your staff see beside a child is the guardian's, because it is the only one there is.

Two children of one parent cannot share a name: the same name added twice returns the child who is already there rather than creating a second row, which is what makes a re-submitted booking form or a repeated import a no-op.

Booking for a child

On an event type that books for a student, the public booking page works like this:

  1. The parent types their own name, email and phone, exactly as before.
  2. When they leave the email field, the page asks whether that address already has children on file here.
  3. Listing existing children requires a verified email address. Until the parent verifies, the page shows the verification step rather than a list, and an unverified request gets an empty list — never a hint that an address is or is not a customer here.
  4. Who is this for? then offers the family's children, an Add a child field, and, in optional mode, Me. The three are exclusive; naming an existing child and typing a new one at the same time is refused rather than guessed at.
  5. Add a child needs no verification, on purpose. Anyone who can reach the booking page can already type any attendee name they like; the new record lands under the contact their address resolves to, where you and the real parent both see it.

The child's name is written to the booking as the attendee name at the moment the booking row is created, so a door tile can never briefly show the parent. Everything that means “who we talk to” — the email, the phone, the consent flag, the contact — keeps pointing at the guardian.

A booking page reached by phone number only has no verified address, so it gets the Add a child field and no picker. Verifying by text message is not built.

If you ran a kids program before this existed, you probably added a required Student's name question. When the picker is turned on for that event type, the question stops being rendered and the picked child's name is written as its answer instead, so a reminder using that answer keeps working. Your question is not edited or deleted. The match is on a short list of spellings of that one question; a question that also asks an age or a level is left on the form.

What you see

  • The contact page has a Family card listing the children under that parent. You can add one, edit the name, notes, pickup line and tags, and remove one.
  • The contacts list shows a “2 students” chip on a parent who has any.
  • The roster shows the child. Their name is on the row and the tile; the detail pane adds the guardian's name and phone, so an instructor with an upset child knows who to call.
  • Visits are counted per child. A first-timer child of a regular parent is flagged as a first-timer, because the count that matters is the one on the child's record.
  • The confirmation email greets the parent by name and says whose class it is: “Maya's Ballet 1 with Priya is confirmed.”

Remove is a soft delete. The child leaves the picker and the Family card, and their past bookings keep pointing at the record, so your attendance history still names who was actually in the room.

Privacy

What the code enforces, and nothing more:

  • A student is reachable only through their guardian. There is no lookup by name and no workspace-wide search that returns children.
  • The public endpoint returns an id and a display label — first name and last initial — and nothing else. Not the notes, not the tags, not the visit counts, not the pickup line.
  • Notes and the pickup line render for signed-in staff on the roster detail pane and the contact page. They are not in any email, text message, webhook payload, door screen or export.
  • The door screen shows a first name and last initial, the same as it shows for an adult.
  • The workspace is resolved from the event type's own owner, so a request naming one studio's booking page cannot read another studio's families.

You are the data controller for these records. Anonymising a child's identity on an erasure request is not built; removing a child today keeps the name on their past bookings.

Plans

Family accounts are not gated. Nothing in the plan ladder mentions students, so the picker, the Family card and the per-child roster work on Free, Pro and Studio alike. The things a studio usually pairs them with are gated: standby, auto close-out and attendance-timed credits need Pro, pairing a door screen needs Studio, and recurring tuition billing needs Pro. See Billing and plans.

Not built yet

  • A dashboard setting for family mode. As above: student_mode has no control anywhere in the product.
  • Tuition that knows about siblings. A tuition plan's coverage still matches on the payer's email, so one enrolled child would cover every sibling. The column for a per-student enrollment exists and nothing reads it. Do not enrol a family in tuition on the assumption that it charges per child.
  • A recurring series per child. Two children in two weekly slots are two runs of bookings that can only be told apart by the name on each one.
  • Standby per child. A waitlist position is not counted against a student.
  • Turning an old booking into a child's. There is no “this booking was for a child” conversion, so history from before you switched the picker on stays under the parent's name.
  • A parent-facing portal. Parents manage nothing themselves; they pick a child at booking time and that is the whole of it.
  • Erasure and anonymising of a student record.
  • Authorised-pickup enforcement. The pickup line is a note, not a rule.

Last checked 2026-09-10.

Still stuck? Email support@calemander.com · Privacy · Terms