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.
Base URL
https://destroy.wtf
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.
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.
Payment flow
The whole integration is: create an order, show the customer the address, and watch the status (by webhook or by polling).
POST /api/order/create returns an order_id, a fresh crypto_address, the exact crypto_amount, and a hosted payment_gateway_url.payment_gateway_url. They send crypto to that address before the 2-hour expiry.PARTIAL PAYMENT.CONFIRMING until then.COMPLETED we forward the funds to your payout address (minus the fee) and fire an order.status_changed webhook./api/order/status. Poll at a sane interval — the API is rate-limited (see rate limits).Create order
Creates an order and returns a deposit address the customer pays to.
| Field | Type | Description |
|---|---|---|
| api_key required | string | Your API key (UUID). |
| amount_usd required | number | Invoice amount in USD. Between 0.50 and 2000. |
| crypto_type optional | string | Asset symbol (see assets). Defaults to LTC. |
| return_url optional | string | Where the hosted page sends the customer after payment. |
| Field | Type | Description |
|---|---|---|
| order_id | string | Unique order identifier. |
| crypto_address | string | The address the customer pays. Freshly generated per order. |
| crypto_amount | string | Exact amount to pay, in the asset. |
| crypto_price | number | USD price of the asset used to compute the amount. |
| payment_gateway_url | string | Hosted payment page (includes the #token= order token). |
| created_at / expire_time | string | Creation and expiry timestamps (expiry is +2 h). |
| destination_tag | number | XRP only — must accompany the payment. |
| asset · network · decimals · contract | mixed | USDTERC20 / USDTTRC20 only — token metadata. |
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" }'
{
"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
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.
| Field | Type | Description |
|---|---|---|
| order_id required | string | The order to look up. |
| api_key optional | string | POST body only. Unlocks the authenticated fields. |
| update_token optional | string | Per-order token, via the x-update-token header. |
| Field | Type | Description |
|---|---|---|
| status | string | See order statuses. |
| paid | bool | Whether a sufficient payment has been detected. |
| paid_usd | number | USD value received so far. |
| confirmations | number | On-chain confirmations seen. |
| crypto_amount · crypto_price · amount_usd | mixed | The expected amount, price, and USD total. |
| created_at · expire_time · last_checked | string | Timestamps. |
| Field | Type | Description |
|---|---|---|
| crypto_address | string | The deposit address. |
| tx_id · merchant_txid | string | Incoming payment tx, and the payout tx to your wallet. |
| withdrawn | bool | Whether the payout to your address has been sent. |
| merchant_amount_crypto · operator_amount_crypto | number | Your settled amount and the fee, in-asset. |
| fee_percentage_applied · network_fee_usd | number | Fee rate applied and any network cost. |
Update order
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.
| Field | Type | Description |
|---|---|---|
| order_id required | string | The order to change. |
| crypto_type required | string | The new asset. |
| api_key / update_token | string | One is required. |
Returns the new crypto_type, crypto_amount, crypto_price, and crypto_address.
Cancel order
Cancels an unpaid order (POST only). Rejected if any payment has been received (paid_usd > 0). Sets the status to CANCELED.
| Field | Type | Description |
|---|---|---|
| order_id required | string | The order to cancel. |
| api_key required | string | Your API key. |
Supported assets
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.
{
"success": true,
"supported": { "BTC": 64012.0, "ETH": 3401.2, "USDTTRC20": 1.0 },
"changes": { "BTC": { "24h": { "pct": 1.42 } } }
}Limits
Returns min_order_amount_usd, max_order_amount_usd, and the supported_cryptos list — handy for validating input before you create an order.
Order statuses
PENDING order passes its 2-hour expiry (reason: expired). There is no separate EXPIRED status.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.
| Leg | Amount |
|---|---|
| You receive | received − fee (− network cost on token forwards) |
| Fee | 3.0% of received, to the operator wallet |
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).
{
"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"
}
}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.
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.
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.
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)