Public API reference · 4 August 2026
Kovira API v1
Build customer integrations and connect ATLAS or VECTOR agents against one versioned, domain-grouped contract. This reference covers REST, GraphQL, SCIM provisioning, provider callbacks, and signed machine traffic.
https://api.kovira.app/v1
01 · URL architecture
Major group before operation
Every externally consumable endpoint follows
/v1/{major-group}/{operation-or-resource}. Group names
are lowercase and case-sensitive. Canonical examples omit the
terminal slash; a single terminal slash is normalized, but nested
suffixes and duplicate separators are rejected.
/v1 ├── atlas/ signed machine inventory ├── calendar/feeds/ opaque-token iCalendar feeds ├── cis/ configuration items ├── docs/ this handbook and OpenAPI ├── graphql/query public GraphQL ├── incidents/ incident records and transitions ├── integrations/ provider-signed callbacks ├── l2/ network observations ├── platform/health unauthenticated service liveness ├── scim/v2/ SCIM 2.0 provisioning └── vector/ signed network discovery
/api/*, /v1.0/*, uppercase group,
check-in, endpoint-ID, or alternate-header aliases. Unknown
endpoints return a version-stamped JSON 404.
02 · Contract conventions
Predictable on the wire
Success envelope
REST resources live in data. Cursor lists also
include meta.next_cursor.
{
"data": [{ "id": "…" }],
"meta": { "next_cursor": null }
}
Error envelope
HTTP status remains authoritative. The body supplies a stable machine code and safe message.
{
"error": {
"code": "validation_failed",
"message": "Invalid input."
}
}
| Convention | Contract |
|---|---|
| Media type |
application/json; send
Content-Type on body-bearing requests.
|
| Identifiers | UUID strings unless a field explicitly says otherwise. |
| Timestamps | UTC ISO-8601 / RFC 3339 strings. |
| Pagination | Keyset cursors are opaque. Pass the returned cursor unchanged. |
| Unknown input | Mutation bodies are strict; extra fields are rejected. |
| Correlation |
Send a UUID in X-Request-ID. Kovira echoes valid
IDs or generates one.
|
| Version |
Every API response carries Kovira-API-Version: 1.
|
Customer API authentication
Create a tenant-bound key in Workspace Settings → API Keys. Send it on REST and GraphQL calls. Keys are hashed at rest, individually scoped, expirable, and revocable.
Authorization: Bearer kvr_live_REDACTED
03 · Failure semantics
Errors, limits, and retries
| Status | Typical code | Meaning |
|---|---|---|
| 400 |
invalid_query, validation_failed
|
Path, cursor, JSON, or fields are invalid. |
| 401 | unauthorized |
Credentials are missing or invalid. Key state is deliberately not disclosed. |
| 403 | insufficient_scope |
Authentication succeeded but the principal cannot perform the operation. |
| 404 | not_found |
The endpoint or tenant-scoped resource does not exist. |
| 409 |
invalid_transition,
read_only_resource
|
The requested state conflicts with the resource contract. |
| 413 | payload_too_large |
Customer request bodies exceed 1 MiB. |
| 429 | rate_limited |
Wait for Retry-After; use exponential backoff
with jitter.
|
| 503 | dependency_unavailable |
A safety dependency failed closed. Retry only idempotent work. |
Customer keys receive 60 requests per rolling minute. Responses
expose X-RateLimit-Limit,
X-RateLimit-Remaining, and
X-RateLimit-Reset. A separate pre-authentication IP
limit bounds credential spraying.
04 · System API
Platform
A lightweight liveness resource for load balancers and external monitors. It checks request handling, not downstream dependency health; operational history remains on the public status page.
| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET | /v1/platform/health | None | Return process liveness, API major, and check time. |
05 · Customer REST
Incidents
Incident fields and lifecycle transitions are separate. Use the transition resource for status changes; PATCH handles descriptive and assignment fields.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /v1/incidents | incidents:read |
List. Filters: status, priority; max
100.
|
| POST | /v1/incidents | incidents:write | Create an incident. |
| GET | /v1/incidents/{id} | incidents:read | Fetch one tenant-scoped incident. |
| PATCH | /v1/incidents/{id} | incidents:write | Update non-lifecycle fields. |
| POST | /v1/incidents/{id}/transitions | incidents:write | Apply the server-enforced state machine. |
Enums. Status: new,
assigned, in_progress,
closed. Priority: p1–p4.
Impact and urgency: high, medium,
low.
06 · Customer REST
Configuration items
The CMDB list is a unified projection across CI tables. Writes
expose a deliberately narrow base shape: type,
name, description, status,
and customer_id.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /v1/cis | cis:read |
List. Filters: canonical type and
status; max 100.
|
| POST | /v1/cis | cis:write | Create a writable CI type; plan limits fail closed. |
| GET | /v1/cis/{id} | cis:read | Return the safe public projection; secret and internal columns are excluded. |
| PATCH | /v1/cis/{id} | cis:write | Version-snapshot, update, audit, and emit a webhook. |
Writable types. device,
network, service, rack,
domain, document, vendor,
location, contract, person,
group, api, license,
software, wan, sla,
saas_app, business_service,
quote.
Incident/change projections, password records, and integration-managed Entra/Intune records are readable where present but cannot be mutated through generic CI routes.
07 · Customer REST
Layer 2 observations
Read-only operational data produced by VECTOR’s signed ingest pipeline. The public key never receives write access to observation tables.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /v1/l2/transceivers | l2:read | Inventory plus the latest lane-0 digital diagnostics. Max 100. |
| GET | /v1/l2/anomalies | l2:read | Open or historical anomalies, filtered by severity, type, or CI. Max 200. |
| GET | /v1/l2/cdp | l2:read | CDP neighbour observations by local switch or neighbour ID. Max 200. |
08 · Customer GraphQL
GraphQL query surface
| Method | Path | Authentication | Purpose |
|---|---|---|---|
| GET POST | /v1/graphql/query | Public API bearer key | GET queries; POST queries and incident mutations. |
Queries cover incidents, problems, changes, service requests, CIs, customers, and audit entries with Relay-style connections. Resolvers enforce field-domain scopes. Query depth is capped at eight and production introspection is disabled.
Mutations are createIncident,
addIncidentComment, and
transitionIncident. Each accepts an optional
idempotencyKey; failures are returned as typed
mutation-union members.
{
"query": "query { incidents(first: 10) { edges { node { id number title status } } pageInfo { hasNextPage endCursor } } }"
}
09 · Identity provisioning
SCIM 2.0
Use the dedicated SCIM bearer issued by Kovira. SCIM resource media types and error shapes follow RFC 7644. The product major and SCIM protocol major remain visibly separated in the path.
| Methods | Path | Purpose |
|---|---|---|
| GET | /v1/scim/v2/ServiceProviderConfig | Supported SCIM features. |
| GET | /v1/scim/v2/ResourceTypes | Resource type discovery. |
| GET | /v1/scim/v2/Schemas | Schema discovery. |
| GET POST | /v1/scim/v2/Users | List/filter or provision users. |
| GET PUT PATCH DELETE | /v1/scim/v2/Users/{id} | Read, replace, modify, or deactivate a user. |
| GET POST | /v1/scim/v2/Groups | List/filter or provision groups. |
| GET PUT PATCH DELETE | /v1/scim/v2/Groups/{id} | Read, replace, modify, or remove a group. |
10 · Signed agent API
ATLAS
ATLAS 0.6.16 uses only the lowercase /v1/atlas group
and wire-signature version 4. Registration binds a persistent
Ed25519 identity; every operational call must prove both possession
of the workspace agent secret and the registered device private key.
An ATLAS route accepts only an ATLAS-typed API key bound to that
exact device registration; VECTOR keys and registrations are
rejected before dispatch.
Enrollment ceremony
An operator explicitly issues an ATLAS-only API key and a separate
15-minute, single-use kovira_enroll_… capability.
Kovira stores only SHA-256 digests. The first
/v1/atlas/register call must HMAC-sign the request with
that exact API key and prove the submitted Ed25519 private key.
Capability consumption, live-key revalidation, collision checks, and
identity registration commit in one database transaction; any
failure consumes nothing. Interactive deployment uses hidden
prompts, while automation accepts two newline-delimited secrets on
stdin. Secrets are never placed in URLs or process arguments.
| Method | Path | Purpose |
|---|---|---|
| GET | /v1/atlas/ping | Connectivity check for an already registered ATLAS identity. |
| POST | /v1/atlas/register | Consume an enrollment capability or rotate device identity. |
| GET | /v1/atlas/config | Current agent schedule and policy. |
| POST | /v1/atlas/telemetry | Strict schema-v5 full snapshot or heartbeat; refresh command flags. |
| POST | /v1/atlas/events | Audit and diagnostic event batch. |
| POST | /v1/atlas/incidents | Create an incident from an authenticated endpoint signal. |
| POST | /v1/atlas/uninstall-ack | Confirm the agent removed itself. |
| POST | /v1/atlas/network-observation | Submit endpoint-visible ARP, LLDP, mDNS, and IPv6 ND evidence. |
| GET | /v1/atlas/agent-pair | Find same-subnet registered peers for local cooperation. |
Wire v4 request
v4:{METHOD}:{EXACT_PATH_AND_QUERY}:{UNIX_SECONDS}:{NONCE}:{MACHINE_ID}:atlas:{SHA256_BODY_HEX}
Send X-API-Key, X-Machine-Id,
X-Timestamp, X-Nonce,
X-Signature, X-Sig-Version: 4,
X-Signed-Path, X-Agent-Kind: atlas,
X-Identity-Proof, and X-Agent-Version.
Telemetry also sends X-Schema-Version: 5. The signed
path includes the query string byte-for-byte. API keys use exactly
kovira_ plus 64 lowercase hexadecimal characters;
timestamps are exactly ten decimal epoch-second digits, and HMAC
signatures are exactly 64 lowercase hexadecimal characters.
11 · Signed agent API
VECTOR
VECTOR 0.6.16 uses the same wire-v4 primitives, with
vector in the group, kind header, and canonical
message. Secret-bearing SNMP results are returned only after the
central registered-identity gate. A VECTOR route accepts only a
VECTOR-typed API key bound to that exact device registration; ATLAS
keys and registrations are rejected before dispatch.
Enrollment ceremony
VECTOR uses its own typed API key and 15-minute, single-use
enrollment capability. First registration proves the submitted
Ed25519 key, binds the X25519 peer identity, and atomically consumes
the capability against the exact tenant, customer, key, kind, and
machine tuple. Rotation proves the currently registered Ed25519 key.
Interactive deploy prompts without echo; secret-manager automation
uses the two-line --credentials-stdin
contract, keeping both values out of shell history, URLs, and argv.
Deploy completes signed registration before installing the service;
the enrollment capability is zeroized after the request and is never
persisted to config or the OS keyring.
| Method | Path | Purpose |
|---|---|---|
| GET | /v1/vector/ping | Connectivity check for an already registered VECTOR identity. |
| POST | /v1/vector/register | Enroll or rotate persistent Ed25519/X25519 identity. |
| GET | /v1/vector/config | Current scanner configuration. |
| GET | /v1/vector/sync-manifest | Cheap versions for delta-sync resources. |
| GET | /v1/vector/peers | Tenant/customer-scoped network and host inventory. |
| GET | /v1/vector/vector-peers | Active VECTOR instances for WAN path classification. |
| POST | /v1/vector/peer-link-observations | Submit classified inter-instance link evidence. |
| GET | /v1/vector/agent-pair | Find registered same-subnet peers. |
| GET | /v1/vector/snmp-credentials?target_ip={ip} | Resolve short-lived target-specific SNMP credentials. |
| POST | /v1/vector/cdp-observations | Ingest Cisco Discovery Protocol observations. |
| POST | /v1/vector/transceiver-observations | Ingest optics inventory and diagnostics. |
| POST | /v1/vector/fhrp-observations | Ingest VRRP/HSRP redundancy observations. |
| POST | /v1/vector/bfd-observations | Ingest BFD session observations. |
| POST | /v1/vector/cfm-observations | Ingest Ethernet CFM observations. |
| POST | /v1/vector/scan-ingest | Publish a complete network discovery result. |
Wire v4 request and response
v4:{METHOD}:{EXACT_PATH_AND_QUERY}:{UNIX_SECONDS}:{NONCE}:{MACHINE_ID}:vector:{SHA256_BODY_HEX}
resp-v4:{REQUEST_SIGNATURE}:{NONCE}:{STATUS}:{CANONICAL_CONTENT_TYPE}:{SHA256_RESPONSE_BODY_HEX}
Successful signed responses include
X-Response-Sig-Version: 4 and
X-Response-Signature. Agents verify status, content
type, and body before consuming the response.
12 · Provider callbacks
Integrations
These are provider-to-Kovira callbacks. Authentication is provider-specific: Stripe signature, Slack signing secret, or Microsoft Bot Framework identity. Public API bearer keys are not accepted.
| Method | Path | Caller |
|---|---|---|
| POST | /v1/integrations/stripe/webhook | Stripe webhook delivery. |
| POST | /v1/integrations/slack/commands | Slack slash commands. |
| POST | /v1/integrations/slack/interactions | Slack interactive payloads. |
| POST | /v1/integrations/teams/activities | Microsoft Teams bot activities. |
13 · Token feeds
Calendar feeds
| Method | Path | Media type | Authentication |
|---|---|---|---|
| GET | /v1/calendar/feeds/{token} | text/calendar |
The high-entropy token is the credential. |
Do not put feed URLs in logs, analytics, support screenshots, or public documents. Rotate a feed token when it may have been disclosed.
14 · Working examples
Start with discovery
curl --fail-with-body https://api.kovira.app/v1
List open high-priority incidents
curl --fail-with-body \ -H 'Authorization: Bearer kvr_live_REDACTED' \ 'https://api.kovira.app/v1/incidents?status=in_progress&priority=p1&limit=25'
Create an incident
curl --fail-with-body -X POST \
-H 'Authorization: Bearer kvr_live_REDACTED' \
-H 'Content-Type: application/json' \
--data '{"title":"Core switch unreachable","impact":"high","urgency":"high","source":"monitoring"}' \
https://api.kovira.app/v1/incidents
Continue a cursor page
curl --get \ -H 'Authorization: Bearer kvr_live_REDACTED' \ --data-urlencode 'cursor=RETURNED_OPAQUE_CURSOR' \ https://api.kovira.app/v1/cis
For SDK generation, use the complete 60-operation contract at
https://api.kovira.app/v1/docs/openapi.yaml.
15 · Lifecycle
Versioning policy
| Change | v1 treatment |
|---|---|
| Add an optional response field or new endpoint | May ship within v1. |
| Add a new optional enum filter value | May ship within v1 when existing requests remain valid. |
| Remove or rename a field/path; change field meaning or auth |
Requires a new major group root such as /v2.
|
| Security removal before production | Removed outright. No alias is retained in this pre-production contract. |
The path major is the compatibility boundary. Agent wire and payload schema versions are independent, explicit subcontracts: current ATLAS/VECTOR wire version is 4; current ATLAS telemetry schema is 5.
16 · Integration checklist
Before enabling production traffic
-
Pin the base origin to
https://api.kovira.app/v1; do not derive internal/apipaths. - Grant the smallest required scopes and store keys in a secrets manager.
-
Set connection and response deadlines; retry
429and transient5xxwith jitter. - Only retry mutations when the operation is idempotent or carries a GraphQL idempotency key.
-
Log
X-Request-ID, status, and stable error code—never credentials or calendar tokens. -
Treat cursors as opaque and validate
Kovira-API-Versionin integration tests.