POST /transfers
Transfer USDX to another ordinary account
Transfer USDX to another ordinary account.
operationId: createOrdinaryTransfer
Declared server:
https://api.testnet.nexus.xyz/v1. See Networks.
Not reachable through CCXT. Ordinary cross-owner payments use a recoverable owner signature and enrollment. CCXT transfer moves funds between balances of the same owner; no CCXT custody/signing adapter is shipped for this operation.
Authentication: ownerSignature.
Atomically debit the source and credit the destination, conserving venue USDX. Both accounts must first enroll by proving their own keys. Distinct ordinary accounts only; no system accounts, agents, keyless subaccounts or vaults. Source must be flat with no reservations or pending funding. Transfers honor existing outflow controls; an already-issued gateway permit may finish within five seconds of a freeze. A 200 receipt is returned only after both cash legs and the ledger posting are durable. Retry with a fresh owner nonce and the same client_transfer_id and identical economic intent to recover the same receipt without another debit. Changing that intent under an existing id returns 409. Receipt history survives snapshot/WAL recovery; the first release retains up to 100000 venue receipts without evicting idempotency keys, then refuses new payments. Both balance events include the same transfer_id.
Owner consent is an EIP-712 typed-data signature by the account's own key: recoverable secp256k1 in X-Signature (65-byte hex r || s || v; low-S, v 0/1 or 27/28). Domain {name: "Nexus Exchange", version: "1", chainId: 20056}, no verifyingContract, the same domain POST /withdrawals signs under. Each operation signs its own struct, named below; X-Timestamp is its timestampMs and must be within 30 seconds of server time, and on the two writes X-Nonce is its nonce. Every string field is signed exactly as sent. Both root and /api/v1 paths sign the same struct. The deployment domain is a struct field, sent in the body for POST and in the query for GET. HMAC/API-key, bearer-only and agent authority cannot authorize these operations. The server sets Cache-Control: no-store. Signed struct: OrdinaryTransfer(address source,address destination,string asset,string amount,string clientTransferId,string domain,uint64 timestampMs,uint64 nonce), each field from the body; amount is the decimal string exactly as sent, not a converted integer.
Recoverable secp256k1 owner signature over an EIP-712 typed-data struct, one per operation. This is not an HMAC API key or an agent signature. See each ordinary transfer operation for its struct.
Unix milliseconds, the timestampMs field of the signed struct; within 30 seconds of server time.
^[0-9]+$Unsigned 64-bit owner nonce, the nonce field of the signed struct. The account has one nonce window across POST /transfers, POST /transfers/enroll and POST /withdrawals, so use what POST /withdrawals advises: the current Unix timestamp in milliseconds. It is consumed durably even if later settlement fails; sign a fresh unused nonce when retrying the same client transfer id. The server keeps the 100 highest nonces the account has spent and refuses any it still holds, so up to 100 signed requests may be in flight and arrive in any order; once 100 are held, anything at or below the lowest is refused too, so a counter starting at 1 is refused once the account has spent 100 timestamp nonces. Reads carry no nonce.
^[0-9]+$^(0x)?[0-9a-fA-F]{40}$^(0x)?[0-9a-fA-F]{40}$Positive USDX, at most six fractional digits and 18446744073709.551615. No rounding, signs, exponent or whitespace.
^[0-9]+(\.[0-9]{1,6})?$Economic id scoped to the source. Never replace this id after an ambiguous response.
^[A-Za-z0-9_-]+$Deployment domain configured by the operator, for example prd-testnet. Signed inside the body.
^[A-Za-z0-9_-]+$Committed result or authoritative read.
^[1-9][0-9]*$null when this side of the transfer is not recorded yet. null only on reads served from Accounts' projection; the Engine and the POST response always state it.
^(0x)?[0-9a-fA-F]{40}$null when this side of the transfer is not recorded yet. null only on reads served from Accounts' projection; the Engine and the POST response always state it.
^(0x)?[0-9a-fA-F]{40}$^[0-9]+\.[0-9]{6}$The projection holds no client transfer ids. null only on reads served from Accounts' projection; the Engine and the POST response always state it.
^[A-Za-z0-9_-]+$The projection does not record the deployment domain. null only on reads served from Accounts' projection; the Engine and the POST response always state it.
^[A-Za-z0-9_-]+$Unix milliseconds. On reads served from Accounts' projection this is an approximation of the commit time.
INVALID_TRANSFER_REQUEST for invalid intent/domain/precision; TRANSFER_RISK_REJECTED for insufficient cash, open exposure, liquidation or system-loss constraints.
TRANSFER_SIGNATURE_REQUIRED: missing, forged, stale, agent or replayed POST owner proof. No additional payment was created.
TRANSFER_ACCOUNT_INELIGIBLE or TRANSFER_OUTFLOW_BLOCKED: ordinary enrollment or live source controls do not permit this request.
TRANSFER_ID_CONFLICT: source/client_transfer_id already identifies different economic intent.
TRANSFER_OUTCOME_UNKNOWN: upstream response was lost or unavailable. Query the original client transfer id before retrying; never invent a replacement payment id.
TRANSFERS_UNAVAILABLE: disabled/unconfigured service, unavailable durable writer, invalid/expired control permit, pending committed fills or receipt capacity reached. No successful outcome is implied.
POST /v1/transfers HTTP/1.1
Host: api.testnet.nexus.xyz
X-Signature: YOUR_API_KEY
X-Timestamp: text
X-Nonce: text
Content-Type: application/json
Accept: */*
Content-Length: 113
{
"source": "text",
"destination": "text",
"asset": "USDX",
"amount": "text",
"client_transfer_id": "text",
"domain": "text"
}{
"transfer_id": "text",
"status": "committed",
"asset": "USDX",
"source": null,
"destination": null,
"amount": "text",
"client_transfer_id": null,
"domain": null,
"committed_at_ms": 1
}API version 0.9.131
Last updated

