---
title: "Get a project"
method: GET
path: "/v1/projects/{id}"
tags: ["projects"]
---

# Get a project

`GET /v1/projects/{id}`

## Request

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

One project, in exactly the shape `GET /v1/projects` returns for it. `counts.sources` is `SUM(runs.sources_fetched)` over the runs filed here — the sources they kept — computed in the same statement as `counts.runs` and `counts.reports`, so this endpoint and the list never disagree (E2E5-03).

## Path parameters

- `id` string, required

## Response `200`

Project

- Project
  - `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)
