API Changelog
Changes to the Flowstate REST API, the MCP server, outbound webhooks and custom integrations, newest first. GraphQL is the app’s own API and isn’t covered here.
Version numbers follow Semantic Versioning. Read Changed and Removed before you upgrade an integration.
For product changes, see Flowstate Updates.
v1.6.0 — 2026-09-10
Functional groups over REST, MCP, webhooks and custom integrations. Teams are archived rather than deleted, and MCP says more about projects and effort.
Added
- Functional groups REST endpoints under
/org/{orgId}/functional-groups:GET /tree(the whole visible hierarchy on a day, up to 500 groups),GET /(list, paged withoffsetandlimit),GET /:id,GET /:id/summary,GET /:id/positions,POST /andPUT /:id(create or update a group),POST /:id/move,POST /positionsandPUT /positions/:id,POST /assignmentsandPUT /assignments/:id,POST /structure/move,POST /accessandDELETE /access/:id, and custom attribute values under/groups/:id/custom-attributesand/positions/:id/custom-attributes. Reads takeasOf; reads and writes take?scenarioId=. Every path returns403 FEATURE_DISABLEDwhile the module is off for the organisation. The endpoints are in the OpenAPI spec. See Functional groups. - Thirteen functional group MCP tools. Read:
list_functional_groups,get_functional_group. Write:add_functional_group,update_functional_group,move_functional_group,add_functional_position,update_functional_position,fill_functional_position,update_functional_assignment,move_functional_position,add_functional_group_manager,remove_functional_group_manager,set_functional_group_cost_visibility. See MCP server. - Three webhook entity types:
functional_group,functional_positionandfunctional_assignment. These records are dated and never deleted, so retiring one arrives as anupdatecarrying itsendDate, never as adelete. See Webhooks. - Custom integration hooks for the functional structure. PULL and PUSH hooks can target
functional_group,functional_positionandfunctional_assignment. See Data model. - Custom attributes on functional groups and positions: the
FUNCTIONAL_GROUPandFUNCTIONAL_POSITIONentity types. See Custom attributes. archivedAtandarchiveAppliedAton teams. Returned byGET /teamsandGET /teams/:id. Both are read-only. See Teams.isOwnershipOnlyon team assignments. Read-only.truewhen a team is attached to a project as its owner without allocating any capacity; those assignments have anfteof0. See Assignments.- Archive state over MCP.
search_teamstakesarchived(active,archivedorall), andsearch_teamsandget_team_detailsreturnarchivedAtandisArchived. - Find projects by PMS link over MCP.
search_projectstakespmsLinked(falsefinds projects linked to no Jira, Linear or Azure DevOps project) andsourceSystem(how the project was created, such asmanualorjira). Each result carriessourceSystemandpmsLinked.get_project_detailsalso returnssourceSystem,pmsLinkedandlinkedPmsProjects. - Effort units over MCP.
get_team_effortandget_project_efforttotals carryunit: "person-days":ftefigures are work-day equivalents summed over the window, not an average FTE.
Changed
- Teams are archived in the app instead of deleted. Archiving sets the day the team goes: from that day it’s hidden in the app and its open allocations end the day before. Archiving sends a
teamupdatewebhook. Over REST:GET /teamsstill returns archived teams, so filter onarchivedAt;PATCH /teams/:idcan’t setarchivedAt; andDELETE /teams/:idstill permanently deletes the team and its allocations. Archive in the app when you want to keep a team’s history. search_teamsleaves archived teams out by default. Passarchived: "all"to include them.search_projectsreturns{ totalCount, returned, projects }instead of a bare list.totalCountcounts every match, not just the page returned.
v1.5.0 — 2026-08-19
Push business metric readings over REST, four Insights tools on MCP, and AI spend questions through query_analytics.
Added
POST /org/{orgId}/business-metrics/readings: push a batch of up to 1,000 readings for one metric from one source. Each reading upserts on metric, source andperiodStart, so sending a period again corrects it. A source that doesn’t exist yet is created on the first push. Needs thebusiness_metrics_ingestpermission (Ingest Business Metric Readings). Limited to 120 requests a minute per API key; over the limit the endpoint returns429with aRetry-Afterheader and{ "error": "too_many_requests", "error_description": "…" }. The endpoint is in the OpenAPI spec. See Business metrics.- Four MCP tools, each returning one Insights screen in a single answer:
get_ai_adoption_summary(AI adoption and idle seats),get_business_metrics_summary(every active metric with volume, AI share and cost per unit),get_hybrid_workforce_summary(employees, contractors and agents with cost and AI share) andget_project_value_summary(a project’s cost against the value it promised). See MCP server. - Top-N and team roll-ups in
query_analytics.sort(one of the requested metrics),order(ASCorDESC) andlimit(up to 25 series) answer “top five” questions. TheDESCENDANT_OFfilter operator, onTEAMonly, matches a team and every team beneath it. - AI and code delivery in
query_analytics. OnACTUALdata it accepts the metricsAI_COST,AI_SESSIONS,AI_FRUSTRATION,AI_INPUT_QUALITY_AVG,AI_TOKENS,AI_REQUESTS,PR_COUNT,COST_PER_PRandLINES_CHANGED, and the dimensionsPROVIDER,MODEL,AI_USE_CATEGORY,AI_BUSINESS_FUNCTION,AI_ACTIVITY_TYPE,REPO,DELIVERY_KINDandOPERATOR.TEAM_PARENTandJOB_ROLE_FAMILYare listed too.COST,AI_COSTandCOST_PER_PRneed financial access.
Removed
get_ai_usage_summary,get_ai_spend_by_teamandget_ai_spend_by_person. Askquery_analyticsforAI_COSTbyPROVIDER,TEAMorEMPLOYEEinstead.
v1.4.0 — 2026-07-10
CapEx, R&D, code delivery and more budget tools on MCP, AI policy webhooks, and one salary per vacancy.
Added
-
MCP tools for effort, budgets, CapEx, R&D and code delivery.
- Effort:
get_effort_gaps,get_uncosted_effort,get_submission_leaderboard. - Budgets and forecast:
list_forecast_budget_snapshots,get_forecast_budget_drift_summary,add_budget_proposal_comment,cancel_budget_request. - CapEx and R&D:
get_capex_project_breakdown,get_capex_initiative_breakdown,get_capex_declared_vs_claimed,list_capex_claims,list_rd_claims,delete_capitalisation. - Code delivery:
get_code_delivery_summary,get_code_delivery_trends,list_pull_requests. - Scenario allocations:
allocate_contractor_to_project,allocate_vacancy_to_project,remove_allocation. - AI sessions:
mark_my_ai_sessions_as_project.
See MCP server.
- Effort:
-
More detail on AI agents over MCP.
add_ai_agentandupdate_ai_agenttakepurpose,agentOrigin,providerNativeAgentId,region,modelSlug,ownerEmployeeId,ownerContractorIdandaiServiceAccountId. -
The
ai_policywebhook entity type. See Webhooks.
Changed
- Vacancies carry one
salary. Sendsalarywhen you create or update a vacancy over REST or from a custom integration.salaryMinandsalaryMaxare still accepted but deprecated: an explicitsalarywins, otherwise a range is stored as its midpoint. Vacancy responses returnsalaryand no longer returnsalaryMinorsalaryMax. See Vacancies. add_ai_agentneedsproviderSlug(for exampleanthropicoropenai) in place ofprovider.monthlyPerSeatPriceis optional.merge_budget_proposalno longer merges. It returns an error telling you to lock the budget request, which finalises the approved budget.approve_budget_proposalreturns the resultingstatus:APPROVED, orMERGEDwhen approval rolls the proposal into its parent.
Removed
set_initiative_commitment. An initiative’s resourcing is the sum of its projects’ allocations.costCentreIdfromget_initiative_details. A project’s cost centre lives on the project.get_ai_wastage_summary.
v1.3.0 — 2026-06-11
Initiatives, objectives and the budget workflow on MCP, custom attributes in MCP searches, project delivery status, and team and initiative hooks.
Added
- Initiative, objective and key result MCP tools. Read:
search_initiatives,get_initiative_details,list_portfolio,list_objectives. Write:add_initiative,update_initiative,delete_initiative,adopt_project_to_initiative,detach_project_from_initiative,set_initiative_commitment,create_capex_claim,add_objective,update_objective,delete_objective,add_key_result,update_key_result,delete_key_result. These writes change live data; no scenario is needed. See MCP server. - Budget workflow MCP tools. Read:
list_budget_requests,get_budget_request,get_budget_proposal,get_budget_envelope. Write, on live data:create_budget_request,assign_budget_proposal,submit_budget_proposal,approve_budget_proposal,reject_budget_proposal,merge_budget_proposal. - Custom attributes over MCP.
list_custom_attributeslists the keys.search_employees,search_teams,search_projects,search_contractorsandsearch_vacanciestakecustomAttributeFiltersand return each record’scustomAttributes, as doget_employee_details,get_team_detailsandget_project_details. get_ai_security_metricsandget_ai_wastage_summaryMCP tools.deliveryStatusfilter onsearch_projects:BACKLOG,TODO,IN_PROGRESS,IN_REVIEW,DONEorCANCELLED.search_projectsandget_project_detailsreturn the project’sstatus.- Vacancy end dates. Vacancies take
targetEndDatefor a fixed-term role over REST and from custom integrations;GET /vacanciescan sort by it. An end date beforetargetStartDatereturns400. Over MCP,add_vacancytakestargetStartDateandtargetEndDate, andupdate_vacancytakestargetEndDate. See Vacancies. - Job roles on contractors.
POSTandPATCH /contractorstakejobRoleId, orjobRolewith atitleorexternalId; contractor records from custom integrations takejobRoletoo. - The
agent_policyandinitiativewebhook entity types. See Webhooks. teamandinitiativehook entities. PULL and PUSH hooks can target teams, including the parent team and team manager, and initiatives. See Data model.
Changed
- Salary and rate data needs
financials_view_detailed. Reading salary adjustments or rate adjustments, andinclude=currentSalary,salaryHistory,currentRateorrateHistory, return403 FORBIDDENfor an API key without it. Reading a record’s custom attribute values needssettings_entity_config_view. See Authentication. - Changing a vacancy’s dates moves its assignments. When
PATCH /vacancies/:idchangestargetStartDateortargetEndDate, the vacancy’s team and project assignments move to the new dates. See Vacancies. - A project’s
statusis its delivery status, such asBACKLOGorIN_PROGRESS. It’s read-only over REST. See Projects. - MCP tools check permissions. Each write tool needs the matching Flowstate permission, and scenario writes need a scenario still in draft; otherwise the tool returns an error. Employee
salary,bonus,currentSalaryandsalaryHistory, and contractorrate,rateTypeandcurrency, come backnullfor people withoutfinancials_view_detailed. get_budget_envelopereports amounts in the envelope’s currency. It returnscurrencyCode,totalCostandtotalFte, anddivergencereportsenvelopeCost,currentCost,deltaCostand the matching FTE figures in that currency.- MCP client registration has limits. Redirect URIs must be
https, orhttponlocalhost,127.0.0.1or[::1]; anything else returns400 invalid_redirect_uri. A client can register at most 5 redirect URIs and aclient_nameof at most 200 characters; beyond that the response is400 invalid_client_metadata. Each IP address can register at most 20 clients an hour. See MCP server. - Custom integration records need an
externalId. A record without a non-emptyexternalIdis rejected on its own with an error; the rest of the run carries on.
Removed
lifecycleStageIdon projects over REST, and onadd_projectandupdate_projectover MCP. ThelifecycleStagefilter and field onsearch_projectsandget_project_detailsare gone too; usedeliveryStatusandstatus.targetFillDateon vacancies, from REST requests, responses andsortBy, and from custom integration vacancy records. It’s ignored if sent. UsetargetStartDateandtargetEndDate.- The
lifecycle_stagewebhook entity type. envelopeAmountUSD,totalCostUSDanddivergence.divergenceCostUSDfromget_budget_envelope.
v1.2.0 — 2026-05-12
Your own IDs everywhere, custom integrations, contractor-filled vacancies, and slicing and filtering in query_analytics.
Added
- Custom integrations. Write PULL hooks that run on a schedule or on demand, and PUSH hooks that run when a record is created, updated or deleted, for
employee,vacancy,contractor,projectandassignment. Hooks getctx.secrets,ctx.http,ctx.kv,ctx.logandctx.org, PUSH hooks getctx.event, and a PULL hook can page through a source by returningmoreandmeta. See Custom integrations. externalIdon employees, contractors, vacancies, teams and projects. Set it on create or update and it comes back in responses. Any path:id, and reference fields such asteamId,projectId,employeeId,managerIdandhiringManagerId, accept either the Flowstate ID or yourexternalId. AnexternalIdshaped like a Flowstate ID returns400.attributeKeyon custom attribute definitions. A stable key of lowercase letters, digits and underscores, generated from the name if you don’t send one. It can’t be changed after creation. Custom integrations keycustomAttributesby it.SELECTandCURRENCYcustom attribute types. Definitions takeselectOptions; values takeselectValue, orcurrencyCodewithcurrencyAmount. See Custom attributes.- Job roles by title or your own ID. Employee and vacancy create and update, the vacancy fill endpoint, and custom integration employee and vacancy records take
jobRole: { title, externalId }. A matching role is used, otherwise one is created.jobRoleIdtakes precedence. - Fill a vacancy with a contractor.
POST /vacancies/:id/filltakesfillerType:employee(the default) orcontractor. The contractor branch needsname,rate,rateTypeandcurrencyCode, and creates the contractor with its first rate adjustment. Sending employee fields withfillerType: "contractor"returns400. The response hasemployeeandcontractor, and the one not used isnull. Filling a vacancy that’s already filled returns409. See Vacancies. filledByLiveContractorIdon vacancy reads, alongsidefilledByLiveEmployeeId. Both are set by the fill endpoint, not byPATCH.- Filled-by references in custom integrations. Vacancy records take
filledBy: { externalId }or the shorthandfilledByExternalId, matched against employees and contractors, orfilledByEmployeeIdorfilledByContractorId.filledBy: nullclears the fill. See Syncing positions as vacancies. - Allocations and deletions in custom integrations. Records take
teamAllocationsandprojectAllocationswithteamId,projectId,startDateandendDate; the earlier field names still work.deletedAton a record, or on a nested allocation, salary or rate entry, deletes it, and an allocation the integration created that’s missing from a sent list is removed. Nested salary, rate and project allocation entries takeexternalId. See Data model. - Filters and effort submissions in
query_analytics.filterstakes a JSON array of{ dimension, operator, values }withEQ,INorNOT_IN.costSectionnarrows actuals toUNLINKED_PMS_WORK,HOLIDAY,NON_PROJECTorUNTRACKED.dataSource: "SUBMISSION"with theSUBMISSION_COUNTmetric answers questions about effort submissions, andPMS_PROJECTis a dimension on actuals.
Changed
- Contractor
rateTypeis one ofhourly,daily,monthlyorannually. Any other value is rejected on REST contractor writes, nestedrateAdjustmentand rate adjustments, onadd_contractorandupdate_contractorover MCP, and on custom integration contractor records.annuallyis newly accepted. - One failing custom integration record no longer fails the rest of its page. Every PULL processes every record it returns.
v1.1.0 — 2026-04-08
The MCP server, outbound webhook events, salary and rate adjustments, custom attributes, nested writes and vacancy fill.
Added
- The MCP server. People connect Claude, ChatGPT and other assistants by signing in with their own Flowstate account over OAuth; MCP doesn’t use API keys. An admin switches it on for the organisation. The first release carried the read tools for people, teams, projects, contractors, vacancies, analytics and AI spend, and scenario write tools. Limited to 100 requests a minute per person, with
X-RateLimit-LimitandX-RateLimit-Remainingon every response and429over the limit. See MCP server and Rate limiting. get_project_effort,get_team_effortandget_unattributed_effortMCP tools.- Outbound webhook events for employees, teams, contractors, projects, vacancies, employee, contractor and vacancy allocations to teams and projects, team allocations to projects, salary adjustments, bonuses, contractor rates and AI agents. Each delivery is a
create,updateordeletewithbeforeandafter, signed inX-Flowstate-Signature, withX-Flowstate-Event-Idfor de-duplication. Merging a scenario sends one event per change withinitiator.typemerge. See Webhooks. - Salary adjustments and contractor rate adjustments. List, create, update and delete them under
/employees/:id/salary-adjustmentsand/contractors/:id/rate-adjustments. See Salary adjustments and Contractor rate adjustments. - Custom attributes. Define
STRING,NUMBER,DATEandDATE_RANGEfields for employees, contractors, vacancies, teams and projects withGET,POST,PATCHandDELETE /custom-attributes. Read a record’s values withGET /{resource}/:id/custom-attributes, and set or remove one withPUTorDELETE /{resource}/:id/custom-attributes/:definitionId.GETfor a single record returnscustomAttributes. See Custom attributes. - Nested writes.
POSTandPATCH /employeestakesalary,teamAssignmentandprojectAssignment;POSTandPATCH /contractorstakerateAdjustment,teamAssignmentandprojectAssignment. OnPATCHthey add a new record rather than replacing one. - Vacancy fill.
POST /vacancies/:id/fillturns a vacancy into an employee and moves the vacancy’s allocations across. ?include=embeds related records. Employees:currentSalary,salaryHistory,assignments. Contractors:currentRate,rateHistory,assignments. Vacancies (single record):assignments,filledByEmployee. An unknown value returns400.
v1.0.0 — 2026-03-11
The Flowstate REST API.
Added
- Employees: create, read, update and delete employee records.
- Contractors: contractors with
rate,rateType,currencyCodeand contract dates. - Vacancies: open roles with a salary range and a status.
- Teams: teams with a parent team.
- Projects: projects with dates and an estimated cost.
- Assignments: allocate employees, contractors and vacancies to a team or a project under
/assignments/employees,/assignments/contractorsand/assignments/vacancies, and teams to projects under/assignments/teams. - Pagination:
page,limit(up to 100),search,sortByandsortDiron every list. See Pagination. - Authentication: API keys sent as
Authorization: Bearer private_…. Each key carries its own permissions, never more than its creator’s, and lasts at most 90 days. A missing permission returns403 FORBIDDEN. See Authentication. - Errors:
{ "error": { "code", "message", "details", "errorId" } }. See Errors. - OpenAPI spec and Swagger UI describing the API.