Recurring work items overview
A recurring work item is a schedule in a project that creates a new work item on a repeating date. It has two parts, and the API returns both in one flat object:
- The blueprint. The work item to create on every run:
name,description_html,priority,state_id,type_id,assignee_ids,label_ids, andmodule_ids. You write these fields under the same names you read them back with. - The schedule. When to create it:
start_at,end_at,interval_type, andinterval_count, plus the read-onlynext_scheduled_at,last_run_at,enabled, andschedule_description.
Plane stores the blueprint with the schedule. The blueprint has no endpoint of its own, and deleting the schedule deletes the blueprint too. Each run creates an ordinary work item, which you then read and change through work items.
Learn more about recurring work items
Requirements
| Requirement | Failure |
|---|---|
| Recurring work items included in the workspace's plan | 402 payment_required |
| Project admin or contributor role | 403 forbidden |
Project commenters and guests can't read or write recurring work items.
The recurring work item object
Attributes
idstring (uuid)Unique identifier for the schedule.
work_item_blueprint_idstring (uuid)The id of the stored blueprint. Read-only.
namestringThe title each created work item gets. Maximum 255 characters.
description_htmlstringThe description each created work item gets, as HTML.
<p></p>when you don't set one.prioritystringOne of
none,low,medium,high, orurgent.nonewhen you don't set one.state_idstring (uuid) or nullThe work item state each created work item starts in.
type_idstring (uuid) or nullThe work item type each created work item gets.
assignee_idsarray of string (uuid)The users each created work item is assigned to.
label_idsarray of string (uuid)The work item labels each created work item carries.
module_idsarray of string (uuid)The modules each created work item is added to.
start_atstring (date-time)The first date a run can happen, stored as 00:05 on that date in the project's timezone.
end_atstring (date-time) or nullThe last date a run can happen, stored as 23:59:59 on that date in the project's timezone.
nullmeans the schedule has no end.interval_typestringOne of
daily,weekly,monthly, oryearly.interval_countintegerHow many intervals between runs.
2withweeklymeans every two weeks. At least1.next_scheduled_atstring (date-time) or nullWhen the next run is due. Read-only.
last_run_atstring (date-time) or nullWhen the last successful run happened.
nulluntil the first run. Read-only.enabledbooleanWhether the schedule runs. Read-only. See Pausing a schedule.
schedule_descriptionstringA readable summary of the schedule in the project's timezone, for example
Every 2 weeks on Monday at 00:05. Read-only.created_atstring (date-time)When the schedule was created.
updated_atstring (date-time)When the schedule was last updated.
created_by_idstring (uuid) or nullThe user who created the schedule. Plane creates each work item as this user.
updated_by_idstring (uuid) or nullThe user who last updated the schedule.
{
"id": "f3a8c1d6-2e5b-4a79-8c04-1b7e9d6f2a53",
"work_item_blueprint_id": "a9d2e6f1-7c3b-4085-b4e8-2f0c6a1d9e37",
"name": "Weekly status report",
"description_html": "<p>Summarize progress, risks, and next steps.</p>",
"priority": "medium",
"state_id": "2c4d16f8-9b3e-4a52-8d71-1f0e6c9a5b48",
"type_id": null,
"assignee_ids": ["16c61a3a-512a-48ac-b0be-b6b46fe6f430"],
"label_ids": ["c1b8f3d6-9a44-4e12-8f7a-2b6d5c9e1a03"],
"module_ids": [],
"start_at": "2026-08-03T00:05:00Z",
"end_at": "2026-12-31T23:59:59Z",
"interval_type": "weekly",
"interval_count": 1,
"next_scheduled_at": "2026-08-10T00:05:00Z",
"last_run_at": "2026-08-03T00:07:12.418520Z",
"enabled": true,
"schedule_description": "Every week on Monday at 00:05",
"created_at": "2026-07-28T09:22:41.478363Z",
"updated_at": "2026-08-03T00:07:12.418520Z",
"created_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430",
"updated_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430"
}Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/v2/workspaces/{slug}/projects/{project_id}/recurring-work-items/ | List recurring work items |
GET | /api/v2/workspaces/{slug}/projects/{project_id}/recurring-work-items/{pk}/ | Get a recurring work item |
POST | /api/v2/workspaces/{slug}/projects/{project_id}/recurring-work-items/ | Create a recurring work item |
PATCH | /api/v2/workspaces/{slug}/projects/{project_id}/recurring-work-items/{pk}/ | Update a recurring work item |
DELETE | /api/v2/workspaces/{slug}/projects/{project_id}/recurring-work-items/{pk}/ | Delete a recurring work item |
How runs are scheduled
- Only the date part of
start_atandend_atcounts. Plane pinsstart_atto 00:05 andend_atto 23:59:59 on those dates in the project's timezone, then stores both in UTC. - Each run is due at 00:05 in the project's timezone, on the dates the interval gives. A
weeklyschedule runs on the weekday ofstart_at, and amonthlyschedule runs on the day of the month ofstart_at. - If
start_atis today, Plane creates the first work item right away. Ifstart_atis in the past, the first run is the next scheduled date after now. - Changing
start_at,interval_type, orinterval_countrecalculatesnext_scheduled_at. The new value isstart_atif that date is still ahead, and otherwise the next scheduled date after now. Changingend_ator any blueprint field leavesnext_scheduled_atalone. - No run happens after
end_at. - Blueprint changes apply only to future runs. Work items already created don't change.
- If a workflow rule stops the schedule's creator from creating work items in the blueprint's state, Plane skips that run, emails the creator, and moves the schedule to the next date.
Pausing a schedule
There is no pause or resume operation, and enabled is read-only. A PATCH that sends enabled succeeds without changing it. Plane sets enabled to false itself when a run finds that the workspace's plan no longer includes recurring work items.
To stop a schedule through the API, set end_at to the last date you want a run on, or delete the schedule.
Recurring work items and workspace governance
These routes have no governance check. Reads and writes also work in a workspace with governance turned on, with two differences:
- A governed workspace can keep workspace-level recurring blueprints that it imports into projects. Those never appear on these project routes. Only schedules that belong to the path project do.
- The blueprint's
state_idandlabel_idsaccept only states and labels that belong to the path project. In a governed workspace, work item states and labels live in the workspace catalog, so their ids return400 invalid_request. Leave both fields out in a governed workspace.
Response shaping
Every recurring work item read accepts ?fields= for sparse responses. See Sparse fields. Errors follow the shared problem+json contract.
Changed from v1
- v1 nests the blueprint under
workitem_blueprint. v2 returns it flat, under the same names you write:name,state_id,assignee_ids, and so on. The blueprint's id iswork_item_blueprint_id. - Reads no longer return
projectorworkspace, and returncreated_by_idandupdated_by_idinstead ofcreated_byandupdated_by. - When the plan doesn't include recurring work items, every operation returns a standard
application/problem+jsonbody withcodeset topayment_required. The status is still402. enabledstays read-only, as in v1. Neither version can pause or resume a schedule.
See Migrating from v1 for the full list.

