Create a cycle
Add a cycle to a project. Only name is required — leave the dates off to create an unscheduled cycle and fill them in later with Update a cycle.
Cycle names must be unique within a project. Reusing one returns 409 conflict.
Path Parameters
slug:requiredstringThe workspace slug. It appears in your Plane URLs — in https://app.plane.so/my-team/projects/, the slug is my-team.
project_id:requiredstring (uuid)The project to add the cycle to.
Body Parameters
name:requiredstringDisplay name for the cycle, unique within the project. Maximum 255 characters.
description:optionalstringFree-form description of what the cycle covers.
start_date:optionalstring (date-time)When the cycle opens, as an ISO 8601 date-time. Nullable — omit it or send null for an unscheduled cycle.
end_date:optionalstring (date-time)When the cycle closes, as an ISO 8601 date-time. Nullable.
timezone:optionalstringThe IANA time zone the cycle's dates are interpreted in, for example America/New_York, Asia/Kolkata, Europe/London, or UTC. Set it to the team's working zone so a cycle boundary lands at local midnight instead of UTC midnight. Any value outside the IANA list is rejected with 400 validation_error.
sort_order:optionalnumberOrdering weight for the cycle within the project. Lower values sort first when you list with ?order_by=sort_order.
logo_props:optionalanyJSON blob holding the cycle's icon configuration, as written by Plane clients. Stored and returned unchanged.
external_id:optionalstringYour system's identifier for this cycle, for sync and import correlation. Maximum 255 characters. You can find the cycle again later with ?external_id= on List cycles.
external_source:optionalstringThe system external_id came from, for example jira or linear. Maximum 255 characters.
Owner is not settable
owned_by_id is returned on the response but is not a body parameter — Plane assigns cycle ownership and the API does not accept an override.
Scopes
projects.cycles:write
Errors
| Status | Code | Cause |
|---|---|---|
400 | validation_error | Missing name, a name over 255 characters, an unparseable date, or a timezone outside the IANA list. |
401 | unauthorized | Missing or invalid credentials. |
403 | forbidden | Your role or token scope can't create cycles in this project. |
404 | resource_not_found | No such workspace or project, or it's outside your tenant. |
409 | conflict | A cycle with this name already exists in the project. |
429 | rate_limited | Throttled. Honor the Retry-After header before retrying. |
curl -X POST \
"https://api.plane.so/api/v2/workspaces/my-team/projects/4af68566-94a4-4eb3-94aa-50dc9427067b/cycles/" \
-H "X-Api-Key: $PLANE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Sprint 24",
"description": "Checkout rewrite and billing cleanup",
"start_date": "2026-01-05T00:00:00Z",
"end_date": "2026-01-19T00:00:00Z",
"timezone": "America/New_York"
}'import requests
response = requests.post(
"https://api.plane.so/api/v2/workspaces/my-team/projects/4af68566-94a4-4eb3-94aa-50dc9427067b/cycles/",
headers={"X-Api-Key": "your-api-key"},
json={
"name": "Sprint 24",
"description": "Checkout rewrite and billing cleanup",
"start_date": "2026-01-05T00:00:00Z",
"end_date": "2026-01-19T00:00:00Z",
"timezone": "America/New_York",
},
)
print(response.json())const response = await fetch(
"https://api.plane.so/api/v2/workspaces/my-team/projects/4af68566-94a4-4eb3-94aa-50dc9427067b/cycles/",
{
method: "POST",
headers: {
"X-Api-Key": "your-api-key",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Sprint 24",
description: "Checkout rewrite and billing cleanup",
start_date: "2026-01-05T00:00:00Z",
end_date: "2026-01-19T00:00:00Z",
timezone: "America/New_York",
}),
}
);
const data = await response.json();{
"id": "7c1f9a4e-3b6d-4a52-8f0c-2d9e6b18c3a7",
"name": "Sprint 24",
"description": "Checkout rewrite and billing cleanup",
"start_date": "2026-01-05T00:00:00Z",
"end_date": "2026-01-19T00:00:00Z",
"timezone": "America/New_York",
"owned_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430",
"sort_order": 65535,
"logo_props": {},
"external_id": null,
"external_source": null,
"created_at": "2026-01-14T09:22:41.478363Z",
"created_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430"
}{
"type": "https://api.plane.so/errors/conflict",
"title": "Conflict",
"status": 409,
"code": "conflict",
"detail": "A cycle with this name already exists in this project."
}
