# Developer > Developer API reference for ML Board Category: BOARDS · Source: https://miciomods.it/docs/ml-board-developer · Last updated: 2026-07-27 ## Overview ML Board provides server exports for querying board state and handler hooks in the `open/` folder for custom logic. ## Server Exports ```lua local boards = exports['ml_board']:GetActiveBoards() local count = exports['ml_board']:GetPlayerBoardCount(identifier) ``` - `GetActiveBoards()`: Returns a table of all active dynamic (player-placed) boards - `GetPlayerBoardCount(identifier)`: Returns the number of boards owned by a player ## Server Handlers Defined in `open/server.lua`. **open/server.lua** ```lua function OpenServer.CanEditBoard(src, boardId) return true -- return false to block editing end function OpenServer.OnContentSaved(src, boardId) -- Triggered after a note is placed or removed end ``` - `CanEditBoard(src, boardId)`: Called before any edit action. Return `false` to block. - `OnContentSaved(src, boardId)`: Fired after board content changes. Use for logging or syncing. **Restrict Editing to Police Jobs** **open/server.lua** ```lua function OpenServer.CanEditBoard(src, boardId) local job = Bridge.GetJob(src) if job and job.name == 'police' then return true end return false end ``` ## Client Handlers Defined in `open/client.lua`. **open/client.lua** ```lua function OpenClient.OnBoardOpen(boardId) -- Triggered when a player opens a board UI end function OpenClient.OnBoardClose(boardId) -- Triggered when the board UI is closed end ``` - `OnBoardOpen(boardId)`: Use for sounds, effects, or analytics - `OnBoardClose(boardId)`: Cleanup or post-view logic ## Permissions Board access is controlled per-location in `shared/config_locations.lua`, not through handlers: - `jobView`: Jobs that can read the board (`nil` = everyone) - `jobWrite`: Jobs that can post notes - `jobClear`: Jobs that can clear all notes - `allowedVariants`: Restrict which note types are available (by id) Each board also carries a `permissions` table with one rule per action, so pinning, moving, deleting, clearing, wiring, drawing and stamping are gated separately. Static boards take it in shared/config_locations.lua, player-placed boards take it on their entry in Config.BoardTypes. Values are 'all', 'own', 'none' or a job list, and the admin permission bypasses all of them. **shared/config_locations.lua** ```lua permissions = { place = 'all', move = 'own', delete = 'own', clear = { 'police' }, connect = 'all', erase_connect = 'own', draw = 'none', erase_draw = 'own', stamp = 'all', }, ```