Streamrise API
Оптовые заказы зрителей, чата и фолловеров для Twitch и Kick. Совместимо с PerfectPanel, плюс собственный HTTP API — авторизация одним API-ключом.
Первый звонок — за две минуты.
Четыре шага от нового аккаунта до живого заказа. Нужны пополненный аккаунт Streamrise и ссылка на канал.
Создайте аккаунт Streamrise
Зарегистрируйтесь на stream-rise.com — регистрация бесплатная. Вы пополняете баланс, и каждый заказ списывается с него.
Скопируйте ваш API-ключ
Аккаунт→Настройки→API
Ваш ключ показан в Настройках, его можно скопировать — перевыпустить в любой момент. Относитесь к нему как к паролю: любой, у кого он есть, может потратить ваш баланс.
Задайте ключ как переменную окружения
export STREAMRISE_KEY=YOUR_API_KEYОтправьте первый заказ
Создайте заказ одним вызовом. A 200 ответ содержит ID заказа и его исходное состояние.
curl "https://stream-rise.com/api/newOrder?key=$STREAMRISE_KEY&service=twitchViewers&channel=yourchannel&amount=100"{
"orderId": 12345,
"order": {
"id": 12345,
"service": "twitchViewers",
"channel": "yourchannel",
"amount": 100,
"status": "active"
}
}"status": "active", вы в эфире.Каждый запрос содержит ключ.
Каждый запрос содержит ваш API-ключ — передавайте его как key query-параметр, a key поле в теле JSON или key cookie. Найдите свой ключ в аккаунте — откройте Settings → API.
# As a query parameter — native /api/* endpoints
GET https://stream-rise.com/api/getOrders?key=YOUR_API_KEY
# In the JSON body — PerfectPanel endpoint
POST https://stream-rise.com/perfectPanel
{ "key": "YOUR_API_KEY", "action": "balance" }Куда вставить ключ
Чтение PerfectPanel key из тела JSON; нативно /api/* читает его из строки запроса. A key cookie тоже подойдёт — что проще в вашем стеке.
Некоторым запросам ключ не нужен
Проверка полей (/api/validateOrderProperty) открыт, так что проверить название канала можно даже до регистрации.
Получить ключ
Откройте Настройки → API в вашем аккаунте, чтобы скопировать или перевыпустить ключ. Аккаунты бесплатные; вы платите только за каждый заказ из баланса.
API справочник.
PerfectPanel
Один POST-эндпоинт, который переключается полем «action», — готовая замена для софта SMM-панелей, работающего по протоколу PerfectPanel.
Возвращает полный каталог услуг с актуальными ставками со скидкой для аккаунта.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
action | string | Обязательно | services | Должно быть «services». |
curl -X POST https://stream-rise.com/perfectPanel -H "Content-Type: application/json" -d '{"key":"YOUR_API_KEY","action":"services"}'[
{
"service": 1,
"name": "Twitch Viewers",
"type": "Default",
"category": "Twitch",
"rate": "0.90",
"min": "10",
"max": "10000",
"cancel": true
},
{
"service": 2,
"name": "Twitch Chatbots",
"type": "Custom Comments",
"category": "Twitch",
"rate": "8.00",
"min": "10",
"max": "1500",
"cancel": false
}
]Возвращает текущий баланс аккаунта и его валюту.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
action | string | Обязательно | balance | Должно быть «balance». |
curl -X POST https://stream-rise.com/perfectPanel -H "Content-Type: application/json" -d '{"key":"YOUR_API_KEY","action":"balance"}'{
"balance": "100.84",
"currency": "USD"
}Возвращает списание, стартовый счётчик, статус и оставшиеся единицы для одного заказа.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
action | string | Обязательно | status | Должно быть "status". |
order | string | Обязательно | — | Один ID заказа. |
curl -X POST https://stream-rise.com/perfectPanel -H "Content-Type: application/json" -d '{"key":"YOUR_API_KEY","action":"status","order":12345}'{
"charge": "0.27",
"start_count": "3572",
"status": "In progress",
"remains": "157",
"currency": "USD"
}{
"error": "Incorrect order ID"
}Возвращает статус сразу для многих заказов, с ключом по ID заказа.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
action | string | Обязательно | status | Должно быть "status". |
orders | string | Обязательно | — | ID заказов через запятую. |
curl -X POST https://stream-rise.com/perfectPanel -H "Content-Type: application/json" -d '{"key":"YOUR_API_KEY","action":"status","orders":"12345,12346,99999"}'{
"12345": {
"charge": "0.27",
"start_count": "3572",
"status": "Partial",
"remains": "157",
"currency": "USD"
},
"12346": {
"charge": "1.44",
"start_count": "234",
"status": "In progress",
"remains": "10",
"currency": "USD"
},
"99999": {
"error": "Incorrect order ID"
}
}Создаёт заказ. Услуга указывается по её числовому ID PerfectPanel из списка услуг.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
action | string | Обязательно | add | Должно быть «add». |
service | integer | Обязательно | — | Числовой ID услуги из списка услуг. |
link | string | Обязательно | — | Полный URL канала, на который направлен заказ. |
quantity | integer | Обязательно | — | Количество единиц к выполнению, в пределах минимума и максимума услуги. |
interval | string | Необязательно | — | Услуги для зрителей: интервал подачи в минутах. |
comments | string | Необязательно | — | Услуги чат-ботов: пользовательские сообщения, разделённые переносом строки. |
periodAmount | string | Необязательно | — | Услуги на период: сколько длится заказ. |
curl -X POST https://stream-rise.com/perfectPanel -H "Content-Type: application/json" -d '{"key":"YOUR_API_KEY","action":"add","service":1,"link":"https://twitch.tv/username","quantity":100}'const res = await fetch("https://stream-rise.com/perfectPanel", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
key: "YOUR_API_KEY",
action: "add",
service: 1,
link: "https://twitch.tv/username",
quantity: 100
})
});
const data = await res.json();import requests
res = requests.post(
"https://stream-rise.com/perfectPanel",
json={
"key": "YOUR_API_KEY",
"action": "add",
"service": 1,
"link": "https://twitch.tv/username",
"quantity": 100,
},
)
data = res.json(){
"order": 23501
}Отменяет один или несколько заказов. Доступность зависит от того, поддерживает ли сервис отмену.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
action | string | Обязательно | cancel | Должно быть «cancel». |
orders | string | Обязательно | — | ID заказов через запятую. |
curl -X POST https://stream-rise.com/perfectPanel -H "Content-Type: application/json" -d '{"key":"YOUR_API_KEY","action":"cancel","orders":"23501,23502"}'[
{
"order": 23501,
"cancel": 1
},
{
"order": 23502,
"cancel": {
"error": "Incorrect order ID"
}
}
]Каталог услуг
Нативные эндпоинты каталога — богаче, чем PerfectPanel «services»: с семействами, полями по каждой услуге, таблицами цен и лимитами.
Перечисляет семейства услуг (платформы) и порядок их отображения.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
curl "https://stream-rise.com/api/getFamilyServices?key=YOUR_API_KEY"[
{
"service": "twitch",
"order": 1
},
{
"service": "kick",
"order": 2
},
{
"service": "youtube",
"order": 3
},
{
"service": "tiktok",
"order": 4
}
]Возвращает все услуги, сгруппированные по семействам, с метаданными полей для каждой услуги.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
curl "https://stream-rise.com/api/getServices?key=YOUR_API_KEY"{
"services": {
"twitch": {
"twitchViewers": {
"service": "twitchViewers",
"serviceFamily": "twitch",
"serviceType": "viewers",
"enabled": true,
"fieldsData": { … }
},
"twitchChatBots": {
"service": "twitchChatBots",
"serviceFamily": "twitch",
"serviceType": "chatbots",
"enabled": true,
"fieldsData": { … }
}
},
"kick": { … }
},
"types": { … }
}Возвращает таблицу цен услуги (цены за единицу по тарифам).
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
service | string | Необязательно | — | Фильтр по одной услуге. |
curl "https://stream-rise.com/api/getPrices?key=YOUR_API_KEY&service=twitchViewers"{
"twitchViewers": {
"1": {
"10": 0.9,
"50": 4.2,
"100": 7.8
}
}
}Перечисляет поля, которые каждая услуга принимает при создании заказа.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
curl "https://stream-rise.com/api/availableToSend?key=YOUR_API_KEY"{
"twitchViewers": [
"channel",
"amount",
"interval"
],
"twitchChatBots": [
"channel",
"amount",
"comments"
],
"types": {
"viewers": [
"channel",
"amount"
],
"chatbots": [
"channel",
"amount",
"comments"
]
}
}Перечисляет поля, которые каждая услуга позволяет менять в существующем заказе.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
curl "https://stream-rise.com/api/availableToChange?key=YOUR_API_KEY"{
"twitchViewers": [
"channel",
"amount"
],
"twitchChatBots": [
"channel",
"comments"
],
"types": {
"viewers": [
"channel",
"amount"
],
"chatbots": [
"channel",
"comments"
]
}
}Перечисляет поля, которые каждая услуга позволяет улучшать в существующем заказе.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
curl "https://stream-rise.com/api/availableToUpgrade?key=YOUR_API_KEY"{
"twitchViewers": [
"amount"
],
"twitchViewersPeriod": [
"amount",
"period"
],
"types": {
"viewers": [
"amount"
]
}
}Возвращает минимальные и максимальные границы для каждого числового поля услуги.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
service | string | Необязательно | — | Услуга, для которой читать лимиты. |
curl "https://stream-rise.com/api/getParamsLimits?key=YOUR_API_KEY&service=twitchViewers"{
"amount": {
"min": 10,
"max": 10000
},
"interval": {
"min": 1,
"max": 60
}
}Проверяет одно поле заказа (например, название канала) до отправки. Ключ не нужен.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
service | string | Обязательно | — | Услуга, к которой относится поле. |
field | string | Обязательно | — | Имя поля, например "channel". |
value | string | Обязательно | — | Значение для проверки. |
curl "https://stream-rise.com/api/validateOrderProperty?service=twitchViewers&field=channel&value=username"200 OK{
"error": {
"channel": "Channel not found"
}
}Заказы
Нативное управление заказами — создание, чтение, изменение, приостановка и удаление заказов. Услуги адресуются по строковому имени (например, twitchViewers).
Создаёт заказ и возвращает его ID и начальное состояние.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
service | string | Обязательно | — | Название услуги, например twitchViewers. |
channel | string | Обязательно | — | Название или ссылка на целевой канал. |
amount | integer | Обязательно | — | Количество единиц к выполнению. |
period | string | Необязательно | — | Услуги по периоду: тип периода. |
periodAmount | string | Необязательно | — | Услуги на период: сколько длится заказ. |
interval | string | Необязательно | — | Услуги для зрителей: интервал подачи в минутах. |
comments | string | Необязательно | — | Услуги чат-ботов: сообщения, разделённые переносом строки. |
curl "https://stream-rise.com/api/newOrder?key=YOUR_API_KEY&service=twitchViewers&channel=username&amount=100"const res = await fetch(
"https://stream-rise.com/api/newOrder?key=YOUR_API_KEY&service=twitchViewers&channel=username&amount=100"
);
const data = await res.json();import requests
res = requests.get(
"https://stream-rise.com/api/newOrder",
params={
"key": "YOUR_API_KEY",
"service": "twitchViewers",
"channel": "username",
"amount": 100,
},
)
data = res.json(){
"orderId": 12345,
"order": {
"id": 12345,
"service": "twitchViewers",
"channel": "username",
"amount": 100,
"status": "active"
}
}{
"error": {
"channel": "channelEmpty"
}
}Возвращает ваши заказы с ключом по ID. При желании можно отфильтровать по конкретным ID.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
ids | string | Необязательно | — | ID через запятую для фильтра. |
curl "https://stream-rise.com/api/getOrders?key=YOUR_API_KEY"{
"12345": {
"id": 12345,
"service": "twitchViewers",
"channel": "username",
"amount": 100,
"pause": false
},
"12346": {
"id": 12346,
"service": "twitchChatBots",
"channel": "username2",
"amount": 50,
"pause": true
}
}Возвращает отсортированную, доступную для поиска, постраничную выборку заказов и необязательный итог.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
start | число | Необязательно | — | Индекс первой строки (с 0). |
end | число | Необязательно | — | Индекс последней строки. |
total | boolean | Необязательно | — | Укажите общее количество строк. |
sortKey | string | Необязательно | — | Столбец для сортировки, например orderTime. |
sortDirection | string | Необязательно | — | "asc" или "desc". |
searchValue | string | Необязательно | — | Фильтр по свободному тексту. |
serviceType | string | Необязательно | — | Фильтр по типу услуги. |
ids | string | Необязательно | — | ID через запятую для фильтра. |
curl "https://stream-rise.com/api/getOrdersPage?key=YOUR_API_KEY&start=0&end=15&total=true&sortKey=orderTime&sortDirection=desc"{
"history": [
{
"id": 12345,
"service": "twitchViewers",
"channel": "username",
"amount": 100,
"orderTime": 1711500000000,
"pause": false
}
],
"total": "42"
}Приостанавливает доставку по активному заказу.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
id | string | Обязательно | — | ID заказа. |
curl "https://stream-rise.com/api/pauseOrder?key=YOUR_API_KEY&id=12345"200 OKВозобновляет приостановленный заказ.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
id | string | Обязательно | — | ID заказа. |
curl "https://stream-rise.com/api/resumeOrder?key=YOUR_API_KEY&id=12345"200 OKБезвозвратно удаляет заказ.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
id | string | Обязательно | — | ID заказа. |
curl "https://stream-rise.com/api/deleteOrder?key=YOUR_API_KEY&id=12345"200 OKРассчитывает цену и скидку на апгрейд заказа, не применяя его.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
id | string | Обязательно | — | ID заказа. |
order | object | Обязательно | — | Свойства нового заказа для расчёта цены. |
curl -X POST "https://stream-rise.com/api/calculateUpgradePrice?key=YOUR_API_KEY" -H "Content-Type: application/json" -d '{"id":12345,"order":{"amount":200}}'{
"price": 5.5,
"totalDiscount": 0.55
}Применяет апгрейд (например, больше единиц) к существующему заказу.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
id | string | Обязательно | — | ID заказа. |
order | object | Обязательно | — | Свойства нового заказа. |
curl -X POST "https://stream-rise.com/api/upgradeOrder?key=YOUR_API_KEY" -H "Content-Type: application/json" -d '{"id":12345,"order":{"amount":200}}'200 OKИзменяет редактируемые параметры заказа, например целевой канал.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Ваш API-ключ. |
id | string | Обязательно | — | ID заказа. |
order | object | Обязательно | — | Свойства для изменения. |
curl -X POST "https://stream-rise.com/api/changeOrder?key=YOUR_API_KEY" -H "Content-Type: application/json" -d '{"id":12345,"order":{"channel":"new_channel_name"}}'200 OK{
"error": {
"channel": "Invalid channel name"
}
}В реальном времени
Статус заказа передаётся по WebSocket — тот же живой поток, на котором работает панель Streamrise. Используйте его вместо цикла опроса; /api/getOrders остаётся запасным вариантом. Классические HTTP-вебхуки (POST на ваш URL) запланированы и пока не работают.
Откройте WebSocket на origin сайта, пройдите авторизацию своим API-ключом и подпишитесь на поток ordersUpdates. Изменения заказов затем передаются вам по мере их появления (пакетами примерно каждые 250 мс), только с полями, которые разрешено читать вашему ключу. Число одновременных сокетов на ключ ограничено (по умолчанию 4; партнёрские лимиты задаются для каждого ключа). Чтобы ограничить поток одним заказом, подпишитесь на orderUpdatesByOrderId; чтобы остановить поток, отправьте {"event":"unsubscribe","thread":"…"}.
| Поле | Тип | Обязательно | По умолчанию | Описание |
|---|---|---|---|---|
key | string | Обязательно | — | Первое сообщение после подключения: {"key": "YOUR_API_KEY"} — аутентифицирует сокет. Неаутентифицированные сокеты получают {"event":"no auth"}. |
event | string | Обязательно | — | "subscribe" или "unsubscribe" — отправляется следующим сообщением после авторизации. |
thread | string | Обязательно | — | "ordersUpdates" для всех ваших заказов или "orderUpdatesByOrderId" для одного заказа. |
# wscat (npm i -g wscat)
wscat -c wss://stream-rise.com
> {"key": "YOUR_API_KEY"}
< {"event":"auth","message":"Authenticated","socketsLeft":3}
> {"event": "subscribe", "thread": "ordersUpdates"}
< {"event":"subscribe","message":"subscribed to ordersUpdates"}const WebSocket = require('ws');
const ws = new WebSocket('wss://stream-rise.com');
ws.on('open', () => ws.send(JSON.stringify({ key: 'YOUR_API_KEY' })));
ws.on('message', (m) => {
const msg = JSON.parse(m.toString());
if (msg.event === 'auth') {
ws.send(JSON.stringify({ event: 'subscribe', thread: 'ordersUpdates' }));
}
if (msg.event === 'threadMessage' && msg.thread === 'ordersUpdates') {
console.log(msg.message.orders); // { "<orderId>": { ...changed fields } }
}
});import asyncio, json, websockets
async def main():
async with websockets.connect("wss://stream-rise.com") as ws:
await ws.send(json.dumps({"key": "YOUR_API_KEY"}))
async for raw in ws:
msg = json.loads(raw)
if msg.get("event") == "auth":
await ws.send(json.dumps({"event": "subscribe", "thread": "ordersUpdates"}))
if msg.get("event") == "threadMessage" and msg.get("thread") == "ordersUpdates":
print(msg["message"]["orders"]) # { "<orderId>": { ...changed fields } }
asyncio.run(main()){
"event": "socketClientId",
"socketClientId": 13
}{
"event": "auth",
"message": "Authenticated",
"socketsLeft": 3
}{
"event": "subscribe",
"message": "subscribed to ordersUpdates"
}{
"event": "threadMessage",
"thread": "ordersUpdates",
"message": {
"orders": {
"12345": { "status": …, /* changed, whitelisted fields */ }
}
}
}{
"event": "too many",
"message": "Too many sockets connected for this client"
}Каждая ошибка — расшифрована.
Специальных HTTP-кодов ошибок для отдельной обработки нет — неудачный вызов всё равно возвращает 200 OK с небольшим error поле. Оно бывает в одном из двух видов: строка из PerfectPanel или { field: reason } сопоставление из native-формата /api/*. Фильтр по любому тексту ниже.
Ошибка PerfectPanel
{ "error": "Incorrect order ID" }Ошибка нативного поля
{ "error": { "channel": "channelEmpty" } }| область | ответ с ошибкой | когда это происходит | как исправить |
|---|---|---|---|
perfectPanel | { "error": "Incorrect order ID" } | ID заказа неизвестен или не относится к этому ключу. | Убедитесь, что ID вернулся на этот аккаунт. |
perfectPanel | { "error": "Access denied" } | Это действие не разрешено для этого ключа. | Используйте ключ, у которого есть право на это действие. |
perfectPanel | { "error": "Service doesn't support cancel" } | Услугу нельзя отменить. | Проверить cancel сначала на сервисе в каталоге. |
/api/* | { "error": { "channel": "channelEmpty" } } | Обязательное поле не заполнено. | Прочитайте ключ поля и укажите значение. |
/api/* | { "error": { "channel": "Channel not found" } } | Канал не существует или недоступен. | Сначала проверьте его с помощью /api/validateOrderProperty. |
/api/* | { "error": { "channel": "Invalid channel name" } } | Поле не прошло проверку при изменении или апгрейде. | Исправьте указанное поле и отправьте снова. |
both | { "error": "..." } | The key отсутствует, неверен или отозван. | Отправьте действующий ключ из раздела «Настройки → API» вашего аккаунта. |
К чему мы стремимся. Цели
Это операционные цели, а не договорные гарантии. Вопросы или инцидент? Напишите нам: /contacts.
Стабильно и без версий.
API Streamrise стабилен и без версий. Новые услуги, поля и эндпоинты добавляются, не ломая существующие вызовы, — поэтому нет переключений версий, за которыми нужно следить, и нет сроков устаревания, которые нужно догонять.
Два интерфейса: эндпоинт, совместимый с PerfectPanel, и собственный /api/* поверхность, обе аутентифицированы вашим key.
Новые услуги и поля добавляются без изменения существующей структуры запросов и ответов.
Webhook'и, уровни частоты запросов и публичная история изменений есть в планах.
Поговорите с теми, кто этим занимается.
Поддержка разработчиков, с приоритетной маршрутизацией.
Проблемы с API обрабатываются вне общей очереди. Пришлите ID заказа и точный запрос, который вы отправили, — и мы сможем отследить его напрямую.
Как получить API-ключ Streamrise?
Войдите в аккаунт Streamrise и откройте Настройки → API — ваш ключ показан там, его можно скопировать (перевыпустить можно в любой момент). Храните его как пароль: с него списываются средства с вашего баланса.
Какой лимит запросов к API Streamrise?
Сейчас принудительного лимита частоты запросов нет. Пожалуйста, распределяйте массовые вызовы разумно; опубликованные объёмные уровни — в планах.
Есть ли у Streamrise вебхуки?
Пока нет — вебхуки запланированы. Пока опрашивайте /api/getOrders или PerfectPanel status отслеживать выполнение.
Streamrise делает докрутку или возврат по заказам?
Отдельного эндпоинта докрутки сейчас нет. Невыполненные или отменённые единицы возвращаются на ваш баланс.
API версионируется?
Нет. API стабильный и без версий — новые услуги и поля добавляются, не ломая существующие вызовы.
Как избежать дублей заказов при повторных попытках?
Ключа идемпотентности сейчас нет, поэтому не повторяйте слепо запись, которая могла уже пройти, — проверьте /api/getOrders первый.