⚙️ Enterprise REST API

Build on the
AssurAI API.

A simple, key-authenticated REST API to read your organization's findings, controls, workpapers, KRIs and projects — and to create findings programmatically. All responses are JSON and scoped to your organization.

Base URL Authentication Rate limits Pagination Errors Endpoints

Base URL

All endpoints are served under a single, versioned base URL:

https://getassurai.com/api/v1

A request to /api/v1/findings therefore resolves to https://getassurai.com/api/v1/findings.

Authentication

Every request must include a valid API key. Create and revoke keys in Settings → Enterprise API. The plaintext key is shown only once at creation time — store it securely. Pass it using either header:

Option A — Authorization header
Authorization: Bearer ak_live_xxxxxxxxxxxxxxxxxxxxxxxx
Option B — x-api-key header
x-api-key: ak_live_xxxxxxxxxxxxxxxxxxxxxxxx

Each key carries scopes:

ScopeGrants
readAll GET endpoints.
writeCreate operations (e.g. POST /findings) in addition to read.

A missing or malformed key returns 401. A revoked or unknown key returns 401 Invalid API key. A request to a write endpoint with a read-only key returns 403. Keys are always scoped to a single organization — you can only ever see and write your own org's data.

Rate limits

Each API key may make 1,000 requests per hour (a rolling 60-minute window). Exceeding the limit returns HTTP 429 with body { "error": "Rate limit exceeded. Limit is 1000 requests per hour." }. Limits are tracked per key, so separate keys do not share a budget.

Pagination

List endpoints accept two query parameters and echo them back in meta:

ParamTypeDefaultNotes
limitinteger50Max 200. Values above 200 are clamped.
offsetinteger0Number of records to skip.

Every list response has the shape:

{
  "data": [ /* records */ ],
  "meta": { "limit": 50, "offset": 0, "count": 128 }
}

meta.count is the total number of matching records (across all pages) when available.

Error format

Errors return a non-2xx status and a JSON body with a single error string. Messages are intentionally generic; detailed diagnostics are logged server-side.

{ "error": "Invalid API key" }
StatusMeaning
200OK (list / read)
201Created (POST)
400Invalid request body / missing required field
401Missing or invalid API key
403Key lacks the required scope (e.g. write)
404Unknown resource
405Method not allowed (only GET and POST are supported)
429Rate limit exceeded (1,000 / hour)
5xxUpstream / internal error

Endpoints

GET/api/v1/projectsList audit projects / engagements
Query parameters
ParamNotes
limit, offsetPagination (see above).
Example request
curl https://getassurai.com/api/v1/projects \
  -H "Authorization: Bearer ak_live_xxxxxxxx"
Example response
{
  "data": [
    { "id": "a1b2…", "name": "FY26 SOX Walkthrough", "status": "active" }
  ],
  "meta": { "limit": 50, "offset": 0, "count": 7 }
}
GET/api/v1/findingsList findings, with filters
Query parameters
ParamNotes
statusExact match, e.g. open, in_progress, remediated.
severityExact match, e.g. Critical, Significant, Moderate.
limit, offsetPagination.
Example request
curl "https://getassurai.com/api/v1/findings?status=open&severity=Critical&limit=25" \
  -H "x-api-key: ak_live_xxxxxxxx"
Example response
{
  "data": [
    {
      "id": "f100…",
      "title": "Missing segregation of duties in AP",
      "severity": "Critical",
      "status": "open",
      "recommendation": "Split invoice entry and approval roles."
    }
  ],
  "meta": { "limit": 25, "offset": 0, "count": 3 }
}
GET/api/v1/controlsList controls
Query parameters
ParamNotes
limit, offsetPagination.
Example request
curl https://getassurai.com/api/v1/controls \
  -H "Authorization: Bearer ak_live_xxxxxxxx"
Example response
{
  "data": [
    { "id": "c55…", "name": "Logical access review", "status": "effective" }
  ],
  "meta": { "limit": 50, "offset": 0, "count": 42 }
}
GET/api/v1/workpapersList workpapers
Query parameters
ParamNotes
limit, offsetPagination.
Example request
curl https://getassurai.com/api/v1/workpapers \
  -H "Authorization: Bearer ak_live_xxxxxxxx"
Example response
{
  "data": [
    { "id": "wp9…", "title": "AP cutoff testing", "status": "review" }
  ],
  "meta": { "limit": 50, "offset": 0, "count": 18 }
}
GET/api/v1/krisList key risk indicators
Query parameters
ParamNotes
limit, offsetPagination.
Example request
curl https://getassurai.com/api/v1/kris \
  -H "Authorization: Bearer ak_live_xxxxxxxx"
Example response
{
  "data": [
    { "id": "k3…", "name": "Overdue remediations", "value": 4, "threshold": 3 }
  ],
  "meta": { "limit": 50, "offset": 0, "count": 12 }
}
POST/api/v1/findingsCreate a finding  write

Requires a key with the write scope. The new finding is automatically attached to your organization. Only title is required.

Body fields
FieldRequiredNotes
titleyesShort finding title.
severitynoCritical · Significant · Moderate · Observation.
conditionnoWhat was observed (the issue).
recommendationnoRecommended remediation.
criteria, cause, effectnoStandard IIA/PCAOB finding components.
module, process, finding_typenoClassification metadata.
due_date, statusnoRemediation tracking.
Example request
curl -X POST https://getassurai.com/api/v1/findings \
  -H "Authorization: Bearer ak_live_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
        "title": "Privileged access not reviewed quarterly",
        "severity": "Significant",
        "condition": "Q1 access review was not performed.",
        "recommendation": "Run and document the review each quarter.",
        "status": "open"
      }'
Example response (201 Created)
{
  "data": {
    "id": "f7a2…",
    "finding_id": "F-2026-014",
    "title": "Privileged access not reviewed quarterly",
    "severity": "Significant",
    "status": "open"
  }
}

Need a key? Head to Settings → Enterprise API to generate one. Questions? Contact support@getassurai.com.