Changelog
Every change you can see, newest first. Additive changes never break a client that ignores unknown fields; breaking ones are announced before they ship.
- Additive
Automated strategies: backtests (flag off)
Behind
OMS_AUTO_BACKTEST(and the automated-strategies allowlist); with the flag off every route answers 403 and nothing users see changes. None of this has shipped.- New
POST /v2/backtests(BacktestInput:strategy_id,version?,from,to,capital?,costs? {chargesindia|zero,slippage_bps}) → 202BacktestView;GET /v2/backtests,GET /v2/backtests/{backtest_id}(statusqueued|running|done|failed|cancelled, orunknownfor a status this server does not know yet,progress,summary, dailyequity,labels,sources,counts),GET /v2/backtests/{backtest_id}/tradesand.../cycles(pages:offset,limit≤ 200),POST /v2/backtests/{backtest_id}/cancel. - A result on modelled option prices says so in
labels.text("Estimated: option prices are modelled from NIFTY and India VIX, not real trades") and on every trade (estimated: true). - New error codes
backtest_not_found(404),backtest_limit_reached(409: 3 queued or running, 50 a day),backtest_finished(409); 429rate_limitedabove 10 submissions a minute. Results are kept 30 days.
- New
- Additive
Automated strategies: adjustments (flags off)
Behind
OMS_AUTO_STRATEGIES(+OMS_AUTO_STRATEGIES_USERS). Nothing users see changes with the flags off, and none of this has shipped.- Strategy documents:
close_leg@1,reduce@1,roll_strike@1,add_hedge@1androll_expiry@1are nowpreview(runnable); newwiden@1(strikes, 1-20: every sold option and its hedge move that many strikes further out). Every adjuster gains an optionaltrigger(on:loss/profit{rupees},loss_pct/profit_pct{pctof the entry premium},elapsed{minutes},premium_ratio{leg,ratio},condition{when},expiry{dte_at_most,at};delta_band{band} is phase C, saved but not deployable), andwhenbecomes optional: give one of the two (validation says so). Normalized documents write"trigger": nullon adjustments that usewhen. Validation refuses closing a hedge a sold leg needs, a hedge added to a leg that is not a sold option, and legs that don't exist. Summaries say the trigger in words. - Engine: an adjustment fires when its trigger turns true (not again while it stays true), at most
max_per_cycleper rule and 10 per trade, at least a minute apart, never while paused, stopped, blocked, tripped, switched off, with stale prices, an exit in flight or the order limit reached. Closes go first (a sold leg is bought back before its replacement is sold), a hedge is replaced first, opens go hedge-first, a roll never opens more than it closed, and no step leaves more sold options unhedged or more sold than when it started. Stops, targets and exits keep precedence and never wait for an adjustment. - Journey step codes (event
auto.code, already "other values may appear"):adjust_sent,adjust_step,adjusted,adjust_skipped,adjust_halted,adjust_unknown(pages likeentry_unknown). Exit reasonadjustmentwhen an adjustment closed the last leg. - Stored / NATS (readers first: these pods read them before any writer ships): the unit plan's
adjustmentsrules; the snapshot'scycle.adjust, legbase/hedge_for/expiry/replaces;StrategyEnterlegs' optionalanchor(the held contract a new leg is placed against);ExitReason::adjustment; adjustment step events reusestrategy_enter/strategy_exit.
- Strategy documents:
- Additive
Automated strategies: sizing by risk or capital, stagger, sharing (flags off)
Behind
OMS_AUTO_STRATEGIES(+OMS_AUTO_STRATEGIES_USERS); sharing also behindOMS_AUTO_STRATEGIES_SHARING(default off). Nothing users see changes with the flags off, and none of these operations has shipped.- Strategy documents:
risk@1andcapital_pct@1sizing are nowpreview(runnable).risk@1needs a combined stop or a defined-risk structure (every sold option covered, one expiry), else validation says "Set a combined stop or add hedges to size by risk."execution.order:
stagger
(withstagger_ms) is no longer a blocker. Summaries say how each sizes and the gap between legs.- Execution:
risk_per_tradelots = floor(risk × multiplier / the most one unit can lose: the contracts' defined risk at expiry, else the combined stop), capped per leg keeping the ratio;capital_pctlots = floor( available margin × pct × multiplier / the broker's margin for one unit), worked out before the entry is stored (write-ahead). Unknown funds or a budget below one lot refuse the entry with the reason (other/zero_lots).staggersends one leg at a time, hedges first, each after the one before is final plusstagger_ms; a main takes its hedge's filled share and is not sent when the hedge filled nothing; every leg is still claimed up front and never resent. - New
PUT/DELETE /v2/strategies/{strategy_id}/sharing(SharingInput:visibilityprivate|users|link,shared_with,linkcreate|revoke; answerSharingView, the link token only in the answer that made it). New error codesno_saved_version(409) andshared_not_found(404). - New
GET /v2/shared,GET /v2/shared/strategies/{strategy_id}andGET /v2/shared/{link_token}(SharedStrategyView: the newest saved version's document and summary, the owner's short name,read_only; never the draft, accounts, deployments, orders, P&L, journeys or webhooks). POST /v2/strategies/import:from.link_token(new, optional) forks the version a share link shows;from.strategy_id(now optional, one of the two) also forks a strategy shared with the caller by name (saved versions only). Forks are the caller's own private drafts and never deploy.GET /v2/strategies/{strategy_id}: optionalupdate_available(UpdateAvailable:version,forked_version,message) on a fork whose source, still visible to the caller, has a newer saved version.visibilitymay now beusersorlink(values already documented).- Stored / NATS (readers first: these pods read them before any writer ships): the unit plan's
sizing.modegainsrisk_per_tradeandcapital_pct(withrisk_rupees,capital_pct),execution.ordergainsstagger(withstagger_ms); entry jobs carryexec.order:
stagger
. Mongoauto_strategiesnow writesvisibility,shared_withandlink(fields existed since phase A) and has two new indexes. - Strategy documents:
- Additive
Signals on algo mode (flag off)
Behind
OMS_SIGNALS_ALGO_MODE(and the automated-strategies allowlist). With the flag off, a signal URL never switched behaves exactly as before (its mode is looked up, and there is none). Fail closed: a URL left in algo mode while algo mode is off (or whose strategy is stopped or gone, or whose mode is unreadable) is never placed directly: the alert is answered 200 and ignored ("algo mode is paused for this URL; switch the URL back to direct to trade it directly"), recorded in the delivery and activity logs, and the user gets a notice (anomalysignal_algo_paused, "Strategy entry refused" event). Listing and switching back todirectwork whatever the flags; switching toalgoneeds them (403 otherwise).- New
GET /v2/signal-modes(SignalModeViewlist: each signal URL with its strategy'smodedirect|algo,deployment_id,switched_at,can_use_algo) andPUT /v2/signal-modes/{endpoint_id}(SignalModeInput:mode,deployment_id), app session only. New error codenot_flat(409): switching needs no position held by the Signals strategy and no open trade on the deployments involved. POST /v1/hooks/{kind}/{secret}: unchanged URLs, payloads, checks and replies. For a TradingView or Chartink strategy switched toalgo, an alert is sent to the bound deployment as a signal (TradingViewentry-> enter,exit-> exit; Chartink -> enter) instead of placing orders; its delivery log says "... alert sent to automated strategy “X”" and the activity log records it. Kuberhunt URLs stay direct.- Strategy documents:
webhook@1as an entry or exit source is nowpreview(runnable); a deploy using it is refused (not_deployable) whileOMS_SIGNALS_ALGO_MODEis off. - Stored: new Mongo collection
signal_modes(new record kind, reader test); engine commands now carryCommandOp::Signalwithsource: webhook(readers shipped in phase A).
- New
- Additive
Groww funds and trades read as the broker reports them
No field, type or enum changes; Groww accounts' values only.
GET /v1/portfolio/margins: a Groww account'savailableis Groww'sequity_margin_details.cnc_balance_available(wasclear_cash, which Groww reports as 0, so funds read 0),opening_balanceis available plus margin in use (a delivery sell's credit no longer makes it negative), andutilisedstays in 0-100.GET /v1/portfolio/tradesandtradewebhooks: a Groww fill read before Groww lists its trade rows is read again on the next refresh instead of staying missing for the day. Found by the first live Groww conformance runs, which also recorded CNC (DELIVERY) place / modify / cancel and a CNC sell refused for lack of holdings. Such a refusal (Groww's HTTP 200 withorder_statusFAILED) is now the order's rejection at once, with Groww's remark as the message, instead of an unconfirmed placement resolved REJECTED on the next order-book poll. - Breaking
Journey paging parameters documented in the query
GET /v2/deployments/{deployment_id}/journey:cursorandlimitwere documented as path parameters; they are, and always were, query parameters (?cursor=&limit=). Only the description changes; the server behaves as before. The diff tool sees two path parameters removed. Notified: 2026-10-19, app-cirrus #296 (the only client) reported it and asked for this fix; the operation has not shipped (PR #130 unmerged, flag off). - Additive
Automated strategies: analytics, P&L, templates, labels (flags off)
Behind
OMS_AUTO_STRATEGIES(+OMS_AUTO_STRATEGIES_USERS); nothing users see changes with the flag off, and none of these operations has shipped.POST /v2/strategies/dry-run: optionalanalytics(StrategyAnalytics, asGET /v1/strategies/{name}?scenario=1: payoff at expiry and today, breakevens, max profit / loss with the unlimited flags, probability of profit, per-leg IV and greeks, spot × IV grid) of the contracts it would pick,margin_estimate(AutoMarginEstimate:amount,methoddefined_risk|contract_value,note), andanalytics_notewhen there are none.GET /v2/strategiesitems,GET /v2/deployments/{id}andGET /v2/strategies/{id}/deployments: optionalpnl(AutoPnl:trading_day,realized,unrealized,total,ltp_stale) from the strategy ledgers by the deployments' strategy tags.GET /v2/deployments/{id}andGET /v2/strategies/{id}/deployments: optionalsafety_pauses(AutoSafetyPause:account,detector,evidence,at,trips_today,locked_until).GET /v2/deployments/{id}/live:unitgains optionalgreeks(net, incl. net delta) andanalytics_note; each leg optionaliv_pctandgreeks.- New
GET /v2/strategies/templates(AutoStrategyTemplate): ready strategy documents with name, goal, description, category, risk badge, components, indicators, broker needs, summary, deployable / blockers. GET /v2/strategies/capabilities:underlying_details(segment, lot size, strike step, expiry kinds, next expiries, spot),labels([{value, label}]for every enum value),enums.hedge_with.GET /v2/strategies/componentsand the published strategy JSON Schema (/v2/strategies/schema/1.json):x-labelsbeside everyenum.
- Additive
Automated strategies phase A wired end to end (flags off)
Everything below is behind
OMS_AUTO_STRATEGIES(+OMS_AUTO_STRATEGIES_USERS; 403 otherwise) orOMS_TRIGGERS_V2_INDICATORS; with the flags off nothing users see changes. None of these operations or records has shipped yet.- New
GET /v2/deployments/{deployment_id}/journey: every step on every account, newest first, paginated (cursor,limit1-200;422invalid_requestotherwise):at,account,day,cycle,kind,what_happened,what_we_did,what_you_should_do,broker_message(schemasAutoJourneyPage,AutoJourneyEntry). POST /v2/deployments/{id}/resumetakes an optional body{"acknowledged": bool}; after a safety pause (circuit breaker) it is required, else422acknowledgement_requiredwith what the breaker saw.GET /v2/deployments/{id}/live: each unit gains an optional typedunit(AutoUnitNumbers: state, cycle, open P&L, day P&L, trades today, floor, open legs, condition values with threshold and distance, P&L series, breaker detector / evidence / trips, blocked) from the engine; cycle details'journeyentries areAutoJourneyEntryobjects.- Deployments gain optional
strategy_name(stored on new deployments). POST /v2/strategies/dry-rungains an optionalat(window and days as at that time); entries are picked from the live chain by the leg previewer (would_enterwith legs and net premium, orwould_skipwith the reason); a condition entry iswould_waitwith what it would pick now.GET /v2/strategies/capabilitiesgainsindicator_functionswhile indicator conditions are on (the engine's registry).- Strategy document format v1:
execution.retry_next_signalis optional (null/ absent: a refused entry is tried again after a short wait;0: no more trades that day). Examples updated in place (only that field and the compiled hashes it changes). - Validation refuses exit conditions with different check / hold settings and API sources with different signal age limits (they used to be merged silently); strategy conditions are checked by the engine's own compiler (watched names
u.ltp; indicators, candles and crossings while indicator conditions are on). - Notifications: new event types
strategy_armed,strategy_refused,strategy_safety_pause,strategy_kill_switch,strategy_error;strategy_enteredandstrategy_exitedare now sent (examples oflist_notification_eventsand the preference defaults gain them). Strategy steps follow the user's preferences, narrowed to the strategy's ownnotifylist; urgent ones go to every channel. New records (readers first: the readers ship in this release, the writers are switched on with the flags):strategy_stepon core NATSoms.strategy.{user}.{deployment_id}(added to theOMS_EVENTSstream and theuser-notifyconsumer's subjects; a consumer created by an earlier build keeps its old subjects until recreated);auto_cyclesrows written by the strategy projector (withlast_seq); the engine's live-values answer gains an optionalautoblock;auto_strategyunits carry the plan's watched symbols inTrigger.watchand their indicator-condition state inSnapshot.cond.
- New
- Additive
Automated strategies wired to the OMS executor
No REST request, response, webhook or
/v1/streammessage changes. New records, read and written only by this code: the resolved entry joboms:auto:{ENV}:entry:{event_id}and its day indexoms:auto:{ENV}:entries:{day}(Redis), the expiry listsoms:auto:{ENV}:expiries(Redis, the shape W2's runtime already reads), and the takeover requestRebuildRequeston core NATS{ENV}.trg.auto.rebuild(readers first: the api reader ships with or before the runtime writer). The worker now writes thefill/entry_outcomecommands W2 added readers for, behindOMS_AUTO_STRATEGIES(default off). Thefillcommand gains an optionalsized_qty(units the worker asked the broker for on an entry leg; the engine takes it as the cycle's plan when sizing scaled the lots down). Readers first: the engine that reads it ships before the worker that writes it is switched on; an older engine ignores it. Theauto_strategyplan gains two optional options:execution.retry_next_signal(refused entries tried again on new signals at most this many times per cycle, then done for the day; absent = as before) andreentry.same_direction_only(default false). The plan is strict, so readers first: this engine ships before W1's compiler writes them. - Additive
Watched instruments on v2 triggers (`watch`)
POST /v2/triggersandPOST /v2/triggers/validateaccept an optionalwatch: up to 3{name, symbol}(instrument token) the conditions read but the trigger never trades, so a condition can saynifty.rsi(14, '5m')ornifty.ltp. Names are[a-z][a-z0-9_]{0,15}and not a variable or function name; each instrument counts toward the distinct-instrument limit;watchis fixed at create (PATCHkeeps it). New422s:watch"indicator conditions are not available yet" while indicator conditions are switched off;watch"at most 3 watched instruments…";watch[i].symbol"instrument … not found or expired";spec"watch[i].name: name watched instruments with lowercase letters, like nifty".validate'sreads.symbolslists the watched instruments a condition reads andreads.fieldstheir fields (nifty.ltp). Themalformed_jsonmessage for an unknown request field now listswatchamong the expected fields: examplescreate_trigger_v2/client_idandvalidate_trigger_v2/client_idre-recorded (only that message changed). - Additive
Automated strategies API, strategy document format (flag off)
New operations under tag
automated_strategies, all off by default (OMS_AUTO_STRATEGIES+OMS_AUTO_STRATEGIES_USERS; 403 otherwise):/v2/strategies(create, list, get, edit draft, archive, versions, clone, export, import, validate, dry-run, components, capabilities, stop-all),/v2/strategies/schema/{n}.json(the published JSON Schema, public),/v2/strategies/{id}/deployments(deploy, list) and/v2/deployments/{id}(get, pause, resume, stop, exit-now, go-live, signals, live, cycles, cycle). New pinned contract: the strategy document format v1,docs/api/strategy.schema.v1.json(additive within v1). New error codes, used only by these operations:strategy_not_found,version_not_found,deployment_not_found,schema_not_found,strategy_busy,strategy_in_use,deployment_finished,deployment_limit_reached,invalid_document,not_deployable,acknowledgement_required,live_not_enabled. New schemasAuto*. API key scopesstrategies,strategies_live,strategies_signalare read and enforced (readers first) but cannot be granted yet: key and partner-app creation refuse them, and theScopeschema still lists onlyread,orders,triggers. Examples recorded for the new operations. - Additive
Automated strategy units in the trigger engine (readers first)
No REST request, response, webhook or
/v1/streammessage changes. Stored and NATS records gain readers for the newauto_strategyengine kind (spec2026-10-18-automated-strategies-design.md§4.2, stage S0): trigger kindauto_strategy; actionsstrategy_enter/strategy_exit; command opsfill,entry_outcome,exit_now,stop,signal; events gain an optionalautoblock (cycle, day, phases, code, detail); snapshots gain an optionalautounit state; notes of kindauto_*. enums inwire_enums.json(TriggerKind,TriggerActionType,Auto*). Nothing writes them yet (OMS_AUTO_STRATEGIESoff; no API creates units).GET /v2/triggersand/v1/strategiesnever list anauto_strategyunit,/v2/triggers/{id}answers404for one, and its updates are not sent on the triggers stream, so no newkindvalue reaches clients.strategy_exitlegs gain optionallot_sizeandhedge_for, the action an optionalchase; afillmay name its cumulative quantityqty(alias offilled_qty). - Additive
Indicator conditions in v2 triggers (switched off)
Behind
OMS_TRIGGERS_V2_INDICATORS(off: nothing users see changes). NewGET /v2/triggers/{trigger_id}/indicators: each indicator value a trigger's conditions read, from the engine's memory (statusok, orunavailablewhen the engine does not answer within 500 ms;429above one request per second per trigger).POST /v2/triggers/validategains an optionalconditions(plain-English reading of conditions that use indicators, what they read and the history they need; absent otherwise).GET /v2/triggers/capabilitiesgains an optionalindicators(functions with parameter ranges, defaults and argument schemas, presets, timeframes, exchanges, limits; absent while switched off).POST /v2/triggers,PATCH /v2/triggers/{trigger_id}andvalidate: a spec using indicator functions,on,hold_sorrepeatis422invalid_request(fieldspec) "indicator conditions are not available yet" while switched off; once on, new422messages: no VWAP or candle volume on an index,repeaton an alert only (spec.repeat), NSE and BSE instruments only. No recorded example changed by this entry; the new operation's responses are listed incoverage-gaps.jsonuntil recorded against a running engine. - Additive
Indicator conditions, engine records (readers first)
Trigger engine v2 records other pods read (no REST change yet; the api keeps refusing the new fields until a later release). A v2 trigger may carry
watch([{name, symbol}], instruments read but never traded), and itsalert/bracketconditionson(close|tick),hold_sand, on alerts,repeat {cooldown_bars, max_per_day}; snapshots in{ENV}_TRG_STATEgain an optionalcond(crossing sides, holds, repeat counters); a repeating alert's events goarmedtoarmed; notes gain kindsstale_prices,data_gap,repeat,repeat_cap,indicator_warming,indicator_ready,indicator_fallback; new KV{ENV}_TRG_INDholds series snapshots (stored kindtrg_ind_series, statuswarming|ready|fallback). Every new field is optional and absent on older records; the engine that reads them ships before anything writes them (OMS_TRIGGERS_V2_INDICATORS, off by default, refuses them at create while off). - Additive
User notifications (Telegram, app, webhooks)
New
notificationsoperations (app session only;503notifications_disabledunless the server turns them on):GET /v1/notifications(the app inbox, 30 days,limit/before),GET /v1/notifications/events(every event type with its group, default,mandatoryandavailable),GET /v1/notifications/channels(Telegramnot_linked/linked/brokenwithbroken_reason, the app, the user's webhooks, andpromptsfor the app to show:connect_telegram,telegram_broken,webhook_failing),GET/PUT /v1/notifications/preferences(per channeltelegram,app_push,webhook: on / off, each event on / off, scopeallorselectedstrategies and triggers, and forwebhookthewebhook_ids),POST/DELETE /v1/notifications/telegram/link(a one-timehttps://t.me/<bot>?start=<token>link; unlink) andPOST /v1/notifications/telegram/test. New error codesnotifications_disabled(503) andtelegram_not_linked(404). New schemasNotificationand friends; examples for every new operation. Every notice sayswhat_happened, and for failureswhat_we_didandwhat_you_should_do./v1/stream: a new opt-in topicnotificationsand messagenotification(data: aNotification), sent only to connections that subscribe to it, and only to the signed-in app session (API keys and partner tokens are refused the topic, as they areGET /v1/notifications), so no existing client sees a new message type. Outbound webhooks: a new eventnotification(componentWebhookNotification), sent only to the webhooks a user picks in thewebhookchannel of their notification preferences; it is not subscribable throughevents, so no existing receiver gets it. Its deliveries listtypenotificationinGET /v1/postbacks/{id}/deliveriesfor those webhooks only. No existing request, response, message or example changed. - Additive
Probability of profit in strategy analytics
GET /v1/strategiesandGET /v1/strategies/{name}:analyticsgains an optionalprobability_of_profit(0 to 1, 4 decimals): the risk-neutral chance that the open positions' P&L at expiry is above zero, with the underlying lognormal fromspotatrate(dividend yield 0), fromferro_ta_coreStrategy::probability_of_profit. The model takes one volatility: the option legs' IVs averaged, each weighted by the leg's |vega| (a plain mean when every vega is ~0), to the options' common expiry. Absent, with a sentence innote, when an option leg has no IV, the options expire on different dates, or there is no option leg. Examplesget_strategies/options_summaryandget_strategy/options_analytics,options_scenariogain the field (nothing else in them changed). Golden comparison treats it as time-dependent, like IV. - Additive
Lock-in-profit stops on held v2 brackets
POST /v2/triggersandPOST /v2/triggers/validate: abracketprotecting a position already held (entry_px, noentry) may now setstop_loss.init_slat or beyondentry_pxto lock in profit (long:entry_px <= init_sl <the current price; short mirrored). Before, any such stop was refused as "not on the protective side of the entry". A stop at or past the current price (it would fire at once), or one with no current price to check against, is422invalid_requestwithfieldspec.stop_loss.init_sland a plain-English message (the dry run lists the same error).PATCH /v2/triggers/{trigger_id}on an active bracket may likewise move the stop into profit (only tighter, never past the market, as before). A bracket waiting forentrykeeps its stop on the protective side. The engine checks the price again at create and refuses the trigger with the same words (last_result) when the market moved through the stop meanwhile. No example changed. - Additive
Where a v2 trigger came from (`created_via`)
GET /v2/triggers(each row) andGET /v2/triggers/{trigger_id}gain an optionalcreated_via, recorded when the trigger is made:app(a signed-in app session),api(an API key or a partner app's token) ororder_ticket(made by the server to protect aPOST /v1/ordersfill, the order ticket's stop-loss / target). Absent for triggers made before this change. The app's Protect flow uses the samePOST /v2/triggersas any app-made trigger and shows asapp. Exampleslist_triggers_v2/successandget_trigger_v2/success,enteredre-recorded. - Additive
Options analytics on strategies (`analytics`)
GET /v1/strategiesandGET /v1/strategies/{name}: a strategy whose open positions are all options / futures on one underlying gains an optionalanalyticsobject (absent otherwise):underlying,spot(the index or stock price used),model(black_scholes, on the underlying's price, dividend yield 0),rate(yearly, default 0.065), netgreeks(delta,gammaper point of the underlying,theta_per_dayper calendar day,vega_per_vol_pointper 1 point of IV; null when an option leg has no IV), exactbreakevensof the expiry payoff,max_profit/max_loss(null withmax_profit_unlimited/max_loss_unlimitedtrue when unbounded) and a plain-Englishnotefor anything left out (no last price, no underlying price, an IV that does not solve, mixed underlyings).GET /v1/strategies/{name}addslegs(per leg:iv_pct,days_to_expiry, the leg's greeks) andpayoff(spots±10% around the underlying, 61 points;at_expiry;todayat the legs' IVs). New optional queryscenarioonGET /v1/strategies/{name}(0or1, other values 422fieldscenario):1addsanalytics.scenario(spot_shifts_pct−5..+5,iv_shifts−5/0/+5 points,today_pnl[iv][spot]). Time to expiry runs to 15:30 IST of the expiry date on a 365-day calendar year. Computed per request from the ledger and our prices; read-only. New examplesget_strategies/options_summary,get_strategy/options_analytics,options_scenario,invalid_scenario,unknown_parameter. Golden comparison treats time-dependent numbers (IV, greeks,today,today_pnl,days_to_expiry) as placeholders. - Additive
v2 entries have their own allowlist (`entries_enabled`)
GET /v2/triggers/capabilitiesgainsentries_enabled(boolean, per user): whether abracketwithentryplaces its entry order for the caller. With automatic entries switched on for the deployment (OMS_TRIGGERS_V2_ENTER), only users in its own allowlist (OMS_TRIGGERS_V2_ENTER_USERS) may make such a bracket: for othersPOST /v2/triggersanswers 422invalid_request(fieldspec.entry) andPOST /v2/triggers/validatelists the same error. With entries off (today) nothing changes. Exampleget_trigger_capabilities_v2updated (the new field only).