> ## Documentation Index
> Fetch the complete documentation index at: https://api-docs.useopenwrench.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Planned maintenance schedules in the Buyer API

> Read planned maintenance schedules, skip upcoming runs, and integrate an external scheduler by recording run logs with the OpenWrench Buyer API.

Planned maintenance (PM) schedules generate recurring work orders on assets at a defined cadence. The Buyer API lets you read schedules, skip a run, and record run logs when an external system drives the scheduling.

All examples assume:

```bash theme={null}
export BASE="https://api.useopenwrench.com/api/external"
export KEY="<your-api-key>"
export SECRET="<shared-secret>"
```

## Reading schedules

```bash theme={null}
# All schedules, and a filtered count
curl -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  "$BASE/v1/buyer/pm/planned_maintenance_schedules?limit=25"
curl -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  "$BASE/v1/buyer/pm/planned_maintenance_schedules/count_by?locationId=1204"

# One schedule
curl -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  "$BASE/v1/buyer/pm/planned_maintenance_schedules/512"
```

Standard pagination and field filtering apply. Work orders generated by a schedule carry `isPM: true` and `plannedMaintenanceScheduleId`, so you can list a schedule's history from the work order side:

```bash theme={null}
curl -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  "$BASE/v1/buyer/work_order/work_orders?plannedMaintenanceScheduleId=512&sort_by=createdAt&order=desc"
```

## Skipping a run

`PATCH /v1/buyer/pm/planned_maintenance_schedules/skip_schedule` advances a schedule past its next scheduled run (for example, when a site is closed for renovation). The schedule `id` is the required field:

```bash theme={null}
curl -X PATCH "$BASE/v1/buyer/pm/planned_maintenance_schedules/skip_schedule" \
  -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "id": 512 }'
```

The updated schedule is returned. This endpoint is not rate limited.

## Driving PM from an external scheduler

If your own system decides when PM work orders get cut, close the loop by recording each run with `POST /v1/buyer/pm/scheduler_run_logs`:

```bash theme={null}
curl -X POST "$BASE/v1/buyer/pm/scheduler_run_logs" \
  -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "scheduleId": 512,
    "status": "success",
    "lastRunAt": "2026-08-21T06:00:05.000-07:00",
    "lastRunDueAt": "2026-08-21T06:00:00.000-07:00",
    "woId": 9105,
    "log": "Created WO 9105 for August PM."
  }'
```

`scheduleId`, `status`, `lastRunAt`, and `lastRunDueAt` are required; `woId` links the work order the run created (create it first via the [work orders](/buyer-api/work-orders#create-a-work-order) endpoint, with `isPM: true` and `plannedMaintenanceScheduleId` set), and `log` holds free-form diagnostics.

The full external-scheduler loop:

1. Read schedules and their cadence from the API.
2. When a run comes due, create the PM work order.
3. Record the run with `scheduler_run_logs`, linking the `woId`.
4. If a run must be skipped instead, call `skip_schedule` so the next due date advances.
