Getting Started
Authenticate against the FlowOS API and make your first request in under 5 minutes.
Prerequisites
You need a FlowOS instance (cloud or self-hosted) and a user account with at least the developer role. Super-admin accounts can generate API keys for any workspace; regular users can only generate keys scoped to workspaces they belong to.
Step 1 — Generate an API key
Navigate to Settings → API Keys inside your FlowOS instance, or call the token endpoint directly:
curl -X POST https://acme.flowos.io/api/v1/auth/token \
-H "Content-Type: application/json" \
-d '{
"email": "you@acme.com",
"password": "your-password"
}'Response:
{
"token": "fos_live_4k2Xm9pQrT8vNwYzA3bCdEfGhIjKlMnOpQrStUvWxYz",
"expiresAt": "2026-12-31T23:59:59Z",
"workspace": {
"id": "ws_01HZ4KPQRSTUV",
"name": "Acme Corp",
"slug": "acme"
},
"user": {
"id": "usr_01HZ4KPQRSTUV",
"name": "Alice Smith",
"roles": ["admin"]
}
}FLOWOS_TOKEN=fos_live_...Step 2 — Set the authorization header
All API requests must include the token as a Bearer credential in the Authorization header, and a X-Workspace header identifying which workspace to scope the request to:
curl https://acme.flowos.io/api/v1/workflows \
-H "Authorization: Bearer fos_live_4k2Xm9..." \
-H "X-Workspace: acme"acme.flowos.io/dashboard). You can also discover it from the /api/v1/workspaces/me endpoint.Step 3 — Your first API call
List workflows in your workspace:
curl https://acme.flowos.io/api/v1/workflows \
-H "Authorization: Bearer $FLOWOS_TOKEN" \
-H "X-Workspace: acme"Response:
{
"data": [
{
"id": "wf_01HZ4KPQRSTUV",
"name": "Employee Onboarding",
"status": "active",
"trigger": { "type": "record_created", "table": "employees" },
"lastRunAt": "2026-06-01T09:32:11Z",
"runCount": 142,
"createdAt": "2026-04-15T12:00:00Z"
}
],
"meta": {
"total": 48,
"page": 1,
"pageSize": 20,
"nextCursor": "cursor_abc123"
}
}Pagination
All list endpoints use cursor-based pagination. Pass cursor from the meta.nextCursor field to get the next page. The default page size is 20; maximum is 100.
# First page (default size 20)
GET /api/v1/workflows
# Next page
GET /api/v1/workflows?cursor=cursor_abc123
# Larger page
GET /api/v1/workflows?pageSize=50
# Filter & sort
GET /api/v1/workflows?status=active&sort=createdAt&order=descError handling
All errors return a consistent JSON envelope with an HTTP status code, error code, and human-readable message.
{
"error": {
"code": "NOT_FOUND",
"message": "Workflow wf_unknown not found in workspace acme",
"statusCode": 404,
"requestId": "req_01HZ9MNPQRSTUV"
}
}| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| UNAUTHORIZED | 401 | optional | — | Missing or invalid Bearer token |
| FORBIDDEN | 403 | optional | — | Token valid but lacks the required role/permission |
| NOT_FOUND | 404 | optional | — | The requested resource does not exist |
| VALIDATION_ERROR | 422 | optional | — | Request body failed schema validation |
| RATE_LIMITED | 429 | optional | — | Too many requests — back off and retry |
| INTERNAL_ERROR | 500 | optional | — | Unexpected server error — include requestId when reporting |
Rate limits
API rate limits are enforced per token per workspace. Limits are returned in response headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1717276800Default limit is 1,000 requests per minute. Bulk endpoints (e.g. batch create) count as 10 per call. Enterprise plans have configurable limits. When rate-limited, retry after the X-RateLimit-Reset Unix timestamp.
Environments
FlowOS supports multiple environments per workspace (development, staging, production). Specify the environment in the X-Environment header. Defaults to production.
curl https://acme.flowos.io/api/v1/workflows \
-H "Authorization: Bearer $FLOWOS_TOKEN" \
-H "X-Workspace: acme" \
-H "X-Environment: staging"Using the Node.js SDK
import { FlowOS } from '@flowos/sdk'
const client = new FlowOS({
token: process.env.FLOWOS_TOKEN!,
workspace: 'acme',
environment: 'production', // optional, defaults to production
})
// List workflows
const { data: workflows, meta } = await client.workflows.list({
status: 'active',
pageSize: 20,
})
// Get a single workflow
const workflow = await client.workflows.get('wf_01HZ4KPQRSTUV')
// Trigger a workflow manually
const run = await client.workflows.trigger('wf_01HZ4KPQRSTUV', {
input: { userId: 'usr_123', department: 'Engineering' },
})
console.log(run.id, run.status) // run_01HZX... "queued"Next steps
Now that you can authenticate and make requests, read the Core Concepts guide to understand workspaces, environments, and entities — then jump into whichever studio is most relevant to your use case.