Skip to Content
Welcome to the Novantra documentation.
DevelopersGetting Started

Getting Started

This page walks an integrator from zero to a successful first API call. It assumes you have a Novantra workspace (Cloud or Sovereign) and admin access to create credentials.

If you’re looking for the long-form conventions, API overview is the authoritative reference; this page is the first thirty minutes.

The five-minute mental model

The Novantra REST API is:

  • Versioned at /api/v1/.... Always use this prefix; the un-versioned internal app routes are not for external use.
  • Authenticated by short-lived OAuth 2.0 bearer tokens issued to service accounts (one per integration).
  • Scoped. Tokens carry only the permissions their service account was given (governance.controls:read, governance.findings:write, etc.).
  • Audited. Every call is attributed to the service account and appears in the workspace audit log.
  • Idempotent on writes via an Idempotency-Key header.

If you’ve used Stripe, GitHub, or any other modern REST API in the last few years, this will feel familiar.

Step 1: Create a service account

In the Novantra web app: Developers → API → Credentials → New service account.

Set:

  • a clear name (the integration’s name; this is what appears in the audit log)
  • a scope set matching what the integration needs (start narrow; you can add scopes later)
  • optionally, an expiry date

When you save, you receive a client id and client secret. The client secret is shown once, at creation time. Capture it and store it in your secrets manager.

If you lose the client secret, you cannot retrieve it. Rotate it instead, which issues a new secret and invalidates the old one.

See Authentication for the full credential-management documentation.

Step 2: Get an access token

Exchange your client credentials for a short-lived access token:

POST /api/v1/auth/token Content-Type: application/json { "grant_type": "client_credentials", "client_id": "svc_01EXAMPLE00000000000000000", "client_secret": "<client-secret>" }

Response:

{ "access_token": "...", "token_type": "Bearer", "expires_in": 3600, "scope": "governance.controls:read governance.findings:write" }

Cache the token in memory and re-fetch when it’s about to expire. Don’t fetch a new token per request.

Step 3: Make your first call

A simple read against the controls endpoint:

GET /api/v1/governance/controls?limit=10 Authorization: Bearer <access-token>

Response (shape):

{ "controls": [ { "id": "ctrl_01HXY...", "controlKey": "access-control-policy", "title": "Access Control Policy", "status": "active" ... } ], "pagination": {} }

If you got back a controls array, your integration is wired up. From here, you can follow the per-module reference under Governance to do whatever your integration needs.

You want to…Read
Understand the shape every endpoint followsv1 conventions
Wire credential rotationAuthentication
Know which versions are stable and when they’ll changeVersioning
Handle errors and rate-limit responsesErrors, Rate limits
Page through large result setsPagination
Implement safe writesErrors → Idempotency keys
Receive event notifications instead of pollingWebhooks
Find the endpoint for a specific governance moduleGovernance reference

A worked first-integration scenario

A regional credit union wants to mirror its open findings into ServiceNow as incidents.

  1. The credit union’s platform team creates a service account named “ServiceNow Findings Mirror” with scopes governance.findings:read and governance.findings:write (read to list, write only to acknowledge resolution back).
  2. The integration starts a daily incremental pull using GET /api/v1/governance/findings?status=open&updated_since=<last_run> with cursor pagination.
  3. New findings become ServiceNow incidents; closed findings close their corresponding incidents.
  4. When ServiceNow marks an incident as a duplicate, the integration POSTs back to the finding with a verified-as-duplicate event, using an Idempotency-Key derived from the ServiceNow incident id so retries are safe.
  5. To avoid polling, the integration subscribes to the finding.status_changed webhook (see Webhooks) and falls back to the daily pull for catch-up.

That’s the whole first integration. No special endpoints, no setup beyond a service account.

v1 is intentionally narrow

What’s in v1 today: reads for the governance foundation modules (controls, risks, evidence, assessments, findings, exceptions, monitoring, indicators, submissions, frameworks, assets, party engagements, change management, vulnerability management), plus targeted writes for findings, evidence claims, and submission events.

What’s not in v1: organization administration, member and role mutation, license operations, billing, key management, backup and restore, bulk destructive writes, cross-organization operations. These stay inside the Novantra application UI for now.

See REST API overview for the full scoping rationale.

Help

If something doesn’t work as documented, check:

  • the v1 conventions for the shape you should be getting back
  • Errors for what your error envelope means
  • the per-module reference under Governance for the endpoint’s exact behavior

If you’re still stuck, your account team can help.

Last updated on