Public API

Программный доступ к справочникам ОКПД-2 и КТРУ через REST API с аутентификацией по API-ключу

Быстрый старт

1

Зарегистрируйтесь

Создайте аккаунт на moy-zakupki.ru

2

Получите API-ключ

Перейдите в Профиль → API-ключи и создайте новый ключ. Ключ показывается только один раз — сохраните его.

3

Сделайте первый запрос

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-ключ показывается только при создании. Если ключ утерян, деактивируйте его и создайте новый в настройках профиля.

КТРУ (Каталог товаров, работ, услуг)

GET/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
    }
  ]
}
GET/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"
  }
}
POST/api/public/v2/ktru/search/

Поиск КТРУ по характеристикам

Request body:

{
  "characteristics": ["мощность", "размер диагонали:27"],
  "status": "Включено в КТРУ",
  "is_enlarged": false
}

Поля status и is_enlarged необязательные. Характеристики можно передавать как ключевые слова или пары "ключ:значение".

ОКПД-2 (Классификатор)

GET/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
    }
  ]
}
GET/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
}

Мои технические задания

Выгрузка ТЗ, созданных в вашем аккаунте. Ключ видит только ваши документы. Эти запросы не расходуют месячный лимит — он отведён под справочники.

GET/api/public/v2/tech-specs/

Список ваших ТЗ без позиций — быстрый, подходит для регулярной синхронизации.

Query параметры:

statusready / draft / generating / error
updated_afterISO-8601. Для инкрементальной выгрузки: забирайте только изменённое
created_afterISO-8601, дата или дата-время
created_beforeISO-8601, дата или дата-время
GET/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. Генерация списывается из квоты генераций вашего тарифа — той же, что тратит интерфейс. Запуск, опрос статуса и выгрузка готового ТЗ месячный лимит запросов не расходуют вовсе: работа со своими ТЗ ничем не ограничена, кроме общего лимита запросов в минуту.

POST/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_typeKTRU или 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
}
GET/api/public/v2/tech-spec-generations/{id}/

Статус запуска. Опрашивайте раз в 5 секунд, пока is_finished не станет true. Генерация занимает около полутора минут, в тяжёлых случаях — до шести.

pendingв очереди
processingгенерируется, progress растёт от 0 до 100
completedготово — забирайте документ по tech_spec_id
failedпричина в поле 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-го числа каждого месяца.

Эта квота — про справочники. Генерация ТЗ тратит отдельную квоту генераций вашего тарифа, а не эти запросы; опрос статуса генерации не расходует ни ту, ни другую.

Коды ошибок

401

Unauthorized

Отсутствует или невалидный API-ключ, ключ деактивирован, истек, или исчерпана месячная квота

400

Bad Request

Некорректные параметры запроса

404

Not Found

Запрашиваемый код КТРУ или ОКПД-2 не найден

429

Too Many Requests

Превышен лимит запросов в минуту. Повторите после значения в заголовке Retry-After

500

Internal 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