FormaOS API
Compliance data, automation events, and delivery primitives in one surface.
The v1 API supports bearer API keys and authenticated sessions, scoped per organization, with rate limits, cursor pagination, and signed webhooks.
Authentication
Use Authorization: Bearer fos_.... If no API key is provided, session authentication is used as a fallback.
Rate Limits
Every response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset.
Envelope
All list endpoints return { data, meta: { cursor, hasMore, total } }.
Endpoint Reference
/api/v1/api-keysList API keys
Scopes: webhooks:manage
/api/v1/api-keysCreate API key
Scopes: webhooks:manage
/api/v1/api-keys/{keyId}Update API key
Scopes: webhooks:manage
/api/v1/api-keys/{keyId}Revoke API key
Scopes: webhooks:manage
/api/v1/organizationsGet current organization
Scopes: organizations:read
/api/v1/membersList organization members
Scopes: members:read
/api/v1/membersInvite member
Scopes: members:write
/api/v1/members/{memberId}Get member or invitation
Scopes: members:read
/api/v1/members/{memberId}Update member role
Scopes: members:write
/api/v1/members/{memberId}Remove member or revoke invitation
Scopes: members:write
/api/v1/frameworksList installed frameworks
Scopes: frameworks:read
/api/v1/controlsList controls
Scopes: controls:read
/api/v1/controls/{controlId}Get control detail
Scopes: controls:read
/api/v1/certificatesList certificates
Scopes: certificates:read
/api/v1/reportsList reports
Scopes: reports:read
/api/v1/reportsGenerate report
Scopes: reports:write
/api/v1/reports/{reportId}Get report job or redirect to download
Scopes: reports:read
/api/v1/notificationsList notifications
Scopes: notifications:read
/api/v1/notificationsMark notifications read
Scopes: notifications:write
/api/v1/searchUnified organization search
Scopes: search:read
/api/v1/webhooks/deliveriesList webhook deliveries
Scopes: webhooks:manage
/api/v1/webhooks/testSend test webhook
Scopes: webhooks:manage
/api/v1/integrationsList available and connected integrations
Scopes: integrations:read
/api/v1/integrations/{integrationId}Connect or test an integration
Scopes: integrations:write
/api/v1/integrations/{integrationId}Disconnect an integration
Scopes: integrations:write
/api/v1/integrations/{integrationId}/eventsList integration events
Scopes: integrations:read
Webhook Events
Member Added
member.addedMember Removed
member.removedTask Created
task.createdTask Completed
task.completedEvidence Uploaded
evidence.uploadedEvidence Verified
evidence.verifiedPolicy Published
policy.publishedIncident Created
incident.createdCompliance Score Changed
compliance.score_changedScopes
Examples
cURL
curl -X GET "https://app.formaos.com.au/api/v1/organizations" \ -H "Authorization: Bearer fos_xxxx.yyyy" \ -H "Content-Type: application/json"
JavaScript
const response = await fetch("https://app.formaos.com.au/api/v1/tasks", {
headers: {
Authorization: "Bearer fos_xxxx.yyyy",
},
});
const payload = await response.json();Python
import requests
response = requests.get(
"https://app.formaos.com.au/api/v1/reports",
headers={"Authorization": "Bearer fos_xxxx.yyyy"},
timeout=30,
)
print(response.json())OpenAPI 3.1
The spec below is generated from route metadata and can be used to bootstrap SDKs.
{
"openapi": "3.1.0",
"info": {
"title": "FormaOS API",
"version": "1.0.0",
"description": "Customer-facing API for compliance data, webhooks, and integrations."
},
"servers": [
{
"url": "https://app.formaos.com.au"
}
],
"components": {
"securitySchemes": {
"bearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "API key or Supabase session token"
}
},
"schemas": {
"ApiKeyScope": {
"type": "string",
"enum": [
"tasks:read",
"tasks:write",
"evidence:read",
"evidence:write",
"compliance:read",
"audit:read",
"webhooks:manage",
"members:read",
"members:write",
"reports:read",
"reports:write",
"frameworks:read",
"organizations:read",
"certificates:read",
"controls:read",
"notifications:read",
"notifications:write",
"integrations:read",
"integrations:write",
"search:read"
]
}
}
},
"paths": {
"/api/v1/api-keys": {
"get": {
"operationId": "listApiKeys",
"summary": "List API keys",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"webhooks:manage"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
},
"post": {
"operationId": "createApiKey",
"summary": "Create API key",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"webhooks:manage"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/api-keys/{keyId}": {
"patch": {
"operationId": "updateApiKey",
"summary": "Update API key",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"webhooks:manage"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
},
"delete": {
"operationId": "revokeApiKey",
"summary": "Revoke API key",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"webhooks:manage"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/organizations": {
"get": {
"operationId": "getOrganization",
"summary": "Get current organization",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"organizations:read"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/members": {
"get": {
"operationId": "listMembers",
"summary": "List organization members",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"members:read"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
},
"post": {
"operationId": "inviteMember",
"summary": "Invite member",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"members:write"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/members/{memberId}": {
"get": {
"operationId": "getMember",
"summary": "Get member or invitation",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"members:read"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
},
"patch": {
"operationId": "updateMember",
"summary": "Update member role",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"members:write"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
},
"delete": {
"operationId": "removeMember",
"summary": "Remove member or revoke invitation",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"members:write"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/frameworks": {
"get": {
"operationId": "listFrameworks",
"summary": "List installed frameworks",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"frameworks:read"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/controls": {
"get": {
"operationId": "listControls",
"summary": "List controls",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"controls:read"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/controls/{controlId}": {
"get": {
"operationId": "getControl",
"summary": "Get control detail",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"controls:read"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/certificates": {
"get": {
"operationId": "listCertificates",
"summary": "List certificates",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"certificates:read"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/reports": {
"get": {
"operationId": "listReports",
"summary": "List reports",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"reports:read"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
},
"post": {
"operationId": "generateReport",
"summary": "Generate report",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"reports:write"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/reports/{reportId}": {
"get": {
"operationId": "getReport",
"summary": "Get report job or redirect to download",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"reports:read"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/notifications": {
"get": {
"operationId": "listNotifications",
"summary": "List notifications",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"notifications:read"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
},
"patch": {
"operationId": "markNotificationsRead",
"summary": "Mark notifications read",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"notifications:write"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/search": {
"get": {
"operationId": "search",
"summary": "Unified organization search",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"search:read"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/webhooks/deliveries": {
"get": {
"operationId": "listWebhookDeliveries",
"summary": "List webhook deliveries",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"webhooks:manage"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/webhooks/test": {
"post": {
"operationId": "sendWebhookTest",
"summary": "Send test webhook",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"webhooks:manage"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/integrations": {
"get": {
"operationId": "listIntegrations",
"summary": "List available and connected integrations",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"integrations:read"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/integrations/{integrationId}": {
"post": {
"operationId": "connectOrTestIntegration",
"summary": "Connect or test an integration",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"integrations:write"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
},
"delete": {
"operationId": "disconnectIntegration",
"summary": "Disconnect an integration",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"integrations:write"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
},
"/api/v1/integrations/{integrationId}/events": {
"get": {
"operationId": "listIntegrationEvents",
"summary": "List integration events",
"security": [
{
"bearerAuth": []
}
],
"x-formaos-scopes": [
"integrations:read"
],
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"429": {
"description": "Rate limited"
}
}
}
}
}
}Error Codes
400Invalid request body, query params, or scope mismatch.401Missing or invalid API key / session.403Organization isolation or admin guard failure.429Rate limit exceeded for API key or session.500Internal processing failure or downstream dependency error.
