Core concepts

Test records

A typed envelope around an untyped payload, and a lock that means something.

Contents

A record is one test, on one device, on one date. The columns the API validates are the envelope; the measurements live in form_data, which is stored as an opaque JSON object.

Record
{
  "id": 88213,
  "equipment_id": 5541,
  "test_date": "2026-09-04",
  "tested_by": "D. Okafor",
  "form_type": "lv_breaker",
  "status": "pass",
  "notes": "As-found settings matched the coordination study.",
  "locked": false,
  "form_data": { /* shape depends on form_type: see below */ },
  "created_at": "2026-09-04 15:22:07.114820"
}

Why form_data is not validated#

Fifteen device types, each with a different set of tests, and a standard that revises. Pinning every field into the request schema would mean a backend deploy every time a form gained a row, and would reject a technician's reading during a shutdown because a column had been added upstream. So the envelope is strict and the payload is not.

The renderers know the shapes. The conventional keys (insulation, contact_resistance, secondary_injection, primary_injection, hi_pot, visual_items) are documented under NETA reports, because that is where they are read.

An unrecognised key is stored and ignored, not rejected

This is the cost of the tradeoff above. A typo in a field name will round-trip perfectly through POST and GET and then be silently absent from the rendered document. If a value is missing from a report, check the key spelling in the stored record before anything else.

Status#

status drives the roll-up counts and the pass/fail table on generated reports. "pass" and "fail" are the two values that count as a completed test; anything else ("incomplete", an empty string) falls into incomplete_count.

Locking#

A locked record cannot be updated by PUT. This is not a UI convenience. A test result that has been issued to a customer is evidence, and silently editing it is the failure mode the lock exists to prevent.

POST/db/records/{rid}/unlock

Unlocking is a deliberate, separate call rather than a field on the update body, so it cannot happen as a side effect of a client sending back an object it fetched. On enterprise organizations the unlock is written to the document history, see Enterprise.