01 / Overview

API Reference

DESTROY.WTF is a crypto payment gateway. You create an order over a single API call; we generate a fresh deposit address, watch the chain for the customer's payment, and once it confirms we forward the funds to the payout address you configure — minus a flat fee. One REST API, twelve assets, JSON everywhere.

12
Assets
3.0%
Flat fee
$0.50–$2K
Per order
2 h
Order expiry

Base URL

base
https://destroy.wtf
How custody worksDESTROY.WTF is custodial in transit. The customer pays an address we generate and hold the key for — not your wallet directly. When the payment confirms, we forward it on-chain to the payout address you set, and take the fee. Funds are never parked on a balance or a payout schedule; the forward is automatic.
02 / Authentication

Authentication

Generate an API key (a UUID) from your dashboard under API Keys. Send it in the JSON request body as api_key on every authenticated call.

Body only — not the query stringThe API key must go in the POST JSON body. Passing api_key as a URL query parameter is rejected, and there is no X-API-Key header. Keep the key server-side; never ship it in browser code.

Order tokens (customer side)

Creating an order also returns an update_token (embedded in the payment_gateway_url as #token=…). It grants read access to that one order without the API key, and is what the hosted payment page uses. Send it in the x-update-token header (or an update_token body field) on status / update.

03 / Payment flow

Payment flow

The whole integration is: create an order, show the customer the address, and watch the status (by webhook or by polling).

1 — Create
POST /api/order/create returns an order_id, a fresh crypto_address, the exact crypto_amount, and a hosted payment_gateway_url.
2 — Pay
Show the address and amount, or redirect the customer to payment_gateway_url. They send crypto to that address before the 2-hour expiry.
3 — Detect
We detect the incoming payment. It must cover at least 99% of the expected amount; anything less holds the order at PARTIAL PAYMENT.
4 — Confirm
We wait for on-chain confirmations (e.g. BTC 2, LTC 3, BCH 3, DOGE 20). The order sits at CONFIRMING until then.
5 — Settle
On COMPLETED we forward the funds to your payout address (minus the fee) and fire an order.status_changed webhook.
Detecting completionRegister a webhook to be pushed each status change, or poll /api/order/status. Poll at a sane interval — the API is rate-limited (see rate limits).
04 / Endpoints

Create order

POST/api/order/createauth: api_key

Creates an order and returns a deposit address the customer pays to.

Request body
FieldTypeDescription
api_key requiredstringYour API key (UUID).
amount_usd requirednumberInvoice amount in USD. Between 0.50 and 2000.
crypto_type optionalstringAsset symbol (see assets). Defaults to LTC.
return_url optionalstringWhere the hosted page sends the customer after payment.
Response
FieldTypeDescription
order_idstringUnique order identifier.
crypto_addressstringThe address the customer pays. Freshly generated per order.
crypto_amountstringExact amount to pay, in the asset.
crypto_pricenumberUSD price of the asset used to compute the amount.
payment_gateway_urlstringHosted payment page (includes the #token= order token).
created_at / expire_timestringCreation and expiry timestamps (expiry is +2 h).
destination_tagnumberXRP only — must accompany the payment.
asset · network · decimals · contractmixedUSDTERC20 / USDTTRC20 only — token metadata.
request
curl -X POST https://destroy.wtf/api/order/create \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "b3f1…UUID",
    "amount_usd": 149.99,
    "crypto_type": "BTC"
  }'
200
{
  "success": true,
  "order_id": "ord_10f83a9c…",
  "crypto_type": "BTC",
  "amount_usd": 149.99,
  "crypto_amount": "0.00234375",
  "crypto_address": "bc1qxy2…0wlh",
  "payment_gateway_url": "https://…/pay/ord_…#token=…",
  "expire_time": "2026-01-01T12:00:00Z"
}

Order status

GETPOST/api/order/statusauth: optional

Returns the current state of an order. Public callers get the core status fields; add your api_key (body) or the order's update_token (x-update-token header) to also receive the address and settlement detail. On GET, the API key may not be in the query string — use POST when sending it.

Request
FieldTypeDescription
order_id requiredstringThe order to look up.
api_key optionalstringPOST body only. Unlocks the authenticated fields.
update_token optionalstringPer-order token, via the x-update-token header.
Response — always
FieldTypeDescription
statusstringSee order statuses.
paidboolWhether a sufficient payment has been detected.
paid_usdnumberUSD value received so far.
confirmationsnumberOn-chain confirmations seen.
crypto_amount · crypto_price · amount_usdmixedThe expected amount, price, and USD total.
created_at · expire_time · last_checkedstringTimestamps.
Response — authenticated only
FieldTypeDescription
crypto_addressstringThe deposit address.
tx_id · merchant_txidstringIncoming payment tx, and the payout tx to your wallet.
withdrawnboolWhether the payout to your address has been sent.
merchant_amount_crypto · operator_amount_cryptonumberYour settled amount and the fee, in-asset.
fee_percentage_applied · network_fee_usdnumberFee rate applied and any network cost.

Update order

POST/api/order/updateauth: api_key or update_token

Switches an unpaid order to a different asset — generates a new address and re-prices at the current rate. Rejected once any payment has been received.

Request body
FieldTypeDescription
order_id requiredstringThe order to change.
crypto_type requiredstringThe new asset.
api_key / update_tokenstringOne is required.

Returns the new crypto_type, crypto_amount, crypto_price, and crypto_address.

Cancel order

POST/api/order/cancelauth: api_key

Cancels an unpaid order (POST only). Rejected if any payment has been received (paid_usd > 0). Sets the status to CANCELED.

Request body
FieldTypeDescription
order_id requiredstringThe order to cancel.
api_key requiredstringYour API key.

Supported assets

GETPOST/api/cryptoauth: optional

Lists supported assets with live USD prices and recent change windows. With an api_key (POST), the list is filtered to the assets that key has enabled. As with status, the key may not be in the query string.

The twelve symbols: BTC LTC ETH SOL BCH BNB DOGE TRX XRP XMR USDTERC20 USDTTRC20. USDT is split by network — ERC-20 on Ethereum and TRC-20 on Tron — and each is its own symbol.

200
{
  "success": true,
  "supported": { "BTC": 64012.0, "ETH": 3401.2, "USDTTRC20": 1.0 },
  "changes": { "BTC": { "24h": { "pct": 1.42 } } }
}

Limits

GET/api/limitsauth: none

Returns min_order_amount_usd, max_order_amount_usd, and the supported_cryptos list — handy for validating input before you create an order.

05 / Reference

Order statuses

PENDING
Created, awaiting payment.
PARTIAL PAYMENT
A payment was received but covers less than 99% of the expected amount.
CONFIRMING
Full payment detected; waiting for the required on-chain confirmations.
COMPLETED
Confirmed. Funds are forwarded to your payout address and a webhook fires.
CANCELED
Cancelled via the API/admin, or auto-cancelled when a PENDING order passes its 2-hour expiry (reason: expired). There is no separate EXPIRED status.
MANUALLY COMPLETED
Marked paid by an operator — used to reconcile an out-of-band or edge-case payment.
Confirmations requiredBTC 2 · LTC 3 · BCH 3 · DOGE 20, with per-chain thresholds for the account-based assets. An order stays CONFIRMING until its threshold is met.

Fees & settlement

DESTROY.WTF deducts a flat 3.0% from the amount received and forwards the remainder to your configured payout address; the fee goes to the operator wallet. Your key can be set to a custom rate. Settlement is automatic on COMPLETED — there is no payout schedule and no balance to withdraw.

What lands in your wallet
LegAmount
You receivereceived − fee (− network cost on token forwards)
Fee3.0% of received, to the operator wallet
Edge casesBTC orders of $5 or less are forwarded in full (no split). For USDT (ERC-20 / TRC-20), the on-chain gas cost of the forward is added to the fee leg, so it comes out of the deducted amount rather than being billed separately.

Webhooks

Register HTTPS endpoints in your dashboard under Webhooks and choose the events to receive. Each delivery is a JSON envelope, signed with a per-endpoint secret. Failed deliveries retry on a backoff, and an endpoint that fails repeatedly auto-disables until you re-enable it.

Events

order.created, order.status_changed, order.updated, plus payout-review signals (order.payout_review, order.payout_review_cleared, order.payout_indeterminate, order.payout_stuck).

delivery body
{
  "id": "<uuid>",
  "type": "order.status_changed",
  "created": "2026-01-01T12:00:00Z",
  "data": {
    "order_id": "ord_10f83a9c…",
    "status": "COMPLETED",
    "old_status": "CONFIRMING",
    "amount_usd": 149.99,
    "paid_usd": 149.99,
    "crypto_type": "BTC"
  }
}
headers
X-Gateway-Event: order.status_changed
X-Gateway-Event-Id: <uuid>
X-Gateway-Timestamp: 1735732800
X-Gateway-Signature: sha256=<hex>

Verifying the signature

Compute HMAC-SHA256 over "{timestamp}.{raw_body}", using the endpoint secret hex-decoded to bytes as the key, and compare to the hex in X-Gateway-Signature. Reject anything whose timestamp is older than 300 seconds.

python
import hmac, hashlib

def verify(secret_hex, timestamp, raw_body, signature):
    mac = hmac.new(bytes.fromhex(secret_hex),
                   f"{timestamp}.{raw_body}".encode(), hashlib.sha256)
    return hmac.compare_digest("sha256=" + mac.hexdigest(), signature)

Errors & rate limits

Errors return { "success": false, "error": "<message>" }. Most failures still use HTTP 200 with success: false — always branch on success, not the status code. Rate-limited requests return 429.

5/s
Unauthenticated
15/s
With API key
30 s
Block on breach

Exceeding the rate triggers a temporary 30-second block and HTTP 429. The client IP is read from CF-Connecting-IP when present.

Examples

Create an order, then poll until it settles.

python
import requests, time

BASE = "https://destroy.wtf"
KEY  = "b3f1…UUID"

# 1. create
r = requests.post(f"{BASE}/api/order/create", json={
    "api_key": KEY, "amount_usd": 149.99, "crypto_type": "BTC",
}).json()
order_id = r["order_id"]
print("Pay", r["crypto_amount"], "to", r["crypto_address"])

# 2. poll (or register a webhook instead)
while True:
    s = requests.post(f"{BASE}/api/order/status",
                      json={"api_key": KEY, "order_id": order_id}).json()
    if s["status"] in ("COMPLETED", "CANCELED"): break
    time.sleep(10)