API Reference
The Customer API (/api/v1/*) is a separate, bearer-key-only surface from the dashboard you sign in to — no session, no cookie, no browser required. It is available on Pro and above.
Last updated August 19, 2026.
Authentication
Every request carries the key as a bearer token. There is no API-key header, no query-string token, and no organization-selector header — the key already names exactly one organization, and that is the only tenant a request against it can ever touch.
Base URL: https://api.nivaronix.com/api/v1
Header: Authorization: Bearer nvx_...Example:
curl -H "Authorization: Bearer nvx_..." \
https://api.nivaronix.com/api/v1/assetsAn unknown token, a revoked token, an expired token, and a malformed header all return the same 401 with the same body — deliberately: distinguishing them would let a caller probe which tokens exist.
Getting a key
From the dashboard: Settings → API keys → Create key → choose a name and scopes. The full token is shown exactly once, at creation — copy it before leaving the page. Nivaronix stores only a hash of it afterward and cannot show it to you again; a lost key has to be rotated.
Key limits by plan:
- Free / Starter — API access not included.
- Pro — up to 2 active keys.
- Studio — up to 5 active keys.
- Scale — up to 20 active keys.
Revoked and expired keys are kept as a record and do not count against that limit.
Scopes
Each key carries only the scopes it was created with — there is no implicit "read everything" grant. A read scope needs only organization membership to issue; a write scope needs the matching write permission in the org (the same permission that gates it in the dashboard itself).
| Scope | Grants | Requires to issue |
|---|---|---|
assets:read | List and fetch assets, imports. | Membership |
assets:write | Create/import assets, set scan schedules. | Assets: write |
scans:read | Fetch scan results. | Membership |
scans:write | Trigger scans. | Assets: write |
monitors:read | List/fetch monitors. | Membership |
monitors:write | Create/update monitors. | Monitors: write |
findings:read | List findings. | Membership |
incidents:read | List incidents. | Membership |
reports:read | List/fetch reports. | Membership |
reports:write | Request reports. | Reports: write |
clients:read | List clients. | Membership |
clients:write | Create clients, bulk assign/unassign. | Clients: write |
protection:read and incidents:write can be granted to a key but do not yet authorize any endpoint below — no route currently reads either scope. Requesting a remedy execution or approval via API key is deliberately not offered at all: a long-lived bearer token is the wrong instrument for an action that changes how your production traffic is handled, and approval is meant to be a human checkpoint.
Pagination & responses
List endpoints take limit/offset query parameters (defaults and maximums vary by endpoint, noted below) and return the matching page alongside the true total count — never a silently truncated list.
{
"assets": [ … ],
"total": 47,
"limit": 25,
"offset": 0
}Errors & rate limits
Errors are a JSON body with a single detail field describing what went wrong.
{ "detail": "Asset not found" }401— missing, invalid, revoked or expired key.403— the key lacks the scope this route requires, or your plan no longer includes API access.404— the resource doesn't exist, or belongs to another organization (the two are indistinguishable on purpose).409— a conflicting resource already exists (e.g. a duplicate asset domain).402— a plan quota (assets, monitors, reports/month, verified scans/month) is exhausted; the body names the limit, current usage and the plan that raises it.422— the request body failed validation.429— rate limited. The same limiter session-authenticated traffic uses; back off and retry.
If your organization's plan drops API access after keys already exist, requests get a grace period rather than an immediate cutoff: responses carry Deprecation/Sunset headers (RFC 8594) and a Warning header naming the date access actually ends, so an integration can find out from its own response headers rather than only from the dashboard.
Assets
GET/assetsassets:readList assets, searchable, filterable and sortable.
Query params: search, status, tag, client_id, sort=created_at, order=desc, limit=25 (max 100), offset=0
POST/assetsassets:writeRegister a new asset. Unverified until ownership is proven — see the customer dashboard's verification flow.
Request body
{
"domain": "example.com",
"name": "Example Co",
"asset_type": "domain",
"description": null,
"tags": []
}GET/assets/{asset_id}assets:readFetch one asset.
Response
{
"id": "…",
"name": "Example Co",
"domain": "example.com",
"status": "healthy",
"health_score": 94,
"is_verified": true,
"client_id": null,
"description": null,
"created_at": "2026-08-17T14:33:58Z",
"updated_at": "2026-08-19T05:14:04Z"
}GET/assets/importassets:readList bulk asset-import jobs for this organization.
Query params: limit=25 (max 100), offset=0
POST/assets/importassets:writeStart a bulk import of many domains (CSV-shaped) as one job, returned pending — poll GET /assets/import/{import_id} for row-level results.
GET/assets/import/{import_id}assets:readOne import job's status and per-row outcome.
Query params: limit=100 (max 500), offset=0
POST/assets/import/{import_id}/commitassets:writeCommit a previewed import job — creates the asset rows that passed validation.
POST/assets/scan-schedule/bulkscans:writeSet a recurring scan schedule across several assets in one call.
Scans
POST/assets/{asset_id}/scansscans:writeTrigger a security scan of an asset. Verified-asset scans count against the plan's monthly quota; unverified assets get a limited number of trial scans.
GET/assets/{asset_id}/scans/{scan_id}scans:readFetch one scan's findings, score, grade and detected technologies.
Monitors
GET/monitorsmonitors:readList monitors.
Query params: status, asset_id
POST/monitorsmonitors:writeCreate a monitor for a verified asset. Re-submitting a type that already has a monitor updates it in place — the new configuration/frequency is applied, it does not create a duplicate.
Request body
{
"asset_id": "…",
"monitor_type": "http",
"frequency": null,
"configuration": {}
}GET/monitors/{monitor_id}monitors:readFetch one monitor.
PATCH/monitors/{monitor_id}monitors:writeUpdate a monitor's frequency, type, or configuration.
Request body
{
"frequency": 300,
"configuration": { "record_type": "A" }
}Findings, incidents & reports
GET/findingsfindings:readList findings across your assets.
GET/incidentsincidents:readList incidents across your assets.
GET/reportsreports:readList generated reports.
Query params: limit=50 (max 200), offset=0
POST/reportsreports:writeRequest a report. Rendering happens off the request path — returns 202 pending; poll GET /reports/{report_id}.
Request body
{
"asset_id": "…",
"report_type": "security_report",
"report_format": "pdf"
}GET/reports/{report_id}reports:readFetch one report's status and, once completed, its download reference.
Clients
The agency grouping primitive — Organization → Client → Asset. A client has no plan of its own; entitlements are always evaluated against the organization.
GET/clientsclients:readList clients (the agency grouping: Organization → Client → Asset).
Query params: limit=25 (max 100), offset=0
POST/clientsclients:writeCreate a client.
Request body
{
"name": "Acme Retail",
"email": "ops@acme.example"
}GET/clients/portfolioclients:readEvery client with its asset-health rollup in one call — the agency dashboard's own view.
Query params: limit=25 (max 100), offset=0
POST/clients/bulk-assignclients:writeAssign several assets to a client in one call. Per-asset results are returned individually — one failing asset does not fail the rest.
POST/clients/bulk-unassignclients:writeRemove several assets from a client in one call.