API Reference
The platform exposes a unified REST API across every security domain: about 166 endpoints across roughly 60 routers, served from a single base path (/api/v1) behind a FastAPI BFF gateway. Every call is tenant-scoped, permission-checked at the engine layer, and idempotent on scan_run_id — you can integrate the platform into any CI/CD pipeline, GRC tool, or custom dashboard with a single set of credentials.
This reference covers authentication, base URLs, pagination, error handling, and the endpoint map. For the exact shape of finding objects, see the Finding Schema.
Authentication
All API requests require a valid signed token. The token is issued by the platform's authentication service when you log in, scoped to your tenant ID, and validated on every request.
Reading the flow top to bottom:
- POST /api/auth/login — the client sends credentials.
- Set-Cookie: access_token — the platform issues a signed token, scoped to your tenant ID.
- GET /api/v1/... — the client makes an API call, sending the token cookie.
- Validate token and build AuthContext — the gateway decodes the token and builds an internal context with tenant ID, role, and permissions.
- Forward to engine with X-Auth-Context — the gateway hands the request to the engine with a signed context header; engines never trust client-supplied identity.
- Engine returns a scoped response — the engine validates the required permission via
require_permission(), runs the query with aWHERE tenant_id = ?filter, and returns the data.
Two properties worth knowing: the token is signed (tampering invalidates it immediately), and the engine layer does its own permission check — the gateway is not the only line of defense. Cross-tenant probes return 404, not 403, so attackers cannot use response codes to map another tenant's resources.
Login
POST /api/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "your-password"
}The response sets an access_token cookie. Include this cookie in all subsequent requests.
API key authentication (coming soon)
Long-lived API keys for programmatic access are on the roadmap. Watch the release notes for availability.
Base URLs and gateway operations
All requests route through the BFF gateway under the /api/v1 prefix. Direct engine access is not supported in production.
| Environment | Base URL |
|---|---|
| Production | https://api.onam.io/api/v1 |
| Staging | https://api.staging.onam.io/api/v1 |
| Local dev | http://localhost:8000/api/v1 |
The gateway also exposes three operational endpoints outside the versioned prefix:
| Endpoint | Returns |
|---|---|
GET /gateway/health | Gateway liveness and upstream engine health summary |
GET /gateway/services | Registered engine services and their status |
GET /gateway/openapi.json | The merged OpenAPI spec for all routed endpoints |
The OpenAPI document drives any client generator — point openapi-generator or your tooling of choice at /gateway/openapi.json.
Common patterns
Pagination
List endpoints return the standard PaginatedList envelope:
GET /api/v1/check/findings?page=1&page_size=50| Parameter | Default | Max | Description |
|---|---|---|---|
page | 1 | — | Page number |
page_size | 50 | 200 | Results per page |
Response envelope:
{
"items": [ ... ],
"total": 1247,
"page": 1,
"page_size": 50,
"has_more": true
}Filtering
Most list endpoints support filtering via query parameters:
GET /api/v1/check/findings?severity=critical&provider=aws&status=OPENCommon filter fields are severity, provider (aws, azure, gcp, oci, alicloud, ibm, k8s), status, region, account_id, and resource_type.
Error responses
Errors return a structured envelope — never a bare string:
{
"page": "vulnerability",
"error_code": "FORBIDDEN",
"message": "Missing permission: vulnerability:read",
"detail": null,
"degraded_engines": []
}The degraded_engines field lists any upstream engines that failed during a multi-engine aggregation, so a dashboard call can succeed partially and tell you which domain is stale.
| Status | Meaning |
|---|---|
400 | Bad request — invalid parameters |
401 | Unauthenticated — missing or expired token |
403 | Forbidden — insufficient permissions |
404 | Not found — includes cross-tenant probes, by design |
422 | Validation error — see the detail field |
500 | Internal server error |
503 | Upstream engine unavailable — check degraded_engines |
Endpoints by engine
The gateway routes /api/v1/<prefix> to the owning engine. Every endpoint shares the same response envelope, error envelope, and pagination contract — once you've integrated one engine, the others work the same way.
| Area | Prefixes |
|---|---|
| Discovery and posture | /di (discovery and inventory) · /check (CSPM rule findings) · /rules (rule catalog) · /compliance (framework scores and reports) |
| Identity and data | /iam-security · /data-security · /database-security · /encryption |
| Workload and network | /network-security · /container-security · /cwpp · /cnapp · /agent (host agents) |
| Threat and detection | /cdr (behavioral detection) · /ai-security · /apisec · /secops (SAST, DAST, SCA) |
| Risk and reporting | /risk (FAIR quantification) · /billing |
| Operations | /scans · /scan-runs · /schedules · /pipeline (pipeline monitor) · /onboarding · /cloud-accounts · /accounts · /tenants · /technology (self-hosted technology scanning) |
Beyond the per-engine prefixes, cross-cutting endpoints live directly under /api/v1 — the dashboard, attack paths, inventory, asset context, and the universal finding-detail views.
Representative endpoints
A sample of the most-used endpoints across the surface. The full, always-current list is in the OpenAPI spec at /gateway/openapi.json.
| Method | Path | Returns |
|---|---|---|
GET | /api/v1/dashboard | Aggregated posture overview across all engines |
GET | /api/v1/attack-paths | Attack paths ranked by risk (Attack Path v2) |
GET | /api/v1/compliance/framework/{framework_id}/report | Full per-framework compliance report |
GET | /api/v1/cdr/heatmap | Detection heatmap from behavioral analysis |
GET | /api/v1/vulnerability/findings/stats | Vulnerability statistics by severity, EPSS, and KEV |
GET | /api/v1/risk/blast-radius | Financial blast-radius analysis (FAIR) |
GET | /api/v1/risk/crown-jewels | Crown-jewel assets and their exposure |
GET | /api/v1/inventory/asset/{resource_uid}/blast-radius | Blast radius for a single asset |
GET | /api/v1/asset-context/{resource_uid} | Cross-engine context for one resource |
GET | /api/v1/views/finding/{engine}/{id} | Full finding detail — header, related findings, compliance, remediation |
PATCH | /api/v1/views/finding/{engine}/{id}/status | Update finding status, with audit log |
Example — per-framework compliance report:
GET /api/v1/compliance/framework/cis-aws-v3/report
Cookie: access_token=<token>{
"framework_id": "cis-aws-v3",
"framework_name": "CIS AWS Foundations Benchmark v3.0",
"score": 78.4,
"pass_count": 312,
"fail_count": 86,
"total_controls": 398,
"last_evaluated": "2026-07-18T10:00:00Z",
"trend": [
{ "date": "2026-06-01", "score": 74.1 },
{ "date": "2026-07-01", "score": 78.4 }
]
}Example — dashboard overview:
GET /api/v1/dashboard{
"posture_score": 72,
"critical_findings": 12,
"high_findings": 47,
"total_resources": 8432,
"accounts_connected": 3,
"last_scan": "2026-07-18T10:00:00Z",
"compliance_summary": {
"cis-aws-v3": 78.4,
"nist-csf-2": 81.2
}
}Rate limits
| Plan | Requests per minute | Requests per hour |
|---|---|---|
| Starter | 60 | 1,000 |
| Growth | 300 | 10,000 |
| Enterprise | 1,000 | 50,000 |
Rate limit headers are returned on every response:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 247
X-RateLimit-Reset: 1784548800Build your client to honorX-RateLimit-Remainingand back off before hitting the limit. Bulk exports should paginate withpage_size=200and respecthas_morerather than issuing parallel page requests.
SDKs and client libraries
Official clients are in development. Until they ship, generate a client from the OpenAPI spec at /gateway/openapi.json.
| Language | Status |
|---|---|
| Python | Planned |
| Go | Planned |
| Terraform provider | Planned |
Next steps
- Finding Schema — the exact shape of every finding object the API returns
- RBAC & SSO — the
feature:actionpermissions each endpoint requires - Integration Catalog — push findings to Jira, Slack, Splunk, and webhooks instead of polling
- Quickstart — connect your first cloud account and run a scan