REST API Integration
MaestroHub exposes a REST API that covers the full platform — pipelines, models, connectors, UNS topics, dashboards, organizations, and user management. This guide walks through authentication, available API areas, a complete end-to-end example, and common error scenarios.
Prerequisites
Before you start, make sure you have:
- A running MaestroHub instance.
- One of the following credentials:
- An OAuth2 Client registered in System Management > API Clients — the recommended approach for any real integration. See OAuth2 Clients for setup instructions.
- A Personal Access Token (PAT) — quick to create from your profile, useful for exploration and quick tests. See Personal Access Tokens.
- Your Organization ID. See Organization Context to find it.
- A tool for making HTTP requests —
curl, an API client, or your application's HTTP library.
Interactive API Reference
MaestroHub ships with a built-in interactive API reference at:
http://<your-host>:<port>/swagger/index.html
From this page you can browse every available endpoint, inspect request and response schemas, and execute live requests directly against your instance. The reference supports two authentication methods:
- OAuth2 — Authorization Code — Sign in as a user via browser. Supports PKCE for public clients.
- OAuth2 — Client Credentials — Authenticate as a service using client ID and secret.
Click the Authorize button in the top right, enter your credentials and select the scopes you need. Once authorized, all requests made from the reference page will include your access token automatically.
Authentication
The API accepts two categories of credentials:
- OAuth2 grant types (recommended) — the best practice for any production or long-lived integration. You register a dedicated client for the integration, pick the grant type that matches your use case, and benefit from scoped, rotatable, per-integration credentials.
- Personal Access Tokens (PAT) — a single long-lived bearer token tied to your user account. Not recommended as a best practice, but a convenient shortcut when you are exploring the API, running quick tests, or prototyping a script.
Start with one of the OAuth2 grant types below. If you just need to send a couple of requests and move on, jump to Personal Access Token.
Authorization Code
For applications where a user is present — web apps, SPAs, or any scenario where the user logs in through a browser. The application redirects the user to MaestroHub, the user approves the requested scopes, and the application receives an access token. Public clients (browser apps) use PKCE instead of a client secret.
When configuring your OAuth2 library or application, you will need the following values:
| Parameter | Value |
|---|---|
| Authorization URL | http://<your-host>:<port>/api/v1/oauth2/authorize |
| Token URL | http://<your-host>:<port>/api/v1/oauth2/token |
| Client ID | Shown when you register the client in System Management > API Clients |
| Client Secret | Shown once at client creation (confidential clients only — public clients use PKCE instead) |
| Redirect URI | Your application's callback URL — must match exactly what you registered on the client |
You can also retrieve these endpoints automatically via the OpenID Connect discovery document at /.well-known/openid-configuration.
For a step-by-step example with screenshots, see OAuth2 Flows — Authorization Code.
Client Credentials
For machine-to-machine integrations — background services, scheduled jobs, ERP syncs — where no user interaction is required. The application authenticates directly with its client ID and secret — no browser or user interaction needed.
When configuring your integration, you will need:
| Parameter | Value |
|---|---|
| Token URL | http://<your-host>:<port>/api/v1/oauth2/token |
| Client ID | Shown when you register the client in System Management > API Clients |
| Client Secret | Shown once at client creation — copy and store it securely |
| Grant Type | client_credentials |
The client secret is displayed only once when the client is created. If you lose it, you must delete the client and create a new one.
For a step-by-step example with screenshots, see OAuth2 Flows — Client Credentials.
Example — obtain a token with Client Credentials:
curl -X POST http://<your-host>:<port>/api/v1/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "scope=uns:read uns:write uns:publish pipelines:read connectors:read"
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "bearer",
"expires_in": 3600,
"scope": "uns:read uns:write uns:publish pipelines:read connectors:read"
}
Use the access token in all subsequent requests:
Authorization: Bearer <access_token>
X-Organization-ID: <your-organization-id>
For a detailed walkthrough of registering clients and choosing grant types, see the API Authentication documentation.
Personal Access Token
A Personal Access Token (PAT) is a long-lived bearer token you create from your own profile and use directly as the access token — no client registration, no grant flow, no token exchange. You create it once, copy the value, and include it in the Authorization header exactly like an OAuth2 access token.
PATs are tied to an individual user account and inherit that user's access. If the user's role changes or the account is deactivated, every integration using that PAT is affected. For anything beyond quick tests — production workloads, services, scheduled jobs, third-party apps — register a dedicated OAuth2 client and pick the grant type that matches the use case. That gives you scoped, per-integration credentials you can rotate or revoke independently of any user.
PATs are a good fit when you want to:
- Try a few API calls from
curlor an HTTP client without setting up an OAuth2 flow. - Prototype a script or explore endpoints before committing to an integration design.
- Run a one-off import, export, or data-publish task.
Creating a PAT: Open your profile's Security tab, click Create Token, give it a name, pick an expiration, and select the scopes you need. The token value is shown only once — copy it immediately. Full step-by-step instructions with screenshots are in Personal Access Tokens — Creating a Token.
Using a PAT: Send it in the Authorization header, together with the X-Organization-ID header:
curl -H "Authorization: Bearer <your-pat>" \
-H "X-Organization-ID: <your-organization-id>" \
http://<your-host>:<port>/api/v1/engine/pipelines
API Areas
The REST API is organized into the following areas. All endpoints are prefixed with /api/v1.
Pipelines & Models
| Group | Base Path | Description |
|---|---|---|
| Pipelines | /engine/pipelines | Create, update, delete, clone, enable/disable pipelines. Manage nodes and edges. Version history with revert support. |
| Models | /engine/models | Create and manage data models with typed fields. Version history with revert support. |
| Nodes | /engine/nodes, /engine/pipelines/{id}/nodes | Add, update, remove, rename, and test individual pipeline nodes. Get available node types. |
| Executions | /engine/executions | List and inspect pipeline execution results. View node-level inputs, outputs, and loop iterations. Retry failed executions. |
Connectors
| Group | Base Path | Description |
|---|---|---|
| Connections | /connections | Create, update, delete, and clone connections. List supported protocols. |
| Functions | /connections/{id}/functions | Create and manage connector functions within a connection. |
| Runtime | /connections/{id}/start, stop, restart | Start, stop, restart connections. Execute functions. Get runtime status and metrics. |
| State History | /connections/state-history | Query connection state change history and health summaries. |
Unified Namespace (UNS)
| Group | Base Path | Description |
|---|---|---|
| Topics | /uns/topics | Create, list, search, and delete topics. Manage schemas and configuration. |
| Data | /uns/data | Publish data to topics and query recent or time-range records. |
| Dashboards | /uns/dashboards | Create, update, and manage dashboards, panels, and folders. |
| Broker | /uns/broker | Check MQTT broker status. |
| Settings | /system/uns/settings | Configure storage backend and broker settings (admin only). |
Organizations & Users
| Group | Base Path | Description |
|---|---|---|
| Organizations | /organizations | Create, update, suspend, and activate organizations. Manage logos. |
| Settings | /organizations/settings | Organization settings, maintenance mode, and change history. |
| Users | /admin/users | Create, update, delete, and restore users. Manage user status. |
| OAuth2 Clients | /oauth2/clients | Register and manage OAuth2 client applications. |
| Personal Access Tokens | /oauth2/tokens | Create, list, and revoke personal access tokens. |
Dependencies & Export
| Group | Base Path | Description |
|---|---|---|
| Dependency Graph | /dependencies/graph | Visualize entity relationships. Query dependents, dependencies, and impact analysis. |
| Export | /dependencies/export | Analyze, generate, and download configuration exports. |
| Import | /dependencies/import | Validate and execute configuration imports. |
Example: Publishing Data to a UNS Topic
This section demonstrates a complete workflow — publishing data to a topic and querying it back. The publish endpoint automatically creates the topic and any parent nodes in the hierarchy if they don't already exist.
Send a value to a topic using the data/publish endpoint. If the topic doesn't exist yet, it will be created automatically along with any parent nodes in the hierarchy.
curl -X POST http://<your-host>:<port>/api/v1/uns/data/publish \
-H "Authorization: Bearer $TOKEN" \
-H "X-Organization-ID: $ORG_ID" \
-H "Content-Type: application/json" \
-d '{
"topic": "mHv1.0/factory/line-1/temperature",
"source": "plc-01",
"value": 72.5
}'
Request body fields:
| Field | Required | Type | Description |
|---|---|---|---|
topic | Yes | string | Full topic path including version prefix. |
value | Yes | any | The data value — can be a number, string, boolean, or a JSON object. |
source | No | string | Identifier for the data source (e.g., plc-01, mqtt-bridge). |
Response (200 OK):
{
"data": {
"message": "Data published successfully"
}
}
The value field accepts any JSON type. For complex sensor payloads, pass an object:
{
"topic": "mHv1.0/factory/line-1/motor",
"source": "plc-01",
"value": {
"temperature": 72.5,
"rpm": 1450,
"status": "running"
}
}
Scopes
Each API operation requires specific scopes. If your token does not include the required scope, the request will be rejected with a 403 Forbidden error. For the full list of available scopes, see Available Scopes.
Error Handling
The API uses standard HTTP status codes. Below are the errors you are most likely to encounter.
401 Unauthorized — Missing or Invalid Token
The request has no Authorization header, the token is expired, or the token signature is invalid.
{
"message": "missing or invalid token"
}
Fix: Obtain a new access token from the token endpoint and include it in the Authorization header.
403 Forbidden — Insufficient Scope
The token is valid but does not include the scope required for this operation. For example, attempting to publish data with a token that only has uns:read.
{
"error": "insufficient_scope",
"message": "Token does not have the required scope for this action"
}
Fix: Request a new token with the correct scopes, or update the OAuth2 client's allowed scopes in System Settings.
400 Bad Request — Validation Error
The request body is malformed or a required field is missing.
{
"error": "bad_request",
"message": "Topic is required"
}
Common causes:
- Missing a required field in the request body.
- Topic name without the version prefix (e.g.,
factory/line-1instead ofmHv1.0/factory/line-1). - Invalid JSON in the request body.
404 Not Found — Resource Does Not Exist
The requested topic, pipeline, connection, or other resource was not found.
{
"error": "not_found",
"message": "Topic not found"
}
422 Missing Organization Header
The X-Organization-ID header is missing or contains an invalid value.
{
"error": "missing_organization",
"message": "Personal Access Token requests require the X-Organization-ID header"
}
Fix: Include the X-Organization-ID header in every request. See Organization Context to find your ID.