POST /bridge/withdrawals
Trigger a bridge withdrawal
Trigger a bridge withdrawal.
operationId: createBridgeWithdrawal
Declared server:
https://api.testnet.nexus.xyz/v1. See Networks.
Not reachable through CCXT. Nexus-specific Halliday-fronted payout. CCXT's withdraw method models a venue paying a user-supplied address from its own custody, not a per-withdrawal one-time-wallet quote settled by a third party.
Authentication: hmacAuth.
Trigger a withdrawal to a Halliday one-time wallet (OTW). The server quotes an OTW from Halliday, debits the account's USDX on the Exchange, and releases the funds on-chain to that OTW; Halliday then settles to the user in the asset and destination they chose.
The request carries only an amount (USDX base units). There is no destination_address -- the destination is the OTW Halliday quotes, never a user-supplied address.
The write path runs synchronously and the response carries the resulting record with its terminal status. The Idempotency-Key header is required and makes the call safe to retry: the same key returns the original withdrawal without moving money again. A replay returns the stored record as 200 even when it is terminal failed, so branch on the returned status, not on the HTTP code. The exception is a failure before any debit was applied (the debit was refused with a 400 or 503, or the payout quote failed): nothing moved, so the key is released and a retry with the same key and amount runs the withdrawal again, which is what a caller wants once it has fixed the cause. Every other failed (a debit or release whose outcome is unknown, or a release that failed and was reversed) keeps replaying.
States advance pending -> quoted -> broadcast -> confirmed | failed. On failed, the Exchange debit is reversed only when the release is provably unpaid (bad config, a terminally-rejected broadcast, or a mined-and-reverted tx); when the release was broadcast and its outcome is unknown the debit is left in place for reconciliation, so failed does not by itself mean the balance was restored -- read failure_reason.
The debit can also be rejected synchronously: a 400 when the account has insufficient balance, or an open position or open orders that must be closed first; a 503 when the Exchange is not currently accepting withdrawals. Neither applies a debit.
Agent keys cannot withdraw. An agent-signed request is refused with 403 (code AGENT_CANNOT_WITHDRAW) before any other validation; see agentAuth.
HMAC API key authentication. Send three headers:
X-API-Key: your key ID (e.g.nx_a1b2c3...)X-Timestamp: current time in unix millisecondsX-Signature:hex(hmac_sha256(secret, timestamp + "\n" + METHOD + "\n" + path + "\n" + query + "\n" + sha256_hex(body)))
Timestamp must be within 30 seconds of server time.
The key is network-scoped; the signature is not. The canonical string above has no network component, so the same signed request is byte-identical on every host. What stops a testnet key from authenticating against mainnet is that the key does not exist in that host's key store — sign only for the host that minted the key, and never replay a signed payload against another network. Presented to the wrong host, a key is refused with the same opaque 401 as an unknown key and must not be retried there. See “API keys are bound to one network” in the API description.
Client-generated key that makes the withdrawal idempotent. Retrying with the same key returns the original withdrawal without triggering a second payout.
Trigger a withdrawal. The only field is the amount; there is deliberately no destination_address -- the destination is the Halliday OTW quoted for this withdrawal (ENG-4625).
Withdrawal amount in USDX base units (a positive integer, 6 decimals). E.g. "10000000" is 10 USDX.
Idempotent replay: the withdrawal this Idempotency-Key already created. May be terminal failed, so branch on its status, not the HTTP code. A withdrawal that failed before any debit was applied does not replay: its key is released and the retry runs again.
A Halliday withdrawal (ENG-4625). Every payout pays a Halliday one-time wallet (OTW), quoted per withdrawal; Halliday then settles to the user asynchronously in the asset and destination the user chose. There is no user-supplied payout address and no route that skips Halliday.
Opaque withdrawal id (wdl_<hex>), minted from a CSPRNG. Account-scoped: a guessed id from another account 404s.
0x-prefixed Nexus account being debited.
Withdrawal amount in USDX base units (integer, 6 decimals), as the request supplied it.
Lifecycle: pending -> quoted -> broadcast -> confirmed | failed. quoted once Halliday has returned an OTW, broadcast once the on-chain release is sent, confirmed once it is mined (Halliday then settles to the user). failed is terminal. On failed the Exchange debit is reversed only when the release is provably unpaid; an unknown-outcome release (broadcast, receipt unread) stays debited pending reconciliation, so failed does not by itself mean the balance was restored -- read failure_reason.
0x-prefixed Halliday OTW this withdrawal pays; null until quoted. Never a user-supplied address.
0x-prefixed source-chain tx hash of the release; null until confirmed. An unknown-outcome failed release records its hash in failure_reason instead, since this field is written only on confirmation.
Confirmations observed for the release tx; null until confirmed.
Operator-facing reason; present only when status is failed.
Unix epoch timestamp in milliseconds.
Unix epoch timestamp in milliseconds.
The withdrawal was triggered.
The request was invalid (e.g. unsupported chain or asset, amount below minimum).
Authentication failed. All 401 responses return the same opaque body to prevent information leakage. A credential minted on a different network is one of the causes it hides — by design, so that a key id cannot be probed for existence on another network. Do not retry it against another host.
Refused by a jurisdiction control. Permanent for the caller's origin — do not retry. Branch on the code (identical to the x-nexus-block-reason header): US_RESTRICTED for the US write restriction, GEO_UNRESOLVED when the origin could not be resolved and the write failed closed, or RESTRICTED_JURISDICTION for the sanctions list. Reads are never refused by the write restriction. See “Jurisdiction restrictions” in the API description.
The Idempotency-Key was already used with a different amount. The key is bound to its first request, so a mismatched retry is rejected rather than silently replaying the original withdrawal.
Rate limit exceeded. Retryable — honour retry-after and back off; this is what separates a 429 from the permanent 403 jurisdiction refusals. Branch on the body's code, which is always RATE_LIMIT_EXCEEDED, and on bucket to learn WHICH budget bottlenecked — the buckets are independent, so a caller at its read ceiling can still submit orders and should not back off the whole client. Do not parse message: it is a diagnostic whose wording is not stable. Requests are charged by weight, so exhausting a budget takes fewer heavy calls than x-ratelimit-limit suggests. See “Rate limits” in the API description.
A downstream step failed (Halliday quote, the Exchange debit, or the on-chain release). On a release failure the debit is reversed only when the failure is provably money-safe; an unknown on-chain outcome leaves the account debited pending reconciliation.
Withdrawals are not available: either not enabled on this deployment (the money path is not provisioned), or the Exchange is not currently accepting withdrawals (withdrawals disabled, or an uncovered system loss outstanding). Transient — no debit was applied; retry once the condition clears.
POST /v1/bridge/withdrawals HTTP/1.1
Host: api.testnet.nexus.xyz
X-API-Key: YOUR_API_KEY
Idempotency-Key: text
Content-Type: application/json
Accept: */*
Content-Length: 17
{
"amount": "text"
}{
"id": "text",
"account_id": "text",
"amount": "text",
"status": "pending",
"destination": "text",
"tx_hash": "text",
"confirmations": 1,
"failure_reason": "text",
"created_at": 1,
"updated_at": 1
}Test it cannot sign this request. X-Signature is an HMAC computed per call: see Authentication, or use an SDK.
API version 0.9.122
Last updated

