- Регистрация
- 03.07.2023
- Сообщения
- 37
- Реакции
- 9
- Баллы
- 8
Многие шаблоны рано или поздно упираются в одно и то же: аккаунты зарегистрированы и прогреты, контент залит — а дальше каналу или посту нужны первые просмотры, подписчики или реакции. Делать это фермой долго и дорого по прокси, поэтому часть задач проще отдать SMM-панели по API прямо из шаблона.
Ниже — рабочая схема на C#: каталог услуг → заказ → статус → отмена или рефилл → баланс. Плюс что делать с ошибками, где хранить ключ и на чём легко потерять деньги.
Что проверено: класс SmmApi из раздела 3 скомпилирован и запущен в .NET 29.10.2026 — запросы к API, ответ на неверный ключ и разбор всех примеров ответов из документации. Обвязку под ZennoPoster (переменные проекта, кубики) в самом ZennoPoster не запускал. Если что-то не заведётся в вашей версии — напишите в теме, поправлю.
Дисклеймер: я из команды MARKET SMM, примеры написаны на API нашей панели. Протокол простой — один адрес, POST, JSON, — так что разбор пригодится и тем, кто подключает что-то своё.
Полная документация с примерами ответов: market-smm.pro/api
Три вещи, которые стоит знать до первой строки кода:
Ключ берётся в личном кабинете на странице «API» — там же его можно перевыпустить. Ключ даёт доступ к балансу: кто его знает, тот может заказывать за ваш счёт.
Поэтому:
Добавьте класс в «Общий код» проекта (внутрь namespace, который ZennoPoster создаёт сам). Внешние библиотеки не нужны — только стандартный .NET.
Почему регулярки, а не полноценный JSON-парсер: ответы API плоские (кроме пачек, о них ниже), а так код не зависит от того, какая JSON-библиотека подключена у вас в ZennoPoster. Если у вас уже есть привычный парсер — используйте его, логика не меняется.
Каталог нужен, чтобы знать ID услуги, минимум и максимум заказа и, главное, флаги
Каталог меняется: услуги добавляются, цены и лимиты обновляются. Обновляйте CSV раз в сутки или перед запуском большой партии, а не один раз навсегда. Поле
Перед кубиком заведите переменные проекта
Сразу запишите
Главная ловушка — повтор add по таймауту. Если запрос ушёл, а ответа нет (
Перед
Один заказ:
Если заказов десятки, опрашивайте пачкой —
Про значения статуса: в примерах документации есть
Частота опроса: заказы выполняются минутами и часами, поэтому опрос каждые несколько минут пачкой по 100 ID — с запасом. Чаще смысла нет.
Отменить можно только заказ услуги, у которой в каталоге
Если отменяете пачку, разбирайте ответ так же, как статус пачкой: по объекту на заказ, ошибка у каждого своя.
Рефилл — докрутка, если часть подписчиков или просмотров списалась в гарантийный срок. Доступен, когда у услуги
Проверяйте баланс перед партией заказов, а не после первой ошибки посреди неё:
Стоимость конкретного заказа — в поле
Если C# в проекте не нужен, то же самое собирается стандартными действиями:
Все примеры — на API MARKET SMM: 1500+ услуг для Telegram, MAX, YouTube, VK и других площадок, ключ — на странице «API» в кабинете после регистрации.
Если подключаете API к своей панели, боту или шаблону, дадим тестовый баланс 100 ₽, чтобы прогнать весь цикл из статьи: напишите в бот @marketsmm1_bot слово ZENNO. Тест — для новых аккаунтов, один раз.
Вопросы по коду и по API пишите в теме — отвечу здесь.
Ниже — рабочая схема на C#: каталог услуг → заказ → статус → отмена или рефилл → баланс. Плюс что делать с ошибками, где хранить ключ и на чём легко потерять деньги.
Что проверено: класс SmmApi из раздела 3 скомпилирован и запущен в .NET 29.10.2026 — запросы к API, ответ на неверный ключ и разбор всех примеров ответов из документации. Обвязку под ZennoPoster (переменные проекта, кубики) в самом ZennoPoster не запускал. Если что-то не заведётся в вашей версии — напишите в теме, поправлю.
Дисклеймер: я из команды MARKET SMM, примеры написаны на API нашей панели. Протокол простой — один адрес, POST, JSON, — так что разбор пригодится и тем, кто подключает что-то своё.
1. Как устроен API
- Адрес:
https://market-smm.pro/api/v2 - Метод:
POST, тело — обычная форма (application/x-www-form-urlencoded) - Ответ: JSON
- В каждом запросе два обязательных поля:
key(ваш ключ API) иaction(что сделать)
| action | Что делает | Параметры | Что вернёт |
|---|---|---|---|
| services | Каталог услуг | — | массив: service, name, type, category, rate, min, max, refill, cancel |
| add | Новый заказ | service, link, quantity (+ параметры типа услуги) | order — ID заказа |
| status | Статус заказа | order, или orders — до 100 ID через запятую | charge, start_count, status, remains, currency |
| cancel | Отмена | orders — до 100 ID | cancel по каждому заказу |
| refill | Рефилл (докрутка по гарантии) | order или orders | refill — ID рефилла |
| refill_status | Статус рефилла | refill или refills | status |
| balance | Баланс | — | balance, currency |
Полная документация с примерами ответов: market-smm.pro/api
Три вещи, которые стоит знать до первой строки кода:
- Числа приходят строками.
"rate": "0.90","remains": "157". И с точкой в качестве разделителя: на русской Windowsdecimal.Parse("0.90")безCultureInfo.InvariantCultureупадёт или посчитает не то. - Ошибка — это поле error в JSON, например
{"error": "Invalid API key"}или{"error": "Incorrect order ID"}. Проверяйте его в каждом ответе. На неверный ключ сервер отвечает HTTP 401 с этим же JSON в теле, а WebClient на 401 бросает исключение — поэтому тело ответа в коде ниже достаём изWebException. - Вебхуков нет. Статусы опрашиваете сами — удобнее пачкой, до 100 ID за запрос.
2. Где хранить ключ
Ключ берётся в личном кабинете на странице «API» — там же его можно перевыпустить. Ключ даёт доступ к балансу: кто его знает, тот может заказывать за ваш счёт.
Поэтому:
- Не вписывайте ключ в шаблон. Шаблон .xmlz рано или поздно уходит заказчику, на фриланс или в архив на форуме — вместе с ключом.
- Держите ключ вне проекта: в переменной окружения Windows
SMM_API_KEYили в файле в папке пользователя. ZennoPoster видит новую переменную окружения только после перезапуска. - Не пишите в лог тело запроса — в нём ключ. Логируйте только ответ.
- Если ключ всё-таки утёк — перевыпустите его в кабинете: старый сразу перестанет работать, новый пропишите в переменной или файле.
3. Общий код: один метод на все запросы
Добавьте класс в «Общий код» проекта (внутрь namespace, который ZennoPoster создаёт сам). Внешние библиотеки не нужны — только стандартный .NET.
C#:
public static class SmmApi
{
public const string Url = "https://market-smm.pro/api/v2";
// Ключ: переменная окружения SMM_API_KEY, иначе файл smm_api_key.txt в папке пользователя
public static string Key()
{
string k = System.Environment.GetEnvironmentVariable("SMM_API_KEY");
if (string.IsNullOrWhiteSpace(k))
{
string path = System.IO.Path.Combine(
System.Environment.GetFolderPath(System.Environment.SpecialFolder.UserProfile),
"smm_api_key.txt");
if (System.IO.File.Exists(path)) k = System.IO.File.ReadAllText(path);
}
if (string.IsNullOrWhiteSpace(k))
throw new System.Exception("Ключ API не найден: задайте SMM_API_KEY или создайте smm_api_key.txt");
return k.Trim();
}
// POST key + action + параметры. Возвращает тело ответа строкой.
public static string Call(string action, System.Collections.Generic.Dictionary<string, string> args = null)
{
System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;
var form = new System.Collections.Specialized.NameValueCollection();
form["key"] = Key();
form["action"] = action;
if (args != null)
foreach (var p in args) form[p.Key] = p.Value;
using (var wc = new System.Net.WebClient())
{
wc.Encoding = System.Text.Encoding.UTF8;
try
{
byte[] raw = wc.UploadValues(Url, "POST", form);
return System.Text.Encoding.UTF8.GetString(raw);
}
catch (System.Net.WebException ex)
{
// Сервер ответил не 200: в теле всё равно может быть {"error": "..."}
var resp = ex.Response as System.Net.HttpWebResponse;
if (resp == null) throw; // ответа нет вовсе: таймаут, DNS, обрыв
using (var r = new System.IO.StreamReader(resp.GetResponseStream()))
return r.ReadToEnd();
}
}
}
// Значение плоского поля: "name": "строка" или "name": 123 / true / null
public static string Field(string json, string name)
{
var m = System.Text.RegularExpressions.Regex.Match(json,
"\"" + name + "\"\\s*:\\s*(?:\"((?:[^\"\\\\]|\\\\.)*)\"|(-?[\\d.]+|true|false|null))");
if (!m.Success) return null;
return m.Groups[1].Success
? System.Text.RegularExpressions.Regex.Unescape(m.Groups[1].Value)
: m.Groups[2].Value;
}
// Текст ошибки или null
public static string Error(string json)
{
return Field(json, "error");
}
// Число из строки ответа ("0.90") независимо от языка Windows
public static decimal Num(string s)
{
return decimal.Parse(s, System.Globalization.CultureInfo.InvariantCulture);
}
}
Почему регулярки, а не полноценный JSON-парсер: ответы API плоские (кроме пачек, о них ниже), а так код не зависит от того, какая JSON-библиотека подключена у вас в ZennoPoster. Если у вас уже есть привычный парсер — используйте его, логика не меняется.
4. Каталог услуг → CSV
Каталог нужен, чтобы знать ID услуги, минимум и максимум заказа и, главное, флаги
cancel и refill: отменить или докрутить можно не каждый заказ. Кубик «C# код»:
C#:
string json = SmmApi.Call("services");
string err = SmmApi.Error(json);
if (err != null) throw new Exception("services: " + err);
string[] cols = { "service", "name", "type", "category", "rate", "min", "max", "refill", "cancel" };
var lines = new System.Collections.Generic.List<string>();
lines.Add(string.Join(";", cols));
// Каждая услуга — плоский объект {...}
foreach (System.Text.RegularExpressions.Match m in
System.Text.RegularExpressions.Regex.Matches(json, "\\{[^{}]*\\}"))
{
var row = new string[cols.Length];
for (int i = 0; i < cols.Length; i++)
row[i] = (SmmApi.Field(m.Value, cols[i]) ?? "").Replace(";", ",");
lines.Add(string.Join(";", row));
}
string file = System.IO.Path.Combine(project.Directory, "services.csv");
System.IO.File.WriteAllLines(file, lines, System.Text.Encoding.UTF8);
return (lines.Count - 1).ToString(); // сколько услуг сохранили
Каталог меняется: услуги добавляются, цены и лимиты обновляются. Обновляйте CSV раз в сутки или перед запуском большой партии, а не один раз навсегда. Поле
type подсказывает, какие параметры нужны в add: у обычной услуги (Default) — ссылка и количество, у комментариев — список comments, у опроса — answer_number, у подписок на новые посты (Subscriptions) — username и диапазон min/max. Подробно — в документации.5. Заказ
Перед кубиком заведите переменные проекта
service_id, target_link, quantity, order_id, api_response.
C#:
string json = SmmApi.Call("add", new System.Collections.Generic.Dictionary<string, string> {
{ "service", project.Variables["service_id"].Value },
{ "link", project.Variables["target_link"].Value },
{ "quantity", project.Variables["quantity"].Value }
});
project.Variables["api_response"].Value = json;
string err = SmmApi.Error(json);
if (err != null) throw new Exception("add: " + err); // кубик уйдёт в красную ветку
string order = SmmApi.Field(json, "order"); // успешный ответ: {"order": 23501}
if (string.IsNullOrEmpty(order)) throw new Exception("add: неожиданный ответ " + json);
project.Variables["order_id"].Value = order;
return order;
Сразу запишите
order_id вместе со ссылкой в таблицу или файл: без ID вы не узнаете статус и не отмените заказ.Главная ловушка — повтор add по таймауту. Если запрос ушёл, а ответа нет (
WebException без Response), заказ мог создаться. Своего идентификатора заказа API не принимает, найти «тот самый» заказ по ссылке через API нельзя. Автоматический повтор в цикле — это два или три одинаковых заказа и списанный баланс. Поэтому:- на
addникаких автоповторов; - ссылку из такого запроса пометьте как «неизвестно» и проверьте вручную в кабинете, в истории заказов;
- повторяйте только запросы, которые ничего не меняют:
services,status,balance.
Перед
add сверьте quantity с min/max услуги из каталога — так ошибка не дойдёт до сервера.6. Статус: один заказ и пачка
Один заказ:
C#:
string json = SmmApi.Call("status", new System.Collections.Generic.Dictionary<string, string> {
{ "order", project.Variables["order_id"].Value }
});
string err = SmmApi.Error(json);
if (err != null) throw new Exception("status: " + err);
project.Variables["order_status"].Value = SmmApi.Field(json, "status"); // например Partial, In progress
project.Variables["order_remains"].Value = SmmApi.Field(json, "remains"); // сколько не докручено
project.Variables["order_start"].Value = SmmApi.Field(json, "start_count"); // сколько было до старта
return project.Variables["order_status"].Value;
Если заказов десятки, опрашивайте пачкой —
orders, до 100 ID через запятую. Ответ — объект, где ключ — ID заказа:
JSON:
{
"1": { "charge": "…", "start_count": "3572", "status": "Partial", "remains": "157", "currency": "…" },
"10": { "error": "Incorrect order ID" }
}
C#:
// ids — до 100 ID через запятую, например из таблицы активных заказов
string ids = project.Variables["order_ids"].Value;
string json = SmmApi.Call("status", new System.Collections.Generic.Dictionary<string, string> { { "orders", ids } });
var report = new System.Text.StringBuilder();
foreach (System.Text.RegularExpressions.Match m in
System.Text.RegularExpressions.Regex.Matches(json, "\"(\\d+)\"\\s*:\\s*\\{([^{}]*)\\}"))
{
string id = m.Groups[1].Value, body = m.Groups[2].Value;
string e = SmmApi.Error(body);
report.AppendLine(id + ";" + (e != null ? "ERROR: " + e
: SmmApi.Field(body, "status") + ";" + SmmApi.Field(body, "remains")));
}
return report.ToString();
Про значения статуса: в примерах документации есть
Partial (выполнен частично, remains показывает недокрученное) и In progress. Полного списка в документации нет, поэтому незнакомый статус не считайте ошибкой: запишите его в лог и продолжайте опрос. Список того, какие статусы считать конечными для вашей логики, соберите из реальных ответов на тестовых заказах.Частота опроса: заказы выполняются минутами и часами, поэтому опрос каждые несколько минут пачкой по 100 ID — с запасом. Чаще смысла нет.
7. Отмена
Отменить можно только заказ услуги, у которой в каталоге
cancel = true. Отмена принимает orders — до 100 ID:
C#:
string json = SmmApi.Call("cancel", new System.Collections.Generic.Dictionary<string, string> {
{ "orders", project.Variables["order_id"].Value }
});
// Успех: [{"order": 2, "cancel": 1}]
// Ошибка: [{"order": 9, "cancel": {"error": "Incorrect order ID"}}]
string err = SmmApi.Error(json);
if (err != null) throw new Exception("cancel: " + err);
return SmmApi.Field(json, "cancel");
Если отменяете пачку, разбирайте ответ так же, как статус пачкой: по объекту на заказ, ошибка у каждого своя.
8. Рефилл
Рефилл — докрутка, если часть подписчиков или просмотров списалась в гарантийный срок. Доступен, когда у услуги
refill = true; срок гарантии указан в названии услуги (R7, R30 и т. п.).
C#:
// Создать рефилл: ответ {"refill": "1"} — это ID рефилла, не заказа
string json = SmmApi.Call("refill", new System.Collections.Generic.Dictionary<string, string> {
{ "order", project.Variables["order_id"].Value }
});
string err = SmmApi.Error(json);
if (err != null) throw new Exception("refill: " + err);
string refillId = SmmApi.Field(json, "refill");
// Позже — статус рефилла: {"status": "Completed"} или {"status": "Rejected"}
string st = SmmApi.Call("refill_status", new System.Collections.Generic.Dictionary<string, string> {
{ "refill", refillId }
});
return SmmApi.Error(st) ?? SmmApi.Field(st, "status");
9. Баланс
Проверяйте баланс перед партией заказов, а не после первой ошибки посреди неё:
C#:
string json = SmmApi.Call("balance");
string err = SmmApi.Error(json);
if (err != null) throw new Exception("balance: " + err);
decimal balance = SmmApi.Num(SmmApi.Field(json, "balance"));
string currency = SmmApi.Field(json, "currency"); // валюта выбирается в настройках аккаунта
decimal minBalance = SmmApi.Num(project.Variables["min_balance"].Value);
if (balance < minBalance) throw new Exception("Мало денег: " + balance + " " + currency);
return balance.ToString(System.Globalization.CultureInfo.InvariantCulture);
Стоимость конкретного заказа — в поле
charge ответа status; её удобно складывать в отчёт по партии.10. Без кода: кубиками
Если C# в проекте не нужен, то же самое собирается стандартными действиями:
- Действие POST-запроса: URL
https://market-smm.pro/api/v2, тело —key={-Variable.smm_key-}&action=status&order={-Variable.order_id-}, тип содержимогоapplication/x-www-form-urlencoded, ответ — в переменную. - Регулярное выражение по ответу:
"error"\s*:\s*"([^"]*)". Нашлось — уходим в ветку ошибки. - Ещё по регулярке на каждое нужное поле:
"status"\s*:\s*"([^"]*)","order"\s*:\s*(\d+)и т. д.
11. Чек-лист перед запуском на ферме
- Ключ — вне шаблона, тело запроса в лог не пишется.
- Каталог загружен свежий,
quantityсверен сmin/max. - На
addнет автоповтора; таймаут → ручная проверка. - Каждый
order_idзаписан вместе со ссылкой. - Статусы опрашиваются пачкой, незнакомый статус не роняет шаблон.
- Отмена и рефилл — только для услуг с
cancel/refill=true. - Баланс проверяется до партии, числа парсятся через
InvariantCulture.
Где взять ключ и на чём попробовать
Все примеры — на API MARKET SMM: 1500+ услуг для Telegram, MAX, YouTube, VK и других площадок, ключ — на странице «API» в кабинете после регистрации.
Если подключаете API к своей панели, боту или шаблону, дадим тестовый баланс 100 ₽, чтобы прогнать весь цикл из статьи: напишите в бот @marketsmm1_bot слово ZENNO. Тест — для новых аккаунтов, один раз.
Вопросы по коду и по API пишите в теме — отвечу здесь.



