Skip to content

CLI

iotpulse is a scriptable command-line client for the IoT Pulse public API. It is a thin wrapper: every command maps to one public API endpoint, authenticates with a scoped API key, and can emit raw JSON for piping into jq or a CI pipeline. It holds no logic of its own — tenant and scope are resolved server-side from your key.

Install the CLI globally from npm:

Terminal window
npm install -g @iotpulse/cli

This puts the iotpulse binary on your PATH. Verify it:

Terminal window
iotpulse --version
iotpulse --help

You need Node.js 20 or newer.

To work on the CLI itself, build it from the platform repository instead of the published package:

Terminal window
cd src/cli
npm install
npm run build
npm link

npm link puts your local build of the iotpulse binary on your PATH.

Mint a scoped API key in the admin app under Settings → API Keys (the secret, format iotp_…, is shown once). The CLI reads the key from the first of these it finds:

  1. the --api-key flag,
  2. the IOTPULSE_API_KEY environment variable,
  3. the config file ~/.config/iotpulse/config.json.

Store it once with the config command:

Terminal window
iotpulse config set apiKey iotp_your_key_here
iotpulse config get # shows the URL and a masked key
iotpulse config path # prints the config file location

The key is sent as the X-API-Key header on every request. You never pass a tenant id — the key is bound to a single tenant, and the API resolves it for you.

The base URL defaults to https://api.iotpulse.io. Override it with the --api-url flag, the IOTPULSE_API_URL environment variable, or iotpulse config set apiUrl <url>. The request timeout defaults to 30s (IOTPULSE_API_TIMEOUT_MS).

By default, list commands print a compact table and single-resource commands print indented JSON. Pass the global --json flag to print the API’s exact response body instead — that is the scriptable contract:

Terminal window
iotpulse devices list # table
iotpulse devices list --json | jq '.[].id' # raw JSON, piped to jq

On an API error, the CLI writes a one-line diagnostic to stderr and exits with a non-zero status, so it composes cleanly in scripts and CI.

Each command requires the matching scope on your key (see Scopes).

Terminal window
iotpulse devices list
iotpulse devices get <device-id>
iotpulse devices update <device-id> --data '{"name":"Boiler A"}' # needs devices:write

Device groups, thresholds, shifts (read-only)

Section titled “Device groups, thresholds, shifts (read-only)”
Terminal window
iotpulse groups list
iotpulse groups get <group-id>
iotpulse thresholds list
iotpulse thresholds get <threshold-id>
iotpulse shifts list
iotpulse shifts get <shift-id>

These resources are read-only in the public API v1, so the CLI exposes only list and get for them.

Terminal window
iotpulse anomalies list --device-id <id> --status open --skip 0 --limit 100
iotpulse anomalies get <anomaly-id>
iotpulse anomalies acknowledge <anomaly-id> # needs anomalies:write
Terminal window
iotpulse tickets list
iotpulse tickets get <ticket-id>
iotpulse tickets update <ticket-id> --data '{"status":"resolved"}' # needs tickets:write

Write commands (devices update, tickets update) take a --data / -d flag with the JSON body. It accepts a raw string, a file, or stdin:

Terminal window
iotpulse devices update dev_1 --data '{"name":"Boiler A"}'
iotpulse devices update dev_1 --data @device.json
cat device.json | iotpulse devices update dev_1 --data -

The body is forwarded verbatim — the API validates it and returns a structured error if it is malformed.

CodeMeaning
0Success.
1API returned an error (4xx/5xx) or the request failed (network/timeout).
2Usage error, including no API key configured.
Terminal window
# Acknowledge every open anomaly for a device.
iotpulse anomalies list --device-id dev_123 --status open --json \
| jq -r '.[].id' \
| while read -r id; do iotpulse anomalies acknowledge "$id"; done