This is the whole shape of the product in four calls. It assumes an account on the Unlimited plan, because the /db/* endpoints are gated to it, see plans and entitlements.
1. Get a token#
curl -X POST https://api.rmsautomation.ai/auth/login \ -H 'Content-Type: application/json' \ -d '{"email":"you@example.com","password":"…"}'
const BASE = 'https://api.rmsautomation.ai' const res = await fetch(`${BASE}/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }), }) if (!res.ok) throw new Error(await res.text()) const { token, refresh_token, user } = await res.json()
import requests BASE = "https://api.rmsautomation.ai" r = requests.post(f"{BASE}/auth/login", json={ "email": email, "password": password, }, timeout=30) r.raise_for_status() data = r.json() token = data["token"]
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
"refresh_token": "9f2c…",
"user": {
"id": 4127,
"name": "Dana Okafor",
"email": "you@example.com",
"role": "owner",
"org": "Piedmont Power Services"
}
}2. Create a project#
Everything in the database hangs off a project. Send the token as a bearer credential on this and every subsequent call.
curl -X POST https://api.rmsautomation.ai/db/projects \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -d '{ "name": "Cedar Ridge Substation - ATS", "customer": "Cedar Ridge Utilities", "site": "Cedar Ridge, SC", "job_number": "2026-0418" }'
// One helper, reused for every call below. async function api(path: string, init: RequestInit = {}) { const res = await fetch(BASE + path, { ...init, headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, ...init.headers, }, }) if (!res.ok) throw new Error(`${res.status} ${await res.text()}`) return res.json() } const project = await api('/db/projects', { method: 'POST', body: JSON.stringify({ name: 'Cedar Ridge Substation - ATS', customer: 'Cedar Ridge Utilities', site: 'Cedar Ridge, SC', job_number: '2026-0418', }), })
# One session, reused for every call below. s = requests.Session() s.headers.update({"Authorization": f"Bearer {token}"}) project = s.post(f"{BASE}/db/projects", json={ "name": "Cedar Ridge Substation - ATS", "customer": "Cedar Ridge Utilities", "site": "Cedar Ridge, SC", "job_number": "2026-0418", }, timeout=30).json()
3. Add an assembly and a device#
Devices do not attach to a project directly. They attach to an assembly, which is the switchgear lineup, MCC or panel they physically sit in. See the data model.
# The lineup curl -X POST "$BASE/db/projects/$PID/assemblies" \ -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \ -d '{"name":"SWGR-1","description":"480 V main switchgear"}' # A breaker inside it curl -X POST "$BASE/db/assemblies/$AID/equipment" \ -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \ -d '{ "device_type": "lv_breaker", "designation": "52-1", "manufacturer": "Square D", "model": "MasterPact NW20H", "serial_number": "SD-2210-4471", "voltage_rating": "480V", "amp_rating": "2000A" }'
4. Record a test and pull the report#
form_data is an open object whose keys depend on form_type. Store what you measured; the report renderer reads it back.
curl -X POST "$BASE/db/equipment/$EID/records" \ -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \ -d '{ "test_date": "2026-09-04", "tested_by": "D. Okafor", "form_type": "lv_breaker", "status": "pass", "form_data": { "insulation": { "ab_open": 5200, "bc_open": 4980, "ca_open": 5310, "test_voltage_vdc": 1000, "temperature_c": 24 }, "contact_resistance": { "phase_a": 121, "phase_b": 118, "phase_c": 124 } } }' # Every record on the project, rendered as one NETA document curl "$BASE/db/projects/$PID/generate-report" \ -H "Authorization: Bearer $TOKEN" -o cedar-ridge.pdf