Skip to content

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/assets

An 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).

ScopeGrantsRequires to issue
assets:readList and fetch assets, imports.Membership
assets:writeCreate/import assets, set scan schedules.Assets: write
scans:readFetch scan results.Membership
scans:writeTrigger scans.Assets: write
monitors:readList/fetch monitors.Membership
monitors:writeCreate/update monitors.Monitors: write
findings:readList findings.Membership
incidents:readList incidents.Membership
reports:readList/fetch reports.Membership
reports:writeRequest reports.Reports: write
clients:readList clients.Membership
clients:writeCreate 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:read

List 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:write

Register 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:read

Fetch 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:read

List bulk asset-import jobs for this organization.

Query params: limit=25 (max 100), offset=0

POST/assets/importassets:write

Start 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:read

One import job's status and per-row outcome.

Query params: limit=100 (max 500), offset=0

POST/assets/import/{import_id}/commitassets:write

Commit a previewed import job — creates the asset rows that passed validation.

POST/assets/scan-schedule/bulkscans:write

Set a recurring scan schedule across several assets in one call.

Scans

POST/assets/{asset_id}/scansscans:write

Trigger 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:read

Fetch one scan's findings, score, grade and detected technologies.

Monitors

GET/monitorsmonitors:read

List monitors.

Query params: status, asset_id

POST/monitorsmonitors:write

Create 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:read

Fetch one monitor.

PATCH/monitors/{monitor_id}monitors:write

Update a monitor's frequency, type, or configuration.

Request body

{
  "frequency": 300,
  "configuration": { "record_type": "A" }
}

Findings, incidents & reports

GET/findingsfindings:read

List findings across your assets.

GET/incidentsincidents:read

List incidents across your assets.

GET/reportsreports:read

List generated reports.

Query params: limit=50 (max 200), offset=0

POST/reportsreports:write

Request 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:read

Fetch 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:read

List clients (the agency grouping: Organization → Client → Asset).

Query params: limit=25 (max 100), offset=0

POST/clientsclients:write

Create a client.

Request body

{
  "name": "Acme Retail",
  "email": "ops@acme.example"
}
GET/clients/portfolioclients:read

Every 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:write

Assign 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:write

Remove several assets from a client in one call.