Тут виднее

Подключение

Как подключиться за пять минут

Три вопроса, три команды, три ответа. Каждый ответ ниже посчитан этой страницей сейчас, тем же обращением, которое показано командой: показать то, чего портал не отдаёт, ей нечем.

Ни ключа, ни токена, ни регистрации, ни личного кабинета на портале не существует — данные открыты всем, и единственное ограничение это частота: не более 60 обращений в минуту с одного адреса. Правила целиком — на странице правил использования; оговорки о самих данных, без которых из них делают неверные выводы, — на странице «Что в данных». Сведения справочные и собраны на 2026-09-06; юридически значима выписка из государственного реестра.

Три примера

Пример 1

В скольких районах субъекта нет ни одного колледжа?

Один показатель по всем 89 субъектам сразу, таблицей. Ничего настраивать не нужно: ответ приходит первой же строкой.

Команда

curl "https://tutvidnee.ru/export/metric/районы-без-колледжа/?формат=машинный"

Заголовки ответа

Content-Disposition: attachment; filename="metric-share_without_spo-data-20260906-structure-20260907.csv"
X-Snapshot-Date: 2026-09-06
X-Structure-Date: 2026-09-07
X-Source: https://tutvidnee.ru/data/

Ответ

код_субъекта,субъект,доля_районов_без_колледжа,организаций_всего
22,Алтайский край,66.7,1664
28,Амурская область,79.3,676
29,Архангельская область,30.8,784
30,Астраханская область,69.2,636

Имя файла несёт обе даты: данные на одно число, структура на другое. Скачали дважды — по имени видно, что изменилось: сведения, разбор или ничего. Те же две даты приходят заголовками ответа, поэтому их не нужно искать внутри таблицы.

Пример 2

Что известно про Владимирскую область одним обращением?

Свод по субъекту в JSON: те же числа, что на его странице, потому что считает их та же функция.

Команда

curl "https://tutvidnee.ru/api/v1/regions/33/"

Ответ

{
  "снимок": "2026-09-06",
  "структура": "2026-09-07",
  "источник": "Реестр лицензий на осуществление образовательной деятельности, Рособрнадзор",
  "оговорка": "Сведения справочные; юридически значима выписка из государственного реестра",
  "код": "33",
  "название": "Владимирская область",
  "организаций": 1099,
  "районов": 21,
  "районов_без_колледжа": 7,
  "районов_без_вуза": 17,
  "районов_без_сада": 0,
  "районов_без_школы": 0,
  "специальностей_с_единственным_колледжем": 202,
  "людей_в_районах_без_колледжа": 162581,
  "доля_людей_без_колледжа": 12.5,
  "специальностей_без_подготовки": 33,
  "юрлиц_не_действующих": 9,
  "почему_пусто": {}
}

Пустое значение здесь означает «не рассчитано», а не ноль: у субъекта без единого вуза в реестре «районов без вуза» это отказ считать, а не утверждение о стране. Строка «значение or 0» в вашем коде превратит одно в другое, и заметить это будет нечем.

Пример 3

Где рядом с Ковровом учат на сварщика?

Тот же вопрос, заданный помощнику: портал отвечает по протоколу MCP, и помощник берёт сведения отсюда, а не сочиняет их.

Команда

curl -X POST "https://tutvidnee.ru/mcp" \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2026-07-28" \
  -H "Mcp-Method: tools/call" \
  -H "Mcp-Name: where_to_study" \
  -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "where_to_study", "arguments": {"специальность": "15.01.05", "откуда": "Ковров", "радиус_км": 100, "сколько": 3}}}'

Ответ

{
  "специальность": {
    "шифр": "15.01.05",
    "название": "Сварщик (ручной и частично механизированной сварки (наплавки)"
  },
  "точка_отсчёта": {
    "название": "Ковров",
    "субъект": "Владимирская область"
  },
  "радиус_км": 100,
  "всего_в_радиусе": 16,
  "показано": 3,
  "организации": [
    {
      "org_id": 46637,
      "наименование": "ГБПОУ ВО \"КТК\"",
      "населённый_пункт": "Ковров",
      "субъект": "Владимирская область",
      "км": 1.2
    },
    {
      "org_id": 46642,
      "наименование": "ГАПОУ ВО \"КПГК\"",
      "населённый_пункт": "Ковров",
      "субъект": "Владимирская область",
      "км": 2.8
    },
    {
      "org_id": 46907,
      "наименование": "ГАПОУ ВО \"НАПК\"",
      "населённый_пункт": "Никологоры",
      "субъект": "Владимирская область",
      "км": 49.1
    }
  ],
  "оговорки": [
    "Расстояние по прямой; дорога длиннее в среднем в 1,41 раза.",
    "Организации без известных координат в отбор не попадают: их расстояние неизвестно, а ноль означал бы «здесь же».",
    "Отбор пересекает границы субъектов намеренно."
  ],
  "дата_снимка": "2026-09-06",
  "источник": "Реестр лицензий на образовательную деятельность Рособрнадзора; реестр государственной аккредитации, ЕГРЮЛ, bus.gov.ru, формы федерального статистического наблюдения",
  "оговорка": "Сведения справочные и собраны на дату снимка. Юридически значима только выписка из государственного реестра.",
  "о_пересказе": "Данные официальные; их изложение, пересказ и выводы — продукт помощника, и за искажения при пересказе источник не отвечает."
}

Показано поле result.structuredContent; конверт JSON-RPC вокруг него опущен. Дата снимка, источник и оговорки едут в каждом ответе сервера — иначе модель, пересказывая ответ человеку, выдумает их сама и выдумает правдоподобно.

Два вида одной выгрузки

По умолчанию выгрузка сделана для человека: UTF-8 с меткой порядка байт, разделитель «точка с запятой», а после таблицы — пустая строка и несколько строк пояснений. Так файл открывается в Excel русской локали и через полгода сам объясняет, что в нём.

Программе всё это мешает: метка порядка байт приклеивается к имени первой колонки, а пояснения читаются как четыре строки данных. Поэтому у каждой выгрузки есть машинный вид — он добавляется параметром формат=машинный и отдаёт UTF-8 без метки, разделяет запятой и после таблицы не дописывает ничего. Адрес тот же, и без параметра он не меняется ни в байте.

Происхождение уехало из футера в заголовки ответа: X-Snapshot-Date — на какое число верны сведения, X-Structure-Date — когда в последний раз менялся состав колонок, X-Source — адрес страницы источников. Обе даты стоят и в имени файла, поэтому скачанный файл не теряет их, даже если заголовки никто не сохранил. Сейчас это 2026-09-06 и 2026-09-07.

Всё, что отдаётся машине

Адресов 9. Имена полей — договор: пока они не меняются, чужая программа продолжает работать, а сменятся — сменится дата структуры, и это будет видно, не открывая файла.

Адрес Тип Что отдаёт Поля
/export/metric/<показатель>/ text/csv один показатель по всем 89 субъектам код_субъекта, субъект, <имя показателя>, организаций_всего
/ministry/export/ text/csv главные числа страны и ряды по годам, в длинной форме раздел, показатель, год, значение
/mo/<октмо>/export/ text/csv организации муниципального образования org_id, инн, наименование, населённый_пункт, субъект
/mo/<октмо>/feed/ application/atom+xml лента изменений территории: появление организаций и смена статуса
/spec/<шифр>/export/ text/csv кто готовит по шифру в радиусе от города org_id, наименование, населённый_пункт, субъект, километров
/api/v1/regions/ application/json показатели по всем субъектам снимок, структура, источник, оговорка, всего, субъекты
/api/v1/regions/<код>/ application/json свод по одному субъекту код, название, организаций, районов, районов_без_колледжа
/api/v1/territories/<октмо>/ application/json свод по муниципальному образованию октмо, название, субъект, организаций, уровни_отсутствуют
/mcp application/json сервер MCP: 7 инструментов на чтение, только POST cohort_forecast, organization, outcomes, regions_by_indicator, specialty, territory, where_to_study

Что подставляется вместо угловых скобок: <октмо> — код ОКТМО территории, ровно пять знаков; более длинная запись того же кода отвечает постоянным переходом на пятизначную. <код> — двузначный код субъекта, как в реестре: отбор идёт по коду, а не по названию, потому что названия в источниках пишутся по-разному. <шифр> — шифр ФГОС с точками, например 15.01.05; у этой выгрузки есть свои параметры: откуда — название населённого пункта без типа («Ковров», а не «г. Ковров»), км — радиус от 5 до 500, по умолчанию 100.

Вместо <показатель> Колонка в файле Что это
организации организаций Организаций с лицензией
на-100-тысяч организаций_на_100_тысяч Организаций на 100 тысяч населения
плечо медиана_расстояния_км Удалённость от ближайшего колледжа
районы-без-колледжа доля_районов_без_колледжа Районов без колледжа
районы-без-сада доля_районов_без_сада Районов без детского сада
районы-без-школы доля_районов_без_школы Районов без школы
спрос-без-подготовки рабочих_мест_без_подготовки Рабочих мест без своей подготовки
люди-без-колледжа доля_людей_без_колледжа Людей в районах без колледжа
единственный-колледж специальностей_с_единственным_колледжем Специальностей с единственным колледжем
Заголовков CORS нет: читать эти адреса из браузера с чужого домена не получится, и это решение, а не недоделка — обращайтесь с сервера. Полного массива данных не отдаётся ни по одному адресу. Фамилий руководителей нет ни в одном машинном канале: на карточке организации они показываются, потоком не отдаются — из потока собирается профиль человека, а на него у нас нет основания.

Для помощников: сервер MCP

Третий пример выше — обращение к нему. Адрес один: /mcp, без косой черты на конце. Ревизия спецификации — 2026-07-28, приветствия и сессий в ней нет: каждый запрос несёт свою версию, и сервер принимает его отдельно от остальных.

Принимается только POST. Обязательны заголовки MCP-Protocol-Version и Mcp-Method, а для вызова инструмента ещё и Mcp-Name; значения обязаны совпадать с телом запроса, иначе ответ будет 400. Методы — server/discover, tools/list и tools/call.

Инструментов 7, все только читают: cohort_forecast, organization, outcomes, regions_by_indicator, specialty, territory, where_to_study. Каждый ответ несёт дату снимка, источник и оговорки — в том числе о том, что пересказ ответа помощником это уже продукт помощника, а не источника.

Дальше: правила использования — частота, что считается и как ссылаться; что в данных — оговорки, без которых из этих чисел делают неверные выводы. Состав источников и паспорт набора — на странице источников.