---
title: "What one account did last time, and how it is likely to do now"
method: GET
path: "/api/v1/order-book/account-anchor"
tags: ["order_book"]
---

# What one account did last time, and how it is likely to do now

`GET /api/v1/order-book/account-anchor`

## Request

- Base URL: `https://api.app.tightly.io`
- URL: `https://api.app.tightly.io/api/v1/order-book/account-anchor`
- Auth: HTTP bearer

What one account did last time and how each style is likely to perform there: what they booked last season, what their doors sold, and the baseline's grade.

`trading_partner_id` and `season_code` are required. `prior_season_code` states the season compared against, `sellout_from` and `sellout_to` the window, `commitment_id` narrows to a Commitment, `as_of` reads at an instant; `prior_reason` says why where a prior season cannot be resolved.

`baseline: null` means the pass never assessed this style; ABSENT means none was served, and `grades_state` says which: `served`, `not_on_plan` (with `grades_reason`) or `unreadable`. Sell-out is the account's own doors, not sell-in; a style they never carried is graded from look-alikes, which `sellout_reported: false` explains.

`ordered_qty` is this season's booked units for the same account and style, off the same statement, so the gap against the prediction is one subtraction on one row. A style with no line is 0.

`baseline.by_door[]` is that level per door, summing to `level_units`. Each row carries `door_id`, `name`, `units`, `share`, a `rung` (`measured`, `category_average`, `account_average`, `not_measured`, whose figure is null), a `rung_label` and a `source`: `door_baseline` for the engine's own per-door figure, with that door's evidence beside it, or `account_split` for the account level divided at read time. Absent, with `by_door_reason`, where unreadable.

Sold with Essentials+: without Tightly Connect, 403 `plan_excludes`.

Scope: `order_book:read`.

## Query parameters

- `trading_partner_id` string, required
- `season_code` string, required
- `prior_season_code` string
- `commitment_id` string
- `sellout_from` string, date
- `sellout_to` string, date
- `as_of` string, date-time

## Headers

- `Tightly-Version` string

## Response `200`

The anchor. Each `styles[]` entry carries the prior book, the prior sell-out and, where the grade is readable, `baseline`: its state, basis, evidence, grade, pace, expected sell-through, level and rate, a range with the reason it is wide or absent, the curve and its bucket size, the members it voted on and the ones it dropped, the doors and weeks reported, the window and where the window came from, one composed sentence, and `by_door`. The header carries `sellout_reported` and `sellout_reason`.
`ordered_qty` on each style is this season's live booked units for the same account and style, off the same statement as the prior figures, so ordered against predicted is a subtraction over one row rather than a crossing of two reads taken at two instants. A style in scope with no live line carries 0 and not null: the book WAS read, and having taken none of a style is the reading a planner came for.
`baseline.by_door[]` is the account's level delivered to each door the account has open, one row each, carrying `door_id`, `name` (the buyer's own key for the same field, character for character, so a face never has the field rename itself under it), `door_reference`, `units`, `share`, `rung`, `rung_label` and `source`. `rung` is `measured` (this door sold the styles the grade stood on), `category_average` (it reported none of them but does sell the category), `account_average` (neither, so it takes the account's average door) or `not_measured` (nothing could be sized, so the row carries a null figure and never a zero). The rows sum to `level_units` by construction, so the account's own figure and the doors under it cannot disagree.

`source` SAYS WHICH READ SERVED THE ROW, and the two are not the same claim. `door_baseline` is the engine's own per-door pass: the availability correction taken on that door's own shelf, with the door's evidence beside the figure (`sold_last_season`, `sold_corrected`, `out_of_stock_days`, `availability`, `weeks_reported`, `styles_reported`). `account_split` is the INTERIM: the account's level divided at read time by each door's measured share of the styles the grade stood on, which cannot correct for availability and never carries `category_average`. The engine's rows are served wherever it has any; the interim answers only for a graded style the pass has not reached yet, so a face that branches on `source` can say which it is looking at rather than guess. An account that reports one total has no doors on file, and `by_door` is then empty rather than one synthetic door holding the whole number. The KEY IS ABSENT, with `by_door_reason` carrying the sentence, where the split could not be read at all: the grades stand either way, because the split is an addition on top of figures that are already complete. `by_door_reason` is null where the split was read.
`basis` and `evidence` are the provenance pair, and a client switching on the grade wants both. `basis` is the rung the grade was read from, in ladder order: `account_predecessor`, `account_kit_member`, `account_cohort`, `account_family`, `brand_analog`, `sell_in_only`, `none`. The first rung carrying enough reported weeks at this account votes alone, and the outranked members are dropped and named rather than blended in at a lower weight. `evidence` is how far to trust it: `measured`, `uncorrected`, `borrowed`, `brand`, `none`. It is `evidence`, not `basis`, that carries the borrowed against measured label, because one clean predecessor of the account's own doors is a measurement and several blended is a borrowing, and the figure looks identical either way. `uncorrected` is that same own record read over weeks nobody reported a shelf for, so a slow week may be an empty shelf rather than absent demand. `brand_analog` with `evidence: brand` is the analog case named above: nothing at this account, so the brand's own answer is served at brand level and labelled as borrowed from us. `grade` is `winner`, `sleeper` or `bleeder`, and `state` is `graded`, `magnitude_only`, `brand_fallback`, `sell_in_only` or `refused`.
The header also says which morning the grades are from: `grades_as_of` is the completion stamp of the last grading run that succeeded, `engine_state` is that engine's state (never_ran, not_measured, running, fresh, stale, partial, failed, not_applicable), `next_run_at` is when it runs again, and `engine` carries the same four facts in the shape every engine read on the platform uses. They are stamped on every path, including the one where the grades themselves could not be read, never from the reader's clock, which is what this page used before.
`grades_state` is a different question from `engine_state` and sits beside it: that one is about the RUN, this one is about the answer in your hands. It is `served`, `not_on_plan` or `unreadable`, and `grades_reason` carries a sentence only for `not_on_plan`, the same text a 403 `plan_excludes` carries. Three responses can hold `engine_state: fresh` and no grades at all, for three unrelated reasons, and this is the field that separates them.
A style with no grade carries `baseline: null` where the pass simply never assessed it, and a `not_assessed` block (`state`, `reason_code`, `sentence`) where the last run named why it did not grade this ACCOUNT at all (a read that failed, reading conventions nobody has confirmed). "Assessed by nobody" and "we could not read their record this morning" send a seller to two different places.
`baseline.by_door[]` is the same level, delivered to each of the account's shops: `door_id`, `name`, `share`, `units`, and `rung`, the word for the evidence the figure stands on. `measured` is the door's own history of the styles the grade was measured on, corrected for its own shelf; `category_average` is a door that reported none of those styles but does sell the category; `account_average` is a door that reported neither, which where nothing was measured at all is the level divided by the doors on file; `not_measured` is a door on a style the engine could not size, and it carries no figure. The units sum to `level_units` exactly, so the door column and the account figure above it cannot disagree. Each row also carries the door's own evidence: `sold_last_season` as the account reported it, `sold_corrected` with the shelf accounted for, `out_of_stock_days`, `availability`, `weeks_reported` and `styles_reported`, because a figure lifted by a third for a shop that was dark for eight weeks has to be able to say so. `availability: null` means no week at that door carried a shelf reading, so the units are taken at face value rather than corrected.
`by_door: []` is a real answer and the commonest one on an account that reports a single total: it has no door to break down. The key ABSENT means the split could not be read, the same distinction `baseline` itself draws one level up.
`baseline_source` on each door row names which rung of the source chain produced its figure: `own_sales` (our own sales on every channel we sell through: the brand's own forecast, served where this account reported nothing for the style), `sell_out` (this account's own reported sell-out for a predecessor, kit member, cohort or family member), `sell_in` (a `sell_in_only` row, off what we shipped or ordered) or `category` (a category-level average, the chain's last resort). `dtc` (our own d2c-typed channels only) is reserved for a figure read off those channels alone; no door row is read that way today. `null` on a refusal, where no rung answered, or on a tenant this field has not yet reached. Served beside `grade_basis`.

- object

## Other responses

- `400`: A required parameter is missing, or the request could not be read
- `401`: No usable key: malformed, unknown, revoked, expired or stopped. One refusal covers all five, telling a caller which is which maps the surface for them. A request with no Authorization header at all is refused 400 before any key is looked for.
- `403`: The key may not reach this operation. `plan_excludes` when Order book is sold with Essentials+ and this organisation's plan does not include it; `scope_missing` when the key does not hold Order book; `organization_mismatch` when the path names an organisation that is not the key's; `ip_not_allowed` when the caller's address is outside the key's allowlist; `account_mismatch` when a key issued to one account names another in `trading_partner_id`, and the sentence names both accounts.
- `429`: The key has spent its allowance for this minute. 600 reads and 120 writes a minute, counted per key, refused calls included. `Retry-After` says how long to wait.
- `503`: The database is briefly out of reach, which is what a failover or a full connection pool looks like from outside. Wait the seconds `Retry-After` names and send the request again. A read is safe to repeat. A write is not, because the connection was lost in the middle of it, so read the object back before sending it a second time. Branch on the status rather than on `code`, which is `POSTGRES_UNAVAILABLE` from one of the two seams that raise this and `SERVICE_UNAVAILABLE` from the other.

---

[API](https://skmtc.dev/tightly/apis/tightly-api.md) · [All operations](https://skmtc.dev/tightly/apis/tightly-api/llms.txt) · [OpenAPI document](https://skmtc.dev/tightly/apis/tightly-api/revisions/199f7eb35afb?raw)
