Get the canonical graph for a project
const url = 'https://api.hydrate.sh/v1/graph/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url https://api.hydrate.sh/v1/graph/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0 \ --header 'Authorization: Bearer <token>'Returns the active main-branch graph (nodes, ports, edges, version) for the project. Read-only: the main branch is merge-only. To make changes, fork a branch (POST /v1/projects/{project_id}/branches) and apply deltas to it.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The project whose main-branch graph to fetch.
The project whose main-branch graph to fetch.
Responses
Section titled “Responses”Successful Response
object
object
Read-path edge: source/target are server-derived NODE ids
(absent from the client-authored h2o.types.Edge); *_handle are the
PORT ids.
object
Read-path node data. NOT h2o.NodeData: the response omits
kind/parent_id (those live on the wrapper) and emits the boundary/
external scalars matrix-conditionally — so the matrix fields are
optional (absent = not-applicable-to-kind).
object
object
Example
{ "nodes": [ { "data": { "config": [ { "contract_name": null, "description": "", "external": false, "name": "", "type": "" } ], "documentation_url": null, "external_kind": null, "inputs": [ { "contract_name": null, "description": "", "external": false, "name": "", "type": "" } ], "language": null, "outputs": [ { "contract_name": null, "description": "", "external": false, "name": "", "type": "" } ], "path_prefix": null, "protocol": null, "source_decisions": null, "user_kind": null, "verifications": [ { "author": "user", "type": null } ] }, "kind": "behavior" } ]}No credentials, malformed credentials, or revoked credentials. The envelope is leak-parity (same shape across all 401 paths) so an attacker cannot distinguish revoked vs. unknown via the body.
object
Example
{ "detail": "unauthenticated"}Credentials are valid but lack the scope required for this route, or the principal lacks membership in the target project.
object
object
Examplegenerated
{ "detail": { "code": "example", "message": "example" }}Resource not found OR not accessible to this principal. Leak parity: the response is identical in both cases so an attacker cannot enumerate resources via 404-vs-403 timing.
object
object
Example
{ "detail": { "code": "not_found" }}Validation Error
object
object
object
Examplegenerated
{ "detail": [ { "ctx": {}, "input": "example", "loc": [ "example" ], "msg": "example", "type": "example" } ]}Per-bucket rate limit exceeded. The response carries Retry-After and the standard X-RateLimit-* headers (Limit / Remaining / Reset).
object
Example
{ "detail": "rate_limited"}