Canvas

The Canvas API provides persistence for drag-and-drop cards and folders. Cards have a type, content, x/y position, optional folder assignment, and arbitrary metadata. Folders are ordered by creation date and can hold any number of cards.

List Cards

GET/api/v2/canvas/cardsAuthenticated

Returns all canvas cards for the authenticated user, ordered by created_at descending. Optionally filter by folder.

Query Parameters

folder_idstring (UUID)

Filter cards belonging to a specific folder. Omit to return all cards.

Request

cURL
400">curl -X 400">GET 400">class="text-emerald-400">"https:400">class="text-zinc-500">//api.lvng.ai/api/v2/canvas/cards?folder_id=d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90" \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_JWT_TOKEN"

Response 200

{
  400">class="text-emerald-400">"cards": [
    {
      400">class="text-emerald-400">"id": 400">class="text-emerald-400">"7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e",
      400">class="text-emerald-400">"400">type": 400">class="text-emerald-400">"note",
      400">class="text-emerald-400">"content": 400">class="text-emerald-400">"## Onboarding Flow\n1. Welcome email\n2. Profile setup",
      400">class="text-emerald-400">"position": { 400">class="text-emerald-400">"x": 120, 400">class="text-emerald-400">"y": 80 },
      400">class="text-emerald-400">"folder_id": 400">class="text-emerald-400">"d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
      400">class="text-emerald-400">"metadata": { 400">class="text-emerald-400">"color": 400">class="text-emerald-400">"#3b82f6" },
      400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-03-12T09:00:00.000Z",
      400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-18T15:30:00.000Z"
    },
    {
      400">class="text-emerald-400">"id": 400">class="text-emerald-400">"2c3d4e5f-6a7b-8c9d-0e1f-2a3b4c5d6e7f",
      400">class="text-emerald-400">"400">type": 400">class="text-emerald-400">"task",
      400">class="text-emerald-400">"content": 400">class="text-emerald-400">"Audit rate-limiting config",
      400">class="text-emerald-400">"position": { 400">class="text-emerald-400">"x": 450, 400">class="text-emerald-400">"y": 80 },
      400">class="text-emerald-400">"folder_id": 400">class="text-emerald-400">"d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
      400">class="text-emerald-400">"metadata": {},
      400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-03-14T11:20:00.000Z",
      400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-14T11:20:00.000Z"
    }
  ]
}

Create Card

POST/api/v2/canvas/cardsAuthenticated

Creates a new canvas card. The type field is required. Position defaults to (0, 0) if omitted.

Body Parameters

typestringrequired

Card type identifier (e.g. "note", "task", "image", "link").

contentstring
Default: ""

Card body content. Defaults to empty string.

positionobject
Default: { x: 0, y: 0 }

Coordinates as { x: number, y: number }. Defaults to { x: 0, y: 0 }.

folder_idstring (UUID)
Default: null

Folder to place the card in. Null if not in a folder.

metadataobject
Default: {}

Arbitrary JSON metadata (color, tags, etc.).

Request

cURL
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/canvas/cards \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_JWT_TOKEN" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d '{
    400">class="text-emerald-400">"400">type": 400">class="text-emerald-400">"note",
    400">class="text-emerald-400">"content": 400">class="text-emerald-400">"- Ship voice notes MVP\n- Fix calendar sync bug",
    400">class="text-emerald-400">"position": { 400">class="text-emerald-400">"x": 200, 400">class="text-emerald-400">"y": 300 },
    400">class="text-emerald-400">"folder_id": 400">class="text-emerald-400">"d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
    400">class="text-emerald-400">"metadata": { 400">class="text-emerald-400">"color": 400">class="text-emerald-400">"#10b981" }
  }'

Response 201

{
  400">class="text-emerald-400">"card": {
    400">class="text-emerald-400">"id": 400">class="text-emerald-400">"9e0f1a2b-3c4d-5e6f-7a8b-9c0d1e2f3a4b",
    400">class="text-emerald-400">"400">type": 400">class="text-emerald-400">"note",
    400">class="text-emerald-400">"content": 400">class="text-emerald-400">"- Ship voice notes MVP\n- Fix calendar sync bug",
    400">class="text-emerald-400">"position": { 400">class="text-emerald-400">"x": 200, 400">class="text-emerald-400">"y": 300 },
    400">class="text-emerald-400">"folder_id": 400">class="text-emerald-400">"d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
    400">class="text-emerald-400">"metadata": { 400">class="text-emerald-400">"color": 400">class="text-emerald-400">"#10b981" },
    400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-03-19T10:00:00.000Z",
    400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T10:00:00.000Z"
  }
}

Update Card

PUT/api/v2/canvas/cards/:idAuthenticated

Updates an existing canvas card. Only provided fields are modified; the type field cannot be changed.

Path Parameters

idstring (UUID)required

The card ID.

Body Parameters

contentstring

Updated card content.

positionobject

Updated position as { x: number, y: number }.

folder_idstring (UUID) | null

Move to a different folder, or null to unlink.

metadataobject

Replacement metadata object.

Request

cURL
400">curl -X 400">PUT https:400">class="text-zinc-500">//api.lvng.ai/api/v2/canvas/cards/9e0f1a2b-3c4d-5e6f-7a8b-9c0d1e2f3a4b \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_JWT_TOKEN" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d '{
    400">class="text-emerald-400">"content": 400">class="text-emerald-400">"- Ship voice notes MVP\n- Fix calendar sync bug\n- Deploy knowledge base v2",
    400">class="text-emerald-400">"position": { 400">class="text-emerald-400">"x": 200, 400">class="text-emerald-400">"y": 350 }
  }'

Response 200

{
  400">class="text-emerald-400">"card": {
    400">class="text-emerald-400">"id": 400">class="text-emerald-400">"9e0f1a2b-3c4d-5e6f-7a8b-9c0d1e2f3a4b",
    400">class="text-emerald-400">"400">type": 400">class="text-emerald-400">"note",
    400">class="text-emerald-400">"content": 400">class="text-emerald-400">"- Ship voice notes MVP\n- Fix calendar sync bug\n- Deploy knowledge base v2",
    400">class="text-emerald-400">"position": { 400">class="text-emerald-400">"x": 200, 400">class="text-emerald-400">"y": 350 },
    400">class="text-emerald-400">"folder_id": 400">class="text-emerald-400">"d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
    400">class="text-emerald-400">"metadata": { 400">class="text-emerald-400">"color": 400">class="text-emerald-400">"#10b981" },
    400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-03-19T10:00:00.000Z",
    400">class="text-emerald-400">"updated_at": 400">class="text-emerald-400">"2026-03-19T10:25:00.000Z"
  }
}

Delete Card

DELETE/api/v2/canvas/cards/:idAuthenticated

Permanently deletes a canvas card. Returns 404 if the card does not exist or does not belong to the authenticated user.

Path Parameters

idstring (UUID)required

The card ID to delete.

Request

cURL
400">curl -X 400">DELETE https:400">class="text-zinc-500">//api.lvng.ai/api/v2/canvas/cards/9e0f1a2b-3c4d-5e6f-7a8b-9c0d1e2f3a4b \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_JWT_TOKEN"

Response 200

{
  400">class="text-emerald-400">"success": true
}

List Folders

GET/api/v2/canvas/foldersAuthenticated

Returns all canvas folders for the authenticated user, ordered by created_at ascending.

Request

cURL
400">curl -X 400">GET https:400">class="text-zinc-500">//api.lvng.ai/api/v2/canvas/folders \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_JWT_TOKEN"

Response 200

{
  400">class="text-emerald-400">"folders": [
    {
      400">class="text-emerald-400">"id": 400">class="text-emerald-400">"d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f90",
      400">class="text-emerald-400">"customer_id": 400">class="text-emerald-400">"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      400">class="text-emerald-400">"user_id": 400">class="text-emerald-400">"f6a7b8c9-0d1e-2f3a-4b5c-6d7e8f901234",
      400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Product Roadmap",
      400">class="text-emerald-400">"color": 400">class="text-emerald-400">"#6366f1",
      400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-02-01T08:00:00.000Z"
    },
    {
      400">class="text-emerald-400">"id": 400">class="text-emerald-400">"b2c3d4e5-f6a7-8901-bcde-f12345678901",
      400">class="text-emerald-400">"customer_id": 400">class="text-emerald-400">"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      400">class="text-emerald-400">"user_id": 400">class="text-emerald-400">"f6a7b8c9-0d1e-2f3a-4b5c-6d7e8f901234",
      400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Design System",
      400">class="text-emerald-400">"color": null,
      400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-02-15T10:00:00.000Z"
    }
  ]
}

Create Folder

POST/api/v2/canvas/foldersAuthenticated

Creates a new folder to organize canvas cards. The name field is required.

Body Parameters

namestringrequired

Folder display name.

colorstring
Default: null

Hex color code for the folder accent.

Request

cURL
400">curl -X 400">POST https:400">class="text-zinc-500">//api.lvng.ai/api/v2/canvas/folders \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_JWT_TOKEN" \
  -H 400">class="text-emerald-400">"Content-Type: application/json" \
  -d '{
    400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Architecture Decisions",
    400">class="text-emerald-400">"color": 400">class="text-emerald-400">"#f59e0b"
  }'

Response 201

{
  400">class="text-emerald-400">"folder": {
    400">class="text-emerald-400">"id": 400">class="text-emerald-400">"c3d4e5f6-a7b8-9012-cdef-123456789012",
    400">class="text-emerald-400">"customer_id": 400">class="text-emerald-400">"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    400">class="text-emerald-400">"user_id": 400">class="text-emerald-400">"f6a7b8c9-0d1e-2f3a-4b5c-6d7e8f901234",
    400">class="text-emerald-400">"name": 400">class="text-emerald-400">"Architecture Decisions",
    400">class="text-emerald-400">"color": 400">class="text-emerald-400">"#f59e0b",
    400">class="text-emerald-400">"created_at": 400">class="text-emerald-400">"2026-03-19T10:30:00.000Z"
  }
}

Delete Folder

DELETE/api/v2/canvas/folders/:idAuthenticated

Deletes a folder. Cards in the folder are unlinked (their folder_id is set to null) rather than deleted.

Path Parameters

idstring (UUID)required

The folder ID to delete.

Request

cURL
400">curl -X 400">DELETE https:400">class="text-zinc-500">//api.lvng.ai/api/v2/canvas/folders/c3d4e5f6-a7b8-9012-cdef-123456789012 \
  -H 400">class="text-emerald-400">"Authorization: Bearer YOUR_JWT_TOKEN"

Response 200

{
  400">class="text-emerald-400">"success": true
}