> ## Documentation Index
> Fetch the complete documentation index at: https://oblodai.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# POST /v1/payout

Создать выплату на внешний адрес. Списывает баланс на `amount`; получателю приходит `amount` минус
сетевая комиссия (если она переложена на получателя — см. [`fee-config`](/reference/payout-fee-config)).

**URL:** `https://api.oblodai.com/v1/payout` · **Аутентификация:** обязательна · **Идемпотентность:** заголовок `Idempotency-Key` и/или `order_id` (для выплат `order_id` обязателен).

<Note>
  Примеры используют хелпер `call()` и переменные `$SECRET`/`$PUBLIC_ID` — их определение см. в
  [Как подписать запрос](/guides/signing-requests). Проще не писать подпись руками, а взять
  [SDK](/sdk/overview).
</Note>

<Warning>
  **Выплаты по API‑ключу авто‑одобряются** и уходят сразу — без белых списков и периодов выдержки.
  Ответственность за адрес назначения на вашей стороне.
</Warning>

### Заголовки

<ParamField header="Idempotency-Key">
  Любое уникальное значение (≤255 символов), одинаковое во всех повторах одной выплаты. Повтор вернёт тот же ответ и заголовок `Idempotent-Replayed: true`. Работает вместе с `order_id`. → [Идемпотентность](/reference/basics-idempotency)
</ParamField>

***

## Параметры запроса

<ParamField body="amount" type="string" required>
  Сумма выплаты в `currency`.
</ParamField>

<ParamField body="currency" type="string" required>
  Код валюты (например `USDT`).
</ParamField>

<ParamField body="order_id" type="string" required>
  Ваш номер выплаты; **ключ идемпотентности**.
</ParamField>

<ParamField body="address" type="string" required>
  Адрес получателя.
</ParamField>

<ParamField body="network" type="string">
  Сеть (`tron`, `ethereum`, …). Обязательна для монет с несколькими сетями.
</ParamField>

<ParamField body="is_subtract" type="bool">
  Кто платит сетевую комиссию. `true` — комиссия **сверх** суммы: с баланса списывается `amount + fee`, получатель получает ровно `amount`. `false` — комиссия **из** суммы: списывается `amount`, получатель получает `amount − fee`. Не передано — действует [fee-config](/reference/payout-fee-config) проекта (иначе дефолт шлюза). Семантика совпадает с предрасчётом `/v1/payout/calculate`.
</ParamField>

<ParamField body="memo" type="string">
  Тег/мемо назначения (TON Jetton). Максимум 120 символов.
</ParamField>

<ParamField body="url_callback" type="string">
  Свой URL вебхука для этой выплаты (SSRF‑проверка).
</ParamField>

<ParamField body="from_currency" type="string">
  Профинансировать выплату конвертацией баланса. Поддерживается только `USDT` → `currency`.
</ParamField>

<ParamField body="source" type="string" default="api">
  Метка происхождения: `api` (по умолчанию) или `manual`.
</ParamField>

**По умолчанию сетевую комиссию выплаты несёт получатель.** Кто её платит, определяется настройкой
проекта [fee-config](/reference/payout-fee-config) (общий дефолт — комиссию несёт получатель), а **не** полем
запроса.

<Note>
  **`is_subtract` учитывается и выплатой, и предрасчётом.** Переданный в `/v1/payout` `is_subtract`
  применяется ровно так же, как его моделирует
  [`/v1/payout/calculate`](/reference/payout-calculate), поэтому превью совпадает с реальной
  выплатой при одинаковом значении поля. Если поле не передавать, плательщик комиссии берётся из
  [fee‑config](/reference/payout-fee-config) проекта.
</Note>

***

## Пример запроса

<CodeGroup>
  ```bash cURL wrap theme={null}
  BODY='{"amount":"25","currency":"USDT","network":"tron","address":"TXY...","order_id":"payout-1"}'
  TS=$(date +%s)
  SIG=$(printf '%s\n%s\n%s\n%s' "$TS" 'POST' '/v1/payout' "$BODY" \
    | openssl dgst -sha256 -hmac "$SECRET" -hex | sed 's/^.* //')
  curl -s https://api.oblodai.com/v1/payout \
    -X POST -H 'Content-Type: application/json' \
    -H "X-Public-Id: $PUBLIC_ID" -H "X-Timestamp: $TS" -H "X-Signature: $SIG" \
    -d "$BODY"
  ```

  ```python Python theme={null}
  call("/v1/payout", {
      "amount": "25", "currency": "USDT", "network": "tron",
      "address": "TXY...", "order_id": "payout-1",
  })
  ```

  ```js Node.js theme={null}
  await call("/v1/payout", {
    amount: "25", currency: "USDT", network: "tron",
    address: "TXY...", order_id: "payout-1",
  });
  ```
</CodeGroup>

***

## Пример ответа

```json theme={null}
{
  "state": 0,
  "result": {
    "uuid": "0c1f...e9",
    "order_id": "payout-1",
    "amount": "25",
    "currency": "USDT",
    "network": "tron",
    "address": "TXY...",
    "txid": "",
    "status": "process",
    "is_final": false,
    "approval_required": false,
    "source": "api",
    "created_at": "2026-07-10T12:00:00Z",
    "updated_at": "2026-07-10T12:00:00Z"
  }
}
```

При `from_currency` в `result` добавляется объект `convert`:

```json theme={null}
{ "from_currency": "USDT", "to_currency": "TRX", "from_amount": "40.12", "rate": "0.062" }
```

Полное описание полей и статусов — [Объект выплаты](/reference/payout-object).

***

## Коды ошибок

| Код                                    | Значение                                   |
| -------------------------------------- | ------------------------------------------ |
| `400 payout.unknown_currency`          | Неизвестная валюта.                        |
| `400 payout.bad_amount`                | Некорректная сумма.                        |
| `400 payout.order_id_required`         | Не передан `order_id`.                     |
| `400 payout.destination_internal`      | Адрес принадлежит шлюзу (self‑dealing).    |
| `400 payout.from_currency_unsupported` | Неподдерживаемая конвертация.              |
| `400 payout.memo_too_long`             | `memo` длиннее 120 символов.               |
| `400 payout.bad_url_callback`          | Некорректный `url_callback` (SSRF).        |
| `400 payout.no_destination`            | Не передан адрес назначения.               |
| `400 payout.asset_mismatch`            | Валюта/сеть не соответствуют друг другу.   |
| `400/403`                              | Валидация адреса под сеть / комплаенс.     |
| `409 payout.frozen`                    | Выплаты заморожены (сработал kill‑switch). |
| `409 payout.insufficient_funds`        | Недостаточно доступного баланса.           |
| `409 payout.funds_maturing`            | Средства ещё дозревают (maturity‑холд).    |

***

## Нюансы

* **Идемпотентность по `(мерчант, order_id)`.** Повтор вернёт уже созданную выплату.
* **Выплата на адрес самого шлюза запрещена** (`payout.destination_internal`).
* **`from_currency`** конвертирует баланс до резервирования и идемпотентна по `order_id`. Поддерживается
  только `USDT` → `currency`.
* Выплаты по API‑ключу авто‑одобряются (`approval_required: false`) — шаг
  [`/approve`](/reference/payout-approve) не нужен.
* Перед созданием можно оценить комиссию и итоговые суммы через
  [`POST /v1/payout/calculate`](/reference/payout-calculate).
* **Много выплат?** → [`POST /v1/payout/batch`](/reference/payout-batch) — до 5000 одним запросом.

***

## Связанные страницы

<CardGroup cols={2}>
  <Card title="Объект выплаты" href="/reference/payout-object" icon="arrow-right" horizontal />

  <Card title="POST /v1/payout/calculate" href="/reference/payout-calculate" icon="arrow-right" horizontal />

  <Card title="POST /v1/payout/batch" href="/reference/payout-batch" icon="arrow-right" horizontal>
    Много выплат сразу — до 5000 одним запросом.
  </Card>

  <Card title="POST /v1/payout/mass (легаси, до 100)" href="/reference/payout-mass" icon="arrow-right" horizontal />

  <Card title="Кто платит сетевую комиссию" href="/reference/payout-fee-config" icon="arrow-right" horizontal />

  <Card title="Первая выплата" href="/guides/first-payout" icon="arrow-right" horizontal />
</CardGroup>
