Skip to content

Cycles overview ​

A cycle is a time-boxed iteration inside a project — a sprint, a release window, or any fixed period a team commits work to. A cycle belongs to exactly one project and is never shared across projects.

Cycles are defined by a start_date and an end_date, interpreted in the cycle's own timezone. Both dates are optional, so a cycle can exist as an unscheduled container and be given dates later.

Learn more about cycles

The cycle object ​

Attributes ​

  • id string (uuid)

    Unique identifier for the cycle.

  • name string

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

  • description string

    Free-form description of what the cycle covers.

  • start_date string (date-time)

    When the cycle opens. null if the cycle has not been scheduled.

  • end_date string (date-time)

    When the cycle closes. null if the cycle has not been scheduled.

  • timezone string

    The IANA time zone the cycle's dates are interpreted in, for example America/New_York or UTC. This is what makes a cycle boundary land at local midnight rather than UTC midnight for a distributed team.

  • owned_by_id string (uuid)

    The user who owns the cycle. Read-only — assigned by Plane and not settable through the API. Use it to filter cycles on list.

  • sort_order number

    Ordering weight for the cycle within the project. Lower values sort first when you order by sort_order.

  • logo_props any

    JSON blob holding the cycle's icon configuration, as written by Plane clients. Passed through unchanged.

  • external_id , external_source string

    Correlation fields for sync and import. Together they let you map a cycle to a record in another system and find it again later — both are exposed as list filters.

  • created_at string (date-time)

    When the cycle was created.

  • created_by_id string (uuid)

    The user who created the cycle.

Dates are timestamps, not calendar days

start_date and end_date are full date-times. Send them as ISO 8601 timestamps and read timezone to interpret where the boundary falls.

Response200
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"
}

Endpoints ​

MethodPathDescription
GET/api/v2/workspaces/{slug}/projects/{project_id}/cycles/List cycles
GET/api/v2/workspaces/{slug}/projects/{project_id}/cycles/{pk}/Get a cycle
POST/api/v2/workspaces/{slug}/projects/{project_id}/cycles/Create a cycle
PATCH/api/v2/workspaces/{slug}/projects/{project_id}/cycles/{pk}/Update a cycle
DELETE/api/v2/workspaces/{slug}/projects/{project_id}/cycles/{pk}/Delete a cycle
POST/api/v2/workspaces/{slug}/projects/{project_id}/cycles/upsert/Upsert a cycle
POST/api/v2/workspaces/{slug}/projects/{project_id}/cycles/bulk-create/Bulk create cycles
POST/api/v2/workspaces/{slug}/projects/{project_id}/cycles/bulk-update/Bulk update cycles
POST/api/v2/workspaces/{slug}/projects/{project_id}/cycles/bulk-delete/Bulk delete cycles
POST/api/v2/workspaces/{slug}/projects/{project_id}/cycles/{pk}/work-items/Add or remove cycle work items
POST/api/v2/workspaces/{slug}/projects/{project_id}/cycles/{pk}/transfer/Transfer work items between cycles

Names are unique per project ​

Cycle names must be unique within a project. Creating a second cycle with a name already in use, or renaming a cycle onto an existing name, returns 409 conflict. Uniqueness is scoped to the project, so two different projects can both have a Sprint 24.

Ownership is read-only ​

owned_by_id is returned on every read but is not part of the write body — you cannot assign a cycle owner through the v2 API. You can still filter by owner on list with ?owned_by_id=, which is the common case for building "my cycles" views.

No ?expand= on cycles ​

Cycles do not support ?expand=. Related records are referenced by id only — resolve owned_by_id and created_by_id against the members endpoints when you need names.

Cycle work items ​

Add work items to a cycle or remove them with Add or remove cycle work items, and move them to another cycle with Transfer work items between cycles. To list a cycle's work items, filter List work items by cycle_id.

Archiving is not part of the v2 cycles surface. Archive and unarchive cycles through the v1 cycle reference.

Changed from v1 ​

  • owned_by is now owned_by_id, and created_by is now created_by_id.
  • start_date and end_date are date-times, not plain calendar dates.
  • Reads no longer return updated_at, updated_by, project, workspace, or view_props.
  • The list endpoint drops cycle_view, expand, and fields, and adds search, owned_by_id, external_id, and external_source filters.
  • Updates are PATCH only — v2 has no PUT.

See Migrating from v1 for the full list.