π What Is an API Connection?
If you've got data that doesn't fit OPC UA, SQL, or MQTT β a custom Python script, a vision system, a LabVIEW VI, a bespoke test rig, a Node-RED flow combining several sources β the API Connection is the path. Your system makes an HTTP POST to Next Plus with the values you want recorded, and they land on the right Production Entity in real time.
This article is for the developer or integrator who'll be writing the push code. For the operator-side overview, start with Production Entity Connections instead.
π When Does API Fit?
API is the right choice when:
Your data source is custom β a script, vision system, in-house service, test fixture
There's no off-the-shelf protocol that fits
You need to bridge a non-supported protocol via a small adapter
You want full control over when and what to send β timestamps, batching, retries β and you're comfortable owning that code
For standard PLCs, prefer OPC UA. For databases, SQL. For existing MQTT brokers, MQTT. The API is for the "none of the above" case.
π How API Connections Work
The API server is already there. Every Next Plus tenant has exactly one, auto-provisioned. There's no "create a new API server" β you just push to the tenant URL.
You declare your parameters (recommended) or let them auto-create on first push. Each parameter has a stable
key, a display name, a type, a precision (for numbers), and a retention period.Your system POSTs values to
/api/ApiServers/pushwith an access token. Single value, batched array, or wrapped object β all three shapes work.The values land on the bound PEs. Next Plus persists each value, broadcasts across worker processes, and feeds dashboards, triggers, OEE, and historical reports.
Unlike OPC UA / SQL / MQTT (where Next Plus reaches out to a server you provide), with the API your system is the initiator. Next Plus is purely a receiver. That means latency is whatever your push cadence is β push every second and values arrive every second; push once an hour and that's what you get.
π Security
Push-only, always. The API endpoint accepts values; it doesn't expose anything else from Next Plus. There's also a complementary read endpoint to confirm the last value of a parameter β useful for verification.
HTTPS β all traffic to the tenant URL is encrypted in transit
Access token β every request needs a Next Plus access token, either as
?access_token=...or as anAuthorizationheaderEditor role or higher required to push or manage parameters. Operator role can read. Viewer cannot.
Dedicated integration user recommended β create a Next Plus user just for this integration, give it the editor role, generate its token, store it in your secret manager. Don't share the token across multiple integrations.
π€ The Push Endpoint
Endpoint:
POST https://<tenant>.nextplus.io/api/ApiServers/push Content-Type: application/json
Authentication: either as a query parameter (?access_token=<TOKEN>) or as an Authorization: <TOKEN> header.
Three equivalent request body shapes:
Array of items (recommended for batches):
json
[ { "key": "temperature", "value": 23.5 }, { "key": "door_open", "value": false, "timestamp": "2026-05-19T08:14:02.000Z" } ]Wrapped object:
json
{ "parameters": [ { "key": "temperature", "value": 23.5 }, { "key": "cycle_count", "value": 1284 } ] }Single item:
json
{ "key": "temperature", "value": 23.5 }Per-item fields:
Field | Required | Description |
| Yes (or | Stable string identifier (e.g. |
| Yes (or | Internal UUID. Use when key may change. |
| Yes | New value. Must match the declared type. |
| No | Sample time (ISO-8601 or epoch ms). Defaults to server time. |
Success response:
json
{ "success": true, "processed": 2 }π§ Parameter Definitions
Each parameter on the API server has:
Field | Notes |
| Unique per API server. Used in push payloads. |
| Display label in dashboards and trigger editors. |
| One of |
|
|
| Retention in minutes. Allowed values: |
Pre-declare vs. auto-create. If you push a key that doesn't exist, Next Plus auto-creates the parameter with type inferred from the value, niceName = key, maxLogPeriod = 720, and precision = 2 if numeric.
Production-grade advice: auto-create is great for prototyping but bad for production. A typo in the first push ("warm" instead of 42) locks in type = string permanently. Pre-declare your parameters β either through the PE wizard or via the management endpoints β so a wrong first push doesn't lock in the wrong type.
β Type Validation
For pre-declared parameters, the push payload's value is validated against the declared type:
Declared type | Accepts |
| Anything (no validation) |
| Numbers only |
| Booleans only |
| Valid ISO date / Date object |
A mismatch returns HTTP 422 with code = API_PUSH_VALUE_TYPE_MISMATCH and a details block telling you what was expected and what was sent.
π» Worked Example β Python
A reusable client with error handling, suitable for a long-running integration script:
python
import os import time import requests NP_URL = os.environ["NP_URL"] # e.g. https://tenant.nextplus.io TOKEN = os.environ["NP_TOKEN"] # editor-role access token class NextPlusAPIError(Exception): pass def push(items, timeout=10): """Push one or more parameter values. items: list of {key, value, [timestamp]}.""" r = requests.post( f"{NP_URL}/api/ApiServers/push", params={"access_token": TOKEN}, json=items, timeout=timeout, ) if r.status_code == 401: raise NextPlusAPIError("Auth failed β check token and editor role") if r.status_code == 422: raise NextPlusAPIError(f"Validation: {r.json()}") r.raise_for_status() return r.json() # Pre-declared params on the API server: # temperature number precision=1 maxLogPeriod=720 # running boolean push([ {"key": "temperature", "value": 42.5}, {"key": "running", "value": True}, ]) # Long-running loop pattern with backoff on failure: def push_with_retry(items, max_retries=3): for attempt in range(max_retries): try: return push(items) except (requests.Timeout, requests.ConnectionError): if attempt == max_retries - 1: raise time.sleep(2 ** attempt) # 1s, 2s, 4s except NextPlusAPIError: raise # don't retry validation/auth failuresπ§ Worked Example β cURL
For a quick test or a shell-script integration. The PE UI's Copy push endpoint button generates this prefilled with your tenant URL and token:
bash
curl -X POST "https://<tenant>.nextplus.io/api/ApiServers/push?access_token=<TOKEN>" \ -H 'Content-Type: application/json' \ -d '[{"key": "temperature", "value": 23.5}]'Typical shell-script integration with a dynamic value:
bash
curl -X POST "$NP_URL/api/ApiServers/push?access_token=$NP_TOKEN" \ -H 'Content-Type: application/json' \ -d "$(jq -n --argjson v "$TEMP" \ '[{key:"temperature",value:$v},{key:"running",value:true}]')"β οΈ Error Handling
The push endpoint returns standard HTTP status codes. Common errors and what to do:
HTTP | Code | What it means / fix |
401 | (auth) | Missing or invalid token. Confirm editor role. |
404 | β | No active API server for this tenant. Contact CS. |
422 |
| Body missing or not JSON. |
422 |
| No items after normalization. Check the JSON shape. |
422 |
| Item has neither |
422 |
| Item is missing |
422 |
| Value doesn't match the declared parameter type. Check the |
503 | β | API server configured but not active in this worker. Usually transient; retry. |
Recommendation: treat 401 / 422 as fatal (don't retry β fix the code or config), and treat 503 / network errors / timeouts as transient (retry with exponential backoff).
π Reading Back the Latest Value
For verification or simple integrations that need to round-trip a value:
GET /api/ApiServers/readParameter/:paramId
paramId is the parameter's internal UUID (not its key). Operator role or higher required. Response:
json
{ "value": 23.5 }value is null if nothing has been pushed yet.
βοΈ Operational Notes
Throttling. Value-change events are debounced per parameter. Pushing the same value repeatedly is safe β only meaningful changes are emitted downstream.
Numeric equality. For
numberparameters, a push that differs from the current value by less than10^-precisionis treated as no-change. Setprecisionbased on the actual resolution of your data.Timestamps. When you supply
timestamp, it's used as the sample time. Otherwise the server clock is used. Sending timestamps is recommended for backfill scenarios or when there's any delay between measurement and push.Retention.
maxLogPeriodcontrols how long change events are retained for that parameter (720 = 12 h, 1440 = 24 h). Aggregated/state data is retained separately.
π What Setup Looks Like
For a fresh integration:
Step 1 β Decide what to push. List the values your system will send. Pick stable keys (snake_case is fine), think about types and precision up front.
Step 2 β Get credentials. Create a Next Plus user dedicated to this integration, give it the editor role, generate an access token, store it in your secret manager.
Step 3 β Pre-declare your parameters. Open a PE that should receive the values. Use the Add Parameter wizard, pick the API server as the source, declare each parameter with the right name/type/precision/retention.
Step 4 β Bind to your Production Entities. In the same wizard, tick the parameters you want on this PE. Repeat for any other PEs that need the same values.
Step 5 β Write and test the push code. Start with cURL. Verify with the
readParameterendpoint. Then build out your integration with proper error handling and retries.
Want help mapping it out? Contact us via chat and we'll walk through the schema, the credentials setup, and any edge cases for your specific source.