Для сервиса — JSON API
Те же числа отдаёт обычный HTTP-запрос. Один запрос — одна конфигурация: модель, память, состояние. Ключей нет, регистрации нет, платить не надо.
https://trofey.app/api/v1
База — адрес ниже. Пять эндпойнтов, все GET, все с Access-Control-Allow-Origin: *, так что ходить можно прямо из браузера.
С этого начинается интеграция · GET /models
Название модели совпадает полностью. Поэтому первый вызов — этот: он отдаёт наши точные строки и количество конфигураций у каждой, без цен. q ищет подстрокой и регистр не важен; без q приедет вся категория.
curl -s -G "https://trofey.app/api/v1/models" \ --data-urlencode "q=iphone 13"{ "attribution": "Trofey — https://trofey.app . Free to use; credit Trofey and link the page the number is published on.", "category": "phones", "count": 4, "currency": "UAH", "definition": "market_price_uah = медіана цін живих оголошень позиції за останні 14 днів; рахується лише за наявності щонайменше 8 живих оголошень", "license": "https://trofey.app/terms/", "method": "https://trofey.app/methodology/", "models": [ {"brand": "iPhone", "configurations": 4, "model": "iPhone 13"}, {"brand": "iPhone", "configurations": 4, "model": "iPhone 13 Pro"}, {"brand": "iPhone", "configurations": 5, "model": "iPhone 13 Pro Max"}, {"brand": "iPhone", "configurations": 2, "model": "iPhone 13 mini"} ], "query": "iphone 13", "source": "https://trofey.app/analytics/phones/", "updated": "2026-09-22"}
«iPhone 16 Pro» и «iPhone 16 Pro Max» — разные телефоны с разными ценами. Именно поэтому совпадение полное, и именно поэтому этот вызов есть. Подстрокой мы ищем только здесь: ошибиться в выборе стоит ещё одного вызова, а подстрока внутри поиска цены стоила бы опубликованного неверного ответа. Пустой результат несёт reason: производителя, которого мы не публикуем, простую опечатку, название линейки и модель из другой категории видно отдельно, потому что действия из них противоположные. В последнем случае рядом едет try_category — то же поле, что и у /configurations, и соседнюю категорию мы спрашиваем тем же поиском, так что неточное название её тоже находит. Ближайшие названия в этой категории приезжают отдельным полем did_you_mean — но никогда вместе с try_category: ответ несёт ровно один следующий шаг, а не два противоположных. Это правило любого отказа с try_category, а не одного вызова — /configurations и /price ведут себя так же.
brand — это линейка, а не производитель. Все девять значений, которые мы публикуем: iPhone, Samsung, Redmi, POCO, Xiaomi, Google Pixel, Apple iPad, Samsung Galaxy Tab, Lenovo. То есть iPhone, а не Apple; Redmi и POCO отдельно от Xiaomi; Samsung в планшетах под другим именем, чем в телефонах. Так задумано: на этом поле стоят страницы брендов и адреса, и именно так люди ищут. Если нужен производитель — его понимает поиск: q=Apple отдаёт 50 моделей под brand=iPhone, q=Xiaomi — 108 под тремя линейками. Поля manufacturer нет.
Цена одной конфигурации · GET /price
Параметры: model (обязательный, совпадает полностью), storage_gb (целое число), condition — used или new, category (по умолчанию phones).
curl -s -G "https://trofey.app/api/v1/price" \ --data-urlencode "model=iPhone 13" \ -d storage_gb=128 \ -d condition=used{ "above_range": 24, "attribution": "Trofey — https://trofey.app . Free to use; credit Trofey and link the page the number is published on.", "below_range": 6, "brand": "iPhone", "category": "phones", "cheapest_live_uah": 5000, "condition": "used", "currency": "UAH", "dearest_live_uah": 26000, "definition": "market_price_uah = медіана цін живих оголошень позиції за останні 14 днів; рахується лише за наявності щонайменше 8 живих оголошень", "finds_14d": 160, "license": "https://trofey.app/terms/", "live_listings": 1293, "market_price_uah": 12500, "method": "https://trofey.app/methodology/", "model": "iPhone 13", "price_range_uah": [ 7000, 17000 ], "slug": "iphone-13-128-used", "source": "https://trofey.app/analytics/phones/", "source_page": "https://trofey.app/analytics/phones/iphone-13-128-used/", "storage_gb": 128, "typical_spread_uah": 1000, "updated": "2026-09-22", "watch_price_credits_per_day": 27}
Полключа — это полответа, и на него мы не отвечаем. Если переданного достаточно, чтобы остался ровно один вариант, приедет цена. Если вариантов остаётся несколько, мы не угадываем, а спрашиваем назад:
curl -s -G "https://trofey.app/api/v1/price" \ --data-urlencode "model=iPhone 13"{ "error": "ambiguous configuration", "model": "iPhone 13", "category": "phones", "choose_from": [ {"storage_gb": 128, "condition": "new"}, {"storage_gb": 128, "condition": "used"}, {"storage_gb": 256, "condition": "used"}, {"storage_gb": 512, "condition": "used"} ], "see": "https://trofey.app/api/v1/configurations?model=iPhone%2013&category=phones", "updated": "2026-09-22", "currency": "UAH", "definition": "market_price_uah = медіана цін живих оголошень позиції за останні 14 днів; рахується лише за наявності щонайменше 8 живих оголошень", "method": "https://trofey.app/methodology/", "license": "https://trofey.app/terms/", "source": "https://trofey.app/analytics/phones/", "attribution": "Trofey — https://trofey.app . Free to use; credit Trofey and link the page the number is published on."}В адресах внутри ответов значения percent-encoded: %20 — это пробел. Так строго правильно для машины, которая их разбирает. В терминале удобнее не кодировать руками, а передавать значения через --data-urlencode, как в примерах выше.
Чего мы не мерили — у того нет цены, а не нулевая цена. В ответе «не найдено» нет ни одного числового поля: market_price_uah: 0 прочитался бы следующим графиком как «телефон ничего не стоит», а подставленная оценка выглядела бы точно как измерение.
curl -s -G "https://trofey.app/api/v1/price" \ --data-urlencode "model=Nokia 3310"{ "attribution": "Trofey — https://trofey.app . Free to use; credit Trofey and link the page the number is published on.", "category": "phones", "found": false, "model": "Nokia 3310", "model_known": false, "reason": "No published configuration matches, and the model name is not one Trofey publishes in this category. Names are matched in full — call `models` (MCP) or GET /models to see the exact strings. Trofey publishes a price only where it measured one; it does not estimate on request.", "source": "https://trofey.app/analytics/phones/", "updated": "2026-09-22"}
Все конфигурации одной модели · GET /configurations
То же, что показывает страница модели. model тут тоже обязателен и тоже совпадает полностью — нет такого значения, которое отдало бы чужую модель, тем более все.
curl -s -G "https://trofey.app/api/v1/configurations" \ --data-urlencode "model=iPhone 13"{ "attribution": "Trofey — https://trofey.app . Free to use; credit Trofey and link the page the number is published on.", "category": "phones", "configurations": [ {"above_range": 1, "below_range": 0, "brand": "iPhone", "cheapest_live_uah": 10000, "condition": "new", "dearest_live_uah": 32000, "finds_14d": 4, "live_listings": 37, "market_price_uah": 14000, "model": "iPhone 13", "price_range_uah": [10000, 27000], "slug": "iphone-13-128-new", "source_page": "https://trofey.app/analytics/phones/iphone-13-128-new/", "storage_gb": 128, "typical_spread_uah": 2500, "watch_price_credits_per_day": 3}, {"above_range": 24, "below_range": 6, "brand": "iPhone", "cheapest_live_uah": 5000, "condition": "used", "dearest_live_uah": 26000, "finds_14d": 160, "live_listings": 1293, "market_price_uah": 12500, "model": "iPhone 13", "price_range_uah": [7000, 17000], "slug": "iphone-13-128-used", "source_page": "https://trofey.app/analytics/phones/iphone-13-128-used/", "storage_gb": 128, "typical_spread_uah": 1000, "watch_price_credits_per_day": 27}, {"above_range": 8, "below_range": 6, "brand": "iPhone", "cheapest_live_uah": 5000, "condition": "used", "dearest_live_uah": 35500, "finds_14d": 20, "live_listings": 240, "market_price_uah": 14500, "model": "iPhone 13", "price_range_uah": [9000, 19500], "slug": "iphone-13-256-used", "source_page": "https://trofey.app/analytics/phones/iphone-13-256-used/", "storage_gb": 256, "typical_spread_uah": 1495, "watch_price_credits_per_day": 4}, {"above_range": 1, "below_range": 0, "brand": "iPhone", "cheapest_live_uah": 12300, "condition": "used", "dearest_live_uah": 27000, "finds_14d": 5, "live_listings": 14, "market_price_uah": 15000, "model": "iPhone 13", "price_range_uah": [12300, 20000], "slug": "iphone-13-512-used", "source_page": "https://trofey.app/analytics/phones/iphone-13-512-used/", "storage_gb": 512, "typical_spread_uah": 1951, "watch_price_credits_per_day": 1} ], "currency": "UAH", "definition": "market_price_uah = медіана цін живих оголошень позиції за останні 14 днів; рахується лише за наявності щонайменше 8 живих оголошень", "license": "https://trofey.app/terms/", "method": "https://trofey.app/methodology/", "model": "iPhone 13", "query": "iPhone 13", "source": "https://trofey.app/analytics/phones/", "updated": "2026-09-22"}
Та же цена по дням · GET /price-history
Второй вопрос после «сколько стоит» — дешевеет оно или дорожает, и одно число на него не отвечает. Это та же линия, что на странице позиции: до 31 точки, по одной на день.
curl -s -G "https://trofey.app/api/v1/price-history" \ --data-urlencode "model=iPhone 13" \ -d storage_gb=128 \ -d condition=used \ -d days=7{ "attribution": "Trofey — https://trofey.app . Free to use; credit Trofey and link the page the number is published on.", "category": "phones", "change_pct": 0.0, "change_uah": 0, "condition": "used", "currency": "UAH", "days": 7, "definition": "market_price_uah = медіана цін живих оголошень позиції за останні 14 днів; рахується лише за наявності щонайменше 8 живих оголошень", "first_point": "2026-09-16", "history_updated": "2026-09-22", "last_point": "2026-09-22", "license": "https://trofey.app/terms/", "live_listings": 1293, "market_price_uah": 12500, "method": "https://trofey.app/methodology/", "model": "iPhone 13", "price_history": [ {"date": "2026-09-16", "market_price_uah": 12500}, {"date": "2026-09-17", "market_price_uah": 12500}, {"date": "2026-09-18", "market_price_uah": 12500}, {"date": "2026-09-19", "market_price_uah": 12500}, {"date": "2026-09-20", "market_price_uah": 12500}, {"date": "2026-09-21", "market_price_uah": 12500}, {"date": "2026-09-22", "market_price_uah": 12500} ], "published_delay_days": 0, "slug": "iphone-13-128-used", "source": "https://trofey.app/analytics/phones/", "source_page": "https://trofey.app/analytics/phones/iphone-13-128-used/", "storage_gb": 128, "updated": "2026-09-22", "window_from": "2026-09-16", "window_to": "2026-09-22"}
Без days приедет весь опубликованный месяц — большего не существует. change_uah считается по вернувшимся точкам. days — это календарные дни, как и в /find-history: window_from и window_to — то, что спросили, а first_point и last_point — дни, на которых у линии действительно есть точки. Потолок — 31 день здесь и 30 в /find-history: разница — день сборки, который у линии цен уже есть. Попросишь больше — приедет requested_days рядом с тем days, что вернулся. Эта линия идёт на день дальше находок, и обе говорят об этом в published_delay_days.
Где на самом деле стоят объявления · GET /price-distribution
price_range_uah в /price — это не самое дешёвое и самое дорогое объявление, а границы гистограммы, и часть лотов стоит вне их. Сколько именно — говорят below_range и above_range в том же ответе. Это та же гистограмма, что на странице позиции: от четырёх до восьми полос между теми же границами.
curl -s -G "https://trofey.app/api/v1/price-distribution" \ --data-urlencode "model=iPhone 13" \ -d storage_gb=128 \ -d condition=used{ "above_range": 24, "attribution": "Trofey — https://trofey.app . Free to use; credit Trofey and link the page the number is published on.", "below_range": 6, "bins": [ {"from_uah": 7000, "listings": 20, "share_pct": 1.5, "to_uah": 8250}, {"from_uah": 8250, "listings": 39, "share_pct": 3.0, "to_uah": 9500}, {"from_uah": 9500, "listings": 143, "share_pct": 11.1, "to_uah": 10750}, {"from_uah": 10750, "listings": 243, "share_pct": 18.8, "to_uah": 12000}, {"from_uah": 12000, "listings": 441, "share_pct": 34.1, "to_uah": 13250}, {"from_uah": 13250, "listings": 211, "share_pct": 16.3, "to_uah": 14500}, {"from_uah": 14500, "listings": 118, "share_pct": 9.1, "to_uah": 15750}, {"from_uah": 15750, "listings": 48, "share_pct": 3.7, "to_uah": 17000} ], "category": "phones", "condition": "used", "currency": "UAH", "definition": "market_price_uah = медіана цін живих оголошень позиції за останні 14 днів; рахується лише за наявності щонайменше 8 живих оголошень", "history_updated": "2026-09-22", "in_range_listings": 1263, "license": "https://trofey.app/terms/", "live_listings": 1293, "market_price_uah": 12500, "method": "https://trofey.app/methodology/", "model": "iPhone 13", "range_uah": [ 7000, 17000 ], "slug": "iphone-13-128-used", "source": "https://trofey.app/analytics/phones/", "source_page": "https://trofey.app/analytics/phones/iphone-13-128-used/", "storage_gb": 128, "unverified_listings": 7, "updated": "2026-09-22"}
below_range и above_range — объявления вне полос: без них полосы в сумме меньше live_listings. in_range_listings — сумма самих полос, то есть то, чего процентам не хватает до сотни: вместе эти три числа и дают live_listings. Распределение есть лишь от восьми живых объявлений — тот же порог, что и у цены.
А самое дешёвое и самое дорогое объявление, которые действительно есть, — это cheapest_live_uah и dearest_live_uah в том же ответе. Именно их стоит называть, когда спрашивают «от скольки». Границы гистограммы — тоже цены живых объявлений, но не крайних: это самое дешёвое и самое дорогое из тех, что помещаются в шкалу. На 651 позиции нижняя граница совпадает с самым дешёвым лотом в 419 случаях, верхняя с самым дорогим — в 274, а весь рынок позиции помещается в график на 222. Там, где что-то осталось вне шкалы, оно осталось далеко: самый дешёвый лот на 44% ниже границы (медиана).
Сколько находок было каждый день · GET /find-history
Количества за день, и ничего больше: лента отдельных лотов платная и доставляется в канал аккаунта. Это finds_14d во времени — разница между «шесть находок» и «шесть за одно утро» видна только здесь.
curl -s -G "https://trofey.app/api/v1/find-history" \ --data-urlencode "model=iPhone 13" \ -d storage_gb=128 \ -d condition=used \ -d days=7{ "attribution": "Trofey — https://trofey.app . Free to use; credit Trofey and link the page the number is published on.", "category": "phones", "condition": "used", "currency": "UAH", "days": 7, "days_with_finds": 7, "definition": "market_price_uah = медіана цін живих оголошень позиції за останні 14 днів; рахується лише за наявності щонайменше 8 живих оголошень", "find_history": [ {"date": "2026-09-15", "finds": 13}, {"date": "2026-09-16", "finds": 12}, {"date": "2026-09-17", "finds": 14}, {"date": "2026-09-18", "finds": 7}, {"date": "2026-09-19", "finds": 16}, {"date": "2026-09-20", "finds": 11}, {"date": "2026-09-21", "finds": 16} ], "finds_14d": 160, "finds_total": 89, "first_find": "2026-09-15", "history_updated": "2026-09-22", "last_find": "2026-09-21", "license": "https://trofey.app/terms/", "live_listings": 1293, "method": "https://trofey.app/methodology/", "model": "iPhone 13", "published_delay_days": 1, "slug": "iphone-13-128-used", "source": "https://trofey.app/analytics/phones/", "source_page": "https://trofey.app/analytics/phones/iphone-13-128-used/", "storage_gb": 128, "updated": "2026-09-22", "window_from": "2026-09-15", "window_to": "2026-09-21"}
В строке ровно два поля: date и finds — ни ссылки, ни заголовка, ни цены. Дни без находок отсутствуют, а не нулевые.
Нормальная ли эта цена · GET /price-check
Главный вопрос, и он ничего нового не публикует: та же арифметика, что в карточке бота. Без него — три вызова и деление руками.
curl -s -G "https://trofey.app/api/v1/price-check" \ --data-urlencode "model=iPhone 13" \ -d storage_gb=128 \ -d condition=used \ -d price_uah=11250{ "above_every_live_listing": false, "attribution": "Trofey — https://trofey.app . Free to use; credit Trofey and link the page the number is published on.", "below_every_live_listing": false, "category": "phones", "cheaper_listings_at_least": 208, "cheaper_listings_at_most": 451, "cheaper_share_at_least_pct": 16.1, "cheapest_live_uah": 5000, "condition": "used", "currency": "UAH", "dearest_live_uah": 26000, "definition": "market_price_uah = медіана цін живих оголошень позиції за останні 14 днів; рахується лише за наявності щонайменше 8 живих оголошень", "discount_vs_market_pct": 10.0, "discount_vs_market_uah": 1250, "history_updated": "2026-09-22", "license": "https://trofey.app/terms/", "live_listings": 1293, "market_price_uah": 12500, "method": "https://trofey.app/methodology/", "model": "iPhone 13", "price_bin": { "from_uah": 10750, "listings": 243, "to_uah": 12000 }, "quoted_uah": 11250, "range_uah": [ 7000, 17000 ], "slug": "iphone-13-128-used", "source": "https://trofey.app/analytics/phones/", "source_page": "https://trofey.app/analytics/phones/iphone-13-128-used/", "spreads_from_market": 1.2, "storage_gb": 128, "typical_spread_uah": 1000, "updated": "2026-09-22", "verdict": "below_market", "verdict_basis": "typical_spread"}
Вердикт меряется прежде всего разбросом самой позиции, а не процентом от медианы: typical_spread_uah — это насколько обычное объявление этой конфигурации отстоит от рыночной цены, и половина живых лотов лежит внутри него. spreads_from_market говорит, на сколько таких разбросов отошла названная цена. Один и тот же процент — разные вещи на разных позициях: «на 20% дешевле» на широком рынке это обычное объявление, а на узком — дешевле почти всего. Под разбросом лежит одна абсолютная граница: 45% от медианы — это far_below_market на любом рынке, потому что после такой скидки она перестаёт выглядеть выгодой и начинает выглядеть причиной. Сам verdict — одно из пяти: far_below_market, below_market, about_market, above_market, far_above_market. А verdict_basis говорит, какая мерка ответила: typical_spread, percent_floor, percent_ceiling (зеркало подпола: там, где разброс позиции слипся, три разброса бывают скидкой в один процент) или percent_of_market — последняя там, где разброс никогда не считался и отвечает сама процентная лестница.cheaper_listings_at_least — нижняя граница, не перцентиль: полоса с названной ценой не делится и едет как price_bin, а cheaper_listings_at_most — потолок вместе с ней. Когда below_every_live_listing — true, более дешёвых живых объявлений нет вообще, а above_every_live_listing говорит то же самое про верх. Оба читаются из самой дешёвой и самой дорогой живой цены, и границы с ними согласованы: цена дороже самого дешёвого объявления имеет под собой как минимум его, а цена не выше самого дорогого не может иметь под собой все. И это не совет: мы говорим, где стоит число, а батарею и царапины видит лишь тот, кто держит телефон.
Что эта служба отдаёт и что ограничивает · GET /info
Один вызов вместо чтения этой страницы: что мы публикуем, сколько это стоит (ничего), под какой лицензией, чего тут осознанно нет — и единственный лимит на всей поверхности. Поля: limits, licence, transports, not_available.
Какая это модель · восемь цифр · GET /device
Первые восемь цифр IMEI — это TAC, то есть модель, а не аппарат. Отдаёт brand, model, as_of — и published_as: тот же аппарат под названием, которое публикуем мы, готовым для запроса цены. Именно здесь цепочка «сфотографировал коробку → точное название → цена» и замыкается: в реестре стоит GALAXY A21, у нас — Galaxy A21s, и это разные телефоны за разные деньги, так что поля два, а не одно. Если цены на этот аппарат у нас нет, published_as пустое, а did_you_mean называет ближайшие опубликованные названия. Восемь цифр, не пятнадцать — кому нужна только модель, тот не обязан присылать весь номер.
Числится ли телефон в розыске · GET /imei-check
Полные пятнадцать цифр против реестра утерянных и украденных, который мы переопубликовываем, плюс аппарат из того же TAC. Поля: reported, status, listed_on, checksum_ok, as_of, и imei_tail вместо самого номера — ответ не повторяет его целиком. published_as приезжает и здесь: то же наше название аппарата, что и в /device.
reported: false — это «номера нет в ЭТОМ реестре», а не гарантия про телефон. Скажите это человеку, который сейчас платит за аппарат. checksum_ok: false обычно означает опечатку, но поиск всё равно выполняется: шестая часть записей самого реестра не проходит собственную контрольную цифру. Если реестр недоступен, придёт error: "registry unavailable" — и это тоже не чистый телефон. Это единственные два вызова с лимитом: 120 в минуту на вызывающего, потому что они единственные тут не являются закешированным файлом.
Что мы вообще меряем · GET /categories
Счётчики и даты, и никогда — сами позиции. Это вызов «покрыт ли мой товар», а не способ забрать всё одним запросом. Если категория утром не собралась, она просто не приедет в список — остальное работает.
curl -s "https://trofey.app/api/v1/categories"{ "attribution": "Trofey — https://trofey.app . Free to use; credit Trofey and link the page the number is published on.", "categories": [ {"category": "phones", "configurations": 566, "currency": "UAH", "definition": "market_price_uah = медіана цін живих оголошень позиції за останні 14 днів; рахується лише за наявності щонайменше 8 живих оголошень", "license": "https://trofey.app/terms/", "method": "https://trofey.app/methodology/", "page": "https://trofey.app/analytics/phones/", "updated": "2026-09-22"}, {"category": "tablets", "configurations": 85, "currency": "UAH", "definition": "market_price_uah = медіана цін живих оголошень позиції за останні 14 днів; рахується лише за наявності щонайменше 8 живих оголошень", "license": "https://trofey.app/terms/", "method": "https://trofey.app/methodology/", "page": "https://trofey.app/analytics/tablets/", "updated": "2026-09-22"} ], "source": "https://trofey.app/"}
Живой и за какой день · GET /health
«Живой» — не самый интересный вопрос: процесс, отдающий недельный файл, тоже живой. Поэтому здесь сразу даты. Этот ответ не кешируется нигде.
curl -s "https://trofey.app/api/v1/health"{ "ok": true, "source": "https://trofey.app/", "updated": { "phones": "2026-09-22", "tablets": "2026-09-22" }}
Ошибки
400 · нет model{ "error": "model is required", "example": "https://trofey.app/api/v1/price?model=iPhone%2013&storage_gb=128"}400 · storage_gb не число{ "error": "storage_gb must be an integer"}400 · condition не из нашего перечня{ "error": "unknown condition", "condition": "refurbished", "category": "phones", "published": [ "new", "used" ]}400 · вариантов остаётся несколько{ "error": "ambiguous configuration", "model": "iPhone 13", "category": "phones", "choose_from": [ {"storage_gb": 128, "condition": "new"}, {"storage_gb": 128, "condition": "used"}, {"storage_gb": 256, "condition": "used"}, {"storage_gb": 512, "condition": "used"} ], "see": "https://trofey.app/api/v1/configurations?model=iPhone%2013&category=phones", "updated": "2026-09-22", "currency": "UAH", "definition": "market_price_uah = медіана цін живих оголошень позиції за останні 14 днів; рахується лише за наявності щонайменше 8 живих оголошень", "method": "https://trofey.app/methodology/", "license": "https://trofey.app/terms/", "source": "https://trofey.app/analytics/phones/", "attribution": "Trofey — https://trofey.app . Free to use; credit Trofey and link the page the number is published on."}404 · такую категорию мы не публикуем{ "error": "unknown category", "category": "cars", "published": [ "phones", "tablets" ]}404 · такую конфигурацию мы не мерили{ "attribution": "Trofey — https://trofey.app . Free to use; credit Trofey and link the page the number is published on.", "category": "phones", "found": false, "model": "Nokia 3310", "model_known": false, "reason": "No published configuration matches, and the model name is not one Trofey publishes in this category. Names are matched in full — call `models` (MCP) or GET /models to see the exact strings. Trofey publishes a price only where it measured one; it does not estimate on request.", "source": "https://trofey.app/analytics/phones/", "updated": "2026-09-22"}503 · файл не читается прямо сейчас{ "error": "data unavailable", "category": "phones"}Ошибки не кешируются нигде (Cache-Control: no-store): ошибка — про этот запрос. И storage_gb=128gb — это 400, а не молчаливое игнорирование параметра: выброшенный фильтр дал бы ответ о другой конфигурации, и ты бы об этом не узнал. По той же причине один и тот же параметр, присланный дважды, тоже 400: у двух разных значений одного имени нет правила, которое сказало бы, какое из них наше. Неизвестный параметр при этом толерируется и может повторяться — кеш-бастер &_cb= остаётся рабочим.
Кеш и вежливый клиент
Успешный ответ едет с public, max-age=3600, stale-while-revalidate=86400 и с ETag, посчитанным из байтов самого ответа. Вежливый клиент шлёт назад If-None-Match и получает 304 без тела, держит свою копию час и опрашивает нас раз в сутки: между утренними сборками не меняется ничего. Лимита, который тебя остановит, нет — именно поэтому это твоё дело, а не наше.
Числа пересчитываются каждый день, и каждый ответ говорит, за какой день он посчитан — чтобы вчерашнее число не выглядело как сегодняшнее.
Что мы просим взамен
Одно: назови Trofey и поставь ссылку на страницу, где число опубликовано. Страница уже приехала к тебе вместе с числом — это поле source_page. Условия — поле license, как считается число — поле method. Просьба едет в каждом ответе полем attribution, а не только здесь.
Вопросы и ответы
Сколько запросов можно делать?
Цены — без лимита: они приходят из файлов, которые сайт публикует раз в день и которые лежат в кеше на краю сети, так что повторный вопрос ничего не стоит. Лимит есть только на проверку IMEI — 120 запросов в минуту.
Как часто обновляются числа?
Раз в сутки. Каждый ответ несёт поле с днём расчёта — ориентируйся на него, а не на день, когда ты сделал запрос.
Можно ли использовать эти данные у себя?
Да, бесплатно. Условие одно: указать Trofey и сослаться на страницу, где число опубликовано. Ссылка на лицензию приходит в каждом ответе.