---
title: "List recent project work"
method: GET
path: "/experimental/projects/{projectId}/work"
tags: ["Projects"]
---

# List recent project work

`GET /experimental/projects/{projectId}/work`

## Request

- Base URL: `https://api.tessl.io`
- URL: `https://api.tessl.io/experimental/projects/{projectId}/work`
- Auth: none declared

Lists tickets and PRs linked to runs in this project, ordered by when their latest run started, not counting runs that finished and changed nothing. Work with only such runs is left out. Each item carries its stage and its latest run, read from all of its runs, as the detail read gives them. PR state comes from the PR record of GitHub webhooks when it has the PR; nothing is read from GitHub or Linear.

## Path parameters

- `projectId` string, uuid, required

## Query parameters

- `limit` integer

## Headers

- `Authorization` string

## Response `200`

Default Response

- object
  - `links` object, required
    - `self` string, uri, required
  - `data` object, required
    - `id` string, uuid, required
    - `type` 'project-work', required
    - `attributes` object, required
      - `items` object[], required
        - `key` string, required
        - `resource` object, required
          - `type` union, required
            - 'github_issue'
            - 'linear_issue'
            - 'github_pr'
          - `url` string, required
          - `label` string, required
          - `title` string, nullable, required
        - `resources` object[], required
          - `type` union, required
            - 'github_issue'
            - 'linear_issue'
            - 'github_pr'
          - `url` string, required
          - `label` string, required
          - `title` string, nullable, required
        - `lastActivity` string, required: When the latest run in this work last changed.
        - `lastStartedAt` string, required: When the latest run in this work started, not counting runs that finished and changed nothing. The project list orders work by it.
        - `stage` union, required: Where the work is, from all of its runs: every PR merged, every PR closed, a loop waiting for an answer, a loop whose latest run failed, a PR still open, a run in progress with no PR, or none of these. Work whose PRs are all merged or closed is done, whatever its loops did.
          - 'needs_you'
          - 'problem'
          - 'pr_merged'
          - 'pr_closed'
          - 'pr_open'
          - 'writing_code'
          - 'no_pr'
        - `runCount` integer, required
        - `runningLoops` string[], required: The loops with a run in progress, by name: its Loop, or its skill when no Loop started it. A run still pending after the longest a run can take is left out.
        - `runs` object[], required: Runs for this work, latest change first. The project list returns only the latest run.
          - `id` string, required
          - `status` union, required
            - 'pending'
            - 'completed'
            - 'failed'
            - 'cancelled'
          - `outcome` union, required
            - 'succeeded'
            - 'no_action'
            - 'needs_input'
            - 'failed'
          - `skill` string, required
          - `message` string, nullable, required
          - `createdAt` string, required
          - `updatedAt` string, required
          - `loops` object[], required
            - `id` string, required
            - `name` string, required
          - `cause` string, nullable, required
        - `gaps` string[], required
      - `hasMore` boolean, required
      - `scope` object, required
        - `truncated` boolean, required: True when a read stopped at `runLimit` runs, so work, counts or history can be missing.
        - `runLimit` integer, required

## Other responses

- `401`: Unauthorized
- `403`: Forbidden
- `404`: Not Found
- `500`: Internal Server Error

## Changes

- **2026-10-29** `06d2142ed144`: 1 info
  - api operation id `getProjectWork` was added
- **2026-10-29** `68c1ace37d92`: 1 info
  - added the required property `data/attributes/items/items/runningLoops` to the response with the `200` status
- **2026-10-29** `6913b271e6d7`: 4 breaking, 4 warning
  - removed the required property `data/attributes/otherRunCount` from the response with the `200` status
  - removed the required property `data/attributes/otherRuns` from the response with the `200` status
  - removed the required property `data/attributes/scope/since` from the response with the `200` status
  - removed the required property `data/attributes/scope/until` from the response with the `200` status
  - …4 more
- **2026-10-29** `842615b367d8`: 2 info
  - added the required property `data/attributes/items/items/lastStartedAt` to the response with the `200` status
  - added the required property `data/attributes/items/items/stage` to the response with the `200` status
- **2026-10-26** `bd98dcac7c81`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/tessl/apis/tessl-api/changes/experimental/projects/:projectId/work/get.md)

---

[API](https://skmtc.dev/tessl/apis/tessl-api.md) - [All operations](https://skmtc.dev/tessl/apis/tessl-api/llms.txt) - [OpenAPI document](https://skmtc.dev/tessl/apis/tessl-api/revisions/4fa2a17154e4?raw)
