# Routine Documentation > Routine is a scheduling system for music studios. Families submit their lesson availability through a private link; studio admins configure the studio, collect those responses, generate a schedule with a solver, and adjust it by hand. Generated from 19 pages. Canonical site: https://docs.myroutine.io --- # Routine Documentation ![An instructor and a group of students gathered around a weekly lesson calendar](/img/illustrations/hero-home-v2.png) Scheduling for music studios. Families say when they're free through a private link — no account, no password — and Routine fits every student into your studio hours. ## Pick your path | For families | For studios | | :---: | :---: | | [![A parent and child tapping time slots on a phone](/img/illustrations/path-students.png)](./students/index.md) | [![A studio admin at a laptop reviewing a filled schedule grid](/img/illustrations/path-admin.png)](./admin/index.md) | | **[I was sent a link](./students/index.md)** | **[I run a studio](./admin/index.md)** | Submit your availability in a few minutes. | Set up your studio and build a schedule. **[Full Reference](./reference/index.md)** --- # Submitting your availability ![A family sitting together choosing lesson times on a phone](/img/illustrations/routine-student-image-gen.png) Your studio sent your family a link. Opening it starts a short wizard that asks when you're free for lessons. It takes a couple of minutes, works on a phone, and needs no account and no password. One link covers your whole household — you don't get a separate one per child. Anyone who has it can see and change your family's availability, so treat it like a password. If it's ever shared by mistake, ask your studio for a new one. ## The five steps | Step | What happens | | --- | --- | | **1. Welcome** | You see your family name and a card for each student being scheduled. Press **START**. | | **2. Question** | One question: would you like lessons scheduled back to back? | | **3. Preference** | Pick your available days, then draw time ranges on each one. | | **4. Verify** | Review everything on a week calendar and fix anything that looks wrong. | | **5. Complete** | Confirmation. If your family has more students, you're moved to the next one automatically. | A progress bar across the top shows where you are. Click an earlier step to go back and change an answer. ![The five steps of the scheduling wizard](/img/illustrations/hero-students.jpg) ## Back to back Step 2 asks one question — **Would you like to schedule back to back?** — with a thumbs-up (**Yes**) and thumbs-down (**No**) control. **Yes** asks the scheduler to put your children's lessons in consecutive slots on the same day, so you make one trip instead of two. It's a strong preference, not a guarantee: if honouring it would push someone outside the times you gave, they get placed separately instead. Answering **No** gives the scheduler more freedom, which usually means a better match against your preferred times. With only one student, the answer makes no difference either way. ## Your availability This is the step that matters most, and you do it for each student. **Pick your days.** Tap every day you could realistically attend. Days you don't select are treated as completely unavailable. Select generously — a day you *could* do but would rather not is better recorded as an available (not preferred) time range than left off entirely, because it gives the scheduler a fallback when your first choices fill up. **Draw your times.** On each selected day, click a start time, then click a later time to set the end. Each range you complete appears in the **Configured Ranges** list, where you can delete it. Ranges can't overlap, so shorten or delete an existing one before drawing across it. **Label each range:** | Label | Meaning | | --- | --- | | **Preferred** | When you'd most like your lesson. The scheduler aims for these. | | **Available** | You can attend, but you'd rather not. Used as a fallback. | | **Unavailable** | You definitely cannot attend. You'll never be scheduled here. | :::note Some studios show only two labels If you don't see an **Available** option, your studio uses the simpler version, and anything you haven't marked is treated as ordinary availability. ::: The more you give, the more likely you are to get one of your preferred slots. A family offering a single 30-minute window is the hardest to place, and usually ends up with the slot nobody else wanted. ## Check and submit The **Verify** step shows everything you entered on one week calendar — your last chance to catch a range that runs an hour long or a day you forgot. - **Drag** an entry to move it. - **Resize** it by its edge to make it longer or shorter. - **Click** it to delete it, confirming in the dialog. - **Drag a chip** — *Drag to add preferred time* or *Drag to add Unavailable time* — onto the calendar to add a range without going back a step. Grey **Unschedulable** bands are your studio's closed hours, not something you set. If your only free time falls entirely inside grey, contact the studio — there's no slot the scheduler could give you. Submitting marks that student as complete. If other children still need filling in, Routine takes you straight to the next one; when everyone is done you reach **Complete**. Give each child their own honest availability even when it's mostly the same — copying an older sibling's answers onto a younger child who can't actually make the later slots is the most common cause of a schedule that has to be redone. You can reopen the link and revise anything while scheduling is still open. ## Timezones Routine reads your timezone from your browser and shows it in a small indicator on the scheduling pages, with a **Change** control next to it. Every time you enter is stored against that zone, so daylight saving is handled for you. If the detected zone is wrong — a work laptop on head-office time, a VPN, a device that travelled — fix it **before** entering any times. If your zone differs from your studio's, Routine asks whether to **Keep mine** or **Use studio's**; either is correct so long as it matches how you're thinking about the numbers you type. ## See also - [If something's not working](./help.md) — link errors, wrong times, missing students - [Glossary](../reference/glossary.md) — what "preferred", "request window", and other terms mean --- # If something's not working Almost everything on this page ends the same way: your studio can fix it in seconds. Contact them directly rather than waiting. ## Messages you might see | Message | What it means | What to do | | --- | --- | --- | | **You're early!** *Scheduling opens on…* | Your studio hasn't opened scheduling yet. | Save the link and come back on the date shown. They'll normally email a reminder. | | **Scheduling has closed** | The deadline has passed. | Contact your studio — they can reopen access for your family alone, or add your times for you. | | **Access Restricted** | The link couldn't be matched to an open request. | Usually a link that's been replaced, or a URL your email app wrapped onto two lines. Ask the studio to resend it. | ## Other things people hit | Problem | What to do | | --- | --- | | The link doesn't open at all | Copy the whole address into your browser in one piece — email apps often break long links across lines. If it still fails, ask for a fresh link. | | The times look shifted by a few hours | Your timezone indicator is set to the wrong zone. Change it, then check your entries. | | A child is missing from the family list | Only your studio can add or remove students. Ask them — the change shows up on your existing link straight away, with no new link needed. | | You want to change an answer after submitting | Reopen the link and edit it, any time before scheduling closes. After that, contact your studio. | | Your only free time is inside a grey band | Grey is outside the studio's opening hours, so nothing can be booked there. Tell the studio — they'll either work around it or extend their hours. | ## See also - [Submitting your availability](./index.md) — the walkthrough --- # For Studio Admins ![A studio owner at a laptop reviewing a generated lesson schedule](/img/illustrations/hero-admin.png) This section follows the order you'll actually work in — from an empty studio to a finished, published schedule. ## The season, start to finish | # | Step | Page | | --- | --- | --- | | 1 | Sign in and work through the setup checklist | [Getting started](./getting-started.md) | | 2 | Set your operating hours, timezone, and request window | [Studio settings](./studio-settings.md) | | 3 | Add students and organise them into family groups | [Students and groups](./students-and-groups.md) | | 4 | Bulk-load an existing roster | [Importing students](./importing-students.md) | | 5 | Understand the per-family scheduling links | [Schedule links](./schedule-links.md) | | 6 | Email every family their link | [Sending schedule links](./sending-schedule-links.md) | | 7 | Watch responses come in | [Tracking responses](./tracking-responses.md) | | 8 | Generate candidate schedules | [Generating a schedule](./generating-a-schedule.md) | | 9 | Adjust the one you like | [Managing a schedule](./managing-a-schedule.md) | | 10 | Check it's actually good | [Schedule quality and feedback](./schedule-quality.md) | Steps 1–2 are one-time setup. Steps 3–10 repeat each season. ## Where things live Every screen below has a fixed address, so these links work for any studio. Follow one and you land on that screen in your own studio — signing in first if you aren't already. | Screen | Purpose | | --- | --- | | [Home](https://app.myroutine.io/company) | Dashboard, setup checklist, at-a-glance stats | | [Your Studio](https://app.myroutine.io/company/users) | Students, groups, parents, CSV import, schedule links | | [Studio Scheduling](https://app.myroutine.io/company/schedule) | Generate, view, and edit schedules | | [Studio Settings](https://app.myroutine.io/company/scheduler) | Hours, request window, timezone, integrations, language | | [Send Schedule Links](https://app.myroutine.io/company/schedule-link-emails) | Bulk email to families | | Student schedule | One student's submitted availability. Opened from **View Schedule** in that student's row — the address is different for every student, so there's no shared link to it. | ![The admin navigation bar](/img/admin/navigation.png) ## Before your first season Two settings cause the most trouble when they're wrong, and both are awkward to change once families have started submitting: - **Timezone** — set it before you send any links. Changing it afterwards reinterprets times that families have already entered. - **Studio hours** — availability outside your operating hours is discarded as unschedulable. Narrow hours set by accident silently throw away good slots. ## See also - [Schedule settings reference](../reference/schedule-settings.md) - [Glossary](../reference/glossary.md) --- # Getting started ## Signing in Click **Sign In** on the home page and use the account your studio was set up with. You only ever see your own studio's students, schedules, and settings. If sign-in succeeds but you land on a *Page Not Found*, your account isn't attached to a studio yet — contact whoever set it up rather than retrying. Families never sign in at all. They submit availability through the private [schedule link](./schedule-links.md) you send them, with no account and no password. ## The dashboard After signing in you land on the **[Company Dashboard](https://app.myroutine.io/company)**, headed *Welcome {your studio name}*. ![The company dashboard](/img/admin/dashboard.png) ### The setup checklist A new studio sees *"Welcome! Let's get your studio set up:"* with four items. Each has a **Set Up** or **Add Now** button that deep-links to the right screen, and a **Dismiss** link if it doesn't apply to you. | # | Item | Goes to | | --- | --- | --- | | 1 | Set your studio's timezone | [Studio settings → Timezone](./studio-settings.md#timezone) | | 2 | Configure studio operating hours | [Studio settings → Studio Hours](./studio-settings.md#studio-hours) | | 3 | Set schedule request window | [Studio settings → Request Window](./studio-settings.md#request-window) | | 4 | Add or import students | [Importing students](./importing-students.md) | Do them in that order. Timezone first matters: it's the frame every other time value is interpreted in. ### Quick actions Three shortcuts sit above the stats — **Import Students**, **View Schedules**, and **Studio Settings**. ### Stat cards | Card | What it tells you | | --- | --- | | **Total Students** | Currently enrolled students. Links to *Manage Students*. | | **Operating Hours** | Your daily start and end times. Links to *Edit Hours*. | | **Request Window** | A status chip — **Open**, **Upcoming**, **Closed**, or **Not Set** — plus the opening or closing date. Links to *Edit Request Window*. | | **Active Schedules** | How many schedule configurations exist. | | **Pending Requests** | Students whose availability is still awaiting schedule generation. | | **Published schedules** | Count of published schedules. | The **Request Window** chip is the one to watch during a season. If it reads **Closed** while you're still expecting responses, families are being turned away at their links. ## See also - [Studio settings](./studio-settings.md) — the next step - [Schedule settings reference](../reference/schedule-settings.md) --- # Studio settings **[Studio Settings](https://app.myroutine.io/company/scheduler)** is headed *Scheduler Configuration* — "Configure studio hours, schedule request windows, and integration settings". Changes are held until you press **Save Changes**; an **Unsaved changes** indicator appears as soon as you edit anything. You'll get either *"Configuration saved successfully!"* or *"Please fix validation errors"*. Each tab has its own address — the dashboard checklist buttons use them, and so do the **Open this tab** links below, which take you straight there. ![The studio settings tabs](/img/admin/studio-settings-tabs.png) ## Studio Hours [Open this tab](https://app.myroutine.io/company/scheduler?tab=hours) — *Operating schedule* Set **Operating Hours by Day** for Sunday through Saturday: a start time, an end time, and a **Closed** toggle per day. These hours are a hard boundary. Anything outside them is **unschedulable** — students see it as a grey band on their calendar, and the scheduler will never place a lesson there. They also set the top and bottom edges of every calendar view in the app. :::warning Set these before collecting availability Narrowing your hours after families have submitted silently discards the availability that now falls outside them. Widen first, collect, then narrow if you must. ::: A day can carry more than one range — useful for a lunch break. Ranges that touch are merged automatically. ## Request Window [Open this tab](https://app.myroutine.io/company/scheduler?tab=request-window) — *Availability period* Two datetimes: **Request Window Opens** and **Request Window Closes**. Between them, families can use their schedule links. Outside them they see ["You're early!" or "Scheduling has closed"](../students/help.md). The tab shows the computed **Request window duration** and rejects a window that ends before it starts: *"The request window must start before it ends"*. A **How Request Windows Work** explainer sits below the fields. Individual families can be exempted from the window — see [schedule links](./schedule-links.md#allow-access-outside-the-request-window). ## Timezone [Open this tab](https://app.myroutine.io/company/scheduler?tab=timezone) — *Location settings* Pick the studio's timezone. The tab shows **Current time in …** so you can sanity-check the choice, a **Why Timezone Matters** explainer, and a **Current Settings** panel with **UTC Offset**, **Earliest Time**, and **Latest Time**. This is the reference zone that student submissions are reconciled against. A student in a different zone is [prompted to choose](../students/index.md#timezones) between their own and yours. :::danger Set this once, before your first season Changing the studio timezone reinterprets availability that families have already submitted. If you must change it mid-season, re-collect availability rather than trusting the shifted values. ::: ## Integrations [Open this tab](https://app.myroutine.io/company/scheduler?tab=integrations) — *External connections* **Integrations & Connectors**. All three tiles are currently marked **Coming Soon**: - Google Calendar Sync - Custom Webhooks - Email Notifications The Zapier / MyMusicStaff connector and the transactional email used by [Send Schedule Links](./sending-schedule-links.md) are configured outside this tab — see [Integrations](../reference/integrations.md). ## Language [Open this tab](https://app.myroutine.io/company/scheduler?tab=language) — *Localization settings* English only today. *"More languages coming soon!"* ## The Summary rail A **Summary** panel on the right recalculates as you edit: | Metric | Meaning | | --- | --- | | **Total Weekly Hours** | Total schedulable hours across the week | | **Active Days** | Days per week the studio is open | | **Daily Average** | Average open hours per active day | Compare **Total Weekly Hours** against the total lesson time you need to place (visible as *Requested Hours* on [Your Studio](./students-and-groups.md)). If requested hours approach or exceed weekly hours, no scheduler can succeed — you need more operating hours, not a better algorithm. ## See also - [Schedule settings reference](../reference/schedule-settings.md) — the underlying fields - [Students and groups](./students-and-groups.md) — the next step --- # Students and groups **[Your Studio](https://app.myroutine.io/company/users)** is where your roster lives. Routine's model is two levels deep: a **group** is a household or family, and each group contains **students**. Groups matter because the schedule link and the [back-to-back preference](../students/index.md#back-to-back) are both per-group. ![The Your Studio page](/img/admin/your-studio.png) ## Statistics overview Six figures across the top: **Total Users**, **Completed**, **Completion Rate**, **Groups**, **Requested Hours**, and **Scheduled Hours**. **Requested Hours** versus **Scheduled Hours** is the fastest health check you have — see [Tracking responses](./tracking-responses.md). ## Toolbar Search, a **Groups / Students** view toggle, and the actions **Import CSV**, **Send Schedule Links**, **Add Group**, **Add User**. ## Students view | Column | Notes | | --- | --- | | **Student Name** | | | **Group** | The family the student belongs to | | **Duration (min)** | Lesson length for this student | | **Schedule Status** | A **Completed** or **Pending** chip | | **Completion Date** | When they submitted | | **Parents** | Linked parent contacts | | **Actions** | **View Schedule**, **Edit**, **Delete** | **View Schedule** opens that student's submitted availability on a read-only calendar. ## Groups view | Column | Notes | | --- | --- | | **Group** | Family name | | **Students** | How many students it contains | | **Completion** | How many have submitted | | **Schedule Link** | The family's private link | ## Adding a student **Add User** opens a dialog with: - **Name** - **Duration (minutes)** — the lesson length, hinted *"Rounded to the nearest 15 minutes"*. Routine snaps durations to 15-minute multiples so lessons tile cleanly against each other. - **User Type** — **Student** or **Parent** - **Parent Email Address** - **Group Assignment** — either **Add to Existing Group** (then *Select Group*) or **Create New Group** (then *New Group Name*) :::tip Get durations right before generating Lesson length is the single biggest input to how well a schedule packs. A student left on the wrong duration produces a schedule that looks fine and then doesn't fit in reality. ::: ## Adding a group **Add Group** takes just a **Group Name**. You'd normally create groups implicitly via *Create New Group* while adding the first student, or in bulk via [CSV import](./importing-students.md). ## Parent contacts **Parent Info** on a group opens a modal listing that family's parent contacts — **Name**, **Contact Email**, and actions. Parent emails matter for one reason: they're the recipients for [Send Schedule Links](./sending-schedule-links.md). A group with no parent contact, or a contact with no email, can't be emailed and will show up under **Missing Email** on that page. ## Group details Opening a group shows its [schedule link and per-group toggles](./schedule-links.md) — **Regenerate Link**, **Allow access outside request window**, and **Exclude from schedule generation** — plus **Add User**, **Parent Info**, and **Delete Group**. ## Deleting | Action | Effect | | --- | --- | | **Delete User** | Removes the student. All their schedule data is permanently deleted. | | **Delete Group Only** | Removes the group, leaving its students in place. | | **Delete Group and All Users** | Removes the group and every student in it. | Both group deletions invalidate that family's schedule link. ## See also - [Importing students](./importing-students.md) — bulk load instead of typing - [Schedule links](./schedule-links.md) - [Tracking responses](./tracking-responses.md) --- # Importing students CSV import is the fastest way to load an existing roster. It runs as a background job: you upload, Routine validates, you review a preview, and only then does anything get written. ![The CSV import dialog](/img/admin/csv-import-dialog.png) ## Uploading **Import CSV** on [Your Studio](./students-and-groups.md) opens **Import Users from CSV**. Drag a file onto the drop zone or click to browse — CSV only. **Download Sample CSV** gives you a correctly-shaped file to start from. Use it; it's faster than matching the header names by hand. ## Required columns | Column | Notes | | --- | --- | | `First Name` | | | `Last Name` | | | `Family Name` | Becomes the group name | | `Lesson Length` | Minutes. Snapped to the nearest 15. | | `Family Email Address` | Used for [schedule link emails](./sending-schedule-links.md) | | `Family ID` | Your external identifier for the household | | `Student ID` | Your external identifier for the student | Some alternate header spellings are accepted, but matching the sample exactly avoids surprises. `Family ID` and `Student ID` are what make re-imports safe — they're stored as external identifiers, so a second import of the same roster matches existing records instead of duplicating them. They're also the join keys used by the [Zapier / MyMusicStaff integration](../reference/integrations.md). ## Job progress Import is asynchronous. The dialog reports: 1. Preparing import… 2. Processing CSV file… 3. Validating data… 4. Ready to import 5. Import completed successfully — or Import failed with a running *"{n} rows processed"* count. Large rosters take a few seconds; the dialog polls until the job finishes. ![Importing a roster from CSV](/img/admin/csv-import.gif) ## The preview Nothing is written until you confirm. The preview splits your file three ways: ![The CSV import preview](/img/admin/csv-import-preview.png) ### Valid Users Rows that will be created as-is. ### Invalid Rows Each with its row number and the specific errors. Fix them in your source file and re-upload — you can't edit rows in the preview. ### Existing Families *"The following families already exist. Please choose an action for each:"* | Choice | Effect | | --- | --- | | **Create New Family** | Makes a second, separate group with the same name | | **Add to Existing Family** | Puts the incoming students into the group you already have | **Add to Existing Family** is almost always what you want when adding a sibling mid-season. **Create New Family** is for genuine name collisions between two unrelated households. :::warning This choice is not reversible in one click Choosing **Create New Family** by mistake leaves you with two groups, two schedule links, and a family who receives both. Merging them means deleting one and re-adding its students. ::: ## Finishing **Import {count} Users** commits. The new students appear immediately on [Your Studio](./students-and-groups.md) with **Pending** status, and each new group gets a schedule link. ## See also - [Students and groups](./students-and-groups.md) - [Sending schedule links](./sending-schedule-links.md) — the natural next step - [Integrations](../reference/integrations.md) — importing from MyMusicStaff instead --- # Schedule links Every group has one **schedule link** — the URL a family uses to submit availability. It's generated when the group is created, and it looks like: ``` https://app.myroutine.io/users/schedulerequest/AB12CD34 ``` The trailing code is the group's **schedule code**. It is the only credential the link carries, so it's what makes the link both convenient and worth protecting. Find it under **Group Details** on [Your Studio](./students-and-groups.md). ![The group details dialog](/img/admin/group-details.png) ## Copying and opening The link is shown read-only with **Copy link** and **Open in new tab**. **Open in new tab** is the fastest way to see exactly what a family sees, including whether the request window is currently letting them in. Use it to verify your setup before sending a hundred emails. ## Regenerate Link **Regenerate Link** issues a new schedule code for the group. The confirmation is explicit: > A new link will be generated for this group. The current link will stop > working immediately. Regenerate when: - A link has been shared somewhere it shouldn't have been. - A family forwards the link to the wrong household. - You want to revoke access after the season without closing the window for everyone. Any availability the family already submitted is kept — regenerating changes the door, not what's behind it. You do need to send them the new link. ## Allow access outside the request window A per-group override. When on, this family can use their link even when the studio's [request window](./studio-settings.md#request-window) is closed or hasn't opened. Use it for the family who emails you three days late, rather than reopening the window for everyone and re-inviting responses you've already processed. ## Exclude from schedule generation When on, this group's students are omitted from schedule generation entirely. They stay in your roster, keep their data, and still show on Your Studio — they just aren't placed. Use it for: - Students on a break for the season - Groups whose lessons are arranged outside Routine - A family whose availability is so constrained you're placing them by hand :::note They still count in the roster stats Excluded students continue to appear in **Total Students**. Only schedule generation skips them. ::: ## See also - [Sending schedule links](./sending-schedule-links.md) — getting links to families - [Students and groups](./students-and-groups.md) - Student view: [Submitting your availability](../students/index.md) --- # Sending schedule links **[Send Schedule Links](https://app.myroutine.io/company/schedule-link-emails)** emails every family their [schedule link](./schedule-links.md) in one pass, and tracks what happened to each one. ![The send schedule links page](/img/admin/send-schedule-links.png) ## The template An **Email Template** card with a **Subject** — default *"Your schedule request is ready"* — and a **Message** body. Two merge tokens are substituted per recipient: | Token | Replaced with | | --- | --- | | `{url}` | That family's schedule link | | `{parentName}` | The parent contact's name | `{url}` is the one that matters. A message without it sends a perfectly friendly email that gives the family no way to actually do anything. :::tip Say when the window closes The email is the only place most families will learn your deadline. Put the request window's closing date in the body — Routine won't add it for you. ::: ## Choosing recipients The recipient table lists one row per group/parent, with a select-all checkbox, a per-row **Send email** icon for one-offs, and **Send Selected (n)** for the batch. Sending runs as a background job with a progress bar; rows update as they go. ## Send statuses | Status | Meaning | What to do | | --- | --- | --- | | **Sent** | On its way to the family | Nothing | | *"Sent yesterday ×2"* | Previously sent, with a count and relative date | Check before sending again | | **Invalid address** | The address isn't a valid email address | Fix it under **Parent Info** and resend | | **Couldn't be delivered** | The receiving mail server refused it | Confirm the address with the family | | **Try again shortly** | Too many messages at once | Wait a minute and resend those rows | | *"Previously failed: …"* | Skipped this run because of an earlier failure | Fix the cause above, then resend | The relative-date labels are what stop you accidentally spamming a family three times in an afternoon — check them before hitting **Send Selected**. ## Missing Email A separate **Missing Email (n)** section lists groups that can't be emailed at all, with the reason: - **No parent contacts assigned** — add one via **Parent Info** on the group - **No email on file** — the contact exists but has no address Both link back to [Your Studio](./students-and-groups.md) to fix. Work this list to zero before your first send; these families will otherwise never receive a link and you won't hear from them until you notice the gap in your completion rate. ## Reset Season **Reset Season** opens **Reset Email History?**: > All send history will be deleted… Use this at the start of a new scheduling > season. It clears the send log so a new season starts with every family showing as un-emailed. It does not delete students, groups, links, or availability. :::warning Don't use this to retry failures Resetting hides the failure reasons you need in order to fix them. To retry a handful of rows, select just those rows and send again. ::: ## See also - [Schedule links](./schedule-links.md) - [Tracking responses](./tracking-responses.md) — the next step - [Integrations](../reference/integrations.md) --- # Tracking responses Once links are out, your job is to get the completion rate up before the request window closes. Everything you need is on [Your Studio](./students-and-groups.md) and the dashboard. ## The numbers that matter | Figure | Where | What it tells you | | --- | --- | --- | | **Completed** / **Total Users** | Your Studio | Raw progress | | **Completion Rate** | Your Studio | The same thing as a percentage | | **Requested Hours** | Your Studio | Total lesson time you need to place | | **Scheduled Hours** | Your Studio | Total lesson time currently placed | | **Pending Requests** | Dashboard | Students awaiting schedule generation | | **Request Window** chip | Dashboard | **Open**, **Upcoming**, **Closed**, or **Not Set** | Compare **Requested Hours** against **Total Weekly Hours** from [Studio settings](./studio-settings.md#the-summary-rail). If requested hours are close to or above your open hours, the season is oversubscribed and no scheduler will fix it — you need more operating hours or fewer students. ## Finding who hasn't responded Switch Your Studio to the **Students** view and scan the **Schedule Status** column for **Pending** chips. The **Groups** view's **Completion** column is better for chasing, because you chase a family, not a child. ![Group completion tracking](/img/admin/groups-completion.png) ## Chasing stragglers Go back to [Send Schedule Links](./sending-schedule-links.md), select only the groups still showing incomplete, and send again. The status column there shows *"Sent {n} days ago"* per row so you can see who has already had two reminders. Groups under **Missing Email** will never respond on their own — call them. ## Inspecting one student's answers **View Schedule** in a student's row opens a page titled *"{Name}'s Schedule"*. It shows: - **Appointment Duration: N minutes** - **Schedule Status: Completed / Pending** - A calendar of what they submitted, with a **Preferred Times** / **Unavailable Times** legend - **Back to Users** Use it when a family says they submitted but the status says otherwise, or when a generated schedule places someone somewhere surprising — the answer is usually visible here. ## When to stop waiting You don't need 100%. Students who never submit are simply unconstrained: the scheduler can place them anywhere inside studio hours. That's often fine for a handful of people, and much better than delaying the whole season. Alternatively, [exclude their group](./schedule-links.md#exclude-from-schedule-generation) and place them by hand afterwards. ## See also - [Generating a schedule](./generating-a-schedule.md) — the next step - [Sending schedule links](./sending-schedule-links.md) --- # Generating a schedule **[Studio Scheduling](https://app.myroutine.io/company/schedule)** is headed *Schedule Management*. It's where you produce candidate schedules and pick one. ![The schedule management page](/img/admin/schedule-management.png) ## The layout **Users to Schedule** runs down the left: a searchable list of everyone who will be placed, with a count. Selecting a student overlays their submitted availability on the calendar — the quickest way to understand why someone landed where they did. **Create Heatmap** aggregates everyone's availability into a density view, showing which parts of the week are contested and which are empty. Check it before generating: a heatmap with one dark band and a lot of white tells you the schedule will be tight no matter how it's arranged. The centre is a week calendar on a 15-minute grid, bounded by your [studio hours](./studio-settings.md#studio-hours), with the allowed hours drawn as a background layer. ## Running the scheduler **Generate Schedule** at the bottom starts a background job — the button reads *Generating…* while it runs. Generation is asynchronous and polled roughly every two seconds. The job moves through **Pending → Running → Completed**, or **Failed**. The finished row flashes green in the schedule list. Generating does not disturb any existing schedule. Each run adds a new candidate, so you can produce several and compare. ## Available Schedules Every generated schedule appears in the table at the bottom: | Column | Notes | | --- | --- | | **Star** | Mark your preferred candidate | | **Name** | Defaults to *"Schedule generated - …"* | | **Fitness** | Routine's own score for the schedule. Comparable between runs, not an absolute. | | **Time Generated** | | The row menu offers **Rename**, **Star / Unstar**, **Duplicate**, **History**, and **Delete**. ## A workflow that works 1. Check the heatmap. 2. Generate two or three candidates. 3. Open the [Quality panel](./schedule-quality.md) on each and compare the metrics — they're more informative than the single fitness number. 4. **Star** the best one. 5. **Duplicate** it before you start editing, so you always have the pristine generated version to fall back to. 6. [Edit the duplicate](./managing-a-schedule.md). Step 5 is cheap insurance. Editing is hands-on, and a duplicate keeps the generated version intact to compare against — or to go back to. ## If generation fails A **Failed** job usually means the constraints can't be satisfied. Check: - Are **Requested Hours** greater than **Total Weekly Hours**? The season is oversubscribed. - Did someone submit availability that falls entirely outside studio hours? - Are lesson durations correct? One student mistakenly set to 480 minutes will consume a whole day. ## See also - [Managing a schedule](./managing-a-schedule.md) — the next step - [Schedule quality and feedback](./schedule-quality.md) - [Schedule settings reference](../reference/schedule-settings.md) --- # Managing a schedule A generated schedule is a starting point. Editing happens directly on the calendar in [Studio Scheduling](https://app.myroutine.io/company/schedule), with the schedule selected. > Drag entries to move them for the selected schedule. ![Dragging a lesson on the schedule calendar](/img/admin/schedule-drag.png) ## Moving a lesson Drag a lesson to empty space and it simply moves there. The grid snaps to 15 minutes. Drops outside your [studio hours](./studio-settings.md#studio-hours) are blocked — the calendar won't accept them. ## Reflow: dropping onto another lesson Dropping a lesson **onto an existing lesson** does something different. Rather than swapping the two or rejecting the drop, Routine *inserts* the dragged lesson at that position and **reflows** the rest of that day's contiguous run, sliding the subsequent lessons along to make room. The rearranged lessons flash blue so you can see exactly what moved. This is the tool for "move Ana to 4:00 and push everyone after her back fifteen minutes" — an operation that would otherwise take six separate drags. The whole reflow is applied as a single operation: every affected lesson moves, or none of them does. :::tip Reflow works within a day's run Reflow slides lessons that are contiguous with the drop target. It won't push a lesson across a gap in the day or into another day. ::: ## Availability conflicts A lesson placed outside the student's stated availability gets an **amber border and a ⚠ marker**. Conflicts are flagged, not blocked. That's deliberate — as an admin you often know something the data doesn't ("their mum called, Thursdays are fine now"). But an amber marker you didn't intend means a family is about to be told to attend at a time they said they couldn't. Scan for amber markers before you consider a schedule finished. ## Schedule actions From the row menu in **Available Schedules**: | Action | Notes | | --- | --- | | **Rename** | Replaces the default *"Schedule generated - …"* name | | **Star / Unstar** | Marks your preferred candidate | | **Duplicate** | Copies the schedule. Use it as a branch point before a risky round of edits. | | **Delete** | Removes the schedule | There is no per-lesson lock. **Star** plus **Duplicate** is the working substitute: duplicate before editing, and if the edits go badly, delete the copy and duplicate the starred original again. ## Publishing Routine does not currently have a publish or export action. Distributing the finished schedule to families is a manual step today — the schedule links handle collecting availability, not announcing results. ## See also - [Schedule quality and feedback](./schedule-quality.md) - [Generating a schedule](./generating-a-schedule.md) --- # Schedule quality and feedback The **Insights** drawer has two tabs: **Quality**, which measures the schedule, and **Feedback**, where you record your own judgement of it. ![The schedule quality panel](/img/admin/insights-quality.png) ## Quality metrics **Schedule Quality** shows six percentage bars. | Metric | What it measures | Why it matters | | --- | --- | --- | | **Student Coverage** | Share of students who got a slot | The first thing to check. Anything below 100% means someone was left out. | | **Scheduling Ratio** | Placed lessons against requested lessons | Reads low when students were excluded or unplaceable | | **Priority Satisfaction** | How well high-priority requests were honoured | Low values mean your most constrained families did badly | | **Time Efficiency** | How densely the timeslots are packed | Low values mean dead air between lessons | | **Break Adequacy** | Consecutive pairs with at least a 5-minute gap | Low values mean back-to-back lessons with no breathing room for the instructor | | **Day Balance** | How evenly load is spread across days | Low values mean one exhausting day and several quiet ones | These metrics trade off against each other. **Time Efficiency** and **Break Adequacy** pull in opposite directions almost by definition — a perfectly packed day has no breaks. Pick which you care about rather than trying to maximise both. **Student Coverage** is the one that isn't a trade-off. If it's below 100%, find out who was dropped before looking at anything else. ## Comparing candidates Open the Quality tab on each generated candidate and compare metric by metric. This is a much better basis for choosing than the single **Fitness** number in the schedule list, which compresses everything into one figure and can't tell you *why* one schedule beat another. ## Admin Feedback The **Feedback** tab records your own assessment: four five-star ratings plus free-text. | Question | | --- | | Overall, how satisfied are you with this schedule? | | How well are all students covered? | | Are the timeslots distributed efficiently? | | Does the schedule allow adequate breaks? | Plus **Comments (optional)**. Rating a schedule takes ten seconds and pays off across seasons: it's a record of what "good" looked like for your studio, attached to the schedule that produced it. When next season's output feels worse, you have something concrete to compare against. ## The metadata strip Alongside the drawer, each schedule shows a metadata strip: | Field | Meaning | | --- | --- | | **People** | Students placed | | **Timeslots** | Slots used | | **Hours** | Total scheduled hours | | **Priority** | Breakdown by High / Med / Low | | **By Day** | Distribution across the week | **By Day** is the quickest sanity check on the shape of a week — it shows a Tuesday carrying twice everyone else's load before you notice it on the calendar. ## See also - [Generating a schedule](./generating-a-schedule.md) - [Managing a schedule](./managing-a-schedule.md) --- # Reference ![An open reference book and index cards laid out on a music stand](/img/illustrations/hero-reference.png) The guides explain how to do things. These pages explain what things *are* — for when you hit a word or a setting mid-task and just need the answer. | Page | Answers | | --- | --- | | [Glossary](./glossary.md) | What "request window", "preferred", "reflow", and the rest actually mean | | [Schedule settings](./schedule-settings.md) | Every studio setting, what it controls, and its limits | | [Integrations](./integrations.md) | Zapier, MyMusicStaff, email — and what's still coming | | [FAQ](./faq.md) | Common questions and a troubleshooting table | ## See also - [Submitting your availability](../students/index.md) — the family-facing walkthrough - [For Studio Admins](../admin/index.md) — the full season, start to finish --- # Glossary ## Appointment length The duration of one student's lesson, in minutes. Set per student. Snapped to 15-minute multiples so lessons tile against each other cleanly. Shown as **Duration (min)** on Your Studio and **Appointment Duration** on a student's schedule page. ## Fitness Routine's own score for a generated schedule, shown in the **Available Schedules** table. Useful for comparing runs; not meaningful as an absolute number. The [quality metrics](../admin/schedule-quality.md) are more informative when choosing between candidates. ## Group A household or family. Contains one or more students. The unit that owns a [schedule link](#schedule-link) and answers the [back-to-back question](../students/index.md#back-to-back). ## Heatmap An aggregated view of everyone's submitted availability, showing which parts of the week are contested. Toggled with **Create Heatmap** on the scheduling page. ## Preference type The label on a submitted time range: | Type | Meaning | | --- | --- | | **Preferred** | The student's first-choice window | | **Available** | Acceptable but not preferred | | **Unavailable** | The student cannot attend | | **Unschedulable** | Outside studio hours — set by the studio, not the student | | **Scheduled** | A placed lesson | ## Reflow Dropping a lesson onto another lesson inserts it at that position and slides the rest of that day's contiguous run along to make room. Applied as a single operation. See [Managing a schedule](../admin/managing-a-schedule.md#reflow-dropping-onto-another-lesson). ## Request window The period during which families may submit availability, set by **Request Window Opens** and **Request Window Closes**. Outside it, links show *"You're early!"* or *"Scheduling has closed"*. Individual groups can be [exempted](../admin/schedule-links.md#allow-access-outside-the-request-window). ## Schedule code The short code at the end of a schedule link that identifies a group. It is the link's only credential. Replaced by **Regenerate Link**. ## Schedule link The private URL a family uses to submit availability, of the form `https://app.myroutine.io/users/schedulerequest/{scheduleCode}`. One per group. See [Schedule links](../admin/schedule-links.md). ## Scheduler The engine that places every student into a slot when you press **Generate Schedule**. It works within your [studio hours](#studio-hours), honours the availability families submitted, and aims for their **Preferred** ranges. ## Studio hours The weekly operating hours, set per day with an optional **Closed** toggle. A hard boundary: everything outside is unschedulable. Also called **Operating Hours by Day**. ## Unschedulable Time outside the studio's operating hours. Rendered as a grey band on student and admin calendars. No lesson can be placed there. ## See also - [Schedule settings reference](./schedule-settings.md) - [FAQ](./faq.md) --- # Schedule settings reference The fields that drive scheduling, and where each is edited in the UI. ## Studio-level settings Held against the studio and edited in [Studio Settings](../admin/studio-settings.md). | Field | UI label | What it controls | | --- | --- | --- | | Allowed schedule | **Operating Hours by Day** | A list of day + start + end ranges. The hard boundary for all scheduling. Multiple ranges per day are allowed; touching ranges merge. | | Request window start | **Request Window Opens** | Before this, links show *"You're early!"* | | Request window end | **Request Window Closes** | After this, links show *"Scheduling has closed"* | | Timezone | **Timezone** | The reference zone all submitted times are reconciled against | | Studio name | — | Shown on the dashboard and student welcome screen | ### Computed values These are derived, not entered. They appear in the **Summary** rail and set calendar bounds. | Value | Derived from | | --- | --- | | Earliest schedule timeslot | Earliest studio start across the week — the calendar's top edge | | Latest schedule timeslot | Latest studio end across the week — the calendar's bottom edge | | Total schedule time | Total schedulable hours per week — shown as **Total Weekly Hours** | ## Student-level settings Held against each student. | Field | UI label | What it controls | | --- | --- | --- | | Appointment length | **Duration (min)** | Lesson length in minutes. Snapped to 15-minute multiples. | | Time entries | The preference calendar | The student's submitted ranges, each with a day, start, end, timezone, and [preference type](./glossary.md#preference-type) | | Priority | — | A 0–10 weighting used when placing lessons, reported as **Priority Satisfaction** | | Schedule request complete | **Schedule Status** | Drives the **Completed** / **Pending** chip and the completion date | | Is scheduled | — | Whether this student has been placed in the current schedule | ## Group-level settings Edited under **Group Details** on [Your Studio](../admin/students-and-groups.md). | Field | UI label | Effect | | --- | --- | --- | | Schedule code | **Schedule Link** | The family's link credential. Replaced by **Regenerate Link**. | | Window override | **Allow access outside request window** | Lets this family submit when the studio window is closed | | Exclude from scheduling | **Exclude from schedule generation** | Omits this group's students from generation entirely | | External identifier | — | Your own ID for the household, set by [CSV import](../admin/importing-students.md) or the Zapier integration | ## The 15-minute rule Lesson durations are snapped to the nearest 15 minutes throughout — in the Add User form, in CSV import, and on the calendar grid. The Add User form hints *"Rounded to the nearest 15 minutes"*. This is what lets lessons tile without leaving unusable two-minute gaps. A roster of genuinely odd durations (say 50-minute lessons) will be rounded, so plan your studio's lesson lengths in 15-minute units. ## Interactions worth knowing - **Studio hours are applied after submission.** Availability a family gave that falls outside your hours is discarded as unschedulable. Narrowing hours after collection silently throws data away. - **Timezone is applied at interpretation time.** Changing the studio timezone after families have submitted reinterprets their entries. - **Excluded groups still count in roster totals.** Only generation skips them. - **Requested Hours vs Total Weekly Hours** is the feasibility check. If the first approaches the second, no schedule can succeed. ## See also - [Studio settings](../admin/studio-settings.md) — the UI for these fields - [Glossary](./glossary.md) --- # Integrations ## MyMusicStaff via Zapier Routine ships a Zapier app that connects MyMusicStaff studio-management events to your Routine roster, so students added or updated there flow through automatically instead of being re-entered. **Available actions** - Student added - Student updated **Connecting** Authentication uses an **API Key** plus your **subdomain**, both found in MyMusicStaff under *Settings → Integrations*. **How records are matched** Incoming records carry external identifiers for the family and the student. Routine stores these against the group and the student, which is what makes repeat syncs update existing records rather than creating duplicates. They're the same identifiers used by the `Family ID` and `Student ID` columns in [CSV import](../admin/importing-students.md) — so a roster imported by CSV and then synced from MyMusicStaff will line up. ## Email [Schedule link emails](../admin/sending-schedule-links.md) are sent for you — there's nothing to set up and no account to connect. The Send Schedule Links page shows a status per recipient so you can see which families received theirs and which addresses need fixing. :::note Not the same as "Email Notifications" The **Email Notifications** tile under [Studio Settings → Integrations](../admin/studio-settings.md#integrations) is a separate, unbuilt feature marked *Coming Soon*. Schedule link emails work today regardless of what that tile says. ::: ## Coming soon Three tiles appear under [Studio Settings → Integrations](../admin/studio-settings.md#integrations) and are not yet functional: | Integration | Status | | --- | --- | | Google Calendar Sync | Coming Soon | | Custom Webhooks | Coming Soon | | Email Notifications | Coming Soon | Until Google Calendar Sync ships, moving a finished schedule into an instructor calendar is a manual step. ## See also - [Importing students](../admin/importing-students.md) - [Sending schedule links](../admin/sending-schedule-links.md) --- # FAQ and troubleshooting Questions studio admins run into. Families have their own short page — [If something's not working](../students/help.md). ## A family says they submitted, but they show as Pending Open their student's page via **View Schedule** and check what's actually recorded. Two common causes: they filled in one child and not the sibling, or they entered ranges but never reached the Verify step's submit. ## Nobody from a particular family has responded Check the **Missing Email** section on [Send Schedule Links](../admin/sending-schedule-links.md). If that group has no parent contact or no address, they never received anything. ## Schedule generation failed Usually infeasible constraints. Check, in this order: 1. **Requested Hours** against **Total Weekly Hours** — is the season oversubscribed? 2. Lesson durations — one student mistakenly set to a huge duration will consume a whole day. 3. Availability that falls entirely outside studio hours. See [Generating a schedule](../admin/generating-a-schedule.md#if-generation-fails). ## Student Coverage is below 100% Someone wasn't placed. Their availability is likely too narrow to fit anywhere inside your studio hours. Open their student page, then either widen studio hours, ask the family for more availability, or place them by hand. ## A lesson has an amber ⚠ border It's outside that student's stated availability. Routine flags rather than blocks these, because admins often know something the data doesn't. If you didn't intend it, move the lesson. See [Managing a schedule](../admin/managing-a-schedule.md#availability-conflicts). ## Can I lock a lesson so it won't be moved? Not currently. Generating a new schedule never modifies an existing one, so the working approach is to **Duplicate** a schedule before editing and keep the original starred. ## How do I send the finished schedule to families? Manually, for now. Routine has no publish or export action yet — schedule links collect availability, they don't announce results. ## Can I change the studio timezone mid-season? Avoid it. It reinterprets availability that families already submitted. If you must, re-collect availability afterwards. See [Studio settings → Timezone](../admin/studio-settings.md#timezone). ## See also - [Glossary](./glossary.md) - [Schedule settings reference](./schedule-settings.md) ---