Skip to content

Create workflow pins ​

POST/api/v2/workspaces/{slug}/work-item-types/{type_id}/governance/pins/

Pin one catalog workflow to a work item type in one or more projects. For each project, Plane creates the pin or moves the project's existing pin for the type to this workflow. It also writes the project's pick to the same workflow. See Pins.

A pinned project can't change its own pick for the type. Update a work item type workflow returns 403 workflow_assigned_by_workspace until you delete the pin.

Pinning moves work items without a mapping

Pins take no state_mapping. Work items of this type whose state the pinned workflow doesn't contain move to the workflow's default state. Plane records each move on the work item. To check the count first, pass the type and the workflow to Preview a workflow fallback.

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.

type_id:requiredstring (uuid)

The work item type to pin. It can be any type in the workspace.

Body Parameters ​

workflow_id:requiredstring (uuid)

The catalog workflow to pin. It must be active. Under constrained mode, it must also be in the type's allowlist, or the request returns 400 workflow_outside_allowlist.

project_ids:requiredarray of string (uuid)

The projects to pin, at least one. Every id must be a project in this workspace. If any isn't, the request returns 400 invalid_request with the offending ids in unknown_project_ids, and Plane pins nothing.

Response shaping ​

fields:optionalstring

Comma-separated list of fields to return on each pin. Unrequested keys are omitted from the response, not returned as null, so absent means "not requested" and null means "actually null". id always comes back whether or not you name it.

Pass all for every requestable field. An unknown name is a 400 that lists the valid set and suggests the closest match, so a typo can't silently cost you the saving.

Requestable here: created_at, id, project_id, updated_at, work_item_type_id, workflow_id.

See Sparse fields.

Scopes ​

workspaces.workflows:write

Errors ​

StatusCodeCause
400invalid_requestworkflow_id or project_ids missing, an empty project_ids, a project outside this workspace (see unknown_project_ids), or an unknown or inactive workflow.
400workflow_outside_allowlistThe type is in constrained mode and the workflow isn't on its allowlist.
401unauthorizedMissing or invalid credentials.
402payment_requiredWorkspace governance isn't on your plan.
403forbiddenYour role or token scope can't edit workspace workflows.
404not_foundNo such work item type in this workspace.
406not_acceptableThe Accept header asks for a representation the API can't produce.
409states_managed_at_projectThe workspace doesn't have governance turned on.
409workflow_pins_unavailableThe type is in required mode. The mandate already fixes the workflow for every project.
413payload_too_largeThe request body is over the size limit.
415unsupported_media_typeThe Content-Type isn't one this endpoint accepts.
429rate_limitedThrottled. Honor the Retry-After header before retrying.
Create workflow pins
bash
curl -X POST \
  "https://api.plane.so/api/v2/workspaces/my-team/work-item-types/d1e7a4c9-2b58-4f36-9a0e-7c3b5d81f240/governance/pins/" \
  -H "X-Api-Key: $PLANE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "workflow_id": "e6b2d9f1-48a7-4c3e-9f50-1d7a8c2b6e93",
  "project_ids": [
    "4af68566-94a4-4eb3-94aa-50dc9427067b",
    "7c19e5b3-2d84-4f6a-b0e7-93a1c5d8f246"
  ]
}'
Response201
json
[
  {
    "id": "6f2a8c41-9d37-4b05-a1e8-3c7b2d9f5e16",
    "project_id": "7c19e5b3-2d84-4f6a-b0e7-93a1c5d8f246",
    "workflow_id": "e6b2d9f1-48a7-4c3e-9f50-1d7a8c2b6e93",
    "work_item_type_id": "d1e7a4c9-2b58-4f36-9a0e-7c3b5d81f240",
    "created_at": "2026-01-14T09:22:41.512907Z",
    "updated_at": "2026-01-14T09:22:41.512907Z"
  },
  {
    "id": "0b6d3f92-7e15-4a48-9c27-5f8e1a4d6b30",
    "project_id": "4af68566-94a4-4eb3-94aa-50dc9427067b",
    "workflow_id": "e6b2d9f1-48a7-4c3e-9f50-1d7a8c2b6e93",
    "work_item_type_id": "d1e7a4c9-2b58-4f36-9a0e-7c3b5d81f240",
    "created_at": "2026-01-14T09:22:41.478363Z",
    "updated_at": "2026-01-14T09:22:41.478363Z"
  }
]
Response409
json
{
  "type": "conflict",
  "code": "workflow_pins_unavailable",
  "detail": "Pinning is unavailable while the type is in required mode — the mandate already fixes the workflow."
}
Response400
json
{
  "type": "invalid_request",
  "code": "workflow_outside_allowlist",
  "detail": "That workflow is not in this type's allowlist."
}
Response400
json
{
  "type": "invalid_request",
  "code": "invalid_request",
  "detail": "Every project_id must belong to this workspace.",
  "unknown_project_ids": ["2e8b4d17-5c93-4a60-8f1d-b7a3e6c09d52"]
}

The response is a plain array

A successful call returns 201 with a JSON array of the pins for the projects you sent, newest first. The array isn't wrapped in the data envelope that List workflow pins uses.