> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.slotflow.dev/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.slotflow.dev/_mcp/server.

# Schedule Management

> Master availability rules and schedule overrides for complex scheduling scenarios.

This guide is a deep dive into Slotflow's scheduling system — availability rules, schedule overrides (blocks and opens), and recurrence patterns. By the end, you'll know how to model any real-world scheduling scenario.

## The two layers

Slotflow uses a two-layer scheduling model:

1. **Availability rules** — the base weekly schedule (e.g., "Monday-Friday, 9am-5pm")
2. **Schedule overrides** — exceptions to the base schedule (vacations, overtime, recurring meetings)

The slot engine combines both layers to compute what's actually available on any given day.

## Setting availability rules

Availability rules define the human's repeating weekly schedule:

```javascript
await fetch(`https://api.slotflow.dev/v1/humans/${humanId}/availability`, {
  method: "PUT",
  headers: {
    "Authorization": `Bearer ${process.env.SLOTFLOW_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    working_days: [1, 2, 3, 4, 5],  // 1=Monday through 7=Sunday
    work_start: "09:00",             // In the human's timezone
    work_end: "17:00",
    meeting_durations: [30, 60],     // Allowed booking lengths in minutes
  }),
});
```

**Important details:**

* Times are in the human's timezone (set when creating the human). Slotflow handles UTC conversion and DST automatically.
* `meeting_durations` controls what durations agents can book. If a human only takes 30-minute meetings, set `[30]`.
* This is a full replace — send all fields every time. There's no partial update.

### Common availability patterns

**Standard 9-5 weekdays:**

```json
{
  "working_days": [1, 2, 3, 4, 5],
  "work_start": "09:00",
  "work_end": "17:00",
  "meeting_durations": [30, 60]
}
```

**Part-time (Mon/Wed/Fri mornings):**

```json
{
  "working_days": [1, 3, 5],
  "work_start": "08:00",
  "work_end": "12:00",
  "meeting_durations": [30]
}
```

**Full week including weekends:**

```json
{
  "working_days": [1, 2, 3, 4, 5, 6, 7],
  "work_start": "10:00",
  "work_end": "18:00",
  "meeting_durations": [15, 30, 60]
}
```

## Schedule overrides

Overrides handle everything the base schedule can't — vacations, holidays, recurring internal meetings, overtime, special events.

### Block overrides (remove availability)

#### All-day vacation

```javascript
await fetch(`https://api.slotflow.dev/v1/humans/${humanId}/overrides`, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SLOTFLOW_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    type: "block",
    title: "Summer vacation",
    all_day: true,
    start_date: "2026-07-14",
    end_date: "2026-07-25",    // Date range — one row, not 12
  }),
});
```

Date ranges are stored as a single override, not one per day.

#### Time-specific block

Block a 2-hour window on a specific date:

```json
{
  "type": "block",
  "title": "Dentist appointment",
  "all_day": false,
  "start_date": "2026-04-15",
  "start_time": "14:00",
  "end_time": "16:00"
}
```

The human is still available the rest of the day — only the 2-4pm window is blocked.

#### Recurring weekly block

Block every Tuesday 2-3pm for a team standup:

```json
{
  "type": "block",
  "title": "Team standup",
  "all_day": false,
  "start_date": "2026-03-01",
  "start_time": "14:00",
  "end_time": "15:00",
  "recurrence": {
    "freq": "weekly",
    "days": [2]
  }
}
```

The `start_date` is when the recurrence begins. The override applies every Tuesday from that date onward.

#### Bi-weekly block

Block every other Monday morning for sprint planning:

```json
{
  "type": "block",
  "title": "Sprint planning",
  "all_day": false,
  "start_date": "2026-03-02",
  "start_time": "09:00",
  "end_time": "10:30",
  "recurrence": {
    "freq": "weekly",
    "interval": 2,
    "days": [1]
  }
}
```

#### Monthly block

Block the first Friday of every month for an all-hands:

```json
{
  "type": "block",
  "title": "Company all-hands",
  "all_day": false,
  "start_date": "2026-03-01",
  "start_time": "11:00",
  "end_time": "12:00",
  "recurrence": {
    "freq": "monthly",
    "week": 1,
    "day": 5
  }
}
```

### Open overrides (add availability)

Open overrides let you add availability **outside** the base schedule — weekends, evenings, or any time that isn't covered by the weekly rules.

#### Saturday overtime

```json
{
  "type": "open",
  "title": "Saturday overtime",
  "all_day": false,
  "start_date": "2026-03-01",
  "start_time": "10:00",
  "end_time": "14:00",
  "recurrence": {
    "freq": "weekly",
    "days": [6]
  }
}
```

If the human's base schedule is Monday-Friday, this adds Saturday 10am-2pm every week.

#### One-time evening event

```json
{
  "type": "open",
  "title": "Evening office hours",
  "all_day": false,
  "start_date": "2026-04-10",
  "start_time": "18:00",
  "end_time": "20:00"
}
```

One-time availability on April 10th from 6-8pm, outside normal working hours.

## How overrides interact with base schedule

The slot engine evaluates overrides in this order for each day:

1. **All-day blocks** — if matched, the entire day is skipped (no slots generated)
2. **Base schedule** — generate candidate slots from working days/hours
3. **Time-specific blocks** — remove slots that overlap with block windows
4. **Open overrides** — add extra slots from open windows (even on non-working days)
5. **Deduplication** — remove duplicate slots if open windows overlap base schedule
6. **Booking conflicts** — filter out slots occupied by confirmed bookings

Block overrides always take precedence over the base schedule. Open overrides add availability regardless of the base schedule.

## Managing overrides

### List all overrides for a human

```javascript
const res = await fetch(
  `https://api.slotflow.dev/v1/humans/${humanId}/overrides`,
  { headers: { "Authorization": `Bearer ${process.env.SLOTFLOW_API_KEY}` } }
);
const { overrides, total } = await res.json();
```

### Delete an override

```javascript
await fetch(
  `https://api.slotflow.dev/v1/humans/${humanId}/overrides/${overrideId}`,
  {
    method: "DELETE",
    headers: { "Authorization": `Bearer ${process.env.SLOTFLOW_API_KEY}` },
  }
);
```

Deleting an override immediately changes slot availability. If you delete a block, those time slots become bookable again.

## Real-world example

Here's a complete setup for a sales rep named Sarah:

```javascript
const API_KEY = process.env.SLOTFLOW_API_KEY;
const headers = {
  "Authorization": `Bearer ${API_KEY}`,
  "Content-Type": "application/json",
};

// Base schedule: Mon-Fri, 9am-5pm, 30-min and 60-min meetings
await fetch(`https://api.slotflow.dev/v1/humans/${sarahId}/availability`, {
  method: "PUT", headers,
  body: JSON.stringify({
    working_days: [1, 2, 3, 4, 5],
    work_start: "09:00",
    work_end: "17:00",
    meeting_durations: [30, 60],
  }),
});

// Block: Summer vacation (Jul 14-25)
await createOverride(sarahId, {
  type: "block", title: "Summer vacation",
  all_day: true, start_date: "2026-07-14", end_date: "2026-07-25",
});

// Block: Weekly team standup (Tuesdays 2-3pm)
await createOverride(sarahId, {
  type: "block", title: "Team standup",
  all_day: false, start_date: "2026-03-01",
  start_time: "14:00", end_time: "15:00",
  recurrence: { freq: "weekly", days: [2] },
});

// Block: Bi-weekly pipeline review (Mondays 9-10am)
await createOverride(sarahId, {
  type: "block", title: "Pipeline review",
  all_day: false, start_date: "2026-03-02",
  start_time: "09:00", end_time: "10:00",
  recurrence: { freq: "weekly", interval: 2, days: [1] },
});

// Open: Saturday morning overtime (10am-1pm)
await createOverride(sarahId, {
  type: "open", title: "Saturday overtime",
  all_day: false, start_date: "2026-03-01",
  start_time: "10:00", end_time: "13:00",
  recurrence: { freq: "weekly", days: [6] },
});

async function createOverride(humanId, data) {
  return fetch(`https://api.slotflow.dev/v1/humans/${humanId}/overrides`, {
    method: "POST", headers, body: JSON.stringify(data),
  });
}
```

With this setup, Sarah's availability for a typical week looks like:

* **Monday**: 9-5pm (minus 9-10am on bi-weekly Mondays for pipeline review)
* **Tuesday**: 9-2pm + 3-5pm (team standup blocks 2-3pm every week)
* **Wednesday-Friday**: 9-5pm (full base schedule)
* **Saturday**: 10am-1pm (overtime window)
* **Sunday**: No availability

## Key takeaways

* **Availability rules** are your base weekly schedule — set them once, they repeat forever
* **Block overrides** remove time — use for vacations, holidays, internal meetings
* **Open overrides** add time — use for overtime, special events, weekend hours
* **Date ranges** are single rows — a 2-week vacation is one override, not 14
* **Recurrence** handles repeating patterns — weekly standups, bi-weekly sprints, monthly all-hands
* **Blocks win over base schedule** — an all-day block cancels everything, including open overrides for that day