Skip to content

Create a cycle

POST/api/v2/workspaces/{slug}/projects/{project_id}/cycles/

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:requiredstring

The 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:requiredstring

Display name for the cycle, unique within the project. Maximum 255 characters.

description:optionalstring

Free-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:optionalstring

The 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:optionalnumber

Ordering weight for the cycle within the project. Lower values sort first when you list with ?order_by=sort_order.

logo_props:optionalany

JSON blob holding the cycle's icon configuration, as written by Plane clients. Stored and returned unchanged.

external_id:optionalstring

Your 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:optionalstring

The 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

StatusCodeCause
400validation_errorMissing name, a name over 255 characters, an unparseable date, or a timezone outside the IANA list.
401unauthorizedMissing or invalid credentials.
403forbiddenYour role or token scope can't create cycles in this project.
404resource_not_foundNo such workspace or project, or it's outside your tenant.
409conflictA cycle with this name already exists in the project.
429rate_limitedThrottled. Honor the Retry-After header before retrying.
Create a cycle
bash
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"
}'
Response201
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"
}
Response409
json
{
  "type": "https://api.plane.so/errors/conflict",
  "title": "Conflict",
  "status": 409,
  "code": "conflict",
  "detail": "A cycle with this name already exists in this project."
}