Skip to main content
Version: 1.0.0

REST Endpoints

Complete reference for the TwinEdge REST API. All endpoints are prefixed with https://api.twinedgeai.com/v1.

Base URL

https://api.twinedgeai.com/v1

Common Headers

All requests should include:

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Accept: application/json

Response Format

All responses follow this structure:

Success:

{
"data": { ... },
"meta": {
"page": 1,
"per_page": 20,
"total": 100
}
}

Error:

{
"error": {
"code": "validation_error",
"message": "Invalid input",
"details": [
{"field": "name", "message": "Name is required"}
]
}
}

Data Sources

List Data Sources

GET /data-sources

Query Parameters:

ParameterTypeDescription
typestringFilter by type (opcua, modbus, mqtt)
statusstringFilter by status (connected, disconnected)
pageintegerPage number (default: 1)
per_pageintegerItems per page (default: 20, max: 100)

Response:

{
"data": [
{
"id": "ds-123",
"name": "Factory OPC UA Server",
"type": "opcua",
"endpoint": "opc.tcp://192.168.1.100:4840",
"status": "connected",
"tag_count": 45,
"created_at": "2026-01-01T00:00:00Z"
}
]
}

Create Data Source

POST /data-sources

Request Body:

{
"name": "Production Line PLC",
"type": "modbus",
"config": {
"host": "192.168.1.50",
"port": 502,
"unit_id": 1
}
}

Get Data Source

GET /data-sources/{id}

Update Data Source

PUT /data-sources/{id}

Delete Data Source

DELETE /data-sources/{id}

Test Connection

POST /data-sources/{id}/test

Telemetry

Query Telemetry

GET /telemetry

Query Parameters:

ParameterTypeDescription
data_source_idstringFilter by data source
asset_idstringFilter by asset
tag_namestringFilter by tag
startISO8601Start time
endISO8601End time
aggregationstringavg, min, max, sum, count
intervalstring1m, 5m, 1h, 1d

Response:

{
"data": [
{
"timestamp": "2026-01-06T10:00:00Z",
"asset_id": "Pump_001",
"tag_name": "temperature",
"value": 65.5,
"quality": "good"
}
]
}

Ingest Telemetry

POST /telemetry

Request Body:

{
"data": [
{
"asset_id": "Pump_001",
"tag_name": "temperature",
"value": 65.5,
"timestamp": "2026-01-06T10:00:00Z"
}
]
}

Get Latest Values

GET /telemetry/latest

Query Parameters:

ParameterTypeDescription
asset_idstringRequired - Asset ID
tagsstringComma-separated tag names

Dashboards

List Dashboards

GET /dashboards

Create Dashboard

POST /dashboards

Request Body:

{
"name": "Pump Monitoring",
"description": "Real-time pump health dashboard",
"layout": {
"columns": 24,
"widgets": [...]
}
}

Get Dashboard

GET /dashboards/{id}

Update Dashboard

PUT /dashboards/{id}

Delete Dashboard

DELETE /dashboards/{id}

Duplicate Dashboard

POST /dashboards/{id}/duplicate

Alerts

List Alert Rules

GET /alert-rules

Create Alert Rule

POST /alert-rules

Request Body:

{
"name": "High Temperature",
"severity": "warning",
"data_source_id": "ds-123",
"condition": {
"tag_name": "temperature",
"operator": "gt",
"value": 80,
"duration_seconds": 60
},
"notifications": ["email", "slack"]
}

Get Alert Rule

GET /alert-rules/{id}

Update Alert Rule

PUT /alert-rules/{id}

Delete Alert Rule

DELETE /alert-rules/{id}

Enable/Disable Alert Rule

POST /alert-rules/{id}/enable
POST /alert-rules/{id}/disable

List Active Alerts

GET /alerts

Query Parameters:

ParameterTypeDescription
statusstringactive, acknowledged, resolved
severitystringcritical, warning, info
startISO8601Start time
endISO8601End time

Acknowledge Alert

POST /alerts/{id}/acknowledge

Request Body:

{
"note": "Investigating the issue"
}

Resolve Alert

POST /alerts/{id}/resolve

ML Models

List Datasets

GET /ml/datasets

Create Dataset

POST /ml/datasets

Upload Dataset File

POST /ml/datasets/{id}/upload
Content-Type: multipart/form-data

Get Dataset Preview

GET /ml/datasets/{id}/preview

List Training Jobs

GET /ml/training

Start Training Job

POST /ml/training

Request Body:

{
"name": "Pump Anomaly Detector",
"dataset_id": "ds-456",
"algorithm": "isolation_forest",
"hyperparameters": {
"n_estimators": 100,
"contamination": 0.05
}
}

Get Training Job Status

GET /ml/training/{id}

Cancel Training Job

DELETE /ml/training/{id}

List Models

GET /ml/models

Get Model

GET /ml/models/{id}

Test Model

POST /ml/models/{id}/test

Request Body:

{
"features": {
"vibration_x": 2.5,
"vibration_y": 2.1,
"temperature": 65.0
}
}

Deploy Model

POST /ml/models/{id}/deploy

Undeploy Model

POST /ml/models/{id}/undeploy

Download Model

GET /ml/models/{id}/download

Fleet Management

List Devices

GET /fleet/devices

Query Parameters:

ParameterTypeDescription
statusstringonline, offline, unknown
group_idstringFilter by group
tagsstringFilter by tags (comma-separated)

Register Device

POST /fleet/devices

Get Device

GET /fleet/devices/{id}

Update Device

PUT /fleet/devices/{id}

Delete Device

DELETE /fleet/devices/{id}

Get Device Health

GET /fleet/devices/{id}/health

Send Command to Device

POST /fleet/devices/{id}/command

Request Body:

{
"command": "restart",
"params": {}
}

List Device Groups

GET /fleet/groups

Create Device Group

POST /fleet/groups

Generate Enrollment Token

POST /fleet/enrollment/token

OTA Updates

List Packages

GET /ota/packages

Upload Package

POST /ota/packages
Content-Type: multipart/form-data

Get Package

GET /ota/packages/{id}

Release Package

POST /ota/packages/{id}/release

List Deployments

GET /ota/deployments

Create Deployment

POST /ota/deployments

Request Body:

{
"name": "Production Update v2.1.0",
"package_id": "pkg-123",
"targets": {
"type": "group",
"group_id": "production"
},
"strategy": "phased",
"rollback_enabled": true
}

Get Deployment Status

GET /ota/deployments/{id}

Cancel Deployment

POST /ota/deployments/{id}/cancel

Initiate Rollback

POST /ota/deployments/{id}/rollback

Organizations

Get Organization

GET /organizations/current

Update Organization

PUT /organizations/current

List Members

GET /organizations/current/members

Invite Member

POST /organizations/current/members/invite

Remove Member

DELETE /organizations/current/members/{id}

Users

Get Current User

GET /users/me

Update Current User

PUT /users/me

Change Password

POST /users/me/password

Health & Status

API Health Check

GET /health

Response:

{
"status": "healthy",
"version": "1.2.3",
"timestamp": "2026-01-06T10:00:00Z"
}

Get API Status

GET /status

Error Codes

CodeHTTP StatusDescription
validation_error400Invalid request body
authentication_error401Invalid or missing token
authorization_error403Insufficient permissions
not_found404Resource not found
conflict409Resource conflict
rate_limited429Too many requests
internal_error500Server error

Business Intelligence (BI)

Get BI Configuration

GET /bi/config

Response:

{
"superset_enabled": true,
"sql_lab_enabled": true,
"chart_builder_enabled": true,
"max_concurrent_queries": 5,
"query_timeout_seconds": 300,
"row_limit": 10000
}

Update BI Configuration

PUT /bi/config

Get Superset Dashboards

GET /superset/dashboards

Get Superset Guest Token

POST /superset/guest-token

Request Body:

{
"dashboard_id": 1,
"resources": [
{
"type": "dashboard",
"id": "1"
}
]
}

Get Embed URL

GET /superset/embed/{dashboard_id}

Execute Query (SQL Lab)

POST /bi/query/execute

Request Body:

{
"sql": "SELECT * FROM telemetry WHERE timestamp > NOW() - INTERVAL '1 day'",
"database": "telemetry",
"limit": 1000
}

Response:

{
"columns": ["timestamp", "asset_id", "value"],
"rows": [...],
"row_count": 150,
"execution_time_ms": 245
}

Save Query

POST /bi/query/save

Request Body:

{
"name": "Daily Temperature Summary",
"sql": "SELECT asset_id, AVG(value) FROM telemetry GROUP BY asset_id",
"database": "telemetry",
"description": "Aggregates daily temperature readings"
}

List Saved Queries

GET /bi/query/saved

Get Query History

GET /bi/query/history

List Scheduled Reports

GET /bi/reports

Create Scheduled Report

POST /bi/reports

Request Body:

{
"name": "Weekly Production Report",
"dashboard_id": 1,
"schedule": "0 9 * * 1",
"format": "pdf",
"recipients": ["team@company.com"],
"enabled": true
}

Run Report Manually

POST /bi/reports/{id}/run

RLS Rules

GET /bi/rls/rules
POST /bi/rls/rules
PUT /bi/rls/rules/{id}
DELETE /bi/rls/rules/{id}
POST /bi/rls/test

Products & Licensing

List Products

GET /products

Response:

{
"data": [
{
"id": "prod-123",
"name": "TwinEdge Pro",
"sku": "TE-PRO-001",
"description": "Professional edge device",
"price": 299.00,
"license_type": "perpetual",
"features": ["mqtt", "opcua", "modbus"]
}
]
}

Create Product

POST /products

Get Product

GET /products/{id}

Update Product

PUT /products/{id}

Delete Product

DELETE /products/{id}

List Licenses

GET /licenses

Response:

{
"data": [
{
"id": "lic-456",
"license_key": "XXXX-XXXX-XXXX-XXXX",
"product_id": "prod-123",
"status": "active",
"max_activations": 3,
"current_activations": 1,
"expires_at": "2027-01-06T00:00:00Z"
}
]
}

Create License

POST /licenses

Request Body:

{
"product_id": "prod-123",
"license_type": "subscription",
"max_activations": 5,
"validity_days": 365,
"customer_email": "customer@company.com"
}

Activate License

POST /licenses/activate

Request Body:

{
"license_key": "XXXX-XXXX-XXXX-XXXX",
"device_id": "device-001",
"hardware_fingerprint": "abc123def456"
}

Response:

{
"activation_id": "act-789",
"license_id": "lic-456",
"activated_at": "2026-01-06T10:00:00Z",
"expires_at": "2027-01-06T00:00:00Z",
"features": ["mqtt", "opcua", "modbus"]
}

Validate License

POST /licenses/validate

Request Body:

{
"license_key": "XXXX-XXXX-XXXX-XXXX"
}

Deactivate License

POST /licenses/{id}/deactivate

Request Body:

{
"activation_id": "act-789"
}

ML Data Labeling

Get Label Classes

GET /ml/datasets/{id}/label-classes

Response:

{
"classes": [
{
"id": "class-1",
"name": "Normal",
"color": "#00E5BF",
"count": 450
},
{
"id": "class-2",
"name": "Anomaly",
"color": "#EF4444",
"count": 50
}
]
}

Create Label Class

POST /ml/datasets/{id}/label-classes

Request Body:

{
"name": "Critical Failure",
"color": "#DC2626",
"description": "Imminent equipment failure"
}

Label Data Row

POST /ml/datasets/{dataset_id}/rows/{row_id}/label

Request Body:

{
"label_class_id": "class-2"
}

Skip Data Row

POST /ml/datasets/{dataset_id}/rows/{row_id}/skip

Flag Data Row

POST /ml/datasets/{dataset_id}/rows/{row_id}/flag

Request Body:

{
"flagged": true
}

Undo Label

DELETE /ml/datasets/{dataset_id}/rows/{row_id}/label

Import Labels

POST /ml/datasets/{id}/labels/import
Content-Type: multipart/form-data

Export Labels

GET /ml/datasets/{id}/labels/export?format=csv
GET /ml/datasets/{id}/labels/export?format=json

Dataset Versioning

List Dataset Versions

GET /ml/datasets/{id}/versions

Response:

{
"versions": [
{
"version": "1.0",
"created_at": "2026-01-01T00:00:00Z",
"created_by": "user@company.com",
"row_count": 1000,
"file_size_bytes": 256000,
"notes": "Initial dataset"
},
{
"version": "1.1",
"created_at": "2026-01-05T00:00:00Z",
"created_by": "user@company.com",
"row_count": 1200,
"file_size_bytes": 307200,
"notes": "Added labeled anomalies"
}
]
}

Create Version

POST /ml/datasets/{id}/versions
Content-Type: multipart/form-data

Get Version

GET /ml/datasets/{dataset_id}/versions/{version}

Compare Versions

GET /ml/datasets/{id}/versions/compare?v1=1.0&v2=1.1

Rollback to Version

POST /ml/datasets/{id}/versions/{version}/rollback

Data Validation

Get Validation Rules

GET /ml/datasets/{id}/validation-rules

Create Validation Rule

POST /ml/datasets/{id}/validation-rules

Request Body:

{
"name": "Temperature Range",
"rule_type": "range",
"column": "temperature",
"config": {
"min": -40,
"max": 150
}
}

Run Validation

POST /ml/datasets/{id}/validate

Response:

{
"valid": false,
"issues": [
{
"rule_id": "rule-1",
"rule_name": "Temperature Range",
"violations": 15,
"rows": [102, 156, 203, ...]
}
],
"quality_score": 0.85,
"grade": "B"
}

Get Data Quality Report

GET /ml/datasets/{id}/quality

API Keys Management

List API Keys

GET /api-keys

Create API Key

POST /api-keys

Request Body:

{
"name": "Production Integration",
"scopes": ["read:telemetry", "write:telemetry"],
"expires_at": "2027-01-06T00:00:00Z"
}

Response:

{
"id": "key-123",
"name": "Production Integration",
"key": "te_live_xxxxxxxxxxxxxx",
"scopes": ["read:telemetry", "write:telemetry"],
"created_at": "2026-01-06T00:00:00Z",
"expires_at": "2027-01-06T00:00:00Z"
}
caution

The API key is only shown once when created. Store it securely.

Revoke API Key

DELETE /api-keys/{id}

Rotate API Key

POST /api-keys/{id}/rotate

Get API Key Usage

GET /api-keys/{id}/usage

Audit Logs

List Audit Logs

GET /audit/logs

Query Parameters:

ParameterTypeDescription
start_timeISO8601Start of time range
end_timeISO8601End of time range
categoriesstringComma-separated categories
event_typesstringComma-separated event types
severitiesstringinfo, warning, critical
user_idstringFilter by user
resource_typestringFilter by resource type
searchstringFull-text search

Get Audit Log

GET /audit/logs/{id}

Get Audit Summary

GET /audit/summary

Export Audit Logs

POST /audit/export

Request Body:

{
"start_time": "2026-01-01T00:00:00Z",
"end_time": "2026-01-31T23:59:59Z",
"format": "csv"
}

Next Steps