Справочник API
REST поверх HTTPS: предсказуемые пути, JSON в UTF-8, время в UTC по ISO 8601, деньги целым числом копеек. Все пути начинаются с /v1.
Введение
Адрес контура, рабочего или песочницы, показан в кабинете рядом с ключом; в примерах он подставлен переменной $API. Запросы без HTTPS отклоняются, а не перенаправляются.
- Неизвестное поле в запросе игнорируется, а не отвергается: так старый клиент переживает появление нового поля.
- Пустая строка и
null- разные вещи. Пустая строка стирает значение,nullозначает «не трогать». - У каждого ответа есть заголовок
X-Request-Id. Пишите его в свои журналы: по нему мы находим запрос за 30 дней.
curl "$API/v1/products?limit=1" \ -H "Authorization: Bearer $NIMBUS_KEY" -i # X-Request-Id: req_7f31c0a8 # X-Ratelimit-Remaining: 119
Аутентификация
Ключ передаётся заголовком Authorization: Bearer. У контура может быть несколько ключей с разными правами: например, ключ только на чтение каталога для витрины и полный ключ для учётной системы.
Ключ песочницы начинается с sk_test_, рабочий - с sk_live_. Перепутать контуры нельзя: ключ одного контура на другом получает 401.
curl "$API/v1/products" \ -H "Authorization: Bearer $NIMBUS_KEY"
import { Client } from '@nimbus/sdk'; const api = new Client({ key: process.env.NIMBUS_KEY });
from nimbus import Client import os api = Client(key=os.environ["NIMBUS_KEY"])
Ошибки
Успешные ответы приходят с кодами 2xx, ошибки запроса - 4xx, сбои на нашей стороне - 5xx. Формат тела ошибки один на все методы, разбирать текст сообщения не нужно: он меняется, а code - нет.
Все коды с объяснением, что делать, - на странице коды ошибок.
{
"error": {
"code": "validation_failed",
"message": "stock должен быть целым неотрицательным числом",
"field": "items[2].stock",
"request_id": "req_7f31c0a8"
}
}Пагинация
Все списки отдаются курсором, до 200 записей за раз. Курсор живёт 15 минут и привязан к фильтрам запроса: менять их на ходу нельзя, перебор придётся начать заново.
- limitцелоеСколько записей вернуть, от 1 до 200. По умолчанию 50.
- cursorстрокаЗначение
cursorиз предыдущего ответа.
GET /v1/orders?limit=100 # "cursor": "b3M6MTIwNA", "has_more": true GET /v1/orders?limit=100&cursor=b3M6MTIwNA # "has_more": false
Идемпотентность
Любой изменяющий запрос принимает заголовок Idempotency-Key, а переводы статуса заказа его требуют. Ключ живёт 24 часа: повтор с тем же ключом возвращает первый ответ, включая его код.
Ключ должен быть уникальным для операции, а не для минуты - хорошая привычка составлять его из действия и идентификатора. Тот же ключ с другим телом запроса получит 409 и код idempotency_conflict.
POST /v1/orders/ORD-25161/cancel HTTP/1.1 Idempotency-Key: cancel-ORD-25161-TRM-1579 Content-Type: application/json { "items": [ { "sku": "TRM-1579", "qty": 1 } ] }
Лимиты
Лимит считается на ключ. При превышении приходит 429 и заголовок Retry-After в секундах. Считать ответы самому не нужно: достаточно уважать этот заголовок и не повторять запрос раньше.
| Контур | Запросов в минуту | Пакет |
|---|---|---|
| Рабочий | 120 | 1000 позиций |
| Песочница | 60 | 200 позиций |
HTTP/1.1 429 Too Many Requests Retry-After: 12 X-Ratelimit-Remaining: 0 { "error": { "code": "rate_limited", "message": "повторите через 12 секунд" } }
Версии
Версия API - в пути. Внутри v1 добавляются только поля и методы, а помеченное устаревшим живёт не меньше шести месяцев и получает заголовок Deprecation в каждом ответе.
История изменений - в журнале, политика поддержки клиентов - на странице SDK и CLI.
HTTP/1.1 200 Deprecation: true Sunset: 2027-03-03 { "sku": "TRM-1579", "price": 129000, "price_rub": 1290 }
Ресурсы
Методы сгруппированы по ресурсам. У каждого ресурса своя страница: объект целиком, методы с параметрами и примеры ответов.