HomeEvidenceAPI docs

API

Send a signal, get it back clean: the nlsys API

Everything below is the public HTTP API: create a stream, send raw samples, read the cleaned signal and the analytics next to it. Your API key, your public API base URL and a ready-to-run curl command are shown in your account — the examples use $BASE and $KEY for those two values.

Get your API key

Authentication

Every request carries your key in a header. Requests that change state (creating a stream, sending data, control) also require an Idempotency-Key — any unique string per operation; retrying with the same key and the same body safely returns the original result instead of repeating the work.

curl -s "$BASE/v2/streams" \
  -H "X-API-Key: $KEY" \
  -H "Idempotency-Key: create-001" \
  -H "Content-Type: application/json" \
  -d '{"names":["pressure","temperature"],"fs":1000.0,"auto_sigma":true}' 

The response is your stream id: {"id":"<stream UUID>","n":1}. A physical stream holds 1 to 264 synchronized response channels. For wider systems, create a logical stream group: the platform shards up to 4,096 channels into streams of at most 264 while preserving column order and tick alignment. Cross-shard coordinated control is withheld; control remains shard-local.

Send data (ingest)

Post raw samples as columns plus timestamps. One value per channel per row; send single rows for live feeds or blocks for batches.

curl -s "$BASE/v2/streams/$STREAM/ingest" \
  -H "X-API-Key: $KEY" \
  -H "Idempotency-Key: ingest-001" \
  -H "Content-Type: application/json" \
  -d '{
    "channels": {"pressure":[1.21,1.19,1.18], "temperature":[42.7,42.8,42.7]},
    "t": [1720000000.125, 1720000000.126, 1720000000.127]
  }' 

Limits per request: up to 100,000 rows per column and 2,000,000 channel-samples total (rows × channels); larger data is simply sent as several requests. All column lengths must match t. A missing observation is null — never substitute a numeric zero, the engine treats them differently.

Read the cleaned signal

curl -s "$BASE/v2/streams/$STREAM/filter?mode=online&since=0&max=1000" -H "X-API-Key: $KEY"

Three modes of the same stream: online — zero-lag output for live display; min_latency — a causal smoother that trades a fixed delay of 120 samples for most of the achievable quality (also declared per-stream in the delay_samples field of this response); offline — the strongest output, re-processing the retained signal tail. max is required (1..20,000); page through history with since. The API retains the last 20,000 rows per stream for retrieval — ship older raw history to your own storage as you ingest.

Honesty during warm-up: while a channel is still calibrating (typically the first few hundred to ~1,500 samples), the response flags it in calibrating and the online output may equal the input — the engine returns a clean passthrough rather than an invented signal.

The Analytics tier on the same stream

Each surface is a GET next to /filter:

/health — per-channel state, calibration flags, noise consistency. /anomalies?since=<cursor> — events with evidence attribution (channel, grade, predictive source); store next_since from each response and pass it back as the cursor. /connections — the directed cross-channel graph with lags. /model?channel=i — the compiled per-channel model diagnostics. /volatility — read-only next-step variance per channel.

System Passport

curl -s "$BASE/v2/passports" \
  -H "X-API-Key: $KEY" -H "Idempotency-Key: passport-001" \
  -H "Content-Type: application/json" \
  -d '{"names":["pressure"],"fs":1000.0,"sigma":0.02,"data":{"pressure":[...]}}'
# then poll:
curl -s "$BASE/v2/passports/$JOB" -H "X-API-Key: $KEY"

An inline Passport needs at least 1,500 samples per channel; a live Passport can be requested from an existing stream's tail instead.

POST /v2/streams/$STREAM/models/ndc/compile
GET  /v2/model-jobs/$JOB
GET  /v2/models/$MODEL/passport
GET  /v2/models/$MODEL/artifact

A generic compile creates one model for one declared target. The hosted routes create a compile job from a stream or stream group, then expose the job status, selected model, Passport and artifact. Product access and processing balance are checked separately; additional targets require separate compiles.

NDC model compile

Control (advisory)

Controller has a dedicated permission and can be purchased independently. It uses a control-ready stream, known applied commands and declared command limits to return supervisory recommendations. The signal processing used by Control does not unlock the separate /filter or Analytics surfaces. Autonomous active=true operation is outside the self-service product and requires a separate restricted approval.

Errors and retries

Beyond this quickstart, the same API also serves: CSV cleaning estimates (/v2/estimates/csv-cleaning → reserve/cancel), individual API keys (/v2/api-keys), usage (/v2/usage/summary), stream groups for wide systems (/v2/stream-groups) and model artifacts (/v2/models/{id}/artifact, /passport) — all visible in your workspace.

Safe rules that cover the sharp edges: never reuse an Idempotency-Key with a different body — that is a conflict by design; on an ambiguous failure, retry the same body with the same key; a missing value is null, not zero; channel names and their order are fixed for the life of a stream — to change them, create a new stream; an unknown or foreign stream id returns 404.

The HTTP API above is the current public integration contract.