Skip to content

Get a work item by identifier

GET/api/v2/workspaces/{slug}/work-items/{identifier}/

Retrieve a work item by its human key — PROJ-142 — anywhere in the workspace.

This route exists for callers that don't know the project UUID. A PROJ-142 in a commit message, a chat command, a support ticket, or an LLM prompt carries no project id, and making the caller first list projects, find the one whose identifier is PROJ, and then call the project-scoped route would be three requests to answer one question. Here it is one request against the workspace.

The route is read-only. Creates, updates, deletes, and archiving all go through the project-scoped UUID routes.

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.

identifier:requiredstring

The work item's human key: the project identifier, a hyphen, and the work item's number — PROJ-142.

The project part must start with a letter, and it is upper-cased before lookup, so proj-142 resolves the same work item as PROJ-142. A project identifier is unique within a workspace, which is what makes this key unambiguous.

Query Parameters

expand:optionalstring

Comma-separated relations to embed alongside the ids: state, type, parent, assignees, labels.

Expansion is separate-key — ?expand=state keeps state_id and adds a state object next to it. An unknown value is a 400.

Everything unresolvable is a 404

A malformed key (PROJ_142, 142, -142), a key from a project you can't see, a key in another workspace, and a key that resolves to nothing all return the same 404. That is deliberate: the response never reveals whether a work item exists, only whether you can read it. Archived work items are not served from this route either.

Scopes

projects.work_items:read

Errors

StatusCodeCause
401unauthorizedMissing or invalid credentials.
403forbiddenYour token scope can't read work items.
404resource_not_foundMalformed identifier, no such work item, it's outside your tenant or visibility, or archived.
429rate_limitedThrottled. Honor the Retry-After header before retrying.
Get a work item by identifier
bash
curl -X GET \
  "https://api.plane.so/api/v2/workspaces/my-team/work-items/PROJ-142/" \
  -H "X-Api-Key: $PLANE_API_KEY"
Response200
json
{
  "id": "8f4c2b1e-0d3a-4f7b-9c21-6e5a8b7d4f13",
  "name": "Fix login redirect loop",
  "identifier": "PROJ-142",
  "sequence_id": 142,
  "priority": "high",
  "state_id": "f960d3c2-8524-4a41-b8eb-055ce4be2a7f",
  "type_id": "2d9d1a97-5c6f-4a1e-9d5b-8c2f7e30b6a4",
  "assignee_ids": ["16c61a3a-512a-48ac-b0be-b6b46fe6f430"],
  "label_ids": ["c1b8f3d6-9a44-4e12-8f7a-2b6d5c9e1a03"],
  "parent_id": null,
  "start_date": "2026-01-12",
  "target_date": "2026-01-20",
  "is_draft": false,
  "archived_at": null,
  "created_at": "2026-01-14T09:22:41.478363Z",
  "created_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430",
  "custom_fields": {
    "severity": {
      "id": "b52e7c18-4d3f-4a90-8e61-0f7a3c9d2b45",
      "value": "Sev-1",
      "value_detail": {
        "id": "7c0a5f39-2e84-4b17-9a6c-1d8e4f2b60c9",
        "name": "Sev-1",
        "logo_props": {}
      }
    }
  }
}
Response404
json
{
  "type": "https://api.plane.so/errors/resource_not_found",
  "title": "Not Found",
  "status": 404,
  "code": "resource_not_found",
  "detail": "The requested resource was not found."
}

Getting from the identifier to a write

The response body is the full read shape, so it hands you everything a follow-up write needs — id for the detail route. The project UUID is not in the read shape, so pair the lookup with the project you already know, or resolve it once and cache it:

bash
# 1. resolve the human key
GET /api/v2/workspaces/my-team/work-items/PROJ-142/

# 2. write against the project-scoped UUID route
PATCH /api/v2/workspaces/my-team/projects/{project_id}/work-items/8f4c2b1e-0d3a-4f7b-9c21-6e5a8b7d4f13/

Identifier vs UUID

identifierid
ExamplePROJ-1428f4c2b1e-0d3a-4f7b-9c21-6e5a8b7d4f13
ScopeUnique within a workspaceGlobally unique
RouteThis page — reads onlyGet a work item and every write
Comes fromThe project identifier plus sequence_idAssigned by Plane at creation

Both are stable. Use the identifier where a human is in the loop, and the UUID everywhere else.