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.
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.
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:
Authorization: Bearer ak_live_xxxxxxxxxxxxxxxxxxxxxxxx
x-api-key: ak_live_xxxxxxxxxxxxxxxxxxxxxxxx
Each key carries scopes:
| Scope | Grants |
|---|---|
| read | All GET endpoints. |
| write | Create 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.
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.
List endpoints accept two query parameters and echo them back in meta:
| Param | Type | Default | Notes |
|---|---|---|---|
limit | integer | 50 | Max 200. Values above 200 are clamped. |
offset | integer | 0 | Number 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.
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" }
| Status | Meaning |
|---|---|
200 | OK (list / read) |
201 | Created (POST) |
400 | Invalid request body / missing required field |
401 | Missing or invalid API key |
403 | Key lacks the required scope (e.g. write) |
404 | Unknown resource |
405 | Method not allowed (only GET and POST are supported) |
429 | Rate limit exceeded (1,000 / hour) |
5xx | Upstream / internal error |
| Param | Notes |
|---|---|
limit, offset | Pagination (see above). |
curl https://getassurai.com/api/v1/projects \
-H "Authorization: Bearer ak_live_xxxxxxxx"
{
"data": [
{ "id": "a1b2…", "name": "FY26 SOX Walkthrough", "status": "active" }
],
"meta": { "limit": 50, "offset": 0, "count": 7 }
}
| Param | Notes |
|---|---|
status | Exact match, e.g. open, in_progress, remediated. |
severity | Exact match, e.g. Critical, Significant, Moderate. |
limit, offset | Pagination. |
curl "https://getassurai.com/api/v1/findings?status=open&severity=Critical&limit=25" \ -H "x-api-key: ak_live_xxxxxxxx"
{
"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 }
}
| Param | Notes |
|---|---|
limit, offset | Pagination. |
curl https://getassurai.com/api/v1/controls \
-H "Authorization: Bearer ak_live_xxxxxxxx"
{
"data": [
{ "id": "c55…", "name": "Logical access review", "status": "effective" }
],
"meta": { "limit": 50, "offset": 0, "count": 42 }
}
| Param | Notes |
|---|---|
limit, offset | Pagination. |
curl https://getassurai.com/api/v1/workpapers \
-H "Authorization: Bearer ak_live_xxxxxxxx"
{
"data": [
{ "id": "wp9…", "title": "AP cutoff testing", "status": "review" }
],
"meta": { "limit": 50, "offset": 0, "count": 18 }
}
| Param | Notes |
|---|---|
limit, offset | Pagination. |
curl https://getassurai.com/api/v1/kris \
-H "Authorization: Bearer ak_live_xxxxxxxx"
{
"data": [
{ "id": "k3…", "name": "Overdue remediations", "value": 4, "threshold": 3 }
],
"meta": { "limit": 50, "offset": 0, "count": 12 }
}
Requires a key with the write scope. The new finding is automatically attached to your organization. Only title is required.
| Field | Required | Notes |
|---|---|---|
title | yes | Short finding title. |
severity | no | Critical · Significant · Moderate · Observation. |
condition | no | What was observed (the issue). |
recommendation | no | Recommended remediation. |
criteria, cause, effect | no | Standard IIA/PCAOB finding components. |
module, process, finding_type | no | Classification metadata. |
due_date, status | no | Remediation tracking. |
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" }'
{
"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.