Skip to main content
The easiest way: ask your AI assistant. With Itoflow MCP connected to Claude or Codex, paste:

Open in Claude

Start this in Claude with the Itoflow plugin.

Open in ChatGPT

Start this in ChatGPT with the Itoflow plugin.
Using another client? Copy the prompt with the button on the code block.No tokens or code needed. You can also do this in the Itoflow app. The rest of this page covers the HTTP API.
A strategy runs a portfolio under a mandate you write. Each run (an execution) reads the mandate, researches, and records a decision: the trades it proposes. Trades record what then happened to each order. Keep execution, decision and trade IDs apart; they are different things. Creating a strategy for an existing portfolio needs a known current value. If an open holding has no usable current price, creation returns 400 PORTFOLIO_VALUE_UNKNOWN with a reason that names each such holding, and leaves the portfolio unlinked. Public showcase holding weights use signed market value divided by net asset value (NAV), including cash. Holdings rank by absolute value and keep their signs. For example, a $1,000 portfolio with $600 and $300 holdings and $100 cash shows 60% and 30%. If value is unknown, each weight is null with valuation_unavailable_reason.

Create a strategy

POST /strategies creates a paper strategy, which trades a simulated portfolio. You can also create one in the app.
max_position_pct stays a ratio from 0.001 to 1, and min_cash_pct stays from 0 to 1. Margin and financing are out of scope. A target may hold more than 100% gross across names: thirteen longs at 10% each and three shorts at 10% each make a 130/30 book, and each position stays within its size limit. Trades are paid for from cash already held. A run’s buys need cash above 110% of their value; a cover may also use what the run’s long sales raise. A short sale’s proceeds reach cash once it fills, so they pay for buys in later runs, not in the run that sells short. A paper book therefore builds a 130/30 position over several runs, and after each run its cash stays above a tenth of that run’s buys. name is required without portfolioId. Other optional fields are description and sourceChatId. The 201 response includes id, portfolioId, isActive, executionStatus, and effectiveConstraints and effectiveRules. The effective fields include the defaults Itoflow filled in, so check them rather than assume an omitted control is off. A portfolio watched by a fund-oversight monitor can’t also have a strategy. Choosing one returns 409 PORTFOLIO_HAS_MONITOR.

Read strategies

  • GET /strategies lists strategies you can see, which may include some you don’t own.
  • GET /strategies/{id} returns one strategy: mandate, whether you own it, portfolio, constraints, run state and version.
  • GET /strategies/public lists the public showcase.
  • GET /strategies/eligible lists strategies that can be linked to a broker. A strategy whose book or latest target holds a short is excluded because live short sales are not supported. A paper book whose current value is not known is also excluded. The response lists these books in ineligibleStrategies, with strategyId, currentValue: null and a reason. It never returns a partial sum as an eligible book’s value.
Only the owner can change a strategy.

Change a mandate

PUT /strategies/{id} takes the fields you want to change. When you change the mandate, constraints, rules, universe or allocation guidance, also send changeDescription, or you get 400 CHANGE_DESC_REQUIRED. Each change creates a new version; the response returns versionId and versionNumber.
Editing cancels pending trades. A new version cancels the strategy’s pending trades, including approved live trades not yet sent to the broker. You can’t edit a running strategy (400 CANNOT_EDIT_RUNNING) unless you change only the model; pause it first.
To avoid overwriting someone else’s edit, send the expectedVersion you last read. If a newer version exists, the request fails; reload the strategy and decide again.

Run a strategy and follow it

execute returns 202 with execution_id, strategy_id, status, estimated_duration_seconds and stream_url. The run has been queued, nothing more, and a 202 is never a fill. Follow it, then check its decision and trades. Each request queues a new run, so if you lose the response, check active-execution before you try again. For strategies on the legacy execution path, each failed automatic run makes the trigger chain wait before it re-arms: 5 minutes, 30 minutes, 2 hours, then 24 hours for each later failure. A real decision from an automatic run clears the count. The first failure on a new strategy version starts at one. Manual runs, cancelled runs, blocked runs, completed runs with no decision, and skips leave the count unchanged. Re-arming checks the trigger rules again; it does not promise a run at that time. The failure wait also holds after a scheduler restart or a change to the trigger rules. A new strategy version does not inherit the old version’s wait. On the legacy execution path, if the model provider rejects saved session content, the run can retry in a fresh session within its three-attempt limit. The agent keeps its saved workspace and states that it lost its prior session context. Follow the run through its final decision or failure. The live stream stays open through retries while the same run remains active, including runs longer than 65 minutes. It sends the final status when the run completes, fails or is cancelled. If the run is no longer marked active, the normal stream timeout applies; check active-execution and the saved events. A manual run queued behind an active run keeps its stream open while its own task state is queued. It does not replace the active run’s marker.

Results

/paper-trading/{strategyId}/status, /trades, /decisions, /approvals and /pending-trades return a strategy’s state and history. /paper-trading/summaries lists portfolios, each with its trading mode, broker sync status and the strategy that manages it. strategy is null for a broker portfolio no strategy manages. A summary’s decisionType says what the strategy decided, not whether an order filled. A holding’s weight is its signed value divided by the portfolio’s net asset value. A book worth zero or less has no weights, so its status returns empty holdings and a valuationError with code PORTFOLIO_VALUE_NOT_POSITIVE and a message that gives the net asset value. Otherwise valuationError is null. Each summary’s status follows the same rule. Both routes include available and reserved cash in net asset value: $100 stock, $100 available cash and $100 reserved for a pending buy give a stock weight of 33.33%. The agent’s history file and day-start returns count the cash a pending buy held at the time. Before a paper-trading agent receives its input tables, preparation checks the price, currency and exchange rate of every open holding. If any line cannot be valued, the decision still runs. The files keep that line with a null value and a reason naming the symbols. Portfolio value, cash weight, all holding weights and returns that need the missing value remain null. Pending-trade projections preserve these null weights. Trade sizing refuses when a stored open holding cannot be valued; a missed live quote in the input files alone does not refuse sizing. Historical reports and emails also check stored marks and show unknown values when the evidence is unusable. An import price placeholder stays out of the input tables, as it does from trade sizing. The agent’s history file uses a stored daily return only from the holdings snapshot’s own UTC date. A missing reading on that date gives a null daily return. Cumulative return uses the latest reading at or before the snapshot; portfolio value comes from that snapshot’s holdings. For holdings and trade approvals, see Portfolios.

Live strategies

POST /strategies/live creates a strategy for a live portfolio linked to a broker connection. It takes the same body as a paper strategy, but portfolioId must name a live portfolio. Its starting capital is the broker account’s total value when you link it. Every live trade needs your approval before Itoflow sends it to the broker. See Approve trades.

Models

Set rules.model_key to a fusion mode or a single model when you create or edit a strategy; edits without it keep the saved choice. New strategies without a choice use the plan’s default_mode from /pricing/model-access. Each run pins both the main model and Guardian when it starts; retries keep those routes. A single choice uses that model for both agents. If you lose access to a paid choice, new runs stop with “Choose the Free model or upgrade” until you change the choice or upgrade. A connected ChatGPT subscription does not fund strategies. See models and plans. For a walk-through, see Run a strategy under a mandate. To design and test one first, see Build and stress-test a strategy idea. See the strategy endpoint reference for every field.