API Reference
API Reference
All PLC-scoped endpoints use the prefix /api/plcs/{plcId}/ where plcId is the configured alias (e.g., Line1, MyPLC).
Response Envelope
Every response uses a standard envelope:
// Success
{ "data": { ... }, "error": null }
// Error
{ "data": null, "error": { "code": "ADS_TIMEOUT", "message": "..." } }Error Codes
| Code | HTTP Status | Description |
|---|---|---|
SYMBOL_NOT_FOUND | 404 | PLC symbol does not exist |
PLC_NOT_FOUND | 404 | PLC alias not configured |
PLC_UNAVAILABLE | 503 | PLC is not connected |
ADS_TIMEOUT | 504 | ADS operation timed out |
ADS_ERROR | 502 | Generic ADS protocol error |
TYPE_MISMATCH | 400 | Value type doesn’t match symbol type |
BATCH_LIMIT_EXCEEDED | 400 | Batch request exceeds 100 symbols |
SUBSCRIPTION_LIMIT_EXCEEDED | 400 | Exceeded max symbols per client |
RATE_LIMITED | 429 | Lifecycle rate limit hit |
FEATURE_DISABLED | 404 | Feature slice is disabled |
UNAUTHORIZED | 401 | Missing or invalid JWT |
FORBIDDEN | 403 | Insufficient role or scope |
PLC_ACCESS_DENIED | 403 | plc_access claim denies this PLC |
MASTER_NOT_FOUND | 404 | EtherCAT master ID not found |
SLAVE_NOT_FOUND | 404 | EtherCAT slave address not found |
Symbol Path Format
TwinCAT dot notation: MAIN.nCounter, MAIN.stMotor.bEnabled, GVL.arr[0]
Array indices with brackets must be URL-encoded in path segments: MAIN.arr%5B0%5D
System Endpoints
GET /api/plcs List all PLCs + connection status
GET /api/plcs/{plcId}/status Detailed status for one PLC
GET /health/live Liveness probe
GET /health/ready Readiness probe (PLC connectivity)
GET /openapi/v1.json OpenAPI spec
GET /swagger Scalar API UI (Development only)