Getting Started
The ecbyts Automation API provides programmatic access to the Environmental Digital Twin application. It enables external tools, scripts, and AI agents to control the application running in the browser via REST endpoints and WebSocket commands.
Quick Start
# Start the API server
npm run api
# Check server health
curl http://localhost:4000/api/health
# List all available actions
curl http://localhost:4000/api/actions
# Generate a random model
curl -X POST http://localhost:4000/api/action \
-H "Content-Type: application/json" \
-d '{"action":"generateRandomModel"}'
Security
- Localhost only — WebSocket connections restricted to 127.0.0.1 / ::1
- JSON required — POST/PATCH requests must use
Content-Type: application/json - Body limit — Maximum 5 MB request body
- Single browser — Only one browser tab connected at a time (new connection replaces previous)
- Port config — Default 4000, override with
ECBYTS_PORTenvironment variable
Scope note - monetization endpoints such as API key validation, telemetry, metering, library checkout, marketplace, and payment webhooks are documented separately in ecbytsadmin monetization docs.
Health & Status
Response
{
"success": true,
"data": {
"browserConnected": true,
"uptime": 142,
"actionsCount": 196,
"pendingRequests": 0
}
}
Returns the complete model state as built by buildModel(). Equivalent to exporting the model as JSON.
Response
{
"selectedElement": "el_abc123",
"elementCount": 12,
"campaignCount": 3,
"sceneCount": 2,
"language": "en",
"activeRibbonTab": "modeling"
}
Runs a visual audit of the UI. Checks icon hydration, font families, open modals, button styling, theme variables, and form input classes.
Elements
Returns all elements with their data (excluding Three.js mesh references). Each element has: id, family, name, visible, label, color, data, stamps.
Parameters
| Param | Type | Description |
|---|---|---|
:id | string | Element ID |
Request Body
{ "familyId": "well" }
Valid family IDs: plume, well, lake, river, spring, building, tank, waste, boundary, sensor, or any custom family.
Request Body
{
"updates": {
"name": "MW-01",
"coordinates": { "easting": 350000, "northing": 7400000 }
}
}
Removes the element and all associated observations, stamps, and edges.
Returns the observations[] array from the element's data.
Returns governance, context, and reporting stamps attached to the element.
Returns all edges (incoming + outgoing) connected to the element.
Campaigns
Returns all campaigns with their date, team, and visibility state.
Creates a new sampling campaign with default values. No request body required.
Request Body
{
"field": "name",
"value": "Q1 2026 Sampling"
}
Removes the campaign. Observations linked to this campaign are NOT removed.
Scenes
Returns all saved scene (camera view) snapshots.
Creates a new scene with default camera position.
Removes the saved camera view.
Families
Returns built-in and custom families with id, name, icon, code, enabled state.
Request Body
{ "id": "piezometer", "name": "Piezometer", "icon": "gauge" }
Removes a custom family. Built-in families cannot be deleted.
Edges
Returns all edges with source, target, type, and metadata.
Parameters
| Param | Type | Description |
|---|---|---|
:id | string | Edge ID |
Stamps
Returns stamps grouped by element. Each entry includes elementId, elementName, family, and stamps[].
Groups
Returns the full groups state: elementGroups[], familyGroups[], elementGroupMap, familyGroupMap.
Returns a single group object with id, name, color, collapsed, order.
Auth
Response
{
"user": { "email": "user@example.com", "provider": "google" },
"loggedIn": true,
"email": "user@example.com",
"role": "admin",
"observerMode": "disabled",
"accessControlActive": true,
"owner": "admin@example.com"
}
Returns the array of access rules. Each rule has: email, role (owner/admin/editor/viewer/observer), areas[].
Returns the complete access configuration: owner, observerMode, rules[].
Ticker
Returns the full ticker config: visible, speed, separator, items[]. Each item has filters[], calculation, label, unitId, precision, color.
Returns the live computed values for all enabled ticker items. Each entry has: id, text, color.
SAO Protocol
Response
{
"active": true,
"scenario": "tailings_dam",
"tier": "recommended",
"matrices": ["agua", "solo", "ar"],
"parameterCounts": { "agua": { "essential": 15, "recommended": 28, "total": 45 } }
}
Returns all currently active parameters based on the selected scenario, tier, and matrices. When SAO is inactive, returns all CONFIG.PARAMETERS.
Governance
Returns the governance section of the model: contracts, WBS items, parties, disbursements, and EVA calculations. Returns null if no governance data exists.
Sensors
Fetches live data for a sensor-family element via its 3-stage pipeline (JSONPlaceholder, FakerAPI, OpenWeatherMap). Element must be of family sensor.
Timeout: 30 seconds (async operation)
Agents
Returns all agents (6 system + user-created). Each agent has: id, name, description, systemPromptAddition, system (boolean).
Response
{ "id": "default" }
Returns the agent object. System agents: default, regulatory-br, regulatory-us, regulatory-intl, campaign, hse.
Modals
Returns visible modal overlays with their ID, title, and structure info.
Returns detailed structure: header, body, footer presence, button audit, dimensions.
Closes all visible modals including SAO, stamp, and edge modals.
Panels
Returns panel visibility, docking state, and dimensions for left, right, and analytics panels.
Chat
Query Parameters
| Param | Default | Description |
|---|---|---|
last | all | Return only the last N messages |
Returns the conversation history from the AI assistant chat panel.
Notifications
Returns all currently visible toast notifications with their text, type (success, error, warning, info), and timestamp.
Tabs
Request Body
{ "tabId": "analysis" }
Switches the active ribbon tab. Common tab IDs: modeling, analysis, tools, view.
Export / Import
Returns the full model state as a JSON object.
Returns the model encoded as an ECBT key string. Timeout: 30 seconds.
Request Body
{ "model": { /* full model object */ } }
Request Body
{ "key": "ECBT.A0000001..." }
Screenshot
Query Parameters
| Param | Default | Description |
|---|---|---|
mode | full | full = entire page, 3d = canvas only |
Returns PNG image binary (Content-Type: image/png).
DOM & Eval
Query Parameters
| Param | Required | Description |
|---|---|---|
selector | Yes | CSS selector (e.g. .panel, #app) |
props | No | Comma-separated: style, box, html, classes |
Example
curl "localhost:4000/api/dom?selector=%23app&props=style,box"
Requires a local control session cookie plus X-ECBYTS-Control-Token. Bootstrap by opening http://localhost:4000/ and then calling GET /api/local-control/token.
Request Body
{
"expr": "document.title",
"timeout": 5000
}
Evaluates a JavaScript expression in the browser context. Default timeout: 30s. Use for testing and automation — wrap async imports in (async () => { ... })().
Sends a reload signal to the connected browser tab. The WebSocket bridge reconnects automatically after reload.
Security note: /api/dom, /api/eval, and /api/reload now require both the local control session cookie and X-ECBYTS-Control-Token.
Pipelines
Returns all registered pipelines with their ID, name, steps, and status.
Request Body
{
"id": "my-pipeline",
"name": "Data Quality Check",
"steps": [...]
}
Saves a pipeline definition. If id matches an existing pipeline, it is updated.
Parameters
| Param | Type | Description |
|---|---|---|
:id | string | Pipeline ID |
Parameters
| Param | Type | Description |
|---|---|---|
:id | string | Pipeline ID |
Parameters
| Param | Type | Description |
|---|---|---|
:id | string | Pipeline ID |
Executes the pipeline steps sequentially. Rate limited: returns 409 Conflict if the pipeline is already running. Timeout: 30s.
EcoTools
Query Parameters
| Param | Required | Description |
|---|---|---|
id | Yes | EcoTool identifier |
Response
{
"success": true,
"data": {
"id": "tool-123",
"name": "Soil Analysis",
"records": [...]
}
}
Aerial Recognition
Query Parameters
| Param | Default | Description |
|---|---|---|
ai | 0 | Set to 1 to include AI-powered analysis |
resolution | 512 | Image resolution for processing |
Runs diagnostic analysis on the aerial/satellite image. Timeout: 30s.
Query Parameters
| Param | Default | Description |
|---|---|---|
method | algorithm | algorithm, ml, or ai |
resolution | 512 | Image resolution for processing |
Request Body (optional)
{ "calibration": { ... } }
Runs aerial recognition and automatically imports detected features as elements. Timeout: 30s.
Query Parameters
| Param | Default | Description |
|---|---|---|
resolution | 512 | Image resolution for calibration |
Auto-calibrates recognition thresholds from the boundary image. Timeout: 30s.
Removes all elements that are not of the boundary family. Used to clean up after recognition runs.
Returns raw SegFormer model output for debugging purposes. Timeout: 30s.
LLM
Returns the current LLM provider, model, and connection status.
Request Body
{
"provider": "openai",
"apiKey": "sk-...",
"model": "gpt-4o"
}
All fields are optional. Only provided fields are updated.
Tests the LLM connection with the current configuration. Timeout: 30s.
Request Body
{
"filePath": "C:/path/to/file.pdf",
"pages": "1-5"
}
Response
{
"success": true,
"data": {
"tables": [...],
"meta": { "cache": "miss" }
}
}
Extracts tables from PDF via Python pdfplumber. Requires Python 3 with pip install pdfplumber. Results cached for 15 minutes. Timeout: 30s.
Security note: /api/llm, /api/llm/test, and /api/pdfplumber now require the same cookie + token pair.
Actions
Returns the ACTION_REGISTRY — array of all registered actions with name, params[], and cat (category).
Request Body
{
"action": "handleAddObservation",
"args": ["el_abc123"]
}
Executes any window.* function matching the handler pattern. The args array is spread as function arguments.
Request Body
{
"actions": [
{ "action": "handleAddElement", "args": ["well"] },
{ "action": "handleAddElement", "args": ["plume"] }
],
"stopOnError": true
}
WebSocket Protocol
The API uses WebSocket for real-time communication between the Node.js server and the browser tab.
Connection
# Connect from localhost only
ws://localhost:4000/ws
Message Types
| Type | Direction | Description |
|---|---|---|
ready | Browser → Server | Browser connected, sends list of available actions |
command | Server → Browser | Execute command (with requestId) |
response | Browser → Server | Command result (with matching requestId) |
reload | Server → Browser | Force page reload |
Timeouts
- Standard API calls: 10 seconds
- Async operations (LLM, sensor, import): 30 seconds
- Heartbeat: 30 seconds ping interval
- Reconnect: Up to 50 attempts, 2 second delay
Actions Reference
All — registered actions available via POST /api/action. Loaded live from the server.
Loading actions from server...
Examples
Create a monitoring well and add an observation
# 1. Create a well
curl -X POST http://localhost:4000/api/elements \
-H "Content-Type: application/json" \
-d '{"familyId":"well"}'
# 2. Add observation to the well (use element ID from step 1)
curl -X POST http://localhost:4000/api/action \
-H "Content-Type: application/json" \
-d '{"action":"handleAddObservation","args":["el_abc123"]}'
# 3. Set the observation parameter to pH
curl -X POST http://localhost:4000/api/action \
-H "Content-Type: application/json" \
-d '{"action":"handleObservationParameterChange","args":["el_abc123",0,"ph"]}'
Generate random model and export
# Generate random model with all element types
curl -X POST http://localhost:4000/api/action \
-H "Content-Type: application/json" \
-d '{"action":"generateRandomModel"}'
# Export as JSON
curl http://localhost:4000/api/export/json -o model.json
# Export as ECO key
curl http://localhost:4000/api/export/key
Query module states
# Check auth status
curl http://localhost:4000/api/auth/status
# Get groups configuration
curl http://localhost:4000/api/groups
# Get ticker computed values
curl http://localhost:4000/api/ticker/values
# Get SAO protocol status
curl http://localhost:4000/api/sao
# List all LLM agents
curl http://localhost:4000/api/agents
Batch actions
curl -X POST http://localhost:4000/api/action/batch \
-H "Content-Type: application/json" \
-d '{
"actions": [
{"action": "handleAddElement", "args": ["well"]},
{"action": "handleAddElement", "args": ["well"]},
{"action": "handleAddElement", "args": ["plume"]},
{"action": "handleAddCampaign"}
],
"stopOnError": true
}'
Error Codes
| Status | Meaning | Common Causes |
|---|---|---|
200 | Success | Request completed. Check success field in response. |
400 | Bad Request | Missing required field (e.g. familyId, action) |
404 | Not Found | Unknown endpoint or element/resource ID not found |
405 | Method Not Allowed | Wrong HTTP method for endpoint (e.g. DELETE on GET-only route) |
413 | Payload Too Large | Request body exceeds 5 MB limit |
500 | Server Error | Internal error in server or browser command execution |
503 | Service Unavailable | Browser not connected to WebSocket |
504 | Gateway Timeout | Browser command did not respond within timeout (10s / 30s) |
Error Response Format
{
"success": false,
"error": "Browser not connected"
}