flowIQ for developers
flowIQ maps how teams actually work: captures (recorded walkthroughs and interviews) become step-by-step workflows, and multiple captures of the same process get synthesized into one process map. this page documents the hosted mcp server that lets ai agents read and act on that data.
hierarchy: workspace (organization) > teams > processes > captures.
getting started
- sign in at app.simplestuff.ai and open settings > api keys (click your name in the sidebar, then workspace settings).
- create a key. it starts with
fiq_and is shown once - store it somewhere safe. we only keep a hash. - connect an mcp client (below) or call the endpoint directly over json-rpc.
# quickest check: list the tools your key can call
curl -X POST https://app.simplestuff.ai/api/mcp \
-H "Authorization: Bearer fiq_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'authentication
every request needs an api key, sent as Authorization: Bearer fiq_... or X-API-Key: fiq_.... keys are user-wide: one key works across every workspace you are a member of, and each call can target a workspace via the workspace_id parameter.
- up to 10 active keys per user.
- revoking a key (settings > api keys) disables it immediately.
- keys inherit your permissions - nothing more. a key can never see workspaces you are not a member of.
connect a client
the mcp server lives at https://app.simplestuff.ai/api/mcp (streamable http, stateless - no session handshake required).
claude code
claude mcp add flowiq --transport http https://app.simplestuff.ai/api/mcp \
--header "Authorization: Bearer fiq_YOUR_KEY"claude desktop / other json config clients
{
"mcpServers": {
"flowiq": {
"type": "http",
"url": "https://app.simplestuff.ai/api/mcp",
"headers": {
"Authorization": "Bearer fiq_YOUR_KEY"
}
}
}
}cursor
// .cursor/mcp.json
{
"mcpServers": {
"flowiq": {
"url": "https://app.simplestuff.ai/api/mcp",
"headers": { "Authorization": "Bearer fiq_YOUR_KEY" }
}
}
}how scoping works
keys are user-wide, so the workspace is chosen per call. tools that operate at workspace level take an optional workspace_id:
- omit it and the call uses your first workspace - fine if you only have one.
- pass it explicitly when you belong to several.
list_workspacesreturns the ids. - membership is re-validated on every call. a
workspace_id, process or capture you cannot access answersnot_found- existence is never revealed across workspaces.
recommended flow for agents:
list_workspacesto see the options.list_teams/list_processesto find the process.list_captures+get_capturefor recorded detail,get_synthesisfor the merged process-level view.
tool reference
30 tools. reads mirror what a member sees in the app; writes are real and follow the same permission rules as the ui.
list_workspacesread
every workspace (organization) this key can act in, with your role in each. call this first; pass the chosen workspace_id to other tools.
params: none
list_teamsread
teams in a workspace. teams group related processes.
params: workspace_id? (uuid)
list_processesread
processes in a workspace, optionally filtered to one team. a process is a mapped piece of how the team works; its captures hold the recorded detail.
params: workspace_id? (uuid), team_id? (uuid)
get_processread
one process: name, team, whether a synthesis exists, and its capture list.
params: process_id (uuid)
list_capturesread
the captures (recorded workflow sessions) of a process.
params: process_id (uuid)
get_captureread
one capture: extracted workflow (steps, exceptions), status, duration, language. transcripts are omitted unless requested - they can be long.
params: capture_id (uuid), include_transcript? (boolean, default false)
get_synthesisread
the process-level synthesis: the merged view built from multiple captures (consensus steps, variations, open questions). fails with no_synthesis if none exists yet.
params: process_id (uuid)
list_membersread
members of a workspace with their names and roles.
params: workspace_id? (uuid)
create_processwrite
create a new process in a team. captures can then be recorded against it.
params: team_id (uuid), name (string, 1-120 chars)
create_teamwrite
create a new team in a workspace. the caller becomes its owner.
params: workspace_id? (uuid), name (string, 1-80 chars)
invite_memberwrite
invite someone to a team by email. new emails get a real invite email; existing accounts are added directly and notified in-app. allowed for a workspace owner/admin or a manager of that team.
params: team_id (uuid), email (string), role? (manager | member, default member)
update_capture_stepswrite
replace the step list of a capture you own. steps are objects with at least step_number and description. owner-only.
params: capture_id (uuid), steps (array of objects, min 1)
finalize_capturewrite
mark a capture as completed (reviewer sign-off) or reopen it. allowed for the capture owner or a manager of its process.
params: capture_id (uuid), finalized (boolean)
delete_capturedestructive
permanently delete a capture you own. irreversible - clients should confirm with the user first.
params: capture_id (uuid)
run_synthesiswrite
start a synthesis run: merges the process’s captures into one process-level view. runs as a background job - poll get_synthesis_status. needs 2+ complete captures with steps. workspace owner/admin or team manager only. idempotent while a job is live.
params: process_id (uuid), language? (string, default English)
get_synthesis_statusread
the latest synthesis job for a process (pending, running, done, failed). when done, read the result with get_synthesis.
params: process_id (uuid)
get_share_linkread
the public share state of a process; returns the public read-only link when sharing is on. workspace owner/admin or team manager only.
params: process_id (uuid)
set_sharingwrite
turn public sharing of a process on or off. on mints a stable unguessable link (readable by anyone with it, transcripts included); off kills the link. workspace owner/admin or team manager only.
params: process_id (uuid), share (boolean)
export_processread
export a process artifact inline as text: steps.csv (consolidated step register, needs a v2 synthesis), report.json (full synthesis payload), or map.json (process map graph).
params: process_id (uuid), artifact (steps.csv | report.json | map.json)
export_captureread
export a capture artifact inline as text: steps.csv (step table), transcript.txt (speaker-turn transcript), or map.svg (workflow map).
params: capture_id (uuid), artifact (steps.csv | transcript.txt | map.svg)
list_invitationsread
pending invitations of a workspace (email, team, role, sent date). ids feed revoke_invitation.
params: workspace_id? (uuid)
revoke_invitationwrite
revoke a pending invitation so its link stops working. workspace owner/admin only.
params: invitation_id (uuid)
delete_processdestructive
permanently delete a process with all its captures, transcripts, and uploaded files. irreversible - clients should confirm with the user first. workspace owner/admin or team manager only.
params: process_id (uuid)
update_teamwrite
rename a team. workspace owner/admin or a manager of that team only.
params: team_id (uuid), name (string, 1-60 chars)
delete_teamdestructive
delete a team. only works when the team has no processes (fails with team_not_empty otherwise). workspace owner/admin or a manager of that team only.
params: team_id (uuid)
add_team_memberwrite
add an existing workspace member to a team (invite_member handles new people). workspace owner/admin or a manager of that team only.
params: team_id (uuid), user_id (uuid), role? (manager | member, default member)
update_team_memberwrite
change a team member’s team role. cannot target yourself or the team owner. workspace owner/admin or a manager of that team only.
params: team_id (uuid), user_id (uuid), role (manager | member)
remove_team_memberwrite
remove a member from a team (their workspace membership stays). cannot target yourself or the team owner. workspace owner/admin or a manager of that team only.
params: team_id (uuid), user_id (uuid)
update_member_rolewrite
change a member’s workspace role. owner grants/demotions are owner-only; the founding workspace owner cannot be changed; cannot target yourself. workspace owner/admin only.
params: workspace_id? (uuid), user_id (uuid), role (owner | admin | member)
remove_memberdestructive
remove a member from a workspace and all its teams. removing an owner is owner-only; the founding workspace owner cannot be removed; cannot target yourself. workspace owner/admin only.
params: workspace_id? (uuid), user_id (uuid)
rate limits
| limit | value | behavior |
|---|---|---|
| calls per key per day | 1,000 | resets at midnight utc; over the limit answers http 429 |
| active keys per user | 10 | creating an 11th answers http 409 |
| request duration | 60s | long tool calls are cut off at the platform limit |
errors
| error | where | meaning |
|---|---|---|
| 401 invalid_api_key | http | missing, malformed, revoked, or unknown key |
| 429 rate_limit_exceeded | http | daily call budget spent; retry after midnight utc |
| 403 forbidden_origin | http | browser request from an origin we do not allow |
| *_not_found | tool result | the resource does not exist or your key cannot access it - deliberately the same answer |
| no_synthesis | tool result | the process has captures but no synthesis has been generated yet |
tool-level failures come back as mcp results with isError: true and a json body like {"error": "process_not_found"} - they are not http errors.