get otb rollup
Open to buy for one season, category by category: the envelope the plan declares, what is already committed, what is reserved against it, what is left, the forward recommended buy and the chase reserve split.
cost_rows is the additive, cost-aware row contract. Prefer it when present, including an empty array; fall back to rows only when absent or null. Recorded purchase costs remain visible, while headroom, variance and status are null when the selected plan's cost basis cannot be compared with those sources. cost_comparison names the selected and recorded bases and explains the absence. The legacy rows contract retains its numeric types and is empty for such an unavailable comparison; standard-plan rows keep their existing values.
A SEASON POOL RATHER THAN A WEEKLY BUDGET. The budget is category x season, so a single week cannot breach on its own; scope selects SS or FW and there is no fiscal-year scope, because rolling two disjoint selling windows into one running variance produced a crossing-week signal that meant nothing. scope=FY is refused 400. Every figure is at cost.
There is no stored budget and no build step: the envelope is read live from the plan's own MFP on every call, so this and get_mfp_table cannot disagree about the same season.
Sold with Pro: an organisation without the planning rail is refused 403 plan_excludes.
Scope: planning:read.
Request
- Base URL: https://api.app.tightly.io
- URL: https://api.app.tightly.io/api/v1/otb/{mfp_id}/rollup
- Auth: HTTP bearer
Path parameters
The plan whose envelope this rollup is read against. The same mfp_id get_mfp_table takes: the envelope is read live from that plan on every call, so the two cannot disagree.
Query parameters
SS (Spring/Summer) or FW (Fall/Winter), each narrows to a single season's half-open window. OMIT IT and the service resolves the plan's CURRENTLY-ACTIVE season, the one of this plan's two whose selling window contains today (SS when today falls outside the plan's fiscal year), and echoes the resolved value back as the response's scope. This is the same resolution /weekly-flow performs, so the rollup and the flow beside it always answer for the SAME season; this parameter used to default to SS at the request boundary, and the two panels disagreed whenever the live season was FW. FY was REMOVED as a client-selectable scope (TIG-2216, 2026-07-22): the rollup is a per-season pool view, so ?scope=FY returns 400 (code VALIDATION_ERROR). Implication for the FE: /risk-timeline is a fixed FY forward horizon (its scope selector was also removed, TIG-2216), so the rollup is a per-season pool (SS|FW) while the risk-timeline is a whole-FY view (no per-season risk-timeline).
URL-encoded JSON array of filters with keys category and sales_channel_id (operation eq/in), e.g. [{"key":"category","operation":"in","value":["Knitwear"]}]. The channel filter narrows only the Envelope (Committed / Reserved / forward Recommended Buy are channel-agnostic).
Optional (TIG-2216). Comma-separated sort spec applied as a STABLE multi-key sort over the rows, e.g. -variance,category (variance descending, then category ascending). Prefix - = descending, + / none = ascending. The sort column is constrained to the rollup's sortable columns: category, season_envelope, committed, reserved, remaining, forward_recommended_buy, variance, status (an unknown column returns 400). status sorts on the status string; the rest on the numeric row value. Omitted preserves the default category-ascending order. It orders ONLY the rows array - summary / totals / guardrail stay whole-scope aggregates.
Optional (TIG-2216). Case-insensitive substring matched against the category NAME to filter the rows (e.g. search=knit). Blank / omitted is a no-op (all rows). Like sort_args it narrows only the rows array, never the summary / totals (so summary still ties out to /header). Additive and backward-compatible.
Headers
The date train to answer on. One train exists today, 2026-11, the one this reference describes and the one every key is minted on, so the call answers on it with or without this header. Send it anyway, so a client built now names its train from the start.
Response
The season pool, category by category. Every figure is at cost. remaining is season_envelope - (committed + reserved); variance is remaining - forward_recommended_buy and is the signal a planner acts on. tight_week and short_week are fiscal weeks and are null while the pool never crosses in the window. The notes block says what the figures leaned on, the cost basis, the category scope, and whether a forward estimate was available at all.
Changes
No recorded changes to this operation across all 1 revision of this API.