User guide

Scheduling and Dispatch

Looking for what it does rather than how to use it? Read the Scheduling and dispatch overview .

What it is

Scheduling and Dispatch is where technician time is planned and assigned: a calendar of appointments, maintenance windows, on-call shifts and time off, and a drag-and-drop board for moving that work between technicians and hours.


Concepts

ConceptWhat it is
EventOne scheduled block of time. Has a type, a status, an organizer, and optional attendees and reminders.
OrganizerThe person the event belongs to. Set from your session at creation; it is not a field you can pass.
AttendeeSomeone invited. Either a person in Solidlio (gets an in-app notification) or an external email address.
ReminderA lead time before the start, delivered in-app or by email.
RecurrenceAn RFC 5545 RRULE on the parent event; occurrences are expanded on read.
Business hoursYour organization’s working week (Settings → SLA & Hours). Drives free/busy and suggested times.
Calendar syncA per-user Microsoft 365 connection, bidirectional, with optional real-time webhooks.

Event statuses

SCHEDULEDCONFIRMEDIN_PROGRESSCOMPLETED, with CANCELLED and NO_SHOW reachable at any point. Every transition is available from the event page’s status control.

Attendee responses

NEEDS_ACTION (default), ACCEPTED, DECLINED, TENTATIVE.


Roles and permissions

PortalCalendar, create/edit, event detail, sync settingsDispatch board
MSPEvery role in the portal, technicians includedSame
Organizationorganization administrator, power user (plus platform administrator, MSP administrator)organization administrator only (plus platform administrator, MSP administrator)
Customer (/user)Not availableNot available

Creating an event follows the view capability rather than a separate manage capability: the organizer is always the caller, and booking your own appointments is the everyday action a technician needs.

Within the API, visibility is not role-based but ownership-based. A caller may see and edit an event when any of these hold:

  1. they organize it, or
  2. they are an attendee of it, or
  3. it belongs to their account and is not marked private.

Rule 3 is why a colleague can move your team meeting but cannot open your private one-to-one. Marking an event Private removes it from rule 3 entirely.

Cross-tenant ids are rejected on write and return 404 on read — an event belonging to another account is indistinguishable from one that does not exist.


Walkthroughs

Schedule an appointment

  1. Go to Calendar → + New Event (/msp/calendar/new or /org/calendar/new).
  2. Give it a title and pick a type. The type sets the colour the event carries on every screen.
  3. Set start and end. Tick All day to span whole days.
  4. Optionally set a recurrence — daily, weekly, every weekday, monthly or yearly.
  5. Under Attendees, tick the staff who should be invited.
  6. Use the Scheduling assistant below the attendee list:
    • Check this time reports which invitees already have something booked, with the conflicting titles and times.
    • Suggest times returns up to five ranked slots over the next 14 days that fit everyone, inside your organization’s business hours. Click one to apply it to the form.
  7. Under Reminders, choose lead times. Each becomes a reminder delivered in-app by default.
  8. Create event. Every in-system attendee receives a “New calendar invitation” notification.

An event’s colour is not chosen — it comes from its type, and is the same colour that type has on the board, in the month grid and on the event page. That is what makes the legend readable, so there is no per-event colour picker.

Dispatch work to another technician

  1. Go to Scheduling (/msp/scheduling or /org/scheduling). The MSP portal opens on the Dispatch board tab.
  2. Rows are technicians, columns are hours from 07:00 to 19:00. Switch between day and week with the toggle. An hour rule marks each hour and a red line marks the current moment.
  3. Drag an event block onto another technician’s row, or to a different time on the same row. The change is saved on drop. A drop target that would overlap an existing booking is outlined in red and refuses the drop.
  4. Each technician carries a load ribbon. Its track is the length of that person’s configured working day, so a six-hour Friday is visibly shorter than an eight-hour Tuesday, and a day the organization does not staff is hatched rather than shown as empty. Bands: Open under 50%, Steady 50–79%, At capacity 80–100%, Over capacity above 100%. In day view the figure comes from the availability engine and divides by that day’s actual configured hours; week view is a local estimate over the grid window and is labelled “estimated”.
  5. If your own calendar contains overlapping events in the visible range, a banner at the top of the board lists them, and the Overlaps tile counts them.
  6. The type legend below the header doubles as a filter — click a type to show only that kind of work.

Connect a Microsoft 365 calendar

  1. Go to Settings → Calendar Sync (/msp/settings/calendar or /org/settings/calendar).
  2. Click Connect Microsoft 365 and complete consent. Solidlio requests offline_access and Calendars.ReadWrite.
  3. Choose which O365 calendar to sync against, then set:
    • Direction — to O365, from O365, or both
    • Frequency — real-time (webhooks), 15/30/60/360 minutes, or manual only
    • Include private events and Auto-accept invites
  4. Turn on Real-time sync to register a Microsoft Graph webhook subscription. Graph caps these at three days; the status card shows the expiry.
  5. Sync History lists each run with its direction, outcome, and counts of events created, updated and deleted.
  6. From an event page, Push to M365 sends that single event immediately. The button only appears when a calendar is connected.

Manage attendees and RSVP

  1. Open the event (/msp/calendar/{id} or /org/calendar/{id}).
  2. The Attendees card header shows accepted-over-total.
  3. Add opens a picker: choose a colleague from the dropdown, or type an external email address. People already invited are filtered out.
  4. Opt toggles an attendee between required and optional. The × removes them.
  5. If you are on the invite list, Your response appears above the list with Yes / Maybe / No.

Configuration

SettingWhereEffect if unset
Business hoursSettings → SLA & HoursAvailability falls back to 09:00–17:00, weekdays only
HolidaysSettings → SLA & HoursNo days are excluded from suggestions
Business-hours timezonePer BusinessHours rowFalls back to UTC — never the server’s local zone
Event timezonePer eventAmerica/Toronto
Sync directionSettings → Calendar SyncBidirectional
Sync frequencySettings → Calendar Sync15 minutes
Include private eventsSettings → Calendar SyncOff — private events are not pushed to O365
Auto-accept invitesSettings → Calendar SyncOff

Plan tiers

Every paying tier gets the whole feature; access differences come from portal and role only.


Troubleshooting

What you seeCause
Invalid state on the OAuth callbackThe signed state was tampered with, or is older than 30 minutes. Start the connect flow again
Invalid recurrence rule formatThe RRULE string does not parse
Invalid ticketId: the referenced record does not exist or is not accessibleThe linked record belongs to another tenant, or does not exist. The message is identical for both, deliberately
Attendee already exists for this event (409)That person or email is already invited
At least one of personId or email must be providedAn attendee entry identified nobody
Event not found (404) on an id you can see elsewhereIt is private and you are neither organizer nor attendee
Suggested times come back emptyNo slot fits everyone inside business hours in the window — widen the range, or check that the days are configured as working days

How the calendar reads

Colour carries exactly one meaning across every scheduling surface: what kind of work an event is. Status, attendee response and privacy are carried in text badges instead, so a board where everything is coloured never becomes a board where nothing stands out.

TypeReads as
AppointmentCyan — customer meeting or visit
MaintenanceAmber — scheduled window
Project taskViolet — project work block
Internal meetingBlue
On-callRed — shift cover
Time offGreen — PTO or vacation
ReminderOrange
OtherNeutral

These resolve through the platform’s theme tokens, so a tenant that rebrands gets a calendar that follows rather than a fixed palette.


Limits and known behaviour

  • SMS reminders are not delivered. ReminderMethod.SMS exists in the schema but this platform integrates no SMS provider. The reminder job counts these under smsSkipped and deliberately leaves them unsent rather than marking them delivered.
  • Reminders fire on a five-minute cadence, so a one-minute lead time is approximate. A reminder whose event started more than 20 minutes ago is retired without delivery rather than arriving late.
  • A failed reminder is retried, not dropped. If no recipient could be reached, the row stays unsent and the next run tries again.
  • Account colleagues can edit and delete your non-private events. Visibility and mutation share one boundary. Use Private for anything that should not be.
  • Recurring occurrences are computed on read. Editing a single occurrence of a series is not supported; edits apply to the parent.
  • Business hours are read from one organization per request. For an MSP-portal caller with no organization context, they resolve from the people being scheduled — and only when those people all sit in a single organization. Otherwise the 09:00–17:00 default applies.
  • Utilization on the dispatch board is business-hours-accurate in day view only. Week view estimates against the board’s fixed 07:00–19:00 window, because the availability route answers for a single day.
  • They are supported API surface, not screens.
  • Email reminders use one template, calendar_event_reminder. Invitations, updates and cancellations are in-app only; there is no email invitation and no .ics attachment.
  • Per-event colours cannot be chosen. Colour means event type everywhere, so the stored color is derived from the type on save. Events created before this change keep their stored value in the database but render by type.
  • The month grid shows three events per day, then a “+N more” count. Switch to week view to see them all.
  • Load ribbons are exact in day view only. Week view estimates against the board’s fixed 07:00–19:00 window, because the availability route answers for a single day; those ribbons are labelled “estimated”.

Questions this guide did not answer?

Ask us. You will get a reply from someone who uses the product every day.

Book a demo Contact us

A 30-minute walkthrough against your own workflow. No slides.