| apps | Yes | UNION: apps COMPETING in at least one storefront, counted ONCE however many they rank in. Competing means a top-10 place on at least one of this market's terms AND a top-50 place on at least two of them — one term is a coincidence and a place nobody scrolls to is not competition. Never the sum of the per-storefront counts: one app in three storefronts is one app. A FLOOR rather than a count when `apps_capped` is true. Everything else the store returned is in `fringe`. | |
| left | No | Apps that fell out of every storefront they held. include: ["movement"]. | |
| name | No | What the market is called. Null for an unsaved reading. | |
| slug | No | Its address in the console. | |
| terms | Yes | SUM of the per-storefront corpora. The corpora are disjoint by construction — a term belongs to one storefront — so nothing is counted twice, and this is exactly what the market costs to crawl. | |
| corpus | No | Every term, with its storefront and why it is in the corpus. Present only with include: ["corpus"]. | |
| fringe | Yes | Apps that rank somewhere in this market's search results and are NOT competing in it: one term only, or no top-10 place anywhere. Typically several times `apps` — measured on a nine-storefront market, 578 competing against 2,001 fringe. They are real placements and worth naming as context (a store that seats an app beside yours), never as rivals. Counted once and never double-counted with `apps`: an app competing in one storefront and fringe in another is competing. | |
| spread | No | open | contested | locked | mixed. `mixed` is the finding rather than a fudge: a niche locked in the US and open in Germany is the answer to "where should I launch this first". Storefronts in the same band report that band. | |
| status | Yes | draft | building | ready | failed. A market is `building` while ANY of its storefronts is — never report it ready because most of them landed. `ready` beats `failed`, so a market can read `ready` and still hold a storefront whose build died: check each storefront's `failed_at` before quoting its figures. | |
| window | Yes | The window read, and what `newcomers`, `departures` and the change figures are measured against. | |
| caveats | Yes | Sentences the reader has to hear before the numbers mean what they look like they mean. Pass them on; do not summarise them away. | |
| entered | No | Apps that arrived somewhere in this market this window. include: ["movement"]. | |
| members | No | The leaderboard, ordered by rating count — the one size figure we measure for every app. Present only with include: ["members"]. | |
| overlap | No | Of the apps holding a top-10 place in ANY storefront, the share holding one in EVERY storefront, 0-100. High means one leaderboard travels and a newcomer meets it wherever they launch; low means each storefront is its own contest, which is where an unowned storefront hides. NULL for a single-storefront market — it is not a question one place can answer. | |
| built_at | No | The OLDEST of the storefronts' build times: a market is only as fresh as its worst. | |
| app_terms | No | Every (term, storefront) place that app holds here, best place first — the evidence `app_verdict` was taken over. Present only with include: ["app_terms"]. | |
| market_id | No | Apptail market id, or NULL when this reading was resolved from a phrase and not saved. Pass it to save_market to keep it, or to get_market to read it again for free. | |
| newcomers | No | Distinct apps that arrived in at least one storefront this window. Arriving in `de` while already ranking in `us` counts as arriving in this market. **NULL means no storefront had a previous window to compare against** — nothing of this corpus was crawled then, which is the normal state of a market built inside the window. Never read null as 0, and never report a new market's whole membership as newcomers. | |
| truncated | Yes | True when any list above was cut. Say so rather than presenting a partial list as the whole thing. | |
| departures | No | Distinct apps that fell out of every storefront they held. Null on the same terms as `newcomers`. | |
| app_verdict | No | Whether the app named by `app_id` is competing in this market, and which clause of the rule decided. Present only with include: ["app_terms"]. | |
| apps_capped | Yes | True when the census stopped at its depth before it ran out of apps. `apps`, `newcomers`, `departures`, `downloads_30d` and `revenue_30d` are then floors, because all of them are summed over the counted set. Say "at least" rather than reporting the number as a total. | |
| console_url | No | This market in the console. | |
| contest_low | No | The least contested storefront's share of top-10 slots held by its top three, 0-100. | |
| revenue_30d | No | ESTIMATE, same basis as downloads_30d. | |
| stale_terms | Yes | Corpus terms across the market past their 72-hour refresh. | |
| storefronts | Yes | One entry per storefront, and the only level at which contest, demand and depth exist. Compare these rather than averaging them. | |
| contest_high | No | The most contested storefront's. A RANGE, deliberately: there is no market-level contest to average. | |
| corpus_total | No | Terms the market holds. Larger than the list means it was cut. | |
| size_covered | Yes | How many of the `apps` above carry an estimate at all, INCLUDING the ones the vendor would only bound as "under 1,000" / "under 5,000". Those contribute nothing to the sums, so a market with many small apps reports a size that is a floor. A total over 40 of 291 apps is a different statement from one over 280 — say which when quoting the size. | |
| downloads_30d | No | ESTIMATE. A third-party model, worldwide and 30-day, summed over the UNION with each app counted once. Adding the per-storefront totals would count the same worldwide figure once per storefront and be wrong by roughly the storefront count. | |
| members_total | No | Members the market actually holds. Larger than the list means it was cut. | |
| pending_terms | Yes | Terms in the corpus that could not be crawled inside the budget. Their ranks are missing from this reading, so it is a floor. Saving the market and asking again returns a deeper answer. | |
| app_terms_total | No | Places the app actually holds. Larger than the list means it was cut. | |
| storefront_count | Yes | How many places this question is asked in. | |
| pending_storefronts | Yes | Storefronts that ran out of budget before they were read at all. Name them; a partial answer that reads as complete is the failure this field exists to prevent. | |