# Employee shift scheduling via API

Source: https://developer.nylas.com/docs/cookbook/scheduler/shift-scheduling-api/

A retail manager builds next week's roster in a spreadsheet, then copies each shift into a group chat and hopes everyone reads it. Half the no-shows trace back to a worker who never saw the message or forgot the start time. If your app already manages staff, you can skip the chat and write each shift straight to the worker's own calendar, with a reminder that fires before they're due in. That's the gap this recipe fills.

This guide shows how to build staff shift scheduling on the Nylas Calendar API: read availability across a team, create each shift as a calendar event on the worker's calendar, and notify workers by reminder or email. It's also honest about where a dedicated workforce management (WFM) tool is the better buy.

## How do I automate employee scheduling using an API integration?

Automate employee scheduling by treating each shift as a calendar event. You check who's free with `POST /v3/calendars/availability`, then write the shift to a worker's calendar with `POST /v3/grants/{grant_id}/events`. One grant connects to Google, Microsoft, iCloud, and EWS calendars, so the same two calls cover every worker on a supported calendar provider.

The flow has three moving parts, and the API handles each one. First, availability: the endpoint accepts every team member as a `participant` and returns open `time_slots` in a single response, so an 8-person team is one request, not 8. Second, assignment: your code picks who works each slot using whatever rule fits, seniority, cost, or a fair rotation. Third, the write: each confirmed shift becomes an event with a `title`, a `when` block, and the worker as a `participant`. Because every provider returns the same JSON shape, you write one parser and one event builder for the whole staff, instead of separate Google and Microsoft code paths.

## How do I push a shift to a worker's calendar?

Create the shift with `POST /v3/grants/{grant_id}/events`, where the `grant_id` is the worker's connected account. Pass a `title`, a `when` block with `start_time` and `end_time` as Unix timestamps, and the `calendar_id` as a query parameter. Set `notify_participants=true` so the worker gets the standard provider invite email the moment the shift lands.

The request below writes a single shift to one worker's primary calendar. The `when` object uses Unix seconds, and the `reminders.overrides` array schedules an alert 60 minutes before the shift starts. The `reminder_method` field (here `popup`) is Google and iCloud only, and the values differ: Google takes `popup` or `email`, iCloud takes `display` or `sound`. Microsoft and EWS ignore it, so rely on `reminder_minutes` alone for those accounts. Note one more quirk: for Microsoft Graph, EWS, and iCloud you can set only one reminder per event, so don't stack overrides if you support those accounts.

```bash
curl --request POST \
  --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/events?calendar_id=primary&notify_participants=true' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "title": "Front desk shift",
    "when": {
      "start_time": 1700038800,
      "end_time": 1700067600,
      "start_timezone": "America/New_York",
      "end_timezone": "America/New_York"
    },
    "participants": [
      { "email": "casey@example.com", "name": "Casey Lin" }
    ],
    "reminders": {
      "use_default": false,
      "overrides": [
        { "reminder_minutes": 60, "reminder_method": "popup" }
      ]
    },
    "metadata": {
      "shift_role": "front_desk",
      "roster_week": "2026-W25"
    }
  }'
```

```python [createShift-Python SDK]
from nylas import Client

nylas = Client(api_key="<NYLAS_API_KEY>")

event = nylas.events.create(
    "<NYLAS_GRANT_ID>",
    query_params={"calendar_id": "primary", "notify_participants": True},
    request_body={
        "title": "Front desk shift",
        "when": {
            "start_time": 1700038800,
            "end_time": 1700067600,
            "start_timezone": "America/New_York",
            "end_timezone": "America/New_York",
        },
        "participants": [{"email": "casey@example.com", "name": "Casey Lin"}],
        "reminders": {
            "use_default": False,
            "overrides": [{"reminder_minutes": 60, "reminder_method": "popup"}],
        },
        "metadata": {"shift_role": "front_desk", "roster_week": "2026-W25"},
    },
)

print(event.data.id)
```

The `metadata` object is worth using from day one. It accepts up to 50 key-value pairs per event, and you can later filter shifts with the `metadata_pair` query parameter, which makes it easy to pull "every front desk shift this week" without scanning every event.


> **Info:** 
> **New to Nylas?** Start with the [quickstart guide](/docs/v3/getting-started/) to set up your app and connect a test account before continuing here.


## How do I check team availability before assigning a shift?

Send `POST /v3/calendars/availability` with every worker as a `participant` and the API returns the windows where staff are free. Each open `time_slot` carries an `emails` array naming exactly who's available, so you can assign a shift only to someone who isn't already booked. One request covers the whole team instead of one lookup per person.

This call is the same primitive that powers meeting booking, repurposed for rosters. You set `duration_minutes` to the shift length, `interval_minutes` to how the day is sliced, and the API generates candidate slots across the date range. For a standard 8-hour shift, set `duration_minutes` to 480. The response tells you who's open in each window; your code applies the assignment rule. Reading raw busy blocks instead? The [check availability](/docs/cookbook/calendar/check-availability/) recipe covers the `POST /v3/grants/{grant_id}/calendars/free-busy` companion, which hands back each worker's busy intervals directly so you can build a custom coverage score.

```bash
curl --request POST \
  --url 'https://api.us.nylas.com/v3/calendars/availability' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "start_time": 1700038800,
    "end_time": 1700125200,
    "duration_minutes": 480,
    "interval_minutes": 60,
    "participants": [
      { "email": "casey@example.com", "calendar_ids": ["primary"] },
      { "email": "jordan@example.com", "calendar_ids": ["primary"] },
      { "email": "sam@example.com", "calendar_ids": ["primary"] }
    ]
  }'
```

For fair distribution across the team, set `availability_method` to `max-fairness` in an `availability_rules` block, and tag each host's events with the reserved metadata `key5` so the ranking can compute participant order. That ranks the least-booked worker first, which is the same logic behind [round-robin scheduling](/docs/cookbook/scheduler/round-robin-scheduling/). Applied to rosters, it spreads shifts so no one person absorbs every opening.

## How can I automate employee scheduling notifications through email?

Send a custom email with `POST /v3/grants/{grant_id}/messages/send` from the manager's connected account. The calendar invite from `notify_participants=true` confirms the shift in the worker's calendar app, but a separate message lets you include the roster link, swap instructions, or pay details that an invite can't carry. Both can fire from the same shift-creation step.

Two notification layers cover different needs. The event reminder (the `reminders.overrides` you set on the event) is a calendar alert that pops on the worker's phone, with a typical lead of 60 minutes before a shift. The email is your own message, sent from a real mailbox, so replies land in the manager's inbox. The send endpoint accepts a `subject`, an HTML `body`, and a `to` array, and it works across Google and Microsoft Graph alike. Keep the volume reasonable: confirm the current per-mailbox sending limit on your provider's pricing page before blasting an entire roster at once.

```bash
curl --request POST \
  --url 'https://api.us.nylas.com/v3/grants/<NYLAS_GRANT_ID>/messages/send' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "subject": "Your shift Mon Jun 15, 9:00 AM",
    "body": "<p>Hi Casey, you are scheduled for the front desk shift on Monday from 9:00 AM to 5:00 PM. Need to swap? Reply to this email.</p>",
    "to": [{ "name": "Casey Lin", "email": "casey@example.com" }]
  }'
```

To send shift reminders on a schedule rather than at creation time, the [schedule event reminders](/docs/cookbook/use-cases/act/schedule-event-reminders/) recipe shows how to drive sends off upcoming events with a cron job, so a "you're on in an hour" message goes out automatically the morning of each shift.

## What is API-based staffing and scheduling, and which platforms offer it?

API-based staffing and scheduling means building rosters, assignments, and notifications programmatically instead of clicking through a UI. Two platform types exist. Dedicated WFM tools like Deputy, When I Work, and Homebase ship labor forecasting and time clocks out of the box. Calendar and email APIs like Nylas give you the availability, event, and messaging primitives to build a custom flow.

The table below maps the two against the work a shift integration actually needs. The unified API column is the right pick when you want shifts living on each worker's real calendar and your scheduling logic is custom enough that an off-the-shelf product would fight you.

| Capability | Dedicated WFM tool | **Calendar + email API (Nylas)** |
| --- | --- | --- |
| Roster builder UI | Built in | You build it |
| Labor forecasting, time clocks | Built in | Not included |
| Shift on worker's own calendar | Often a one-way export | Native, two-way, any provider |
| Provider coverage | Varies | Google, Microsoft, iCloud, EWS |
| Custom assignment logic | Limited to vendor rules | Fully yours |
| Reminders and email | Vendor templates | `reminders` overrides plus `/messages/send` |

Here's the honest tradeoff. If you need predictive labor costing, break-compliance enforcement, or punch-clock payroll exports, a WFM tool earns its subscription, and rebuilding that on raw APIs would take months. Reach for the Calendar API when the value is putting shifts on real calendars across mixed providers and wiring assignment logic that's specific to your business, like routing by certification, language, or store. The two also compose: many teams run a WFM tool for forecasting and use the API to mirror finalized shifts onto each worker's personal calendar.

## What's next

- [Check availability](/docs/cookbook/calendar/check-availability/) for the availability and Free/Busy request and response fields
- [Round-robin scheduling](/docs/cookbook/scheduler/round-robin-scheduling/) to distribute shifts fairly with `max-fairness`
- [Schedule event reminders](/docs/cookbook/use-cases/act/schedule-event-reminders/) to send shift reminders automatically off upcoming events
- [Getting started with Nylas](/docs/v3/getting-started/) to create a project, connector, and your first grant