API сервер и выгрузка остатков
Загрузка…
Справка по разделу
Персональный доступ к данным вашей базы по токену — без входа в программу. Подходит для сайта, маркетплейса, 1С, скрипта на сервере или cron-задачи.
У каждой фирмы свой токен и свой набор данных. Запросы идут на общий адрес API Меркурий-ИИ, но по токену система понимает, из какой базы читать остатки и цены.
Это не общий ключ приложения (APP_API_KEY) — он нужен только внутренним сервисам. Для вашей интеграции достаточно токена из раздела «Настройка».
У всех методов один и тот же входной адрес на сервере Меркурий-ИИ. Меняются только параметры route (какой метод вызвать) и token (ваш ключ):
https://mercury-ai.ru/api/public/index.php?route=МАРШРУТ&token=ВАШ_КЛЮЧ
Если вы разворачиваете программу на своём сервере, базовый адрес будет другим — его показывает вкладка API сервер, блок «Маршруты и URL». Готовые строки с вашим ключом — в таблице «Примеры URL» сразу после «Создать ключ».
Ключ можно не добавлять в URL, а передать заголовком Authorization: Bearer ВАШ_КЛЮЧ или X-Api-Key: ВАШ_КЛЮЧ — тогда в query достаточно ?route=….
Подставьте свой ключ вместо {token} (или используйте заголовок, см. ниже).
| Данные | route | Пример URL |
|---|---|---|
| Остатки (YML) | public/firm-api/stocks.yml | https://mercury-ai.ru/api/public/index.php?route=public/firm-api/stocks.yml&token={token} |
| Остатки (JSON) | public/firm-api/stocks.json | https://mercury-ai.ru/api/public/index.php?route=public/firm-api/stocks.json&token={token} |
| Ассортимент | public/firm-api/catalog.json | https://mercury-ai.ru/api/public/index.php?route=public/firm-api/catalog.json&token={token} |
| Контрагенты | public/firm-api/contragents.json | https://mercury-ai.ru/api/public/index.php?route=public/firm-api/contragents.json&token={token} |
| Склады | public/firm-api/stores.json | https://mercury-ai.ru/api/public/index.php?route=public/firm-api/stores.json&token={token} |
| Приходы | public/firm-api/prih-docs.json | https://mercury-ai.ru/api/public/index.php?route=public/firm-api/prih-docs.json&date_from=2026-07-01&date_to=2026-07-31&token={token} |
| Расходы | public/firm-api/rash-docs.json | https://mercury-ai.ru/api/public/index.php?route=public/firm-api/rash-docs.json&date_from=2026-07-01&date_to=2026-07-31&token={token} |
| Заказы поставщику | public/firm-api/supplier-orders.json | https://mercury-ai.ru/api/public/index.php?route=public/firm-api/supplier-orders.json&date_from=2026-07-01&date_to=2026-07-31&token={token} |
| Заявки покупателей | public/firm-api/customer-orders.json | https://mercury-ai.ru/api/public/index.php?route=public/firm-api/customer-orders.json&date_from=2026-07-01&date_to=2026-07-31&token={token} |
| Фото товара | public/firm-api/tovar-photo/{id} | https://mercury-ai.ru/api/public/index.php?route=public/firm-api/tovar-photo/1001&token={token} |
Для журналов приходов, расходов и заказов добавьте date_from и date_to (формат YYYY-MM-DD). Фильтр по складу — store_id или id_sklad.
Заказы поставщику и заявки покупателей также принимают POST на тот же route (без дат в URL) — см. разделы ниже.
403, токен при этом сохраняется.HTTP: GET · route: public/firm-api/stocks.yml
Только позиции с ненулевым остатком. URL: https://mercury-ai.ru/api/public/index.php?route=public/firm-api/stocks.yml&token=КЛЮЧ — см. базовый URL.
Ответ: XML (application/xml), формат YML-каталога Yandex с несколькими складами.
HTTP: GET · Маршрут: public/firm-api/stocks.json
Те же данные, что в YML, в обычном JSON — удобнее для скриптов и интеграций. URL — поле «URL остатков (JSON)» в настройках API.
{
"updated_at": "2026-07-01 15:00:00",
"stores": [
{"id": 12, "name": "Основной склад", "phone": "...", "address": "...", "city": "Москва"}
],
"products": [
{
"id": 1001,
"name": "Молоко 3,2% 1л",
"barcode": "4601234567890",
"unit": "шт",
"measure_unit": "1",
"price": 89.00,
"stocks": [{"store_id": 12, "price": 89.00, "amount": 24}]
}
]
}
В отличие от catalog.json, здесь только товары с остатком > 0.
HTTP: GET · Маршрут: public/firm-api/catalog.json
Весь ассортимент фирмы: названия, группы, штрихкоды, цены и остатки по каждому складу. Готовый URL — поле «URL ассортимента (JSON)» в настройках API.
Ответ: JSON (application/json).
{
"updated_at": "2026-07-01 15:00:00",
"stores": [
{"id": 12, "name": "Основной склад", "phone": "...", "address": "...", "city": "Москва"}
],
"products": [
{
"id": 1001,
"name": "Молоко 3,2% 1л",
"group_id": 5,
"group_name": "Молочные",
"unit": "шт",
"barcode": "4601234567890",
"barcodes": ["4601234567890"],
"composition": "",
"nds": 10,
"purchase_price": 65.00,
"web_photo_url": "https://…/api/public/index.php?route=public/firm-api/tovar-photo/1001&token=…",
"prices": [{"store_id": 12, "price": 89.00}],
"stocks": [{"store_id": 12, "amount": 24}]
}
]
}
Поле web_photo_url — ссылка на «Большое фото для интернета» из карточки товара (если загружено). Фото отдаётся отдельным запросом GET public/firm-api/tovar-photo/{id} с тем же токеном.
HTTP: GET · Маршрут: public/firm-api/contragents.json
Справочник контрагентов и групп: поставщики, покупатели, склады, реквизиты. URL — поле «URL контрагентов (JSON)» в настройках API.
{
"updated_at": "2026-07-01 15:00:00",
"groups": [
{"id": 0, "parent_id": null, "name": "Все"},
{"id": 2, "parent_id": 0, "name": "Поставщики"}
],
"contragents": [
{
"id": 15,
"group_id": 2,
"group_name": "Поставщики",
"name": "ООО Ромашка",
"is_sklad": false,
"is_system": false,
"id_selful": null,
"inn": "7701234567",
"kpp": "770101001",
"fullname": "Общество с ограниченной ответственностью «Ромашка»",
"phone": "+7…",
"email": "info@example.ru",
"url": "https://example.ru",
"addr_legal": "…",
"addr_physical": "…",
"city": "Москва",
"ogrn": "",
"okpo": "",
"bik": "044525225",
"bank_name": "…",
"rs": "40702810…",
"ks": "30101810…",
"debt_flag": 1,
"allow_lower_rash_prih": 0
}
]
}
Склады отмечены is_sklad: true. Служебные записи (касса, покупатель по умолчанию и т.п.) — is_system: true. Токены кассы и маркировки в ответ не попадают.
HTTP: GET · Маршрут: public/firm-api/stores.json
Только собственные склады фирмы (контрагенты с признаком «это склад»). URL — поле «URL складов (JSON)» в настройках API. Те же id, что в store_id у остатков и цен.
{
"updated_at": "2026-07-01 15:00:00",
"stores": [
{
"id": 12,
"name": "Основной склад",
"id_selful": 1,
"phone": "+7…",
"email": "sklad@example.ru",
"addr_physical": "ул. …",
"addr_legal": "…",
"address": "ул. …",
"city": "Москва"
}
]
}
HTTP: GET · Маршрут: public/firm-api/prih-docs.json
Приходные накладные с заголовками и табличной частью. Пример URL — в настройках API (период — текущий месяц).
Параметры (query, кроме токена):
date_from, date_to — обязательны, формат YYYY-MM-DD, период до 366 днейstore_id — необязательно; склад из stores.json. Без параметра — по всем складамid_sklad (= store_id)Черновики попадают в выборку независимо от дат; проведённые — только за указанный период (как в журнале ERP). Приходы из производства не включаются.
{
"updated_at": "2026-07-01 15:00:00",
"filter": {"store_id": 12, "date_from": "2026-07-01", "date_to": "2026-07-31"},
"store": {"id": 12, "name": "Основной склад", "address": "…", "city": "Москва"},
"stores": [{"id": 12, "name": "Основной склад", …}],
"docs": [
{
"id": 501,
"date_prih": "2026-07-15",
"nomer_nakl": "ПН-123",
"date_nakl": "2026-07-14",
"store_id": 12,
"store_name": "Основной склад",
"contragent_id": 15,
"contragent_name": "ООО Ромашка",
"posted": true,
"summa": 12500.00,
"dolg": 0,
"is_return": false,
"is_auto": false,
"rows": [
{
"id": 9001,
"product_id": 1001,
"product_name": "Молоко 3,2% 1л",
"unit": "шт",
"qty": 24,
"nds": 10,
"price": 65.00,
"retail_price": 89.00,
"summa": 1560.00
}
]
}
]
}
Поле store — выбранный склад (если передан store_id), иначе null. Массив stores — все склады фирмы для сопоставления store_id в документах.
HTTP: GET · Маршрут: public/firm-api/rash-docs.json
Расходные накладные с заголовками и табличной частью. Пример URL — в настройках API (период — текущий месяц).
Параметры (query, кроме токена):
date_from, date_to — обязательны, формат YYYY-MM-DD, период до 366 днейstore_id — необязательно; склад из stores.json. Без параметра — по всем складамid_sklad (= store_id)Черновики попадают в выборку независимо от дат; проведённые — только за указанный период (как в журнале ERP). Расходы из производства не включаются.
{
"updated_at": "2026-07-01 15:00:00",
"filter": {"store_id": 12, "date_from": "2026-07-01", "date_to": "2026-07-31"},
"store": {"id": 12, "name": "Основной склад", "address": "…", "city": "Москва"},
"stores": [{"id": 12, "name": "Основной склад", …}],
"docs": [
{
"id": 701,
"date_rash": "2026-07-15",
"nomer_nakl": "РН-456",
"date_nakl": "2026-07-15",
"store_id": 12,
"store_name": "Основной склад",
"contragent_id": 20,
"contragent_name": "Иванов И.И.",
"posted": true,
"summa": 8900.00,
"summa_dohod": 2100.00,
"dolg": 0,
"is_return": false,
"is_auto": false,
"linked_prih_id": null,
"rows": [
{
"id": 9101,
"product_id": 1001,
"product_name": "Молоко 3,2% 1л",
"unit": "шт",
"qty": 10,
"nds": 10,
"price": 89.00,
"summa": 890.00,
"cost": 65.00,
"profit": 240.00
}
]
}
]
}
Поле store — выбранный склад (если передан store_id), иначе null. Массив stores — все склады фирмы для сопоставления store_id в документах. Поле linked_prih_id — связанный приход (возврат поставщику).
Маршрут: public/firm-api/supplier-orders.json
Заказы поставщикам с заголовками и табличной частью. Пример URL — в настройках API (период — текущий месяц).
Параметры (query, кроме токена):
date_from, date_to — обязательны, формат YYYY-MM-DD, период до 366 днейstore_id — необязательно; склад из stores.json. Без параметра — по всем складамid_sklad (= store_id)Документы отбираются по дате заказа (date_order) в указанном периоде (как в журнале ERP).
{
"updated_at": "2026-07-01 15:00:00",
"filter": {"store_id": 12, "date_from": "2026-07-01", "date_to": "2026-07-31"},
"store": {"id": 12, "name": "Основной склад", "address": "…", "city": "Москва"},
"stores": [{"id": 12, "name": "Основной склад", …}],
"docs": [
{
"id": 301,
"date_order": "2026-07-10",
"nomer": "ЗП-15",
"date_nomer": "2026-07-09",
"store_id": 12,
"store_name": "Основной склад",
"contragent_id": 15,
"contragent_name": "ООО Ромашка",
"sent": true,
"summa": 5400.00,
"linked_prih_id": 501,
"prih_posted": true,
"rows": [
{
"id": 8001,
"product_id": 1001,
"product_name": "Молоко 3,2% 1л",
"unit": "шт",
"qty": 24,
"price": 65.00,
"summa": 1560.00
}
]
}
]
}
Поле sent — заказ отправлен поставщику по email. linked_prih_id и prih_posted — связь с приходной накладной и её проведение.
HTTP: POST · тот же маршрут (без date_from/date_to). Тело — JSON.
Обязательные поля: store_id, contragent_id (поставщик из contragents.json), массив rows с хотя бы одной строкой.
date_order — необязательно; по умолчанию сегодняnomer, date_nomer — необязательно; пустой номер заменится на id документаproduct_id (или id_tovar), qty (или cnt), price (или cena) — цена необязательна, подставится последняя закупочная{
"date_order": "2026-07-10",
"nomer": "ЗП-15",
"store_id": 12,
"contragent_id": 15,
"rows": [
{"product_id": 1001, "qty": 24, "price": 65.00},
{"product_id": 1002, "qty": 10}
]
}
Ответ 201 Created — созданный документ в том же формате, что элемент массива docs при GET:
{
"doc": {
"id": 302,
"date_order": "2026-07-10",
"nomer": "ЗП-15",
"store_id": 12,
"contragent_id": 15,
"sent": false,
"summa": 1560.00,
"linked_prih_id": null,
"prih_posted": false,
"rows": [ … ]
}
}
Товар в заказе поставщику должен относиться к выбранному поставщику (как в ERP). Отправка по email через API недоступна.
Маршрут: public/firm-api/customer-orders.json
Заявки покупателей с заголовками и табличной частью. Пример URL — в настройках API (период — текущий месяц).
Параметры (query, кроме токена):
date_from, date_to — обязательны, формат YYYY-MM-DD, период до 366 днейstore_id — необязательно; склад из stores.json. Без параметра — по всем складамid_sklad (= store_id)Документы отбираются по дате заявки (date_order) в указанном периоде (как в журнале ERP).
{
"updated_at": "2026-07-01 15:00:00",
"filter": {"store_id": 12, "date_from": "2026-07-01", "date_to": "2026-07-31"},
"store": {"id": 12, "name": "Основной склад", "address": "…", "city": "Москва"},
"stores": [{"id": 12, "name": "Основной склад", …}],
"docs": [
{
"id": 401,
"date_order": "2026-07-12",
"nomer": "ЗК-22",
"date_nomer": "2026-07-12",
"store_id": 12,
"store_name": "Основной склад",
"contragent_id": 20,
"contragent_name": "Иванов И.И.",
"sent": false,
"summa": 1780.00,
"description": "Доставка до 18:00",
"linked_rash_id": 701,
"rash_posted": false,
"rows": [
{
"id": 8101,
"product_id": 1001,
"product_name": "Молоко 3,2% 1л",
"unit": "шт",
"qty": 20,
"price": 89.00,
"summa": 1780.00
}
]
}
]
}
Поле description — текст заявки. linked_rash_id и rash_posted — связь с расходной накладной и её проведение.
HTTP: POST · тот же маршрут (без date_from/date_to). Тело — JSON.
Обязательные поля: store_id, contragent_id (покупатель из contragents.json), массив rows с хотя бы одной строкой.
date_order — необязательно; по умолчанию сегодняnomer, date_nomer, description — необязательноproduct_id, qty, опционально price (иначе последняя закупочная цена товара){
"date_order": "2026-07-12",
"store_id": 12,
"contragent_id": 20,
"description": "Доставка до 18:00",
"rows": [
{"product_id": 1001, "qty": 20, "price": 89.00}
]
}
Ответ 201 Created — поле doc с созданной заявкой и строками (формат как при GET).
Ключи создаются в Настройка → API сервер — по тому же принципу, что выносные ссылки на ТСД: несколько ключей на базу, комментарий, отзыв без затрагивания других ключей. Ключи бессрочные; полный ключ показывается один раз при создании.
Ключ передаётся одним из способов (достаточно одного):
?token=…Authorization: Bearer ВАШ_КЛЮЧX-Api-Key: ВАШ_КЛЮЧСессия пользователя и ключ APP_API_KEY для этого метода не нужны. API должен быть включён в настройках базы.
В каталог попадают только позиции с ненулевым остатком хотя бы на одном складе.
IS_SKLAD_FLAG): id, название, телефон, адрес, город.id = код товара в базе): название, цена, единица измерения, штрихкод.id, price, amount.Пример фрагмента:
<?xml version="1.0" encoding="UTF-8"?>
<yml_catalog updated_at="2026-07-01 14:30:00">
<shop/>
<sklads>
<store id="12" useForDelivery="false" phone="+7..." address="..." name="Основной склад" city="Москва"/>
</sklads>
<offers>
<offer id="1001">
<name>Молоко 3,2% 1л</name>
<price>89.00</price>
<measure>шт</measure>
<measureUnit>1</measureUnit>
<barcode>4601234567890</barcode>
<store id="12" price="89.00" amount="24"/>
</offer>
</offers>
</yml_catalog>
При ошибке авторизации или отключённом API сервер возвращает JSON:
{"error": "Неверный токен API"}
| Код | Значение |
|---|---|
401 | Токен не передан или неверный |
403 | API выключен в настройках фирмы |
500 | Ошибка на сервере при формировании YML |
Замените TOKEN на ваш ключ. Базовый адрес на сервере Меркурий-ИИ:
BASE=https://mercury-ai.ru/api/public/index.php
curl -sS "BASE?route=public/firm-api/stocks.yml&token=TOKEN" -o stocks.yml
curl -sS \
"BASE?route=public/firm-api/prih-docs.json&date_from=2026-07-01&date_to=2026-07-31&store_id=12&token=TOKEN" \
-o prih-docs.json
curl -sS -H "Authorization: Bearer TOKEN" \
"BASE?route=public/firm-api/rash-docs.json&date_from=2026-07-01&date_to=2026-07-31&store_id=12" \
-o rash-docs.json
curl -sS -H "Authorization: Bearer TOKEN" \
"BASE?route=public/firm-api/supplier-orders.json&date_from=2026-07-01&date_to=2026-07-31&store_id=12" \
-o supplier-orders.json
curl -sS -X POST -H "Authorization: Bearer TOKEN" -H "Content-Type: application/json" \
-d '{"store_id":12,"contragent_id":15,"rows":[{"product_id":1001,"qty":24,"price":65}]}' \
"BASE?route=public/firm-api/supplier-orders.json"
curl -sS -H "Authorization: Bearer TOKEN" \
"BASE?route=public/firm-api/customer-orders.json&date_from=2026-07-01&date_to=2026-07-31&store_id=12" \
-o customer-orders.json
curl -sS -X POST -H "Authorization: Bearer TOKEN" -H "Content-Type: application/json" \
-d '{"store_id":12,"contragent_id":20,"description":"Доставка до 18:00","rows":[{"product_id":1001,"qty":20}]}' \
"BASE?route=public/firm-api/customer-orders.json"
curl -sS -H "Authorization: Bearer TOKEN" \
"BASE?route=public/firm-api/stores.json" \
-o stores.json
curl -sS -H "Authorization: Bearer TOKEN" \
"BASE?route=public/firm-api/contragents.json" \
-o contragents.json
curl -sS -H "Authorization: Bearer TOKEN" \
"BASE?route=public/firm-api/stocks.json" \
-o stocks.json
curl -sS -H "Authorization: Bearer TOKEN" \
"BASE?route=public/firm-api/catalog.json" \
-o catalog.json
import requests
catalog = requests.get("BASE", params={"route": "public/firm-api/catalog.json", "token": "TOKEN"}, timeout=60)
catalog.raise_for_status()
data = catalog.json()
for product in data.get("products", []):
photo_url = product.get("web_photo_url")
if photo_url:
img = requests.get(photo_url, timeout=60)
img.raise_for_status()
with open(f"photo_{product['id']}.jpg", "wb") as f:
f.write(img.content)
curl -sS -H "Authorization: Bearer TOKEN" \
"BASE?route=public/firm-api/stocks.yml" \
-o stocks.yml
$token = "TOKEN"
$url = "BASE?route=public/firm-api/stocks.yml"
$headers = @{ Authorization = "Bearer $token" }
Invoke-WebRequest -Uri $url -Headers $headers -OutFile "stocks.yml"
$url = 'BASE?route=' . rawurlencode('public/firm-api/stocks.yml');
$ctx = stream_context_create([
'http' => [
'header' => "Authorization: Bearer TOKEN\r\n",
'timeout' => 30,
],
]);
$xml = file_get_contents($url, false, $ctx);
if ($xml === false) {
throw new RuntimeException('Не удалось загрузить YML');
}
file_put_contents(__DIR__ . '/stocks.yml', $xml);
import requests
url = "BASE"
params = {"route": "public/firm-api/stocks.yml", "token": "TOKEN"}
response = requests.get(url, params=params, timeout=30)
response.raise_for_status()
with open("stocks.yml", "wb") as f:
f.write(response.content)
const url = new URL("BASE");
url.searchParams.set("route", "public/firm-api/stocks.yml");
url.searchParams.set("token", "TOKEN");
const res = await fetch(url);
if (!res.ok) throw new Error(await res.text());
const xml = await res.text();
// дальше: парсинг XML или сохранение в файл
*/10 * * * * curl -sS -H "Authorization: Bearer TOKEN" \
"BASE?route=public/firm-api/stocks.yml" \
-o /var/www/shop/feeds/mercury-stocks.yml
store_id в остатках и ценах).date_from, date_to, опционально store_id).date_from, date_to, опционально store_id).00095__tovars_web_photo_path.sql (фото), 00010__firm_public_api.sql, 00011__firm_public_api_tokens.sql и 00012__firm_public_api_tokens_no_expiry.sql (ключи API).YouTube и Rutube могут быть недоступны в зависимости от региона и провайдера. Выберите площадку, которая у вас открывается — настройка сохранится в браузере.
Загрузка…