Place an order directly
appIdbearerAuthx-app-id<token>Your application ID. Required on app-tier and user-tier routes. Omitted on routes that authenticate with x-app-api-key only.
AuthorizationBearer <JWT>JWT access token from POST /auth/verify. Required with x-app-id on user routes. On the smart-route quote it is optional and turns a preview into an executable quote.
application/json- body
venue*stringThe venue to trade on. Singular by design — this endpoint never splits an order.
"kalshi""polymarket""limitless""predict""pred""tiprun""myriad""hyperliquid""novig""prophetx""betdex""lighter"venueMarketOutcomeId*stringThe outcome to trade. May be the outcome on another venue: it is resolved through matched-outcome links to the equivalent outcome on venue. Passing the id that already lives on venue is the unambiguous form.
1 <= lengthside*stringTrade direction. sell closes an existing position on venue.
"buy""sell"maxSpend?numberBuy only. Maximum all-in USD spend, inclusive of app fee.
0 <= valuesellShares?numberSell only. Number of contracts to sell.
0 <= valueexternalId*stringIdempotency key. Your own id for this trade — required, and unique within your app: two different users of the same app cannot share one. A repeat is rejected with 409 rather than trading twice, so it is safe to retry a request that timed out using the same value. A request rejected before its order was queued leaves the value free to reuse.
1 <= length <= 36slipCapBps?numberSlippage cap in basis points. Defaults to 500 (5%) when omitted. On sells set this explicitly: sellShares bounds the shares sold, not the proceeds.
0 <= valueallowedSourceChainIds?array<>Restrict funding to these source chains. Omitted, the order may be funded from any chain the user holds, bridging in when the venue's own chain is short. Listing only the venue's chain (56 for predict.fun, 137 for Polymarket) makes the order fail with insufficient funding instead of bridging. Balances are still read on-chain: this narrows which of them may be spent, it never adds capacity.
1 <= itemschainBalances?Per-chain USD funding budgets, e.g. {"56": 50}. Caps refreshed wallet balances; never adds capacity. A chain-only budget is shared across its token buckets. Omitted chains cannot fund the order; an empty map allows no on-chain funding. Combines with allowedSourceChainIds: excluded chains cannot fund the order.
appFeeBips?numberPer-trade app fee in basis points of routed notional, 0..10000. Replaces the app's configured rate for this order only. Honoured only when the request carries x-app-api-key; otherwise 400 app_fee_override_requires_api_key. Buy only.
10 <= value <= 10000appFeeBipsByVenue?Per-venue app fee in basis points, e.g. {"polymarket":20,"hyperliquid":10}. Keys are venue names; a rate applies to the legs filled on that venue and overrides appFeeBips there. The scalar appFeeBips still applies to venues the map omits. Honoured only when the request carries x-app-api-key; otherwise 400 app_fee_override_requires_api_key. Buy only.
referrerFeeBipsByVenue?Per-venue referral fee in basis points, e.g. {"polymarket":20,"hyperliquid":10}. Keys are venue names; a rate applies to the legs filled on that venue and overrides referrerFeeBips there, which still applies to venues the map omits. referrerFeeBips is optional when this is sent; 0 = no referral on that venue, but at least one venue must end up with a positive rate. Needs referrer. Same rules as referrerFeeBips: x-app-api-key required, buy only.
referrer?stringReferral: the EVM address that receives the referral fee. Requires referrerFeeBips or referrerFeeBipsByVenue. Honoured only when the request carries x-app-api-key; a JWT-only request that sends it is rejected with 400 referral_requires_api_key. Buy only.
42 <= length <= 42referrerFeeBips?numberReferral fee in basis points of the routed notional, 1..10000. sufwan-local-test takes no share of it. With referralPayer "user" it is reserved from maxSpend next to the app fee; with "app" the user pays nothing.
11 <= value <= 10000referralPayer?stringWho funds the referral. Default "user".
"user""app"referralPayerAddress?stringRequired when referralPayer is "app": the wallet that settles the payout. After the fill, a pendingSignatures entry appears with signerAddress set to this address and purpose "referral_payout"; answer it on POST /execution/fill/:quoteId/signatures. Read its type: on an EVM chain it is a transaction to broadcast (post the hash), on HyperCore an eip712 to sign (post the signature).
42 <= length <= 42referralPayoutChainId?numberOptional, and only with referralPayer "app": the chain the referrer is paid on. Must carry USDC. On an EVM chain the payout is an ERC-20 transfer the partner's wallet broadcasts, needing USDC plus native gas there; on HyperCore (1337) it is a user-signed sendAsset from the partner's HyperCore spot balance — a signature, nothing to broadcast — and the referrer receives spot USDC on Hyperliquid. A first payout to a referrer with no Hyperliquid account costs the partner an extra 1 USDC that Hyperliquid charges to create it; later payouts to the same referrer cost nothing. Solana does not support app-paid payouts and is refused. Defaults to the trade's fee chain, or Polygon when that chain is not EVM. Sending it with a user-paid referral is rejected with 400 referral_invalid.
11 <= valuereferralActivationSponsorAddress?stringOptional, and only with a user-paid referral (referralPayer "user" or absent): a wallet that pays Hyperliquid's one-time 1 USDC account-activation fee when the referrer has never received anything on HyperCore. Honoured on self-custody Hyperliquid buys only; ignored otherwise. Before the fill a pendingSignatures entry appears with signerAddress set to this address, purpose "hl_activation_sponsor" and optional: true — an eip712 sendAsset of 0.000001 USDC to the referrer. Sign it and post the signature on POST /execution/fill/:quoteId/signatures. After the fill it is posted just before the referral transfer, only if the referrer still has no HyperCore account. This wallet's HyperCore spot balance must hold at least 1.000001 USDC. Declining it is safe: the trade proceeds and the referral is attempted as usual. Must differ from referrer; rejected with referralPayer "app". The request reaches your signer through the user's client: sign only the exact transfer described here (see Fees → Securing the paying wallet's signer).
42 <= length <= 42skipQuote?booleanSkip the smart-route solver and send one order straight to venue. predict, hyperliquid, kalshi, novig and prophetx only; any other venue returns 400. Requires a read_write x-app-api-key (401 without a key, 403 with a read key). No bridging: the funds must already sit on the venue's own chain, and allowedSourceChainIds / chainBalances are ignored. A buy the stored balance cannot fund returns 400 quote_insufficient_balance before acceptance. Referral fields apply to buys as on a routed order; on a sell they return 400. You own the price and minimum checks — an order the venue refuses fails after acceptance and uses up its externalId. Kalshi and connected ProphetX/Novig API buys use fixed-price admission automatically; the venue decides available cash when accepting the order.
skipBalance?booleanWith skipQuote, skip the balance check and fund hold on a buy: nothing checks the balance and an underfunded order fails at the venue. Sells still check and hold the position. Without skipQuote, skip only the quote-time balance refresh: the route uses the last stored balances, and the fund hold and balance check still run, so a stale balance can fail the order after acceptance but never overspend. Requires a read_write x-app-api-key.
price?numberWith skipQuote or a native API buy, the price limit, e.g. 0.52. Optional: omitted, the best available price at submission is used (best ask for a buy, best bid for a sell), and an empty side returns 400. A hyperliquid buy is sized as the whole contracts that fit maxSpend at this price plus slippage. Ignored on clearinghouse prophetx, which prices the order itself within slipCapBps.
0 <= value <= 1200
application/json- response
orderId*stringThe single order this call created.
externalId*stringEchoed back so a webhook or socket event can be tied to this response.
venue*stringThe venue the order was placed on.
"kalshi""polymarket""limitless""predict""pred""tiprun""myriad""hyperliquid""novig""prophetx""betdex""lighter"status*"pending"Always pending: the order is accepted and queued for execution, not yet filled. Poll GET /execution/orders or listen for order events for the terminal state.
"pending"quoteId*stringServer-minted quote backing this order. Useful for support, not required.
quotedPriceRaw*stringQuoted price, decimal string (e.g. "0.53"). null if the order row does not carry a quoted price — the order is still live; re-fetch it from GET /execution/orders rather than treating this as zero.
quotedCostRaw*stringQuoted cost, 6-decimal atomic USDC. null under the same conditions as quotedPriceRaw.
quotedSharesRaw*stringQuoted shares, 6-decimal atomic. null under the same conditions as quotedPriceRaw.
curl -X POST 'https://api.t.sufwankhalid.com/execution/orders' \ -H 'Content-Type: application/json' \ -d '{ "venue": "polymarket", "venueMarketOutcomeId": "cmf3q8z2m00a4mw0lr5t1k7yc", "side": "buy", "maxSpend": 25, "externalId": "trade-2f9c61d4", "slipCapBps": 200}'{ "orderId": "cmf3r1a2b00c4mw0lq8y7e3uj", "externalId": "trade-2f9c61d4", "venue": "polymarket", "status": "pending", "quoteId": "k2r8v5n1x7c4m9t3b6q0w2za", "quotedPriceRaw": "0.52", "quotedCostRaw": "25000000", "quotedSharesRaw": "48076923"}