Message API/docs/components/symbol-management/api

REST API

Combined route and backend behavior reference for Symbol Management.

Routes

These are the routes used by the Symbol Management module.

  • Folders: left-panel library grouping.
  • Symbols: main-panel library records.
  • Base URL: current frontend default is `http://localhost:5203/api`.
  • Auth header: include `x-api-key: CLIENT_API_KEY` on folder and symbol requests.
GET    http://localhost:5203/api/symbol/folders
POST   http://localhost:5203/api/symbol/folders
GET    http://localhost:5203/api/symbol/folders/:id
PATCH  http://localhost:5203/api/symbol/folders/:id
DELETE http://localhost:5203/api/symbol/folders/:id

GET    http://localhost:5203/api/symbol/folders/:folderId/symbols
POST   http://localhost:5203/api/symbol/folders/:folderId/symbols
GET    http://localhost:5203/api/symbol/symbols/:id
PATCH  http://localhost:5203/api/symbol/symbols/:id
DELETE http://localhost:5203/api/symbol/symbols/:id
Routes

Prerequisite

Protected Symbol Management routes require a valid client API key before folder and symbol requests will succeed.

Request Contracts

Folders use name-based payloads. Symbols use name, MIME type, serialized `data`, and optional folder reassignment.

Protected deployments expect `x-api-key` in the request headers, even for read operations.

type CreateFolderRequest = {
  name: string;
};

type UpdateFolderRequest = {
  name: string;
};

type CreateSymbolRequest = {
  name: string;
  type: string;
  data: string;
};

type UpdateSymbolRequest = {
  name: string;
  type: string;
  data: string;
  folderId: number;
};
Request Contracts

Backend Behavior

Handle these backend behaviors explicitly in the client.

  • 404 Not Found: missing folder or symbol record.
  • 409 Conflict: duplicate folder name.
  • 400 Bad Request: validation failure.
  • 401/403: missing or invalid client API key when route protection is enabled.
  • Unique folder names: the backend should reject duplicates.
  • Auth requirement: current client integrations send `x-api-key` on all Symbol Management routes.

Frontend Note

This module belongs in your backend service layer and client application logic, not in the viewer postMessage contract.

A common flow is to load folders first, load symbols when a folder ID is available, and refresh the affected collection after every successful mutation.

React Usage Example

This example shows one client-side integration pattern using React state and effects.

React Page Types

import { useEffect, useState } from 'react'

const API_BASE_URL = 'http://localhost:5203/api'

type SymbolFolder = {
  id: number
  name: string
}

type SymbolRecord = {
  id: number
  name: string
  type: string
  data: string
  folderId: number
}

Load Folders

async function loadFolders() {
  const response = await fetch(`${API_BASE_URL}/symbol/folders`, {
    headers: {
      'x-api-key': CLIENT_API_KEY,
    },
  })
  if (!response.ok) throw new Error(await response.text())

  const nextFolders = await response.json()
  setFolders(nextFolders)

  if (nextFolders.length > 0) {
    setSelectedFolderId((current) => current ?? nextFolders[0].id)
  }
}

Load Symbols For Selected Folder

async function loadSymbols(folderId: number) {
  const response = await fetch(`${API_BASE_URL}/symbol/folders/${folderId}/symbols`, {
    headers: {
      'x-api-key': CLIENT_API_KEY,
    },
  })
  if (!response.ok) throw new Error(await response.text())

  setSymbols(await response.json())
}

React Effects

useEffect(() => {
  void loadFolders()
}, [])

useEffect(() => {
  if (selectedFolderId == null) return
  void loadSymbols(selectedFolderId)
}, [selectedFolderId])

Page Skeleton

export function SymbolManagementExample() {
  const [folders, setFolders] = useState<SymbolFolder[]>([])
  const [selectedFolderId, setSelectedFolderId] = useState<number | null>(null)
  const [symbols, setSymbols] = useState<SymbolRecord[]>([])

  async function loadFolders() {
    const response = await fetch(`${API_BASE_URL}/symbol/folders`, {
      headers: {
        'x-api-key': CLIENT_API_KEY,
      },
    })
    if (!response.ok) throw new Error(await response.text())

    const nextFolders = await response.json()
    setFolders(nextFolders)

    if (nextFolders.length > 0) {
      setSelectedFolderId((current) => current ?? nextFolders[0].id)
    }
  }

  async function loadSymbols(folderId: number) {
    const response = await fetch(`${API_BASE_URL}/symbol/folders/${folderId}/symbols`, {
      headers: {
        'x-api-key': CLIENT_API_KEY,
      },
    })
    if (!response.ok) throw new Error(await response.text())

    setSymbols(await response.json())
  }

  useEffect(() => {
    void loadFolders()
  }, [])

  useEffect(() => {
    if (selectedFolderId == null) return
    void loadSymbols(selectedFolderId)
  }, [selectedFolderId])

  return null
}