API 1С: как подключиться к базе извне — 5 способов

Дата: 19.09.2026 09:47:59
API
REST API
OData
HTTP-сервисы
Web-сервисы
Интеграция
Python
Комментарий:
0
Платформа:
8.3
Конфигурация:
Любая
Формы:
Любые

API 1С — это механизмы, через которые внешняя программа (сайт, CRM, мобильное приложение, скрипт на Python) читает и записывает данные в базе 1С:Предприятия. Одного «API 1С:Предприятия» нет: платформа даёт пять способов подключиться к базе извне, и от выбора зависит объём кода и поведение базы под нагрузкой. Ниже — таблица выбора, публикация, права и примеры вызова из Postman, curl и Python.

Обратная задача, когда 1С сама вызывает чужой API через HTTPСоединение, разобрана в статье 1С и Яндекс Маркет: интеграция через API.

Где нужен доступ к 1С извне

  • Интернет-магазин забирает остатки и цены, заказы с сайта попадают в 1С без ручного ввода.
  • Мобильное приложение агента или курьера показывает долги клиентов и создаёт заказы.
  • BI или Excel через Power Query строит отчёты по справочникам и регистрам.
  • CRM или склад обращается к 1С по событию, а не ждёт ночной выгрузки.

API 1С: пять способов и когда какой выбирать

СпособЧто нужноКогда выбиратьОграничения
OData (стандартный интерфейс)Платформа 8.3.5+, веб-публикация, объекты в составе интерфейсаОтдать справочники, документы и регистры внешней системе или BI без программированияТолько стандартные операции, своих методов нет; клиент должен знать структуру метаданных
HTTP-сервис (свой REST)8.3.5+, объект в конфигурации или расширении (8.3.7+), публикацияСвой API под задачу: адреса, формат JSON и проверки решаете выНужно программировать и сопровождать
Web-сервис (SOAP)Публикация, типы в пакете XDTOДругая сторона работает только по SOAP; связь баз 1С со строгой схемойГромоздкий XML
COM-соединениеWindows, платформа той же версии, что сервер, та же разрядностьСкрипты во внутренней сети, пакетные загрузкиДолгое открытие соединения, не для сайта
Файловый обмен (XML, JSON, CSV)Папка или FTP, регламентное заданиеНет постоянной связи, пакетный обмен между базами 1СЗадержка, нужен контроль ошибок загрузки

Коротко: читать данные «как есть» — OData; всё, где есть бизнес-логика (создать заказ, проверить остаток), — HTTP-сервис; SOAP — когда его требует партнёр; COM и файлы — для внутренних задач.

Что настроить для работы с 1С через API

OData, HTTP- и веб-сервисы работают только через веб-сервер:

  1. На машину с Apache или IIS установите платформу с компонентом «Модули расширения веб-сервера».
  2. Запустите Конфигуратор (на Windows — от имени администратора) → «Администрирование» → «Публикация на веб-сервере».
  3. Задайте имя публикации, например trade, отметьте «Публиковать стандартный интерфейс OData» и нужные HTTP- и веб-сервисы.

Настройки попадают в default.vrd в каталоге публикации. Если сервисы не отвечают, проверьте там <standardOdata enable="true"/> и <httpServices publishByDefault="true"/>.

Внешняя система входит в 1С как обычный пользователь и получает его права. Заведите технического пользователя:

  • имя латиницей (api_user): кириллический логин в Basic-авторизации ломает часть HTTP-клиентов;
  • включена «Аутентификация 1С:Предприятия», задан пароль;
  • права только на нужное: чтение справочников и регистров, запись тех документов, которые создаёт API; для COM — право «Внешнее соединение»; «Полные права» — никогда.

Если публикация доступна из интернета, включите HTTPS и ограничьте доступ по IP. О ролях — на странице услуги по настройке прав доступа в 1С.

OData: REST-интерфейс без программирования

Стандартный интерфейс OData появился в платформе 8.3.5. Это автоматический REST: каждый объект, включённый в состав интерфейса, становится коллекцией со своим адресом:

http://srv/trade/odata/standard.odata/
http://srv/trade/odata/standard.odata/$metadata
http://srv/trade/odata/standard.odata/Catalog_Номенклатура
http://srv/trade/odata/standard.odata/Document_ЗаказКлиента
http://srv/trade/odata/standard.odata/InformationRegister_ЦеныНоменклатуры

Корень возвращает список доступных сущностей, $metadata — описание полей. После публикации список пуст, состав надо задать. В конфигурациях на БСП для этого есть форма настройки стандартного интерфейса OData (обычно «Администрирование» → «Синхронизация данных»). В своей конфигурации состав задают методом УстановитьСоставСтандартногоИнтерфейсаOData() под администратором:

// Модуль формы внешней обработки. Запускать под пользователем
// с административными правами. Платформа 8.3.5+.
&НаСервереБезКонтекста
Процедура ВключитьОбъектыВODataНаСервере()

	// копируем текущий состав, чтобы не потерять уже включённые объекты
	Состав = Новый Массив;
	Для Каждого ОбъектМД Из ПолучитьСоставСтандартногоИнтерфейсаOData() Цикл
		Состав.Добавить(ОбъектМД);
	КонецЦикла;

	Нужные = Новый Массив;
	Нужные.Добавить(Метаданные.Справочники.Номенклатура);
	Нужные.Добавить(Метаданные.РегистрыСведений.ЦеныНоменклатуры);

	Для Каждого ОбъектМД Из Нужные Цикл
		Если Состав.Найти(ОбъектМД) = Неопределено Тогда
			Состав.Добавить(ОбъектМД);
		КонецЕсли;
	КонецЦикла;

	УстановитьСоставСтандартногоИнтерфейсаOData(Состав);

КонецПроцедуры

Проверка в Postman: GET http://srv/trade/odata/standard.odata/Catalog_Номенклатура?$format=json&$top=5, вкладка Authorization → Basic Auth. Тот же запрос на Python:

import os
import requests

BASE = "http://srv/trade/odata/standard.odata"
AUTH = ("api_user", os.environ["ONEC_API_PASSWORD"])

url = (BASE + "/Catalog_Номенклатура"
       "?$format=json&$top=5"
       "&$select=Ref_Key,Code,Description"
       "&$filter=DeletionMark eq false")

resp = requests.get(url, auth=AUTH, timeout=30)
resp.raise_for_status()
for item in resp.json()["value"]:
    print(item["Ref_Key"], item["Code"], item["Description"])
  • Стандартные реквизиты называются по-английски (Ref_Key, Code, Description), свои — как в конфигурации; ссылочные поля приходят как GUID с суффиксом _Key.
  • У регистров есть виртуальные таблицы (Balance, SliceLast и др.) — остатки и цены доступны без своего кода.
  • Писать тоже можно: POST создаёт объект, PATCH изменяет, у документов есть действие Post. Модуль объекта отрабатывает, логика формы — нет.
  • Без $top и $select запрос к большому справочнику отдаёт всё целиком — заметная нагрузка на рабочую базу.

HTTP-сервис: свой REST API в 1С

Когда нужна логика — проверить входные данные, собрать ответ из нескольких таблиц, создать документ, — пишут HTTP-сервис: объект в ветке «Общие» → «HTTP-сервисы», доступен с платформы 8.3.5, а с 8.3.7 — и в расширении, без снятия типовой с поддержки. Адрес вызова:

http://<сервер>/<имя публикации>/hs/<корневой URL>/<шаблон URL>
http://srv/trade/hs/api/v1/products?sku=A-100

Ниже — сервис PublicAPI с корневым URL api: GET /v1/products ищет товары по артикулу, POST /v1/products/search принимает список артикулов в JSON. Функцию-обработчик указывают в свойстве «Обработчик» метода; конфигуратор предлагает имя вида ИмяШаблонаИмяМетода (здесь ТоварыGET). Она принимает Запрос и возвращает HTTPСервисОтвет. Создание сервиса в конфигураторе по шагам — в статье HTTP-сервис 1С: создание с нуля и пример.

// Модуль HTTP-сервиса PublicAPI. Корневой URL: api
// Шаблоны URL и методы:
//   Товары        /v1/products          GET  -> ТоварыGET
//   ПоискТоваров  /v1/products/search   POST -> ПоискТоваровPOST
// Платформа 8.3.6+, режим совместимости не ниже 8.3.6 (ЗаписьJSON, ЧтениеJSON).
// Справочник Номенклатура с реквизитом Артикул есть в УТ 11, БП 3.0, УНФ, КА, ERP;
// в другой конфигурации поправьте текст запроса в ТекстЗапросаТоваров.

#Область ОбработчикиМетодов

// GET /v1/products?sku=A-100&limit=20
Функция ТоварыGET(Запрос)

	Лимит = ЧислоИзПараметра(Запрос.ПараметрыЗапроса.Получить("limit"), 50, 500);
	Если Лимит = Неопределено Тогда
		Возврат ОтветОшибка(400, "Параметр limit должен быть целым числом больше нуля");
	КонецЕсли;

	Артикулы = Новый Массив;
	Артикул = Запрос.ПараметрыЗапроса.Получить("sku");
	Если ЗначениеЗаполнено(Артикул) Тогда
		Артикулы.Добавить(Артикул);
	КонецЕсли;

	Попытка
		Товары = НайтиТовары(Артикулы, Лимит);
	Исключение
		Возврат ОтветПриИсключении(ИнформацияОбОшибке());
	КонецПопытки;

	Возврат ОтветJSON(200, Новый Структура("items", Товары));

КонецФункции

// POST /v1/products/search, тело: {"skus": ["A-100", "B-200"]}
Функция ПоискТоваровPOST(Запрос)

	Данные = ПрочитатьТелоJSON(Запрос);
	Если ТипЗнч(Данные) <> Тип("Соответствие") Тогда
		Возврат ОтветОшибка(400, "Тело запроса должно быть JSON-объектом");
	КонецЕсли;

	Список = Данные.Получить("skus");
	Если ТипЗнч(Список) <> Тип("Массив") Тогда
		Возврат ОтветОшибка(400, "Ожидается массив skus");
	КонецЕсли;
	Если Список.Количество() > 500 Тогда
		Возврат ОтветОшибка(400, "Не больше 500 артикулов в одном запросе");
	КонецЕсли;

	Артикулы = Новый Массив;
	Для Каждого Значение Из Список Цикл
		Если ТипЗнч(Значение) = Тип("Строка") И ЗначениеЗаполнено(Значение) Тогда
			Артикулы.Добавить(Значение);
		КонецЕсли;
	КонецЦикла;
	Если Артикулы.Количество() = 0 Тогда
		// пустой список означал бы "без отбора" - весь справочник
		Возврат ОтветОшибка(400, "В skus нет ни одного непустого артикула");
	КонецЕсли;

	Попытка
		Товары = НайтиТовары(Артикулы, 1000);
	Исключение
		Возврат ОтветПриИсключении(ИнформацияОбОшибке());
	КонецПопытки;

	Возврат ОтветJSON(200, Новый Структура("items", Товары));

КонецФункции

#КонецОбласти

#Область Данные

Функция НайтиТовары(Артикулы, Лимит)

	ЗапросБД = Новый Запрос(ТекстЗапросаТоваров(Лимит));
	ЗапросБД.УстановитьПараметр("БезОтбора", Артикулы.Количество() = 0);
	ЗапросБД.УстановитьПараметр("Артикулы", Артикулы);

	Товары = Новый Массив;
	Выборка = ЗапросБД.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		Товар = Новый Структура;
		Товар.Вставить("id", Строка(Выборка.Ссылка.УникальныйИдентификатор()));
		Товар.Вставить("name", Выборка.Наименование);
		Товар.Вставить("sku", Выборка.Артикул);
		Товары.Добавить(Товар);
	КонецЦикла;

	Возврат Товары;

КонецФункции

Функция ТекстЗапросаТоваров(Лимит)

	// ЭтоГруппа есть только у иерархического справочника - иначе уберите условие
	Текст =
	"ВЫБРАТЬ ПЕРВЫЕ 50
	|	Номенклатура.Ссылка КАК Ссылка,
	|	Номенклатура.Наименование КАК Наименование,
	|	Номенклатура.Артикул КАК Артикул
	|ИЗ
	|	Справочник.Номенклатура КАК Номенклатура
	|ГДЕ
	|	НЕ Номенклатура.ПометкаУдаления
	|	И НЕ Номенклатура.ЭтоГруппа
	|	И (&БезОтбора
	|			ИЛИ Номенклатура.Артикул В (&Артикулы))
	|
	|УПОРЯДОЧИТЬ ПО
	|	Наименование";

	// в ПЕРВЫЕ нельзя передать параметр запроса, подставляем число в текст
	Возврат СтрЗаменить(Текст, "ПЕРВЫЕ 50", "ПЕРВЫЕ " + Формат(Лимит, "ЧГ=0"));

КонецФункции

#КонецОбласти

#Область Служебные

Функция ПрочитатьТелоJSON(Запрос)

	Попытка
		Чтение = Новый ЧтениеJSON;
		Чтение.УстановитьСтроку(Запрос.ПолучитьТелоКакСтроку());
		Данные = ПрочитатьJSON(Чтение, Истина); // Истина - объекты в Соответствие
		Чтение.Закрыть();
	Исключение
		Возврат Неопределено; // пустое тело или невалидный JSON
	КонецПопытки;

	Возврат Данные;

КонецФункции

// Целое число из параметра строки запроса: ПоУмолчанию, если параметра нет,
// Неопределено, если передано не число.
Функция ЧислоИзПараметра(Значение, ПоУмолчанию, Максимум)

	Если Не ЗначениеЗаполнено(Значение) Тогда
		Возврат ПоУмолчанию;
	КонецЕсли;

	Попытка
		Результат = Число(Значение);
	Исключение
		Возврат Неопределено;
	КонецПопытки;

	Если Результат < 1 Или Результат <> Цел(Результат) Тогда
		Возврат Неопределено;
	КонецЕсли;

	Возврат Мин(Результат, Максимум);

КонецФункции

Функция ОтветJSON(КодСостояния, Данные)

	Запись = Новый ЗаписьJSON;
	Запись.УстановитьСтроку();
	ЗаписатьJSON(Запись, Данные);

	Ответ = Новый HTTPСервисОтвет(КодСостояния);
	Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
	Ответ.УстановитьТелоИзСтроки(Запись.Закрыть(), КодировкаТекста.UTF8,
		ИспользованиеByteOrderMark.НеИспользовать);
	Возврат Ответ;

КонецФункции

Функция ОтветОшибка(КодСостояния, Текст)

	Возврат ОтветJSON(КодСостояния, Новый Структура("error", Текст));

КонецФункции

Функция ОтветПриИсключении(Информация)

	// подробности - только в журнал, клиенту - короткий текст
	ЗаписьЖурналаРегистрации("PublicAPI", УровеньЖурналаРегистрации.Ошибка, , ,
		ПодробноеПредставлениеОшибки(Информация));
	Возврат ОтветОшибка(500, "Внутренняя ошибка сервиса");

КонецФункции

#КонецОбласти

Разбор ключевых строк

  • Запрос.ПараметрыЗапроса — параметры после «?», отсутствующий ключ даёт Неопределено. Параметры из пути (шаблон /v1/products/{id}) лежат в Запрос.ПараметрыURL.
  • Лимит подставляется в текст через СтрЗаменить: в ПЕРВЫЕ параметр запроса не передать. Сверху он ограничен, чтобы клиент не выгрузил справочник одним вызовом.
  • ПрочитатьJSON(Чтение, Истина) читает объекты в Соответствие: в Структура ключ вроде "order-id" вызовет исключение.
  • Пустой после фильтрации список артикулов отсекается отдельно: иначе БезОтбора стал бы истиной и сервис вернул бы до тысячи товаров.
  • ИспользованиеByteOrderMark.НеИспользовать (параметр есть с 8.3.6) явно отключает BOM: без него результат зависит от режима совместимости, а BOM перед JSON ломает разбор у части клиентов.
  • Подробности исключения уходят в журнал регистрации, клиенту — короткий JSON с кодом 500: в тексте ошибки 1С бывают имена таблиц и данные.
  • Модуль HTTP-сервиса выполняется на сервере, директивы компиляции не нужны.

Вызов из Postman, curl и Python

В Postman для GET хватит адреса и Basic Auth. Для POST выберите Body → raw → JSON и вставьте {"skus": ["A-100", "B-200"]}; ответ — {"items": [...]} с полями id, name, sku. Из командной строки и Python:

# curl спросит пароль сам, в истории команд он не останется
curl -u api_user "http://srv/trade/hs/api/v1/products?sku=A-100&limit=10"

curl -u api_user -H "Content-Type: application/json" \
     -d "{\"skus\": [\"A-100\", \"B-200\"]}" \
     "http://srv/trade/hs/api/v1/products/search"
import os
import requests

BASE = "http://srv/trade/hs/api/v1"
AUTH = ("api_user", os.environ["ONEC_API_PASSWORD"])

resp = requests.post(BASE + "/products/search",
                     json={"skus": ["A-100", "B-200"]},
                     auth=AUTH, timeout=30)
if resp.ok:
    for item in resp.json()["items"]:
        print(item["sku"], item["name"], item["id"])
else:
    print(resp.status_code, resp.text)

Если сервис вызывают часто, установите у него свойство «Повторное использование сеансов» в значение «Автоматически использовать» (платформа 8.3.9+): сеанс берётся из пула, а не открывается на каждый вызов. Значение «Использовать» помогает, только если клиент сам управляет сеансом: шлёт заголовок IBSession: start и возвращает полученную куку IBSession. Вызовы из примеров выше этого не делают.

Web-сервисы (SOAP)

Web-сервис — объект конфигурации с операциями, типы параметров описываются в пакете XDTO. WSDL платформа отдаёт сама по адресу http://srv/trade/ws/<имя файла публикации>?wsdl. В Python клиент обычно строят на библиотеке zeep, из другой базы 1С вызывают через WSОпределения и WSПрокси. Про типы — в статье XDTO в 1С: что это, фабрика и объекты XDTO.

COM-соединение

Внешнее соединение даёт программе тот же доступ, что у серверного кода 1С: запросы, объекты, общие модули с флагом «Внешнее соединение». Условия: только Windows, платформа той же версии, что и сервер 1С, зарегистрированная comcntr.dll (regsvr32 от администратора), совпадение разрядности программы и компоненты. Соединение открывается долго, поэтому COM — для скриптов и пакетных загрузок, а не для сайта. Имена методов через COM доступны и по-английски, и по-русски.

import os
import win32com.client  # pip install pywin32; разрядность Python = разрядности 1С

connector = win32com.client.Dispatch("V83.COMConnector")
conn = connector.Connect('Srvr="srv";Ref="trade";Usr="api_user";Pwd="{}";'
                         .format(os.environ["ONEC_API_PASSWORD"]))
# для файловой базы: 'File="D:\\Bases\\Trade";Usr="api_user";Pwd="...";'

query = conn.NewObject("Запрос")
query.Text = "ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК Cnt ИЗ Справочник.Номенклатура"
selection = query.Execute().Select()
if selection.Next():
    print(selection.Cnt)

Файловый обмен

Одна сторона кладёт файл XML, JSON или CSV в папку или на FTP, регламентное задание 1С его загружает. Между базами 1С есть готовые механизмы — «Синхронизация данных» в формате EnterpriseData и правила Конвертации данных. Это уже не API, но для интеграции и обмена данными 1С между базами он надёжнее живых вызовов: обмен переживает недоступность одной из сторон. Сравнение — в статье Обмен данными 1С: способы обмена между базами.

Типичные ошибки

  • 404 на /hs/... или /odata/.... Сервис не отмечен при публикации, ошибка в имени публикации или корневом URL, путь не совпал ни с одним шаблоном, либо не обновлена конфигурация базы данных.
  • 401 Unauthorized. Неверный логин или пароль, у пользователя выключена «Аутентификация 1С:Предприятия», клиент не отправляет заголовок Authorization.
  • OData не показывает нужную сущность. Объект не включён в состав стандартного интерфейса — проверьте корень standard.odata/.
  • Python: JSONDecodeError: Unexpected UTF-8 BOM (decode using utf-8-sig). Сервис отдаёт тело с BOM. Передайте третьим параметром УстановитьТелоИзСтроки значение ИспользованиеByteOrderMark.НеИспользовать.
  • Python: UnicodeEncodeError: 'latin-1' codec can't encode characters при авторизации. Логин 1С на кириллице, а requests кодирует его в latin-1. Заведите пользователя с латинским именем.
  • COM: «Недопустимая строка с указанием класса» (0x800401F3) или «Класс не зарегистрирован». comcntr.dll не зарегистрирована или не совпадает разрядность: 32-битный Python не видит 64-битный коннектор. Отказ даёт и версия платформы на клиенте, отличная от серверной.
  • Документ создан через API, но заполнен не так, как из формы. Логика формы (заполнение по умолчанию, пересчёт сумм) при записи из кода не работает — повторите её в HTTP-сервисе.

Частые вопросы

Есть ли у 1С готовый REST API?

Да, стандартный интерфейс OData: опубликуйте базу и включите объекты в состав, конфигурацию менять не нужно. Но он отдаёт «сырые» справочники, документы и регистры. Метод вроде «создать заказ с проверкой остатка» пишут в HTTP-сервисе.

Можно ли сделать API для типовой конфигурации без снятия с поддержки?

Да. OData работает поверх типовой без изменений, а HTTP-сервис с платформы 8.3.7 можно разместить в расширении.

Как подключиться к 1С из Python?

Библиотекой requests к OData или к своему HTTP-сервису — примеры выше. COM через pywin32 работает только на Windows с установленной платформой.

Работает ли API с файловой базой?

Да, файловая база публикуется так же, как серверная. Но при частых запросах от нескольких клиентов она упирается в блокировки, для постоянной интеграции нужен клиент-серверный вариант.

Чем API отличается от обмена данными?

API — вызов «здесь и сейчас»: сайт спросил остаток и сразу получил ответ. Обмен — пакетная передача изменений по расписанию с повтором после сбоя. Сайту и приложениям нужен API, двум базам 1С — обмен.

Когда проще заказать

Если 1С нужно связать с сайтом, CRM или приложением, а своего программиста 1С нет, отдайте задачу исполнителю: он опубликует базу, заведёт пользователя с нужными правами и напишет HTTP-сервис под ваш формат. Посмотрите услуги по доработке 1С и обмен 1С с сайтом или сразу разместите задачу: оценка бесплатная, ответ в течение рабочего дня.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.


1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.