Skip to content
Translated page. The English version is the source of truth.

POST /apiv2/withdraw ​

Виведення TRX з вашого балансу Netts на адресу TRON. Запит повертає номер замовлення миттєво; фактична виплата в мережі (on-chain) виконується асинхронно бекендом (протягом ~5 хвилин). Відстежуйте результат шляхом опитування ендпойнта статусу або налаштувавши вебхук.

ℹ️ Як це працює. Створення заявки на виведення одразу резервує суму з вашого балансу (баланс списується в момент прийняття замовлення). Потім фоновий процес (daemon) бекенда надсилає TRX і позначає замовлення як completed або failed. У початковій відповіді немає синхронного результату в мережі — ви завжди спочатку отримуєте підтвердження pending.

Перед прийняттям замовлення перевіряється адреса призначення. Якщо виведення коштів на цю адресу недоступне, або перевірку наразі неможливо завершити, запит відхиляється: замовлення не створюється і з вашого балансу нічого не резервується.

URL кінцевої точки ​

POST https://netts.io/apiv2/withdraw

Заголовки запиту ​

HeaderRequiredDescription
Content-TypeТакapplication/json
X-API-KEYТакВаш API-ключ із панелі керування Netts
X-Idempotency-KeyНіНеобов'язковий ключ, згенерований клієнтом (base64), для безпечних повторних спроб без подвійного виведення коштів. Якщо його пропущено, сервер генерує його автоматично. Це значення стає вашим orderId.

Тіло запиту ​

json
{
    "amount": 15,
    "address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

Параметри запиту ​

ParameterTypeRequiredDescription
amountnumberТакВалова (gross) сума в TRX (мінімум 3). Комісія вираховується з цієї суми — одержувач отримує amount − fee (net).
addressstringТакTRON-адреса призначення (T…, 34 символи, base58). Перевіряється перед прийняттям замовлення.
sub_and_robot_outbooleanНіРежим виплат для роботів/субакаунтів: застосовує комісію 2 TRX замість 1 TRX. За замовчуванням false.

Комісія. Фіксована комісія утримується з валової суми amount: 1 TRX за звичайних умов, або 2 TRX, якщо sub_and_robot_out = true. Замовлення відхиляється, якщо amount − fee ≤ 0.

Приклади ​

Наведені нижче приклади також формують і надсилають X-Idempotency-Key, щоб випадковий повторний запит не створив друге виведення. Повні правила див. у розділі Ідемпотентність.

cURL ​

bash
API_KEY="your_api_key"
ADDR="TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
AMOUNT=15
NONCE=$(( $(date +%s) / 2 ))   # stable for retries within a 2s window; or your own order UUID

# X-Idempotency-Key = base64url( HMAC-SHA256( API_KEY, "addr:amount:nonce" ) )
IDEMP=$(printf '%s' "${ADDR}:${AMOUNT}:${NONCE}" \
  | openssl dgst -sha256 -hmac "$API_KEY" -binary | basenc --base64url | tr -d '=')

curl -X POST https://netts.io/apiv2/withdraw \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: $API_KEY" \
  -H "X-Idempotency-Key: $IDEMP" \
  -d "{\"amount\": $AMOUNT, \"address\": \"$ADDR\"}"

Python ​

python
import time, hmac, hashlib, base64, requests

API_KEY = "your_api_key"
url = "https://netts.io/apiv2/withdraw"
payload = {"amount": 15, "address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}

# X-Idempotency-Key = base64url( HMAC-SHA256( API_KEY, "addr:amount:nonce" ) ), padding stripped.
# Generate ONCE per order and resend the same value on every retry.
nonce = str(int(time.time() // 2))   # 2s bucket; or your own order UUID
message = f"{payload['address']}:{payload['amount']}:{nonce}"
idem_key = base64.urlsafe_b64encode(
    hmac.new(API_KEY.encode(), message.encode(), hashlib.sha256).digest()
).decode().rstrip("=")

headers = {
    "Content-Type": "application/json",
    "X-API-KEY": API_KEY,
    "X-Idempotency-Key": idem_key,
}

resp = requests.post(url, headers=headers, json=payload)
detail = resp.json().get("detail", {})

if resp.status_code == 202 and detail.get("status") == "pending":
    d = detail["data"]
    print(f"Order ID: {d['orderId']}")            # use it for the status endpoint / webhook
    print(f"Net to recipient: {d['net']} TRX (fee {d['fee']})")
else:
    print(f"Code {detail.get('code')}: {detail.get('msg', detail)}")

Відповідь ​

Прийнято — виведення коштів поставлено в чергу (202 Accepted) ​

Сума резервується з вашого балансу, а виплата планується. Опитуйте ендпойнт статусу (або чекайте на вебхук), поки стан не зміниться на completed / failed.

json
{
    "detail": {
        "code": 10000,
        "status": "pending",
        "msg": "Withdrawal request accepted, processing within 5 minutes.",
        "data": {
            "orderId": "EXAMPLEorderId0000000000000000000000000000Aa",
            "amount": 15.0,
            "fee": 1.0,
            "net": 14.0,
            "address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
        }
    }
}

Поля відповіді ​

FieldTypeDescription
detail.codeinteger10000 прийнято
detail.statusstringpending
detail.data.orderIdstringНомер замовлення — URL-безпечний рядок із 43 символів. Використовуйте його для ендпойнта статусу, також він ідентифікує замовлення в корисних навантаженнях вебхуків.
detail.data.amountnumberЗапитана валова сума (TRX)
detail.data.feenumberУтримана комісія (1 або 2 TRX)
detail.data.netnumberСума, яку отримує одержувач (amount − fee)
detail.data.addressstringАдреса призначення

Кінцева точка статусу ​

GET https://netts.io/apiv2/withdraw/status/{orderId}

Заголовки: X-API-KEY (замовлення має належати автентифікованому користувачеві). Значення orderId є URL-безпечним — передавайте його як є, без кодування URL.

Стан замовленняHTTPcodestatus
Завершено (TRX надіслано)20010000completed (з processed_at)
У черзі / надсилається20010001pending
Помилка2005003failed (з error_message)
Не знайдено / не ваше404-1—
json
{
    "detail": {
        "code": 10000,
        "status": "completed",
        "data": {
            "orderId": "EXAMPLEorderId0000000000000000000000000000Aa",
            "amount": 15.0, "fee": 1.0, "net": 14.0,
            "address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "processed_at": "2026-01-01 00:00:00+00:00"
        }
    }
}

Субакаунти ​

Виведення коштів субакаунтом працює точно так само, як і для звичайних користувачів — просто з власним API-ключем субакаунта. Субакаунт викликає цей самий ендпойнт POST /apiv2/withdraw, автентифікуючись власним ключем; кошти списуються з власного балансу цього субакаунта і надсилаються на address, указаний у запиті. Той самий мінімум, та сама комісія (1 TRX), та сама перевірка адреси, той самий процес. Окремого ендпойнта для субакаунтів немає — кожен акаунт, основний чи субкористувач, завжди виводить лише власний баланс за допомогою власного ключа.

Вебхуки ​

Замість опитування налаштуйте вебхук один раз, і Netts надсилатиме підписане POST-сповіщення, коли кожне з ваших виведень коштів перейде в кінцевий стан (completed / failed). Вебхук зберігається для кожного користувача окремо та застосовується до виведень коштів цього акаунта. Якщо вебхук не налаштовано, просто опитуйте ендпойнт статусу.

Налаштування / перегляд / видалення ​

POST   https://netts.io/apiv2/withdraw/webhook      # create or update
GET    https://netts.io/apiv2/withdraw/webhook      # view current config (secret is never returned)
DELETE https://netts.io/apiv2/withdraw/webhook      # unsubscribe

Заголовки: X-API-KEY.

json
// POST body
{
    "callback_url": "https://your-server.example/netts/withdraw-hook",
    "secret": "your_shared_secret_min_8_chars",
    "enabled": true
}
ParameterTypeRequiredDescription
callback_urlstringТакURL-адреса http(s) (≤ 2048 символів), яка приймає POST-запит
secretstringТакСпільний секрет (8…256 символів), що використовується для підпису кожного корисного навантаження
enabledbooleanНіУвімкнення/вимкнення доставки без видалення конфігурації. За замовчуванням true

GET повертає { callback_url, enabled, secret_set, updated_at } — сам секрет ніколи не повертається у відповіді.

Тіло повідомлення доставки ​

Netts надсилає POST-запит на ваш callback_url із заголовком X-Netts-Signature: base64( HMAC-SHA256( secret, raw_body ) ) та таким JSON-тілом:

json
{
    "orderId": "EXAMPLEorderId0000000000000000000000000000Aa",
    "status": "completed",
    "amount": 15.0,
    "fee": 1.0,
    "net": 14.0,
    "address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "processed_at": "2026-01-01 00:00:00+00:00",
    "error_message": null
}
  • status має значення completed або failed (у разі failed заповнюється error_message).

Перевірка підпису ​

Підпис обчислюється над канонічним JSON тіла запиту: ключі відсортовані, пробіли відсутні (separators=(",", ":")). Обчисліть його так само та порівняйте.

python
import hmac, hashlib, base64, json

def verify(raw_body: bytes, signature_header: str, secret: str) -> bool:
    expected = base64.b64encode(
        hmac.new(secret.encode(), raw_body, hashlib.sha256).digest()
    ).decode()
    return hmac.compare_digest(expected, signature_header)

# Flask example: verify against the EXACT bytes received, then parse.
# if verify(request.get_data(), request.headers["X-Netts-Signature"], SECRET): ...

Завжди перевіряйте підпис за необробленими отриманими байтами (raw bytes). Якщо ви повторно серіалізуєте розібраний JSON, відтворіть канонічну форму: json.dumps(payload, ensure_ascii=False, separators=(",",":"), sort_keys=True).

Гарантії доставки ​

  • Дайте відповідь із кодом HTTP 2xx для підтвердження отримання. Будь-яка інша відповідь (або тайм-аут) вважається невдалою спробою.
  • До 3 спроб на замовлення протягом 21-хвилинного вікна з моменту створення замовлення (інтервал повторних спроб ≈ 5 хвилин). Після цього спроби припиняються — перейдіть до ендпойнта статусу.
  • Доставки дедуплікуються: кожне замовлення успішно доставляється щонайбільше один раз.
  • Зробіть ваш обробник ідемпотентним за orderId.

Відповіді з помилками ​

Помилка автентифікації (401) ​

json
{ "detail": { "code": -1, "msg": "Invalid API key or IP not in whitelist" } }

Недостатньо коштів на балансі (403) ​

json
{ "detail": { "code": 1004, "status": "failed", "msg": "Insufficient balance: 2.0 < 15 TRX" } }

Адреса недоступна (403) ​

Виведення коштів на цю адресу призначення не приймається. Замовлення не створюється і нічого не резервується. Використовуйте іншу адресу або зверніться до служби підтримки.

json
{ "detail": { "code": 1006, "status": "failed", "msg": "Withdrawals to this address are not available. Contact support." } }

Перевірка адреси недоступна (503) ​

Наразі не вдалося перевірити адресу призначення. Замовлення не створюється і нічого не резервується. Повторіть спробу незабаром — той самий X-Idempotency-Key можна використати повторно.

json
{ "detail": { "code": 1009, "status": "failed", "msg": "Address check is temporarily unavailable. No request was created. Retry shortly." } }

Наявне незавершене виведення коштів (409) ​

Ви можете мати лише одне незавершене виведення коштів одночасно на власному балансі. Зачекайте, поки поточне не буде оброблено.

json
{ "detail": { "code": 4090, "status": "failed", "msg": "You have a pending withdrawal. Wait until it is processed." } }

Помилка валідації (400) ​

json
{ "detail": { "code": 5004, "status": "failed", "msg": "Minimum withdrawal is 3 TRX" } }

Довідник кодів помилок ​

CodeDescriptionHTTP Status
10000Прийнято (виведення в черзі) / Завершено (ендпойнт статусу)202 / 200
10001Очікує на обробку — у черзі або надсилається (ендпойнт статусу)200
208Дублікат уже прийнятого запиту — кешована відповідь208
-Той самий запит ще обробляється (поки не повторюйте спробу)409
4090У вас уже є виведення коштів в обробці409
-1Недійсний API-ключ / IP не в білому списку, або замовлення не знайдено401 / 404
1004Недостатній баланс403
1006Виведення коштів на цю адресу недоступне403
1009Перевірка адреси тимчасово недоступна — замовлення не створено, повторіть спробу пізніше503
5004Помилка валідації (сума < 3, комісія ≥ суми, невірна адреса, невірний ключ ідемпотентності)400
5003Не вдалося виконати виведення коштів / сервіс недоступний200 (status) / 503
5000Внутрішня помилка сервера500

Ліміти запитів ​

Обмеження діють для кожного API-ключа (заголовок X-API-KEY):

PeriodLimit
1 секунда5 запитів
1 хвилина150 запитів

Перевищено ліміт запитів (429) ​

json
{ "message": "API rate limit exceeded" }

Idempotency ​

Надсилайте необов'язковий заголовок X-Idempotency-Key, щоб випадковий повторний запит не створив друге виведення коштів — повертається початкова відповідь із кодом HTTP 208. Якщо ви не надсилаєте цей заголовок, сервер генерує ключ автоматично на основі параметрів вашого запиту протягом короткого проміжку часу. Цей ключ також є вашим orderId.

Як сформувати ключ ​

Ключ являє собою base64url( HMAC-SHA256( secret, message ) ) з видаленим заповненням = — рядок із 43 символів, безпечний для URL, де:

  • secret = ваш API-ключ (X-API-KEY);
  • message = поля, об'єднані через : — address:amount:nonce.

nonce — це будь-яке значення, яке є стабільним між повторними спробами того самого логічного замовлення, але різним для різних замовлень — наприклад, UUID, який ви зберігаєте для цього замовлення, або округлена часова мітка. Генеруйте ключ один раз на замовлення та надсилайте точно те саме значення під час кожної повторної спроби.

python
import hmac, hashlib, base64, time

def make_idempotency_key(api_key, address, amount, nonce=None):
    if nonce is None:
        nonce = str(int(time.time() // 2))   # 2-second bucket; or your own order UUID
    message = f"{address}:{amount}:{nonce}"
    digest = hmac.new(api_key.encode(), message.encode(), hashlib.sha256).digest()
    return base64.urlsafe_b64encode(digest).decode().rstrip("=")  # 43-char URL-safe

Валідація. Переданий X-Idempotency-Key має містити від 16 до 64 символів із набору A–Z a–z 0–9 + / = _ -. Некоректний або занадто довгий ключ відхиляється з кодом HTTP 400 (code 5004).

Код статусуЗначення
202Прийнято (перший запит)
208Вже прийнято — повернуто кешовану відповідь (без повторного виведення)
409Той самий запит наразі обробляється — зачекайте, поки не повторюйте запит

Повторна спроба після помилки. Кешуються лише прийняті результати. Якщо попередня спроба завершилася помилкою (наприклад, недостатньо коштів, помилка валідації), ви можете безпечно повторити спробу з тим самим ключем — запит буде виконано знову, а не повернено стару помилку. Поки спроба ще триває, ви отримуватимете 409; зачекайте та повторіть спробу.

Примітки ​

  • Асинхронна виплата. Відповідь завжди є підтвердженням зі статусом pending; TRX надсилаються фоновим процесом бекенда, як правило, протягом ~5 хвилин. Для отримання результату використовуйте ендпойнт статусу або вебхук.
  • Баланс резервується миттєво під час прийняття замовлення (а не тоді, коли TRX остаточно надсилаються).
  • Мінімум: 3 TRX. Комісія: 1 TRX (або 2 TRX з параметром sub_and_robot_out), утримується з валової суми amount; одержувач отримує net = amount − fee.
  • Лише одне незавершене виведення одночасно на вашому власному балансі (code 4090).
  • Перевірка адреси призначення. Кожен запит перевіряється перед прийняттям замовлення: code 1006 (HTTP 403) — виведення на цю адресу недоступні; code 1009 (HTTP 503) — перевірка тимчасово недоступна, повторіть спробу незабаром. В обох випадках замовлення не створюється.
  • Субакаунти виводять кошти так само, як і звичайні користувачі — той самий ендпойнт POST /apiv2/withdraw, ті самі правила, але з автентифікацією власним API-ключем субакаунта. Субакаунт виводить власний баланс на вказаний ним address. Окремого ендпойнта для субакаунтів не існує.
  • orderId — це безпечний для URL рядок із 43 символів; передавайте його як є в URL статусу (кодування не потрібне).
  • Вебхуки: налаштовуються для кожного користувача, підписуються за допомогою X-Netts-Signature; до 3 спроб протягом 21-хвилинного вікна. Налаштування здійснюється через POST /apiv2/withdraw/webhook.