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

  1. sign in at app.simplestuff.ai and open settings > api keys (click your name in the sidebar, then workspace settings).
  2. create a key. it starts with fiq_ and is shown once - store it somewhere safe. we only keep a hash.
  3. 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.
treat keys like passwords. if one leaks, revoke it in settings and mint a new one - the raw key is never stored on our side, so there is nothing to rotate server-side.

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_workspaces returns the ids.
  • membership is re-validated on every call. a workspace_id, process or capture you cannot access answers not_found - existence is never revealed across workspaces.

recommended flow for agents:

  1. list_workspaces to see the options.
  2. list_teams / list_processes to find the process.
  3. list_captures + get_capture for recorded detail, get_synthesis for 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

limitvaluebehavior
calls per key per day1,000resets at midnight utc; over the limit answers http 429
active keys per user10creating an 11th answers http 409
request duration60slong tool calls are cut off at the platform limit

errors

errorwheremeaning
401 invalid_api_keyhttpmissing, malformed, revoked, or unknown key
429 rate_limit_exceededhttpdaily call budget spent; retry after midnight utc
403 forbidden_originhttpbrowser request from an origin we do not allow
*_not_foundtool resultthe resource does not exist or your key cannot access it - deliberately the same answer
no_synthesistool resultthe 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.