---
id: projects-get-project
title: "GET /api/projects/:id — Получить проект"
domain: projects
kind: api-method
http: "GET /api/projects/:id"
---

# GET /api/projects/:id — Получить проект {#projects-get-project}

## Сводка

| Поле | Значение |
|---|---|
| **HTTP** | `GET /api/projects/:id` |
| **Auth** | `optionalAuth, requireProjectAccess` — гость + авторизованный, доступ к проекту (read/write) |
| **Scope токена** | `read` |
| **PG-функции** | `api.get_project_graph` |
| **Таблицы** | `project`, `project_node`, `project_edge`, `project_node_role`, `content_item` |
| **SRM** | SRM-002 |
| **RP (права)** | RP-010, RP-012 |
| **Файл роута** | `server/routes/projects.js` |
| **Статус** | done |

**Аргументы запроса** (best-effort из хендлера; путь-параметры опущены):

_аргументов не обнаружено (подтвердить вручную по `server/routes/projects.js`)_

**Коды ответов/ошибок** (из хендлера): `404`, `500` (+ `200`) — _уточнить причины вручную_

Чтение — достаточно токена со scope `read` (см. [Конвенции](../../../shared/conventions.md#conventions)). `requireProjectAccess` загружает проект и проверяет доступ владельца токена; если проект не найден или невидим — `404`. Тела и query-параметров нет, всё в пути.

**Пример запроса:**

```bash
curl https://specbuilder.vnimanie.ai/api/projects/a1b2c3d4-1111-4aaa-9bbb-000000000001 \
  -H "Authorization: Bearer tak_..." \
  -H "Accept: text/markdown"
```

**Ответ `200` (Markdown-зеркало, токен с `Accept: text/markdown`):** ресурс `kind=project` (`server/agent/negotiate.js → sendResource`) — компактные поля + список доступных вашему токену действий. Граф не разворачивается целиком: нода и рёбра отдаются числом (`nodes`/`edges`), за подробностями — отдельный [`/graph`](get-project-graph.md#projects-get-project-graph):

```
# project a1b2c3d4-1111-4aaa-9bbb-000000000001
version: 2026-06-20T11:42:08.512Z
updated: 2026-06-20T11:42:08.512Z

title: Сервис аналитики продаж
prompt: Сервис аналитики продаж для отдела маркетинга
status: ready
nodes: 12
edges: 17

## Actions
- GET /api/projects/a1b2c3d4-.../graph — read-graph — view=summary|full, diff_from=version
- GET /api/projects/a1b2c3d4-.../doc-content — read-doc — design-document content
```

Блок `## Actions` перечисляет только аффордансы, доступные данному токену (его scope и роль владельца) — `server/agent/affordances.js`.

**Ответ `200` (JSON, cookie-клиент):** полный объект проекта плюс развёрнутый граф под ключом `graph` (ноды с ролями, рёбра, роли, junction `nodeRoles`, `contentItems`):

```json
{
  "id": "a1b2c3d4-1111-4aaa-9bbb-000000000001",
  "title": "Сервис аналитики продаж",
  "prompt": "Сервис аналитики продаж для отдела маркетинга",
  "status": "ready",
  "space_id": "f9e8d7c6-...",
  "updated_at": "2026-06-20T11:42:08.512Z",
  "graph": {
    "nodes": [ { "id": "n1", "label": "Сбор требований", "roles": "[\"ba\"]" } ],
    "edges": [ { "source_id": "n1", "target_id": "n2" } ],
    "roles": [ { "id": "ba", "label": "Бизнес-аналитик" } ],
    "nodeRoles": [ { "node_id": "n1", "role_id": "ba" } ],
    "contentItems": []
  }
}
```

У ресурса есть `ETag` (= `updated_at`); повтор с `If-None-Match` → `304` — для агента, который опрашивает проект на изменения, это экономит токены. Если нужен только граф (без шапки проекта) и топо-порядок — берите [`GET /api/projects/{id}/graph`](get-project-graph.md#projects-get-project-graph).

<!-- gen:start:related -->
## Связанные
- Экраны: [Список проектов](../screens/project-list.md#projects-screen-project-list)
- [Конвенции](../../../shared/conventions.md#conventions) · [Роли](../../../shared/roles.md#roles) · [Ошибки](../../../shared/errors.md#errors) · [Глоссарий](../../../shared/glossary.md#glossary)
<!-- gen:end:related -->

---

Human view: https://docs.vnimanie.ai/specbuilder/v1/domains/projects/api/get-project/