Bet
Place, execute, and exit bets
Per-asset constraints so you can validate bounds without a /quote round-trip. Same source as the server-side gates, so values never drift.
coin is optional and defaults to the launch asset. URL-encode HIP-3 names: ?coin=xyz%3ATSLA, not ?coin=xyz:TSLA.
JWT access token from POST /auth/authenticate
Asset name (e.g. BTC, ETH). URL-encode HIP-3 names.
BTCLimit constraints for the asset
Error response
GET /api/which-first/limits HTTP/1.1
Host: api.bound.exchange
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"code": "1",
"message": "common.success",
"data": {
"coin": "BTC",
"mark": "61000",
"maxLeverage": 40,
"maxBoundDistance": "0.1",
"minAgainstDistance": {
"upper_first": "0.015158",
"lower_first": "0.014846"
}
}
}Pure pricing preview. No wallet gates, no persistence, no side effects.
wager is isolated margin, not order notional. payoutMultiple is profit / wager. To show a total-return multiple, use 1 + payoutMultiple.
This endpoint deliberately does not enforce the configured wager range or Hyperliquid's $10 minimum order notional. Treat /proposals as the authoritative gate.
JWT access token from POST /auth/authenticate
Which bound you bet on being touched first
Upper price boundary
Lower price boundary
Isolated margin amount in USDC
Asset name (e.g. BTC, ETH). Optional — defaults to the launch asset if omitted.
Construction preview
Error response
POST /api/which-first/quote HTTP/1.1
Host: api.bound.exchange
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 90
{
"side": "upper_first",
"upperBound": "63500",
"lowerBound": "59000",
"wager": "20",
"coin": "BTC"
}{
"code": "1",
"message": "common.success",
"data": {
"direction": "long",
"leverage": 17,
"notional": "340",
"coinSize": "0.0056",
"chosenBound": "63500",
"losingBound": "59000",
"takeProfitPrice": "63500",
"liquidationPrice": "58656.39",
"payoutMultiple": "0.66",
"payoutEstimate": "13.25",
"maxSlippage": "0.01",
"entryPrice": "61000",
"wager": "20"
}
}Runs every gate, persists a proposed bet (which holds the per-asset slot), and returns the actions to sign.
Only one open bet per asset per account — including from a different wallet on the same account. A retry while one is open returns 26007.
Enforces the configured wager range (default 10-100,000 USDC) and requires price * coinSize >= $10 for both order wires.
JWT access token from POST /auth/authenticate
Optional — defaults to the launch asset if omitted
EVM wallet that signs and owns the position
Proposal with unsigned actions to sign
Error response
POST /api/which-first/proposals HTTP/1.1
Host: api.bound.exchange
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 149
{
"side": "upper_first",
"upperBound": "63500",
"lowerBound": "59000",
"wager": "20",
"coin": "BTC",
"userAddress": "0xc12b0a4a5fdd42d1f4aa2a08c2193d1ac49c8167"
}{
"code": "1",
"message": "common.success",
"data": {
"betId": "6a3d…",
"state": "proposed",
"proposalExpiresAt": "2026-06-26T10:30:00.000Z",
"construction": {
"leverage": 17,
"takeProfitPrice": "63500"
},
"unsignedActions": [
{
"kind": "update_leverage",
"action": {
"type": "updateLeverage"
}
},
{
"kind": "entry",
"action": {
"type": "order",
"grouping": "normalTpsl"
}
}
]
}
}The only signed bodies Bound relays. Sign the unsignedActions from /proposals (entry) or /cash-out, keep each original kind, and send them in order.
Relay-once: 26028 fires when order ids are already recorded, another relay is in flight, or a retry found venue evidence. Never re-sign — a new nonce defeats Hyperliquid's dedup.
26025 is the only definitive "nothing landed" verdict — retrying after it is safe.
JWT access token from POST /auth/authenticate
Bet ID (24-char hex string)
6a3d1f2e3b4c5d6e7f8a9b0cUpdated bet after execution
Error response
POST /api/which-first/{id}/execute HTTP/1.1
Host: api.bound.exchange
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 226
{
"actions": [
{
"kind": "update_leverage",
"action": {
"type": "updateLeverage"
},
"nonce": 1719396000000,
"signature": "0x…"
},
{
"kind": "entry",
"action": {
"type": "order",
"grouping": "normalTpsl"
},
"nonce": 1719396000001,
"signature": "0x…"
}
]
}{
"code": "text",
"message": "text",
"data": {
"_id": "text",
"accountId": "text",
"coin": "text",
"evmAddress": "text",
"side": "upper_first",
"upperBound": "text",
"lowerBound": "text",
"wager": "text",
"construction": {
"direction": "long",
"leverage": 1,
"notional": "text",
"coinSize": "text",
"chosenBound": "text",
"losingBound": "text",
"takeProfitPrice": "text",
"liquidationPrice": "text",
"payoutMultiple": "text",
"payoutEstimate": "text",
"maxSlippage": "text",
"entryPrice": "text",
"assetIndex": 1,
"szDecimals": 1,
"maintenanceMarginFraction": "text",
"builderFeeRate": "text"
},
"state": "proposed",
"proposalExpiresAt": "2026-01-01T00:00:00.000Z",
"activatedAt": "2026-01-01T00:00:00.000Z",
"resolvedAt": "2026-01-01T00:00:00.000Z",
"abortReason": "proposal_expired",
"voidReason": "tp_cancelled",
"cashOutPending": true,
"boundBreachFlagged": true,
"venueRefs": {
"entryOid": "text",
"takeProfitOid": "text",
"closeOid": "text"
},
"actuals": {
"actualEntryPrice": "text",
"actualLiquidationPrice": "text",
"actualPayoutMultiple": "text",
"actualCoinSize": "text",
"actualMarginUsed": "text",
"fundingAtActivation": "text",
"finalProceeds": "text",
"feesPaid": "text",
"fundingPaid": "text",
"netProceeds": "text"
},
"relayClaimedAt": "2026-01-01T00:00:00.000Z",
"createdAt": 1,
"updatedAt": 1,
"deletedAt": "2026-01-01T00:00:00.000Z"
}
}Returns an unsigned bundle that cancels the resting take-profit and closes the position reduce-only. Only for an active bet.
Sign both actions and send them to POST /{id}/execute — same as the entry bundle. Repeating a cash-out is a no-op; a bet that is no longer active returns 26012.
JWT access token from POST /auth/authenticate
Bet ID (24-char hex string)
6a3d1f2e3b4c5d6e7f8a9b0cCash-out bundle with unsigned actions
Error response
POST /api/which-first/{id}/cash-out HTTP/1.1
Host: api.bound.exchange
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 2
{}{
"code": "1",
"message": "common.success",
"data": {
"betId": "6a3d…",
"unsignedActions": [
{
"kind": "cancel",
"action": {
"type": "cancel"
}
},
{
"kind": "cash_out_close",
"action": {
"type": "order"
}
}
]
}
}Last updated