---
title: "Get a project graph"
method: GET
path: "/workspaces/{workspaceId}/projects/{projectId}/graph"
tags: ["Canvas"]
---

# Get a project graph

`GET /workspaces/{workspaceId}/projects/{projectId}/graph`

## Request

- Base URL: `https://app.flora.ai/api/v1`
- URL: `https://app.flora.ai/api/v1/workspaces/{workspaceId}/projects/{projectId}/graph`
- Auth: HTTP bearer

Returns the full state of a project canvas: every node's short id, node UUID, type, label, prompt, model, parameters, absolute position, generation status, current output and, for document-bearing nodes such as timelines and decks, a summary of its authored content with the document revision, plus the edges between them and a revision marker. Full documents are read per node from the node document endpoint. Short ids are persisted as part of the read, so the id reported for a node is the same on every subsequent read and is the id canvas write operations accept. The revision is opaque: an identical value means nothing this endpoint reports has changed, a different value means something has, and no ordering can be inferred from two values.

## Path parameters

- `workspaceId` string, required: Workspace identifier
- `projectId` string, required: Project identifier

## Response `200`

Project graph returned.

- object
  - `project_id` string, required: Project identifier
  - `canvas_url` string, uri, required: Project canvas URL
  - `revision` string, required: Opaque change-detection marker for the reported graph. An identical value means nothing this endpoint reports has changed; a different value means something has. It is not a counter, so no ordering can be inferred from two values.
  - `nodes` object[], required: Complete canvas node list
    - `id` string, required: Short node identifier. Stable across reads and the vocabulary canvas edges use.
    - `node_id` string, required: Canvas node UUID. Stable for the node's life.
    - `type` string, required: Node type in agent vocabulary, for example image, video, text, model3d, action, batch, or group
    - `label` string, required: Node display label
    - `group` string, nullable: Direct parent group short id (n7), or null for top-level nodes and pinned labels. Use this to verify existing field membership; omitted on older API deployments.
    - `prompt` string, nullable, required: Configured generation prompt, or null when the node has none
    - `model` string, nullable, required: Configured model name, or null when the node generates nothing
    - `model_id` string, nullable, required: Configured model endpoint identifier. Preferred over model because it survives catalog renames.
    - `params` object, nullable, required: Configured model parameters excluding prompt, which is reported separately. Null when the node sets none.
    - `action` object, nullable, required: Action-node configuration. Null for every node type other than action.
      - `action_id` string, nullable, required: Prebuilt action slug the node runs, for example rotate-image. Null when the node runs custom code.
      - `params` object, nullable, required: Configured action parameter values, keyed by the snake_case parameter ids the actions endpoints expose. Null when none are set.
    - `position` object, required: Absolute canvas position of the node's anchor, with parent groups resolved. Every node type except group anchors at the top-center of its box, so its visual left edge is x minus half its width; a group anchors top-left.
      - `x` number, required: Horizontal canvas coordinate
      - `y` number, required: Vertical canvas coordinate
    - `size` object, required: The node's on-canvas footprint: the rendered box once the node has painted, else its stored or default size. With position this is the box the arrange endpoint lays out, so neighbours can be placed without guessing card sizes.
      - `width` number, required: Node width in canvas units
      - `height` number, required: Node height in canvas units
    - `status` 'idle' | 'generating' | 'done' | 'error', nullable, required: Derived generation status. Null for node types that carry no generation lifecycle, such as groups, comments, batches, routers, switches, exports, and labels.
    - `error_code` string: Machine-readable failure code. Present only when status is error.
    - `error_message` string: User-facing failure message. Present only when status is error.
    - `output_url` string, nullable, required: URL of the node's current media output, or null when it has none or its output is not externally addressable
    - `output_text` string, nullable, required: The node's current text output, or null when it has none
    - `text` string, nullable, required: Annotation body for a notes or label node — the text a reader sees on the canvas, in full. Null on every node type that carries none. Distinct from output_text, which is generated output.
    - `document` object, nullable, required: Summary of the node's authored content for document-bearing nodes (timeline), or null when the node carries no document or none has been written yet. Read the full document from the node document endpoint.
      - `kind` string, required: Document kind, for example "timeline". Kinds you do not recognise may appear on newer nodes: keep the wrapper and ignore the body.
      - `schema_version` integer, required: Version of the document schema the body follows
      - `revision` integer, required: Revision of this node's document. Pass it as base_revision on a changeset update to reject a stale write.
      - `updated_at` integer: Last document write, Unix milliseconds; absent for Deck documents
      - `summary` object, required: Kind-specific one-line facts. A timeline reports duration_in_frames, duration_in_seconds, fps, composition_width, composition_height, track_count, item_count and asset_count.
  - `edges` object[], required: Complete canvas edge list
    - `from` string, required: Short identifier of the source node
    - `to` string, required: Short identifier of the target node
    - `in` string, nullable, required: Input slot the edge lands in on the target node, for example "image" or "enabled". Null when the edge names no slot.

## Other responses

- `400`: 400
- `401`: 401
- `402`: 402
- `403`: 403
- `404`: 404
- `409`: 409
- `429`: 429
- `500`: 500
- `503`: 503

## Changes

- **2026-10-28** `a8351619f225`: 9 warning
  - added the new `not_configured` enum value to the `error/code` response property for the response status `400`
  - added the new `not_configured` enum value to the `error/code` response property for the response status `401`
  - added the new `not_configured` enum value to the `error/code` response property for the response status `402`
  - added the new `not_configured` enum value to the `error/code` response property for the response status `403`
  - …5 more
- **2026-10-16** `e54130373b10`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/florafauna-ai/apis/flora-ai-api/changes/workspaces/:workspaceId/projects/:projectId/graph/get.md)

---

[API](https://skmtc.dev/florafauna-ai/apis/flora-ai-api.md) - [All operations](https://skmtc.dev/florafauna-ai/apis/flora-ai-api/llms.txt) - [OpenAPI document](https://skmtc.dev/florafauna-ai/apis/flora-ai-api/revisions/87cfe2c4ac29?raw)
