---
title: "List projects"
method: GET
path: "/v1/projects"
tags: ["projects"]
---

# List projects

`GET /v1/projects`

## Request

- Base URL: `https://api.hyperresearch.ai`
- URL: `https://api.hyperresearch.ai/v1/projects`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `hr_session`

Projects in this workspace, most recently updated first. `status` defaults to `active`; pass `archived` or `all` to widen it. `counts.runs`, `counts.reports` and `counts.sources` come from one statement over one snapshot, so this list and `GET /v1/projects/{id}` can never publish different totals for the same project. `counts.sources` is `SUM(runs.sources_fetched)` — the sources these runs kept.

## Query parameters

- `status` 'active' | 'archived' | 'all': Defaults to `active`.

## Response `200`

Projects

- ProjectList
  - `items` Project[], required
    - `id` string, required
    - `name` string, required
    - `description` string, nullable, required
    - `status` 'active' | 'archived', required
    - `created_at` string, required
    - `updated_at` string, required
    - `counts` ProjectCounts, required
      - `runs` integer, required: Runs filed under this project.
      - `reports` integer, required: Those runs that finished (`done`).
      - `sources` integer, required: Sources the runs filed here KEPT, summed: `SUM(runs.sources_fetched)` over the runs filed here, under the same definition as `runs.sources_fetched` on a run (a failed attempt is not a source). Computed in the same statement as `runs` and `reports`, so the list and the detail always agree; a run that has recorded no count yet contributes 0.
    - `latest_run` ProjectLatestRun, nullable, required
      - `id` string, required
      - `status` string, required
      - `tier` string, required
      - `created_at` string, required
      - `started_at` string, nullable, required: When the run actually began, as opposed to when it was queued.
      - `finished_at` string, nullable, required: When the run ENDED, null while it is still going. The project header says "latest finished N ago" and was printing `created_at` — the moment the run was launched — so a run that finished three minutes ago read as nineteen minutes ago (E2E7-09). Read this for that sentence.
      - `duration_ms` integer, nullable, required: Wall time of the run; the same number `GET /v1/runs` and `GET /v1/runs/{id}` serve.
      - `query_preview` string, nullable, required: Server-derived excerpt of that run’s canonical question.

## Other responses

- `400`: Invalid request
- `401`: Authentication failed
- `403`: Insufficient scope or plan
- `404`: Not found
- `429`: Rate limited or over quota
- `500`: Internal error

---

[API](https://skmtc.dev/hyperresearch/apis/hyperresearch-cloud-api.md) · [All operations](https://skmtc.dev/hyperresearch/apis/hyperresearch-cloud-api/llms.txt) · [OpenAPI document](https://skmtc.dev/hyperresearch/apis/hyperresearch-cloud-api/revisions/726ef831ebf4?raw)
