Разработчикам2026-11Предпросмотр

NinjaBuy Business API

Импортируйте товары с Taobao, Weidian и 1688, синхронизируйте их цены и остатки и отслеживайте каждый заказ от продавца в Китае через проверку на нашем складе до двери покупателя. JSON по HTTPS, один аккаунт, один баланс.

Базовый URL

Все маршруты на этом сайте находятся под одним базовым URL. Приложение Shopify и всё, что вы разрабатываете, вызывает одни и те же маршруты, поэтому всё, что делает приложение, может сделать и ваш код.

https://www.ninjabuy.com/api/v1

Предпочитаете спросить ИИ-ассистента? Тот же аккаунт работает через MCP по адресу https://www.ninjabuy.com/mcp: ИИ-ассистенты (MCP).

Каталог
Заказы
Аккаунт
Ваш первый запрос
curl "https://www.ninjabuy.com/api/v1/balance" \
  -H "Authorization: Bearer $NINJABUY_API_KEY" \
  -H "NinjaBuy-Version: 2026-11"

Аутентификация

Передавайте API-ключ как bearer-токен в каждом запросе. Ключи начинаются с nb_. В период предварительной версии их выдаёт наша команда: когда аккаунт Business настроен, мы один раз отправляем каждый ключ по выбранному вами каналу с запрошенными областями доступа. Попросите нас отозвать ключ, и он перестанет работать со следующего запроса.

Храните ключи на сервере. Ключ в браузере, приложении или публичном репозитории может прочитать кто угодно, и им можно потратить ваш баланс.

Приложение, действующее от имени других продавцов NinjaBuy, использует OAuth 2.1: динамическую регистрацию клиента, поток authorization code с PKCE (S256) и собственный экран подтверждения продавца. Его токен доступа передаётся в том же заголовке и работает на тех же маршрутах. Токены доступа действуют час; токены обновления продлевают их на семь дней. ИИ-ассистенты подключаются так же (MCP).

products:readscope
Чтение импортов, товаров, вариантов и правил синхронизации.
products:writescope
Импорт, редактирование, отправка и удаление товаров; изменение правил синхронизации.
inventory:readscope
Чтение уровней запасов.
orders:readscope
Чтение заказов, заказов на выполнение и отправлений.
orders:writescope
Создание, удержание, освобождение и отмена заказов. Расходует ваш баланс.
balance:readscope
Чтение баланса и его транзакций.
webhooks:writescope
Управление эндпоинтами вебхуков.

Запрос вне областей доступа ключа получает ответ 403 insufficient-scope с названием нужной области.

Заголовок
Authorization: Bearer nb_7Qk2...vX9e
Response 401
HTTP/2 401

{
  "type": "https://www.ninjabuy.com/api/v1/problems/unauthorized",
  "title": "Unauthorized",
  "status": 401,
  "detail": "The API key is missing, wrong, expired or revoked.",
  "request_id": "req_7Hq2Lw9c"
}

Версионирование

Путь содержит основную версию, /v1. Внутри неё версии с датами меняют поля и поведение. Закрепите ту, под которую вы разрабатывали, заголовком NinjaBuy-Version; каждый ответ называет использованную версию в том же заголовке.

2026-11 — текущая версия, и это предварительная версия: названия и поля ещё могут измениться, пока она не помечена как стабильная. Все изменения — в журнале изменений, а перед изменением, которое может что-то сломать, мы пишем на почту каждому владельцу ключа.

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

Закрепление версии
GET /api/v1/orders
NinjaBuy-Version: 2026-11

HTTP/2 200
NinjaBuy-Version: 2026-11

Запросы и ответы

  • Отправляйте JSON с Content-Type: application/json; ответы — JSON в UTF-8. Ошибки — application/problem+json.
  • Деньги — это объект с десятичной строкой и валютой: { "amount": "264.20", "currency": "CNY" }. Суммы NinjaBuy указаны в CN¥; ваши цены продажи — в валюте вашего магазина.
  • ID — это строки с префиксом, обозначающим их тип (prd_, ord_, shp_). Считайте их непрозрачными.
  • Время — ISO 8601 в UTC. Страны — двухбуквенные коды ISO.
  • Каждый ответ содержит заголовок X-Request-Id, а каждая ошибка — тот же id в request_id. Указывайте его, когда пишете нам.
Деньги, ID и даты
{
  "id": "ord_3n7q",
  "created_at": "2026-11-01T09:14:02Z",
  "total": { "amount": "264.20", "currency": "CNY" },
  "suggested_price": { "amount": "49.99", "currency": "USD" }
}

Пагинация

Списки возвращаются от новых к старым как data, has_more и cursor. Отправляйте этот cursor обратно за следующей страницей, пока has_more равно true. Cursor работает только с теми фильтрами, с которыми получен.

limitinteger
От 1 до 100. По умолчанию 25.
cursorstring
cursor предыдущей страницы. Для первой страницы не указывайте.
curl "https://www.ninjabuy.com/api/v1/orders?limit=25&cursor=c_2v9kq" \
  -H "Authorization: Bearer $NINJABUY_API_KEY" \
  -H "NinjaBuy-Version: 2026-11"
Response 200
HTTP/2 200 OK

{
  "data": [
    { "id": "ord_3n7q", "status": "checked" },
    { "id": "ord_3n6z", "status": "shipped" }
  ],
  "has_more": true,
  "cursor": "c_1q4ea"
}

Лимиты запросов

Лимиты действуют на аккаунт и общие для всех его ключей, OAuth-токенов и MCP-подключения. Каждый ответ сообщает ваше положение в заголовках IETF RateLimit-Policy и RateLimit; отказ — это 429 rate-limited с Retry-After в секундах.

ПериодЧто учитывается
"create-links";q=30;w=60Запросы, читающие карточку с маркетплейса: создание или обновление импорта, отправка товара. 30 в минуту, общий лимит с API ссылок и MCP.
"default";q=120;w=60Все остальные запросы. 120 в минуту.
Ответ 429
HTTP/2 429
Content-Type: application/problem+json
Retry-After: 12
RateLimit-Policy: "create-links";q=30;w=60
RateLimit: "create-links";r=0;t=12

{
  "type": "https://www.ninjabuy.com/api/v1/problems/rate-limited",
  "title": "Too many requests",
  "status": 429,
  "detail": "Try again in 12 seconds.",
  "request_id": "req_7Hq2Lw9c"
}

Идемпотентность

Передавайте Idempotency-Key (от 1 до 255 печатных символов ASCII; идеально — UUID) в любом POST, и повтор после тайм-аута не создаст второй заказ. В течение 24 часов тот же ключ на том же маршруте с тем же телом возвращает первый ответ байт в байт, с Idempotent-Replayed: true, без повторного выполнения и без учёта в лимите.

  • Тот же ключ с другим телом или маршрутом: 422 idempotency-key-reused.
  • Первый запрос ещё выполняется: 409 idempotency-key-in-progress с Retry-After.
  • Отказ из-за лимита запросов — не ответ: ключ остаётся свободным, поэтому повтор после Retry-After выполнит запрос.

Заказы также несут ваш собственный external_id: второй заказ с тем же значением отклоняется с 409 duplicate-order, каким бы ключом он ни был отправлен.

Повторный запрос
POST /api/v1/orders
Idempotency-Key: 4f0c2b4e-9d1a-4e0f-b0a8-5d1d3c7e2f61

HTTP/2 201
Idempotent-Replayed: true
X-Request-Id: req_7Hq2Lw9c

Ошибки

Ошибки возвращаются в формате problem JSON (RFC 9457): type — стабильный URL для ветвления, title называет ошибку, detail объясняет этот случай словами, которые можно показать, а request_id позволяет найти его в наших логах. Тело, не прошедшее валидацию, добавляет errors, каждый с JSON-pointer на поле.

СтатусТипКогда
400bad-jsonТело не является JSON.
400bad-bodyПоле отсутствует или заполнено неверно; errors[] указывает на него.
400bad-idempotency-keyIdempotency-Key пустой, слишком длинный или содержит непечатаемые символы ASCII.
401unauthorizedКлюч или токен отсутствует, неверен, истёк или отозван.
403insufficient-scopeУ ключа нет области доступа, нужной маршруту.
404not-foundВ этом аккаунте нет такого объекта. ID другого аккаунта дают тот же ответ.
405method-not-allowedМаршрут существует, но не с этим методом; Allow перечисляет допустимые.
409duplicate-orderЗаказ с этим external_id уже существует; order указывает на него.
409idempotency-key-in-progressПервый запрос с этим ключом ещё выполняется.
409invalid-stateОбъект не может сделать это сейчас, например отменить отправленный заказ.
415unsupported-media-typeТело не в формате application/json.
422idempotency-key-reusedКлюч использовался для другого запроса.
422unprocessableКорректный JSON, с которым мы не можем ничего сделать: непрочитанная ссылка, распроданный вариант. detail указывает, что именно.
429rate-limitedСлишком много запросов за период. Подождите Retry-After секунд.
500internal-errorОшибка на нашей стороне. Повторите с тем же Idempotency-Key.
503service-unavailableСейчас мы не смогли проверить ключ или связаться с магазином. Повторите после Retry-After.
Response 400
HTTP/2 400

{
  "type": "https://www.ninjabuy.com/api/v1/problems/bad-body",
  "title": "Invalid request body",
  "status": 400,
  "detail": "1 field is invalid.",
  "request_id": "req_7Hq2Lw9c",
  "errors": [
    {
      "pointer": "/ship_to/country",
      "detail": "Must be a two-letter country code."
    }
  ]
}