Подробный гайд Saby OpenAPI
Экосистема Saby (СБИС) от компании «Тензор» предоставляет мощный OpenAPI для интеграции внешних систем (ERP, CRM, бухгалтерских порталов) с сервисами СБИС: ЭДО, отчетностью, КЭДО, торговлей и CRM.
Оглавление
- Подготовка и регистрация
- Авторизация (OAuth 2.0)
- Архитектура и базовые концепции
- Основные модули API
- Пример кода (Python)
- Вебхуки (События)
- Ошибки и лимиты (Best Practices)
- Полезные ссылки
1. Подготовка и регистрация
Прежде чем писать код, необходимо зарегистрировать приложение в кабинете разработчика СБИС.
1. Вход в систему:
У вас должен быть аккаунт в СБИС (обычно это аккаунт администратора или разработчика вашей организации).
2. Портал разработчиков:
Перейдите на dev.saby.ru (или в раздел «Разработчикам» в вашем личном кабинете СБИС).
3. Создание приложения:
- Создайте новое «Приложение» (Интеграция).
- Укажите тип интеграции (серверное приложение / веб-сервис).
- Настройте Redirect URI (если используете авторизацию от имени пользователя) или выберите Server-to-Server (Client Credentials) для фоновых серверных интеграций (например, для автоматической отправки ЭДО или отчетности).
4. Получение ключей:
После создания вы получите Client ID и Client Secret. Храните Secret в секретах (env-переменных), не коммитьте его в Git.
2. Авторизация (OAuth 2.0)
СБИС использует стандарт OAuth 2.0. Для серверных интеграций (где скрипт работает от имени организации без участия человека) используется грант-тип client_credentials.
Эндпоинт для получения токена:
POST https://api.saby.ru/oauth/at
Тело запроса (JSON):
{
"client_id": "ваш_client_id",
"client_secret": "ваш_client_secret",
"grant_type": "client_credentials"
}
Ответ:
{
"access_token": "eyJhbGciOiJIUzI1...",
"token_type": "Bearer",
"expires_in": 86400
}
Важно:
Токен живет определенное время (обычно 24 часа). Не запрашивайте новый токен перед каждым API-запросом. Кэшируйте его в Redis/Memcached или в памяти приложения и обновляйте за 5-10 минут до истечения expires_in. За спам запросами токена СБИС может временно заблокировать IP.
3. Архитектура и базовые концепции
Base URL:
Зависит от модуля. Основной шлюз часто находится на https://api.saby.ru/, но для ЭДО или Отчетности могут использоваться специфичные домены (указаны в документации к конкретному методу).
Формат данных:
Современный API использует JSON. Однако некоторые старые методы (особенно в глубоких недрах ЭДО или специфичной отчетности) могут требовать XML.
Заголовки:
Authorization: Bearer <ваш_access_token>
Content-Type: application/json
Пагинация:
В списках документов используется offset и limit (или page / size). Всегда обрабатывайте пагинацию, так как API не отдаст более 100-500 сущностей за раз.
Идентификаторы:
СБИС использует внутренние GUID/UUID для документов, а также специфичные строковые идентификаторы (например, ИдентификаторДокумента в ЭДО).
4. Основные модули API
А. ЭДО (Электронный документооборот)
Самый популярный модуль. Позволяет автоматизировать обмен УПД, актами, накладными.
- Входящие/Исходящие: Получение списков документов (
/edo/v2/documents). - Отправка: Загрузка подписанных файлов (PDF/XML + файлы подписи
.sig). - Роуминг: API прозрачно работает с роуминговыми контрагентами (Калуга Астрал, Такском, Диадок и др.).
- Статусы: Отслеживание статусов доставки и подписания (В пути, Подписан, Отклонен).
Б. Отчетность (FNS, SFR, Росстат)
- Формирование и отправка: Загрузка XML-файлов деклараций и отчетов.
- Получение протоколов: Скачивание квитанций о приеме, протоколов ошибок от ФНС/СФР.
- Требования: Получение списков требований от налоговой и отправка ответов на них.
В. КЭДО (Кадровый ЭДО)
- Отправка приказов, трудовых договоров, ознакомление сотрудников.
- Интеграция с 1С:ЗУП или внешними HR-порталами.
Г. СБИС Розница / Торговля
- Синхронизация справочника номенклатуры, цен, остатков.
- Выгрузка заказов из интернет-магазина в СБИС.
5. Пример кода (Python)
Ниже приведен пример получения списка входящих документов ЭДО с использованием библиотеки requests.
import requests
import time
import json
class SabyAPI:
def __init__(self, client_id, client_secret):
self.client_id = client_id
self.client_secret = client_secret
self.base_url = "https://api.saby.ru"
self.token = None
self.token_expires_at = 0
def _get_token(self):
"""Получение или обновление OAuth токена"""
if self.token and time.time() < self.token_expires_at - 300:
return self.token
url = f"{self.base_url}/oauth/at"
payload = {
"client_id": self.client_id,
"client_secret": self.client_secret,
"grant_type": "client_credentials"
}
response = requests.post(url, json=payload)
response.raise_for_status()
data = response.json()
self.token = data["access_token"]
self.token_expires_at = time.time() + data["expires_in"]
return self.token
def _make_request(self, method, endpoint, **kwargs):
"""Универсальный метод для запросов с автоматической подстановкой токена"""
headers = kwargs.pop("headers", {})
headers["Authorization"] = f"Bearer {self._get_token()}"
headers["Content-Type"] = "application/json"
url = f"{self.base_url}{endpoint}"
response = requests.request(method, url, headers=headers, **kwargs)
# Обработка ошибок
if response.status_code == 429:
raise Exception("Rate Limit Exceeded. Нужно подождать.")
response.raise_for_status()
return response.json()
def get_incoming_edo_documents(self, limit=50, offset=0):
"""Пример: Получение входящих документов ЭДО (упрощенный эндпоинт)"""
# Примечание: точный URL и параметры нужно сверять с актуальной документацией dev.saby.ru
endpoint = "/edo/v1/documents/incoming"
params = {
"limit": limit,
"offset": offset,
"status": "received" # Фильтр по статусу
}
return self._make_request("GET", endpoint, params=params)
# Использование
if __name__ == "__main__":
CLIENT_ID = "ваш_client_id"
CLIENT_SECRET = "ваш_client_secret"
api = SabyAPI(CLIENT_ID, CLIENT_SECRET)
try:
docs = api.get_incoming_edo_documents(limit=10)
print(f"Получено документов: {len(docs.get('items', []))}")
for doc in docs.get('items', []):
print(f"ID: {doc['id']}, Тип: {doc['type']}, Контрагент: {doc['partner']['name']}")
except Exception as e:
print(f"Ошибка при работе с API: {e}")
6. Вебхуки (События)
Опрос API (polling) каждые 5 минут — плохая практика, которая ведет к исчерпанию лимитов. СБИС поддерживает Webhooks (Push-уведомления).
- Настройка: В кабинете разработчика укажите URL вашего сервера, который будет принимать POST-запросы.
- События: Подпишитесь на нужные события (например,
edo.document.status_changed— смена статуса документа ЭДО, илиreporting.protocol_received— получен протокол от ФНС). - Безопасность: СБИС подписывает вебхуки. Обязательно проверяйте заголовок подписи (обычно
X-Saby-Signatureили аналогичный, используя вашClient Secretили специальный ключ вебхука), чтобы злоумышленники не могли слать вам фейковые статусы. - Ответ сервера: Ваш эндпоинт должен отвечать
HTTP 200 OKкак можно быстрее (до 1-2 секунд). Тяжелую обработку (сохранение в БД, обновление 1С) нужно ставить в очередь (RabbitMQ, Kafka, Celery).
7. Ошибки и лимиты (Best Practices)
HTTP Коды ответов
200 OK— Успех.400 Bad Request— Ошибка в теле запроса (неверный JSON, не проходит валидацию XSD-схемы).401 Unauthorized— Истек токен или неверный Client ID/Secret.403 Forbidden— У организации нет лицензии на данный модуль (например, нет тарифа на ЭДО) или нет прав у приложения.404 Not Found— Документ не найден или неверный URL.429 Too Many Requests— Превышен Rate Limit.500 / 502 / 503— Ошибка на стороне серверов Тензор (случается в периоды высокой нагрузки, например, в конце отчетных периодов).
Rate Limits (Ограничения)
Тензор жестко лимитирует запросы, чтобы защитить свою инфраструктуру. Лимиты зависят от вашего тарифа и типа API.
- Правило: Используйте Exponential Backoff (экспоненциальную задержку) при получении
429или5xxошибок. - Пример: Если получили 429, ждите 2 сек, затем 4 сек, затем 8 сек перед повтором.
Специфика ЭДО и XML
Если вы работаете с ЭДО (УПД, счета-фактуры), вам придется работать не только с JSON-оберткой API, но и с XML-содержимым самого документа, которое должно строго соответствовать XSD-схемам ФНС. СБИС предоставляет методы для валидации XML перед отправкой.
8. Полезные ссылки
- Официальная документация: ev.saby.ru (Требует авторизации, документация разбита по модулям: ЭДО, Отчетность, КЭДО).
- Postman-коллекции: На портале разработчиков часто лежат готовые
.jsonфайлы для импорта в Postman с настроенными переменными окружения. - SDK и библиотеки: Официальных SDK от Тензора мало, но на GitHub можно найти community-driven библиотеки (например,
sbis-apiна Python/PHP), хотя надежнее писать обертку самому поверхrequests/aiohttp, так как API часто обновляется. - Тестовый стенд (Sandbox): Для ЭДО существует тестовый контур, где можно обмениваться документами с тестовыми контрагентами без юридической значимости. Всегда тестируйте интеграцию там перед продом.
Мы делимся этой технической информацией, чтобы помочь вам в решении задач — используйте её с пониманием. Статья носит рекомендательный характер, поэтому, пожалуйста, применяйте описанные методы осмотрительно.