API
Российская статистика приходит прямо в ваши модели, дашборды и внутренние системы: JSON или CSV, готовые ряды вместо разбора выгрузок, с указанием происхождения каждой цифры.
Публичная витрина бесплатна. Программный доступ для компаний работает на коммерческих условиях, но начать можно с бесплатного тарифа: он не урезан по данным, ограничен только объём выгрузки.
Начать за три шага
- Заведите учётную запись В личном кабинете введите почту и получите ссылку для входа. Пароля нет: в следующий раз вход тоже по ссылке на почту.
- Выпустите токен Он показывается один раз, поэтому сразу сохраните его. Токенов может быть несколько, например по одному на проект.
-
Передавайте его заголовком
Подходит любой из двух видов:
Authorization: BearerилиX-API-Key.
Первый запрос: средняя цена пива по всем регионам с начала 2024 года
curl -H "Authorization: Bearer ВАШ_ТОКЕН" \
"https://rustata.ru/api/v1/data?dataset=fedstat/indicator_31448&class=3203&geo=region&start=2024-01"
Данные по территориям
Главный метод - GET /api/v1/data. Он отдаёт показатель сразу по
многим территориям, поэтому «цены на пиво по всем регионам» это один запрос, а не восемьдесят
пять.
Собирать данные пачками выгодно и по расходу квоты: она считается в значениях, поэтому один срез по всем регионам стоит ровно столько, сколько в нём точек, - а восемьдесят пять отдельных запросов стоили бы столько же плюс время на них.
Параметры
| Параметр | Что задаёт |
|---|---|
dataset | набор данных, например fedstat/indicator_31448. Обязателен |
geo | уровень территории или перечень кодов через запятую |
class | код продукта в классификаторе набора |
measure, transformation | вид показателя и преобразование |
freq, unit | частота и единица измерения |
start, end | период; можно писать месяцем: 2024-01 |
format | json (по умолчанию) или csv |
limit, offset | сколько рядов взять и с какого начать |
bom | только для CSV: 1 добавляет BOM для Excel на Windows |
Уровни территории
geo | Что вернётся | Территорий |
|---|---|---|
country | Россия целиком | 1 |
district | федеральные округа | 13 с историческими |
macroregion | экономические районы (прежнее деление) | 11 |
region | субъекты федерации | до 85 |
city | города и районы внутри субъектов | сотни |
all | все уровни сразу | - |
46000000000,RU-50 | только перечисленные территории | по списку |
Коды принимаются в обоих видах: исходный ОКАТО и наш нормализованный
(RU-46). Угадывать территорию по коду не придётся: у каждого ряда в ответе есть
geo, geo_label и geo_level.
Все территории с их кодами - в справочнике территорий. Оттуда же удобно брать коды, когда нужны не все регионы, а несколько конкретных.
Коды продуктов
Классификатор у каждого набора свой: в потребительских ценах это номер
товара из корзины Росстата, в промышленности - код ОКПД2. Что подставлять в class,
показано в справочнике кодов - по каждому набору отдельная таблица с поиском
по названию.
Россия приходит двумя рядами
«Российская Федерация» и «Российская Федерация без учёта новых субъектов (с 01.01.2023)» -
оба на уровне country.
Это не дубль, а две методики счёта. Различить их можно по полю geo_label,
выбор между ними за вами.
Что приходит в ответе
Ответ состоит из двух частей: список рядов с описанием территории и плоский список значений, по строке на каждое.
Такая форма разворачивается в привычную таблицу «период на территории» одной строкой кода и не требует разбирать многоэтажную шапку, как в исходных выгрузках.
{
"series": [
{ "series_key": "s1_23sqev7ozzer4t73", "geo": "14000000000",
"geo_label": "Белгородская область", "geo_level": "region",
"title": "Пиво отечественное, л", "freq": "M", "unit": "RUB" }
],
"observations": [
{ "series_key": "s1_23sqev7ozzer4t73", "period": "2025-06-01",
"value": 198.23, "as_of": "2025-06-01" }
],
"series_count": 100, "series_total": 470,
"offset": 0, "has_more": true, "next_offset": 100
}
На каждый период приходит одно значение - последняя опубликованная оценка.
Рядом идёт as_of: дата публикации именно этой оценки. Статистику
уточняют задним числом, и по этому полю видно, какая версия цифры у вас на руках.
В CSV те же данные с разделителем ; и колонками
series_key;geo;geo_label;geo_level;period;value;as_of. Кодировка UTF-8 без BOM: так
её ждут pandas, readr и CSV.jl. Для Excel на Windows добавьте &bom=1, иначе
кириллица откроется кракозябрами.
Примеры
Все три примера решают одну задачу: берут среднюю цену пива по регионам с начала 2024 года и разворачивают в таблицу «период на территории». Каждый проверен исполнением.
Python
import pandas as pd
import requests
TOKEN = "rst_ваш_токен"
resp = requests.get(
"https://rustata.ru/api/v1/data",
params={"dataset": "fedstat/indicator_31448", "class": "3203",
"geo": "region", "start": "2024-01"},
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=60,
)
resp.raise_for_status()
payload = resp.json()
series = pd.DataFrame(payload["series"]).set_index("series_key")
obs = pd.DataFrame(payload["observations"])
obs["region"] = obs["series_key"].map(series["geo_label"])
obs["period"] = pd.to_datetime(obs["period"])
table = obs.pivot(index="period", columns="region", values="value")
print(table.tail())
# у тарифов без месячной квоты этого заголовка нет, поэтому .get, а не []
print("остаток квоты:", resp.headers.get("X-Quota-Values-Remaining", "без ограничения"))
R
library(httr)
library(readr)
library(tidyr)
# Windows: если консоль печатает кириллицу как <U+0411><U+0435>…, дело в локали сессии,
# а не в данных - сами строки целы. Лечится одной строкой:
if (.Platform$OS.type == "windows") Sys.setlocale("LC_CTYPE", "Russian_Russia.utf8")
token <- "rst_ваш_токен"
resp <- GET(
"https://rustata.ru/api/v1/data",
query = list(dataset = "fedstat/indicator_31448", class = "3203",
geo = "region", start = "2024-01", format = "csv"),
add_headers(Authorization = paste("Bearer", token))
)
stop_for_status(resp)
# content(resp, "raw") + locale(): readr сам разбирает UTF-8, без промежуточной строки
df <- read_delim(content(resp, "raw"), delim = ";",
locale = locale(encoding = "UTF-8"), show_col_types = FALSE)
table <- pivot_wider(df, id_cols = period, names_from = geo_label, values_from = value)
head(table)
Julia
using HTTP, CSV, DataFrames
token = "rst_ваш_токен"
resp = HTTP.get("https://rustata.ru/api/v1/data";
query = Dict("dataset" => "fedstat/indicator_31448", "class" => "3203",
"geo" => "region", "start" => "2024-01", "format" => "csv"),
headers = ["Authorization" => "Bearer $token"])
df = CSV.read(IOBuffer(resp.body), DataFrame; delim = ';')
table = unstack(df, :period, :geo_label, :value)
first(table, 5)
Справочник
Методы
| Метод | Что делает |
|---|---|
GET /api/v1/data | срез показателя по территориям, JSON или CSV |
GET /api/v1/series/search | поиск рядов по строке, отдаёт series_key |
GET /api/v1/series/{series_key}/observations | значения одного ряда |
GET /api/v1/series/{series_key}/evidence | происхождение: файл-источник, релиз, прогон загрузки |
GET /api/v1/concepts/search | поиск показателей, а не отдельных рядов |
GET /api/v1/concepts/{concept_id} | карточка показателя со сводкой |
Интерактивный справочник, где запрос можно выполнить своим токеном прямо в браузере - Swagger. Машиночитаемое описание - openapi.json.
Лимиты
| Тариф | Значений в месяц | Запросов в минуту |
|---|---|---|
| бесплатный | 100 000 | 20 |
| академический | без ограничения | 120 |
| коммерческий | без ограничения | 120 |
Квота считается в значениях, а не в запросах. Один запрос возвращает то десяток точек, то десятки тысяч, поэтому счёт запросов не отражал бы ни пользы вам, ни нагрузки на нас.
100 000 значений - это, например, два десятка полных срезов по всем регионам за десять лет или сотни небольших выборок. Для знакомства, учёбы и разовых расчётов этого хватает; для регулярной работы напишите нам.
Отдельно стоит минутный лимит запросов: он про всплески, а не про объём. Отклонённый запрос квоту не расходует.
Остаток приходит в заголовках X-Quota-Values-Remaining и
X-RateLimit-Remaining-Minute. При отказе 429 в Retry-After
сказано, через сколько секунд повторять.
Академический тариф - для университетов, научных институтов и их сотрудников: месячной квоты у такой учётной записи нет. Для части организаций он включается автоматически при входе с рабочей почты, просить ничего не нужно.
Если вы из научной организации и упёрлись в квоту, напишите через форму связи - подключим. Нужен объём для компании - тоже напишите, обсудим условия под задачу.
Постраничная выдача
За один раз приходит 100 рядов, параметром limit
можно взять до 300. Сколько подходит всего, видно в series_total, а
next_offset подсказывает, с чего начать следующую страницу.
Постранично идут ряды, а не значения: каждый ряд приходит целиком по времени, склеивать разрезанную историю не нужно.
Потолок ответа - 60 000 значений. Если страница набирает больше,
придёт SLICE_TOO_BIG: сузьте период или уменьшите limit. Потолок нужен
не для строгости - ответ целиком собирается в памяти сервера, который обслуживает и сайт.
Кэширование
Ответ несёт ETag и Cache-Control на час. Повторите
запрос с этим ETag в заголовке If-None-Match - придёт 304 без тела, за
десяток миллисекунд и без расхода квоты.
ETag меняется при любом обновлении данных набора: не только когда выходит новый период, но и когда пересматривают старое значение. На него можно опираться в регулярной загрузке: пришло 304 - у вас уже актуальная копия.
curl -H "Authorization: Bearer ВАШ_ТОКЕН" \
-H 'If-None-Match: W/"b3392e076b592a86b3f8"' \
"https://rustata.ru/api/v1/data?dataset=fedstat/indicator_31448&class=3203&geo=region"
Ошибки
Все ошибки выглядят одинаково, каким бы методом вы ни пользовались: код, объяснение и номер запроса.
Номер стоит сохранять в логах: по нему мы найдём конкретный запрос и
разберём, что пошло не так. Он же приходит в заголовке X-Request-Id при удачных
ответах.
{
"error": { "code": "RATE_LIMITED",
"message": "Исчерпана месячная квота тарифа: 100 000 значений…" },
"request_id": "req_4325b22dc77347b1"
}
| Код | HTTP | Когда |
|---|---|---|
UNAUTHENTICATED | 401 | токен не передан |
INVALID_TOKEN | 401 | токен неизвестен или отозван |
RATE_LIMITED | 429 | исчерпана квота тарифа |
SLICE_TOO_BIG | 400 | запрос выбирает слишком много данных |
NOT_FOUND | 404 | под фильтры ничего не подошло |
INTERNAL | 500 | ошибка на нашей стороне |
Что дальше
В планах:
- выгрузка больших срезов файлом, без ограничения на размер ответа;
- надстройка для Excel;
- доступ к истории пересмотров: не только текущая оценка, но и все предыдущие.
Расскажите через форму связи, чего не хватает вам - это прямо влияет на очередь работ.