curl --request POST \
--url https://api.agg.market/execution/orders \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'x-app-id: <api-key>' \
--data '
{
"venue": "polymarket",
"venueMarketOutcomeId": "cmf3q8z2m00a4mw0lr5t1k7yc",
"side": "buy",
"maxSpend": 25,
"externalId": "trade-2f9c61d4",
"slipCapBps": 200
}
'import requests
url = "https://api.agg.market/execution/orders"
payload = {
"venue": "polymarket",
"venueMarketOutcomeId": "cmf3q8z2m00a4mw0lr5t1k7yc",
"side": "buy",
"maxSpend": 25,
"externalId": "trade-2f9c61d4",
"slipCapBps": 200
}
headers = {
"x-app-id": "<api-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-app-id': '<api-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
venue: 'polymarket',
venueMarketOutcomeId: 'cmf3q8z2m00a4mw0lr5t1k7yc',
side: 'buy',
maxSpend: 25,
externalId: 'trade-2f9c61d4',
slipCapBps: 200
})
};
fetch('https://api.agg.market/execution/orders', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.agg.market/execution/orders",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'venue' => 'polymarket',
'venueMarketOutcomeId' => 'cmf3q8z2m00a4mw0lr5t1k7yc',
'side' => 'buy',
'maxSpend' => 25,
'externalId' => 'trade-2f9c61d4',
'slipCapBps' => 200
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"x-app-id: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.agg.market/execution/orders"
payload := strings.NewReader("{\n \"venue\": \"polymarket\",\n \"venueMarketOutcomeId\": \"cmf3q8z2m00a4mw0lr5t1k7yc\",\n \"side\": \"buy\",\n \"maxSpend\": 25,\n \"externalId\": \"trade-2f9c61d4\",\n \"slipCapBps\": 200\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-app-id", "<api-key>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.agg.market/execution/orders")
.header("x-app-id", "<api-key>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"venue\": \"polymarket\",\n \"venueMarketOutcomeId\": \"cmf3q8z2m00a4mw0lr5t1k7yc\",\n \"side\": \"buy\",\n \"maxSpend\": 25,\n \"externalId\": \"trade-2f9c61d4\",\n \"slipCapBps\": 200\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.agg.market/execution/orders")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-app-id"] = '<api-key>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"venue\": \"polymarket\",\n \"venueMarketOutcomeId\": \"cmf3q8z2m00a4mw0lr5t1k7yc\",\n \"side\": \"buy\",\n \"maxSpend\": 25,\n \"externalId\": \"trade-2f9c61d4\",\n \"slipCapBps\": 200\n}"
response = http.request(request)
puts response.read_body{
"orderId": "cmf3r1a2b00c4mw0lq8y7e3uj",
"externalId": "trade-2f9c61d4",
"venue": "polymarket",
"status": "pending",
"quoteId": "k2r8v5n1x7c4m9t3b6q0w2za",
"quotedPriceRaw": "0.52",
"quotedCostRaw": "25000000",
"quotedSharesRaw": "48076923"
}{
"message": "<string>",
"code": "quote_not_found"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}Place an order directly
Places a market order on a single named venue without a prior quote. The route is priced and funded server-side and always produces exactly one order. externalId is required and unique within your app — two different users of the same app cannot share one — so retrying a timed-out request with the same value returns 409 instead of trading twice.
curl --request POST \
--url https://api.agg.market/execution/orders \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'x-app-id: <api-key>' \
--data '
{
"venue": "polymarket",
"venueMarketOutcomeId": "cmf3q8z2m00a4mw0lr5t1k7yc",
"side": "buy",
"maxSpend": 25,
"externalId": "trade-2f9c61d4",
"slipCapBps": 200
}
'import requests
url = "https://api.agg.market/execution/orders"
payload = {
"venue": "polymarket",
"venueMarketOutcomeId": "cmf3q8z2m00a4mw0lr5t1k7yc",
"side": "buy",
"maxSpend": 25,
"externalId": "trade-2f9c61d4",
"slipCapBps": 200
}
headers = {
"x-app-id": "<api-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-app-id': '<api-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
venue: 'polymarket',
venueMarketOutcomeId: 'cmf3q8z2m00a4mw0lr5t1k7yc',
side: 'buy',
maxSpend: 25,
externalId: 'trade-2f9c61d4',
slipCapBps: 200
})
};
fetch('https://api.agg.market/execution/orders', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.agg.market/execution/orders",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'venue' => 'polymarket',
'venueMarketOutcomeId' => 'cmf3q8z2m00a4mw0lr5t1k7yc',
'side' => 'buy',
'maxSpend' => 25,
'externalId' => 'trade-2f9c61d4',
'slipCapBps' => 200
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"x-app-id: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.agg.market/execution/orders"
payload := strings.NewReader("{\n \"venue\": \"polymarket\",\n \"venueMarketOutcomeId\": \"cmf3q8z2m00a4mw0lr5t1k7yc\",\n \"side\": \"buy\",\n \"maxSpend\": 25,\n \"externalId\": \"trade-2f9c61d4\",\n \"slipCapBps\": 200\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-app-id", "<api-key>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.agg.market/execution/orders")
.header("x-app-id", "<api-key>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"venue\": \"polymarket\",\n \"venueMarketOutcomeId\": \"cmf3q8z2m00a4mw0lr5t1k7yc\",\n \"side\": \"buy\",\n \"maxSpend\": 25,\n \"externalId\": \"trade-2f9c61d4\",\n \"slipCapBps\": 200\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.agg.market/execution/orders")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-app-id"] = '<api-key>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"venue\": \"polymarket\",\n \"venueMarketOutcomeId\": \"cmf3q8z2m00a4mw0lr5t1k7yc\",\n \"side\": \"buy\",\n \"maxSpend\": 25,\n \"externalId\": \"trade-2f9c61d4\",\n \"slipCapBps\": 200\n}"
response = http.request(request)
puts response.read_body{
"orderId": "cmf3r1a2b00c4mw0lq8y7e3uj",
"externalId": "trade-2f9c61d4",
"venue": "polymarket",
"status": "pending",
"quoteId": "k2r8v5n1x7c4m9t3b6q0w2za",
"quotedPriceRaw": "0.52",
"quotedCostRaw": "25000000",
"quotedSharesRaw": "48076923"
}{
"message": "<string>",
"code": "quote_not_found"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}{
"message": "<string>"
}Authorizations
Your application ID. Required for all app-tier and user-tier routes.
JWT access token returned by POST /auth/verify. Required for user-tier routes.
Body
The venue to trade on. Singular by design — this endpoint never splits an order.
kalshi, polymarket, limitless, opinion, predict, pred, tiprun, probable, myriad, hyperliquid, novig, prophetx, betdex The 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.
1Trade direction. sell closes an existing position on venue.
buy, sell Idempotency 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.
1 - 36Buy only. Maximum all-in USD spend, inclusive of app fee.
x > 0Sell only. Number of contracts to sell.
x > 0Slippage cap in basis points. Defaults to 500 (5%) when omitted. On sells set this explicitly: sellShares bounds the shares sold, not the proceeds.
x >= 0Restrict 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.
1x >= 1Per-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.
Show child attributes
Show child attributes
Per-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.
0 <= x <= 10000Must be a multiple of 1Referral: the EVM address that receives the referral fee. Requires referrerFeeBips. 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.
42Referral fee in basis points of the routed notional, 1..10000. AGG takes no share of it. With referralPayer "user" it is reserved from maxSpend next to the app fee; with "app" the user pays nothing.
1 <= x <= 10000Must be a multiple of 1Who funds the referral. Default "user".
user, app Required 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).
42Optional, 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.
x >= 1Must be a multiple of 1Skip the smart-route solver and send one order straight to venue. predict, hyperliquid, 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. Referral fields are rejected with 400. You own the price and minimum checks — an order the venue refuses fails after acceptance and uses up its externalId.
With 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.
With skipQuote, the price to trade at, 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 prophetx, which prices the order itself within slipCapBps.
0 < x < 1Response
200
The single order this call created.
Echoed back so a webhook or socket event can be tied to this response.
The venue the order was placed on.
kalshi, polymarket, limitless, opinion, predict, pred, tiprun, probable, myriad, hyperliquid, novig, prophetx, betdex 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 Server-minted quote backing this order. Useful for support, not required.
Quoted 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.
Quoted cost, 6-decimal atomic USDC. null under the same conditions as quotedPriceRaw.
Quoted shares, 6-decimal atomic. null under the same conditions as quotedPriceRaw.