API

Maps API Pro

The REST endpoints for reading and writing maps. Every call needs a workspace token; responses are JSON unless noted. Base URL: https://canopy.8starlabs.com/api/v1.

List maps

GET
https://canopy.8starlabs.com/api/v1/maps

List every map in the workspace.

curl https://canopy.8starlabs.com/api/v1/maps \
  -H "Authorization: Bearer $CANOPY_TOKEN"

Responses

StatusMeaning
200 OKAn array of maps in maps.
401 UnauthorizedMissing or invalid token.
429 Too Many RequestsRate limit exceeded - see Rate limits.
{
  "maps": [
    {
      "id": "acme-platform",
      "name": "8StarLabs Platform",
      "isPublic": false,
      "nodes": [
        { "id": "api", "label": "API", "tech": "node · trpc", "spend": "$2.1k", "x": 240, "y": 120 }
        /* … */
      ],
      "edges": [
        { "source": "web", "target": "api", "line": "bezier" }
        /* … */
      ],
      "createdAt": "2026-05-01T10:00:00.000Z",
      "updatedAt": "2026-06-01T12:30:00.000Z"
    }
    /* … */
  ]
}

Get a map

GET
https://canopy.8starlabs.com/api/v1/maps/{id}

Fetch a single map with its nodes and edges.

curl https://canopy.8starlabs.com/api/v1/maps/acme-platform \
  -H "Authorization: Bearer $CANOPY_TOKEN"

Responses

StatusMeaning
200 OKThe map, under map.
401 UnauthorizedMissing or invalid token.
404 Not FoundNo map with that id in your workspace.
429 Too Many RequestsRate limit exceeded.
{
  "map": {
    "id": "acme-platform",
    "name": "8StarLabs Platform",
    "isPublic": false,
    "nodes": [
      { "id": "api", "label": "API", "tech": "node · trpc", "x": 240, "y": 120 }
    ],
    "edges": [
      { "source": "web", "target": "api", "line": "bezier" }
    ],
    "createdAt": "2026-05-01T10:00:00.000Z",
    "updatedAt": "2026-06-01T12:30:00.000Z"
  }
}

Create a map

POST
https://canopy.8starlabs.com/api/v1/maps

Create a new map. The body is the architecture JSON.

curl -X POST https://canopy.8starlabs.com/api/v1/maps \
  -H "Authorization: Bearer $CANOPY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "name": "8StarLabs Platform", "nodes": [], "edges": [] }'

Responses

StatusMeaning
201 CreatedThe new map, under map.
400 Bad RequestInvalid payload (e.g. missing name); see fields.
401 UnauthorizedMissing or invalid token.
403 ForbiddenMap exceeds your plan's node limit.
429 Too Many RequestsRate limit exceeded.
{
  "map": {
    "id": "acme-platform",
    "name": "8StarLabs Platform",
    "isPublic": false,
    "nodes": [],
    "edges": [],
    "createdAt": "2026-06-09T09:00:00.000Z",
    "updatedAt": "2026-06-09T09:00:00.000Z"
  }
}

Update a map

PATCH
https://canopy.8starlabs.com/api/v1/maps/{id}

Update a map's name, nodes, edges, or metadata. Only the fields you send change.

curl -X PATCH https://canopy.8starlabs.com/api/v1/maps/acme-platform \
  -H "Authorization: Bearer $CANOPY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Acme Platform v2" }'

Responses

StatusMeaning
200 OKThe updated map, under map.
400 Bad RequestEmpty or invalid payload.
401 UnauthorizedMissing or invalid token.
404 Not FoundNo map with that id in your workspace.
429 Too Many RequestsRate limit exceeded.
{
  "map": {
    "id": "acme-platform",
    "name": "Acme Platform v2",
    "isPublic": false,
    "nodes": [ /* … */ ],
    "edges": [ /* … */ ],
    "createdAt": "2026-05-01T10:00:00.000Z",
    "updatedAt": "2026-06-09T09:05:00.000Z"
  }
}

Delete a map

DELETE
https://canopy.8starlabs.com/api/v1/maps/{id}

Permanently delete a map.

curl -X DELETE https://canopy.8starlabs.com/api/v1/maps/acme-platform \
  -H "Authorization: Bearer $CANOPY_TOKEN"

Responses

StatusMeaning
200 OKThe map was deleted.
401 UnauthorizedMissing or invalid token.
404 Not FoundNo map with that id in your workspace.
429 Too Many RequestsRate limit exceeded.
{
  "deleted": true,
  "id": "acme-platform"
}

Export a map

GET
https://canopy.8starlabs.com/api/v1/maps/{id}/export/{format}

Export a map as markdown, claude, agents, png, figma, or notion.

curl https://canopy.8starlabs.com/api/v1/maps/acme-platform/export/claude \
  -H "Authorization: Bearer $CANOPY_TOKEN" -o CLAUDE.md

Responses

The body is the exported artifact itself - text/markdown for markdown / claude / agents, application/json for figma / notion, image/png for png - not a JSON envelope.

StatusMeaning
200 OKThe exported file, in the format's content type.
400 Bad RequestUnknown :format.
401 UnauthorizedMissing or invalid token.
403 ForbiddenFormat is gated behind Pro (e.g. claude, agents).
404 Not FoundNo map with that id in your workspace.
429 Too Many RequestsRate limit exceeded.
# Acme Platform

> Architecture map exported from Canopy.

## Services

- **API** - node · trpc ($2.1k)

## Dependencies

- web → api

The map object

A GET returns a map wrapped in { "map": … } (or { "maps": [ … ] } for the list). The full object:

FieldTypeNotes
idstringStable map id (the :id in URLs).
workspaceIdstringThe workspace the map belongs to.
namestringMap name.
isPublicbooleanWhether the map has a public share link.
nodesNode[]The services - see below.
edgesEdge[]The connections - see below.
createdAt / updatedAtstringISO‑8601 timestamps.

Node - id is always present; the rest appear only when set:

FieldTypeNotes
idstringStable node key (edges reference it).
labelstringDisplay name.
techstringSub-label, e.g. "node · trpc".
spendstringMonthly cost as a whole-dollar string, e.g. "$2100".
billingstring[]Any of seat, team, usage, flat.
x, ynumberCanvas position.

Edge - source and target are node ids; line is the curve style (bezier · smoothstep · step · straight).

JSON
{
  "map": {
    "id": "acme-platform",
    "workspaceId": "ws_8s7d6f5g",
    "name": "8StarLabs Platform",
    "isPublic": false,
    "nodes": [
      {
        "id": "web",
        "label": "Web",
        "tech": "next.js",
        "spend": "$1200",
        "x": 0,
        "y": 96
      },
      {
        "id": "api",
        "label": "API",
        "tech": "node · trpc",
        "spend": "$2100",
        "billing": ["flat"],
        "x": 240,
        "y": 120
      }
    ],
    "edges": [{ "source": "web", "target": "api", "line": "bezier" }],
    "createdAt": "2026-05-01T10:00:00.000Z",
    "updatedAt": "2026-06-01T12:30:00.000Z"
  }
}

Request body

When you create or update a map you send only the editable fields - name, nodes, edges, and optional isPublic. The server assigns id, workspaceId, and the timestamps.

JSON
{
  "name": "8StarLabs Platform",
  "nodes": [{ "id": "web", "label": "Web", "tech": "next.js" }],
  "edges": [{ "source": "web", "target": "api" }]
}

to paste into any AI.

Ask ChatGPT about this page.

Ask Claude about this page.

Need help? Sign in to chat with support

Have ideas?

General inquiry? Email support.