Skip to main content
Version: 1.0.4

REST Endpoints

A pipeline can publish an HTTP endpoint. An ERP posts an order, an MES asks for line status, a label printer requests the next job — each arrives as a message that runs your graph and returns whatever you build.

Published routes are served by the RestGateway on port 8090.

Building one

REST API (ingress) → Python (validate) → MongoDB (insert) → HTTP Response
  1. REST API node in ingress mode defines the method and URL pattern.
  2. Middle nodes do the work.
  3. HTTP Response sends the reply. Every ingress path must reach one, or the caller waits for the timeout.

Route configuration

SettingDefaultPurpose
MethodGETGET, POST, PUT, DELETE, PATCH, or * for any.
URL pattern/api/v1/exampleSupports parameters: /api/v1/orders/:id.
Timeout30 sHow long the caller waits before the gateway gives up.
Auth typeapi_keyapi_key or none.
Required scopes(none)Capability scopes the caller's key must hold, e.g. tag:write,db:read.
Allowed IPs(any)Comma-separated CIDR allow-list.
Rate limit0 (off)Requests per second.
Burst limit0Burst size above the sustained rate.
Max payload size1 MBRequest body cap.
CORS enabledfalseAllow browser cross-origin calls.
Allowed origins*Origins permitted when CORS is on.
Header whitelist(none)Request headers passed through to the pipeline.

Fail-closed by default

A route persisted without an explicit auth type requires an API key. A route is public only when its author deliberately sets auth to none.

This is the correct default for an industrial system: a route that silently defaulted to public would be a data leak created by omission.

API keys

Keys are project-scoped credentials created in settings.

Keys are managed in Settings → API keys, which requires Access settings.

  • The key value is shown once, at creation. Only a hash is stored.
  • Revocation is immediate.
  • Give each consumer its own key, so one can be revoked without disrupting the others.

API keys

Scopes

A key carries capability scopes; a route can require some. A key without a required scope is rejected even though it is otherwise valid.

Key "mes-integration" scopes: db:read, tag:read
Route POST /api/v1/setpoint requires: tag:write → rejected
Route GET /api/v1/status requires: tag:read → allowed

Scopes let one key serve several routes at a bounded level of privilege.

Defence in depth

Layer the controls; each is cheap and independent.

ControlStops
API keyUnauthenticated callers
ScopesAn authenticated caller doing more than it should
IP allow-listCalls from outside the expected network
Rate limit + burstRunaway clients and brute-force attempts
Max payload sizeMemory-exhaustion attempts
CORS offBrowser-based cross-origin abuse

An integration endpoint for a known MES should have: an API key, the narrowest scopes, the MES's CIDR, a rate limit slightly above its real traffic, and CORS off.

Calling an endpoint

curl -X POST https://qubiq.example.com:8090/api/v1/orders \
-H "X-API-Key: <key>" \
-H "Content-Type: application/json" \
-d '{"orderId":"SO-1042","line":"L1","qty":500}'

Reading request data

The request arrives as the message payload — body, path parameters, query string and whitelisted headers.

def transform(payload, message):
order = payload.get("body", {})
if not order.get("orderId"):
return {"status": 400, "body": {"error": "orderId is required"}}

system.db.runNamedQuery("insert_order", {
"id": order["orderId"],
"line": order.get("line"),
"qty": order.get("qty", 0),
})
return {"status": 201, "body": {"accepted": order["orderId"]}}

Only whitelisted headers are passed through — an explicit choice, so that authorization headers and cookies are not handed to pipeline code by accident.

Outbound calls (egress)

The same node in egress mode calls out: post an alarm to a webhook, fetch a work order, push a report to an external API.

SettingPurpose
URL, methodThe target
Static headersAdded to every request (e.g. an authorization header)
TimeoutGive up after this long

Egress calls made from a pipeline are covered by store-and-forward, so a webhook that is briefly down does not lose the event.

Operational notes

  • Port 8090 must be reachable by the caller; it is separate from the UI port.
  • The pipeline must be running. A stopped pipeline's routes return an error.
  • Version your URLs (/api/v1/...). Changing a pipeline's response shape breaks callers exactly as changing any API does.
  • Return meaningful status codes from the HTTP Response node. A 200 carrying an error message is hostile to whoever integrates with you at 03:00.

Troubleshooting

SymptomCheck
404Pipeline stopped, or the URL pattern does not match (leading slash, trailing slash, method).
401 / 403Missing or revoked API key; missing required scope; source IP outside the allow-list.
413Body exceeds max payload size.
429Rate limit hit — raise it or fix the client.
TimeoutNo HTTP Response node was reached on that path.
CORS error in a browserCORS disabled, or the origin is not in the allowed list.

Next

Designer