Skip to main content

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

get/api/v1/api-keys

List API keys

Scopes: webhooks:manage

post/api/v1/api-keys

Create API key

Scopes: webhooks:manage

patch/api/v1/api-keys/{keyId}

Update API key

Scopes: webhooks:manage

delete/api/v1/api-keys/{keyId}

Revoke API key

Scopes: webhooks:manage

get/api/v1/organizations

Get current organization

Scopes: organizations:read

get/api/v1/members

List organization members

Scopes: members:read

post/api/v1/members

Invite member

Scopes: members:write

get/api/v1/members/{memberId}

Get member or invitation

Scopes: members:read

patch/api/v1/members/{memberId}

Update member role

Scopes: members:write

delete/api/v1/members/{memberId}

Remove member or revoke invitation

Scopes: members:write

get/api/v1/frameworks

List installed frameworks

Scopes: frameworks:read

get/api/v1/controls

List controls

Scopes: controls:read

get/api/v1/controls/{controlId}

Get control detail

Scopes: controls:read

get/api/v1/certificates

List certificates

Scopes: certificates:read

get/api/v1/reports

List reports

Scopes: reports:read

post/api/v1/reports

Generate report

Scopes: reports:write

get/api/v1/reports/{reportId}

Get report job or redirect to download

Scopes: reports:read

get/api/v1/notifications

List notifications

Scopes: notifications:read

patch/api/v1/notifications

Mark notifications read

Scopes: notifications:write

get/api/v1/search

Unified organization search

Scopes: search:read

get/api/v1/webhooks/deliveries

List webhook deliveries

Scopes: webhooks:manage

post/api/v1/webhooks/test

Send test webhook

Scopes: webhooks:manage

get/api/v1/integrations

List available and connected integrations

Scopes: integrations:read

post/api/v1/integrations/{integrationId}

Connect or test an integration

Scopes: integrations:write

delete/api/v1/integrations/{integrationId}

Disconnect an integration

Scopes: integrations:write

get/api/v1/integrations/{integrationId}/events

List integration events

Scopes: integrations:read

Webhook Events

Member Added

member.added

Member Removed

member.removed

Task Created

task.created

Task Completed

task.completed

Evidence Uploaded

evidence.uploaded

Evidence Verified

evidence.verified

Policy Published

policy.published

Incident Created

incident.created

Compliance Score Changed

compliance.score_changed

Scopes

tasks:readtasks:writeevidence:readevidence:writecompliance:readaudit:readwebhooks:managemembers:readmembers:writereports:readreports:writeframeworks:readorganizations:readcertificates:readcontrols:readnotifications:readnotifications:writeintegrations:readintegrations:writesearch:read

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

  • 400 Invalid request body, query params, or scope mismatch.
  • 401 Missing or invalid API key / session.
  • 403 Organization isolation or admin guard failure.
  • 429 Rate limit exceeded for API key or session.
  • 500 Internal processing failure or downstream dependency error.