Public API
Программный доступ к справочникам ОКПД-2 и КТРУ через REST API с аутентификацией по API-ключу
Быстрый старт
Зарегистрируйтесь
Создайте аккаунт на moy-zakupki.ru
Получите API-ключ
Перейдите в Профиль → API-ключи и создайте новый ключ. Ключ показывается только один раз — сохраните его.
Сделайте первый запрос
curl -H "Authorization: Api-Key mz_live_ваш_ключ" \
https://moy-zakupki.ru/api/public/v2/ktru/?per_page=2Аутентификация
Все запросы к Public API требуют заголовок Authorization с вашим API-ключом.
Формат заголовка:
Authorization: Api-Key mz_live_ваш_ключBase URL
https://moy-zakupki.ru/api/public/v2 Формат ответов
JSON (REST API) Важно: API-ключ показывается только при создании. Если ключ утерян, деактивируйте его и создайте новый в настройках профиля.
КТРУ (Каталог товаров, работ, услуг)
/api/public/v2/ktru/Получить список позиций КТРУ с пагинацией и фильтрацией
Query параметры:
statusСтатус КТРУ (например, "Включено в КТРУ")is_enlargedУкрупненные позиции (true / false)okpd2_codeФильтр по коду ОКПД-2 (например, "26.20.11")pageНомер страницы (по умолчанию: 1)per_pageЗаписей на странице (по умолчанию: 15, макс: 50)Пример ответа:
{
"count": 77000,
"next": "https://moy-zakupki.ru/api/public/v2/ktru/?page=2",
"previous": null,
"results": [
{
"code": "01.11.11.110-00000001",
"name": "Пшеница продовольственная",
"shortname": "Пшеница",
"status": "Включено в КТРУ",
"is_enlarged": false,
"okpd2_code": "01.11.11",
"okpd2_name": "Выращивание зерновых культур",
"unit_name": "тонн",
"characteristics_count": 3
}
]
}/api/public/v2/ktru/{code}/Получить детальную информацию о позиции КТРУ, включая характеристики и ограничения
Пример ответа:
{
"code": "26.20.11.110-00000165",
"name": "Компьютеры портативные массой не более 10 кг",
"shortname": "Ноутбук",
"description": "...",
"status": "Включено в КТРУ",
"is_enlarged": false,
"okpd2_code": "26.20.11",
"okpd2_name": "Компьютеры портативные",
"unit_name": "шт",
"characteristics": [
{
"key": "Диагональ экрана",
"values": ["13.3", "15.6", "17.3"]
}
],
"limitations": [
{
"name": "Ограничение по цене",
"group": "price"
}
],
"last_version": {
"version": 3,
"publish_date": "2024-10-15",
"application_date_start": "2024-11-01",
"inclusion_date": "2024-10-15"
}
}/api/public/v2/ktru/search/Поиск КТРУ по характеристикам
Request body:
{
"characteristics": ["мощность", "размер диагонали:27"],
"status": "Включено в КТРУ",
"is_enlarged": false
} Поля status и is_enlarged необязательные. Характеристики можно передавать как ключевые слова или пары "ключ:значение".
ОКПД-2 (Классификатор)
/api/public/v2/okpd2/Получить список кодов ОКПД-2 с пагинацией и фильтрацией
Query параметры:
levelУровень иерархии (2, 3, 4, 5...)is_actualТолько актуальные (true по умолчанию)pageНомер страницы (по умолчанию: 1)per_pageЗаписей на странице (по умолчанию: 15, макс: 50)Пример ответа:
{
"count": 20372,
"next": "https://moy-zakupki.ru/api/public/v2/okpd2/?page=2",
"previous": null,
"results": [
{
"code": "01.11.11",
"name": "Выращивание зерновых культур",
"level": 5,
"parent_code": "01.11",
"is_actual": true
}
]
}/api/public/v2/okpd2/{code}/Получить детальную информацию о коде ОКПД-2, включая дочерние коды и ограничения
Пример ответа:
{
"code": "01.11",
"name": "Выращивание зерновых и зернобобовых культур",
"level": 4,
"parent_code": "01",
"is_actual": true,
"children": [
{
"code": "01.11.11",
"name": "Выращивание зерновых культур",
"level": 5
}
],
"limitations": [
{
"name": "Ограничение",
"group": "regulatory"
}
],
"ktru_count": 42
}Мои технические задания
Выгрузка ТЗ, созданных в вашем аккаунте. Ключ видит только ваши документы. Эти запросы не расходуют месячный лимит — он отведён под справочники.
/api/public/v2/tech-specs/Список ваших ТЗ без позиций — быстрый, подходит для регулярной синхронизации.
Query параметры:
statusready / draft / generating / errorupdated_afterISO-8601. Для инкрементальной выгрузки: забирайте только изменённоеcreated_afterISO-8601, дата или дата-времяcreated_beforeISO-8601, дата или дата-время/api/public/v2/tech-specs/{id}/Полная структура: позиции, коды ОКПД-2/КТРУ и характеристики.
Пример ответа:
{
"id": "3f1c…",
"name": "Закупка лестниц",
"status": "ready",
"products_count": 2,
"products": [
{
"position": 1,
"name": "Лестница алюминиевая трёхсекционная",
"quantity": "5.00",
"unit": "шт",
"is_included": true,
"ktru_code": "25.99.29.190-00000123",
"okpd2_code": "25.99.29.190",
"characteristics": [
{
"name": "Объем встроенного накопителя",
"unit": "Гигабайт",
"source": "ktru",
"is_included": true,
"values": [
{
"value": "512",
"display": "≥ 512",
"requirement_type": "range",
"range_type": "greater_or_equal",
"extra_value": null,
"extra_range_type": null
}
]
}
]
}
]
}О значениях характеристик. Требование описывается всей связкой requirement_type / range_type / extra_value, а не одним value: например «не менее 512» — это range с greater_or_equal. Ориентируйтесь на них, если строите документ программно.
Коды могут быть null. Часть позиций не сопоставлена ни с КТРУ, ни с ОКПД-2 — это штатная ситуация, а не ошибка выгрузки. Отключённые позиции и характеристики возвращаются с is_included: false, а не пропускаются.
Генерация ТЗ
Запуск генерации технического задания — та же операция, что кнопка в личном кабинете, с тем же телом запроса. Работает асинхронно: запрос ставит задачу в очередь и сразу возвращает её идентификатор.
Генерации не расходуют лимит в 1 000 запросов/мес. Тот лимит отведён под справочники КТРУ и ОКПД-2. Генерация списывается из квоты генераций вашего тарифа — той же, что тратит интерфейс. Запуск, опрос статуса и выгрузка готового ТЗ месячный лимит запросов не расходуют вовсе: работа со своими ТЗ ничем не ограничена, кроме общего лимита запросов в минуту.
/api/public/v2/tech-spec-generations/ Ставит генерацию в очередь. Списывает одну генерацию за каждую позицию в items.
Тело запроса:
{
"items": [
{
"product_name": "Ноутбук офисный",
"product_code": "26.20.13.000-00000002",
"classifier_type": "KTRU",
"quantity": 5,
"unit": "шт"
}
]
} Обязательно только product_name. Остальное необязательно: classifier_type — KTRU или OKPD2, max_resources (1–20, по умолчанию 5) и max_sites (1–10, по умолчанию 3) управляют широтой поиска источников. Блок settings с header и footer задаёт шапку и подвал документа.
Ответ 201:
{
"id": "8c2e…",
"status": "processing",
"progress": 0,
"is_finished": false,
"product_name": "Ноутбук офисный",
"tech_spec_id": "3f1c…",
"error": null,
"generation_quota_remaining": 47
}/api/public/v2/tech-spec-generations/{id}/ Статус запуска. Опрашивайте раз в 5 секунд, пока is_finished не станет true. Генерация занимает около полутора минут, в тяжёлых случаях — до шести.
pendingв очередиprocessingгенерируется, progress растёт от 0 до 100completedготово — забирайте документ по tech_spec_idfailedпричина в поле error, квота возвращена Список всех ваших запусков — GET /api/public/v2/tech-spec-generations/.
Полный цикл
import time, requests
H = {"Authorization": "Api-Key mz_live_…"}
BASE = "https://moy-zakupki.ru/api/public/v2"
# 1. Запускаем генерацию
r = requests.post(f"{BASE}/tech-spec-generations/", headers=H, json={
"items": [{"product_name": "Ноутбук офисный", "quantity": 5, "unit": "шт"}]
})
r.raise_for_status()
task = r.json()
# 2. Ждём завершения
while not task["is_finished"]:
time.sleep(5)
task = requests.get(
f"{BASE}/tech-spec-generations/{task['id']}/", headers=H
).json()
if task["status"] == "failed":
raise RuntimeError(task["error"])
# 3. Забираем готовое ТЗ
spec = requests.get(
f"{BASE}/tech-specs/{task['tech_spec_id']}/", headers=H
).json()
print(spec["name"], spec["products_count"])Кончились генерации — придёт 429 с полем error: "insufficient_generation_quota". Этим он отличается от 429 при превышении лимита запросов в минуту: там такого поля нет. В первом случае нужно пополнить квоту, во втором — просто подождать.
Завершение не гарантирует полноту. Иногда пайплайн отрабатывает, но по части позиций характеристики найти не удаётся. Если результат важен для дальнейшей автоматики, проверяйте содержимое ТЗ, а не только status.
Тарифы и лимиты
Каждый API-ключ привязан к тарифу, определяющему месячную квоту и ограничение по частоте запросов. Месячная квота расходуется только справочниками (КТРУ и ОКПД-2); работа со своими ТЗ — генерация, опрос статуса и выгрузка — из неё не списывается.
| Тариф | Запросов / месяц | Запросов / мин |
|---|---|---|
| Free | 1 000 | 10 |
| Starter | 10 000 | 30 |
| Business | 100 000 | 60 |
| Enterprise | 1 000 000 | 120 |
При превышении лимита API вернет 429 Too Many Requests с заголовком Retry-After. Месячная квота сбрасывается 1-го числа каждого месяца.
Эта квота — про справочники. Генерация ТЗ тратит отдельную квоту генераций вашего тарифа, а не эти запросы; опрос статуса генерации не расходует ни ту, ни другую.
Коды ошибок
401Unauthorized
Отсутствует или невалидный API-ключ, ключ деактивирован, истек, или исчерпана месячная квота
400Bad Request
Некорректные параметры запроса
404Not Found
Запрашиваемый код КТРУ или ОКПД-2 не найден
429Too Many Requests
Превышен лимит запросов в минуту. Повторите после значения в заголовке Retry-After
500Internal Server Error
Внутренняя ошибка сервера. Повторите запрос позже
Пагинация
Все списочные эндпоинты возвращают результаты с пагинацией. Для навигации по страницам используйте параметры page и per_page.
pageНомер страницы (по умолчанию: 1)per_pageЗаписей на странице (по умолчанию: 15, максимум: 50)GET /api/public/v2/ktru/?page=3&per_page=25
{
"count": 77000,
"next": "https://moy-zakupki.ru/api/public/v2/ktru/?page=4&per_page=25",
"previous": "https://moy-zakupki.ru/api/public/v2/ktru/?page=2&per_page=25",
"results": [...]
}Примеры кода
Python (requests)
import requests
API_KEY = "mz_live_ваш_ключ"
BASE_URL = "https://moy-zakupki.ru/api/public/v2"
HEADERS = {"Authorization": f"Api-Key {API_KEY}"}
# Получить список КТРУ
response = requests.get(
f"{BASE_URL}/ktru/",
headers=HEADERS,
params={"status": "Включено в КТРУ", "per_page": 10}
)
data = response.json()
print(f"Всего записей: {data['count']}")
for item in data["results"]:
print(f" {item['code']} — {item['name']}")
# Получить детали по коду
response = requests.get(
f"{BASE_URL}/ktru/26.20.11.110-00000165/",
headers=HEADERS
)
detail = response.json()
print(f"Характеристик: {len(detail['characteristics'])}")JavaScript (Fetch API)
const API_KEY = "mz_live_ваш_ключ";
const BASE_URL = "https://moy-zakupki.ru/api/public/v2";
// Получить список КТРУ
const response = await fetch(
`${BASE_URL}/ktru/?status=Включено+в+КТРУ&per_page=10`,
{ headers: { "Authorization": `Api-Key ${API_KEY}` } }
);
const data = await response.json();
console.log(`Всего записей: ${data.count}`);
data.results.forEach(item =>
console.log(` ${item.code} — ${item.name}`)
);
// Получить детали ОКПД-2
const okpdResponse = await fetch(
`${BASE_URL}/okpd2/26.20.11/`,
{ headers: { "Authorization": `Api-Key ${API_KEY}` } }
);
const okpd = await okpdResponse.json();
console.log(`Дочерних кодов: ${okpd.children.length}`);cURL
# Список КТРУ
curl "https://moy-zakupki.ru/api/public/v2/ktru/?per_page=5" \
-H "Authorization: Api-Key mz_live_ваш_ключ"
# Детали КТРУ по коду
curl "https://moy-zakupki.ru/api/public/v2/ktru/26.20.11.110-00000165/" \
-H "Authorization: Api-Key mz_live_ваш_ключ"
# Список ОКПД-2 (уровень 3)
curl "https://moy-zakupki.ru/api/public/v2/okpd2/?level=3&per_page=10" \
-H "Authorization: Api-Key mz_live_ваш_ключ"
# Поиск КТРУ по характеристикам
curl -X POST "https://moy-zakupki.ru/api/public/v2/ktru/search/" \
-H "Authorization: Api-Key mz_live_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{"characteristics": ["мощность", "напряжение:220"]}'Интерактивная документация
Полная интерактивная документация доступна через Swagger UI. Можно выполнять запросы прямо из браузера.
Открыть Swagger UI