inNovaAPI
REST API

Orders

Place bets, manage limit orders, and query order history

Place a Bet

POST /api/ext/v1/orders

Scope: orders:write

Request Body

FieldTypeRequiredDescription
market_idstringYesMarket UUID
outcomestringYes (BUY FOK)"a" or "b" (first or second outcome)
amountnumberYes (BUY)Bet amount in USDC
sidestringNo"BUY" (default) or "SELL"
sharesnumberYes (SELL)Number of shares to sell
order_typestringNo"FOK" (default), "GTC", or "GTD"
limit_pricenumberNoLimit price 0.01–0.99 (required for GTC/GTD)
token_optionstringNo"yes" or "no" (required for limit orders)
expirationintegerNoGTD expiry (Unix seconds)
take_profit_pricenumberNoAuto take-profit price 0.01–0.99
stop_loss_pricenumberNoAuto stop-loss price 0.01–0.99

Order Types

TypeDescription
FOK (Fill or Kill)Market order — fills immediately at best price or cancels entirely
GTC (Good Till Cancel)Limit order — stays on orderbook until filled or manually cancelled
GTD (Good Till Date)Limit order — stays until filled, cancelled, or expiration date

Example: Market Order (FOK)

{
  "market_id": "550e8400-e29b-41d4-a716-446655440000",
  "outcome": "a",
  "amount": 50
}

Example: Limit Order (GTC)

For limit orders, use token_option ("yes" or "no") instead of outcome:

{
  "market_id": "550e8400-e29b-41d4-a716-446655440000",
  "amount": 100,
  "order_type": "GTC",
  "limit_price": 0.45,
  "token_option": "yes"
}

cURL Example — Market Order

API_KEY="po_live_your_api_key"
API_SECRET="your_api_secret"
TIMESTAMP=$(date +%s%3N)
NONCE=$(openssl rand -hex 16)
PATH="/api/ext/v1/orders"
BODY='{"market_id":"550e8400-e29b-41d4-a716-446655440000","outcome":"a","amount":50}'

BODY_HASH=$(echo -n "$BODY" | openssl dgst -sha256 -hex | awk '{print $NF}')
SIGNING_STRING="POST\n${PATH}\n${TIMESTAMP}\n${NONCE}\n${BODY_HASH}"
SIGNATURE=$(echo -ne "$SIGNING_STRING" | openssl dgst -sha256 -hmac "$API_SECRET" -hex | awk '{print $NF}')

curl -s -X POST "https://api.winnova.pro${PATH}" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: $API_KEY" \
  -H "X-API-TIMESTAMP: $TIMESTAMP" \
  -H "X-API-SIGNATURE: $SIGNATURE" \
  -H "X-API-NONCE: $NONCE" \
  -d "$BODY"

Response

HTTP Status: 201 Created

{
  "success": true,
  "data": {
    "order_id": "ord-550e8400-e29b-41d4-a716-446655440001",
    "notification_id": "notif-9f8e7d6c"
  }
}

Error Responses

Status 400 — invalid request body or parameters:

{
  "success": false,
  "error": "invalid request body"
}

Status 400 — insufficient balance:

{
  "success": false,
  "error": "insufficient balance"
}

Status 403 — scope not granted:

{
  "success": false,
  "error": "forbidden: missing scope orders:write"
}

Cancel a Limit Order

DELETE /api/ext/v1/orders/:id

Scope: orders:write

Cancels an active limit order (status: live). FOK orders cannot be cancelled.

Path Parameters

ParameterTypeDescription
idUUIDOrder ID

cURL Example

ORDER_ID="ord-550e8400-e29b-41d4-a716-446655440001"
API_KEY="po_live_your_api_key"
API_SECRET="your_api_secret"
TIMESTAMP=$(date +%s%3N)
NONCE=$(openssl rand -hex 16)
PATH="/api/ext/v1/orders/${ORDER_ID}"

BODY_HASH=$(echo -n "" | openssl dgst -sha256 -hex | awk '{print $NF}')
SIGNING_STRING="DELETE\n${PATH}\n${TIMESTAMP}\n${NONCE}\n${BODY_HASH}"
SIGNATURE=$(echo -ne "$SIGNING_STRING" | openssl dgst -sha256 -hmac "$API_SECRET" -hex | awk '{print $NF}')

curl -s -X DELETE "https://api.winnova.pro${PATH}" \
  -H "X-API-KEY: $API_KEY" \
  -H "X-API-TIMESTAMP: $TIMESTAMP" \
  -H "X-API-SIGNATURE: $SIGNATURE" \
  -H "X-API-NONCE: $NONCE"

Response

{
  "success": true,
  "data": {
    "order_id": "ord-550e8400-e29b-41d4-a716-446655440001",
    "status": "cancelled"
  }
}

Error Response

{
  "success": false,
  "error": "order not found"
}

Status 404 — order does not exist or does not belong to you.


List Orders

GET /api/ext/v1/orders

Scope: orders:read

Query Parameters

ParameterTypeDescription
statusstringFilter by order status: pending, signing, submitted, live, matched
pageintegerPage number (default: 1)
page_sizeintegerItems per page (default: 20, max: 100)

cURL Example

API_KEY="po_live_your_api_key"
API_SECRET="your_api_secret"
TIMESTAMP=$(date +%s%3N)
NONCE=$(openssl rand -hex 16)
PATH="/api/ext/v1/orders?status=matched&page=1&page_size=20"

BODY_HASH=$(echo -n "" | openssl dgst -sha256 -hex | awk '{print $NF}')
SIGNING_STRING="GET\n${PATH}\n${TIMESTAMP}\n${NONCE}\n${BODY_HASH}"
SIGNATURE=$(echo -ne "$SIGNING_STRING" | openssl dgst -sha256 -hmac "$API_SECRET" -hex | awk '{print $NF}')

curl -s "https://api.winnova.pro${PATH}" \
  -H "X-API-KEY: $API_KEY" \
  -H "X-API-TIMESTAMP: $TIMESTAMP" \
  -H "X-API-SIGNATURE: $SIGNATURE" \
  -H "X-API-NONCE: $NONCE"

Response

{
  "success": true,
  "data": {
    "orders": [
      {
        "id": "2c87c1ba-adde-41c8-ae3e-9fa90e922530",
        "user_id": "d9f8fb6e-5144-4377-b12a-3a56feb63a7c",
        "market_id": "550e8400-e29b-41d4-a716-446655440000",
        "outcome": "a",
        "amount": 50.00,
        "making_amount": 49.999,
        "taking_amount": 70.422,
        "odds": 0.71,
        "potential_profit": 20.42,
        "status": "matched",
        "side": "BUY",
        "order_type": "FOK",
        "order_source": "manual",
        "order_source_id": null,
        "clob_order_id": "0x452134a9...",
        "original_size": 50.001,
        "size_matched": 70.422,
        "clob_price": 0.71,
        "tx_hashes": [
          "0xc4aa72de..."
        ],
        "settlement_status": "won",
        "settlement_amount": 20.42,
        "settled_at": "2026-04-04T12:00:00Z",
        "submitted_at": "2026-04-04T10:00:00Z",
        "matched_at": "2026-04-04T10:00:01Z",
        "created_at": "2026-04-04T10:00:00Z",
        "updated_at": "2026-04-04T12:00:00Z"
      }
    ],
    "total_count": 204,
    "page": 1,
    "page_size": 20
  }
}

Error Response

{
  "success": false,
  "error": "unauthorized"
}

Get Order Detail

GET /api/ext/v1/orders/:id

Scope: orders:read

Returns full order details including status, fill amount, and associated market data.

Path Parameters

ParameterTypeDescription
idUUIDOrder ID

cURL Example

ORDER_ID="ord-550e8400-e29b-41d4-a716-446655440001"
API_KEY="po_live_your_api_key"
API_SECRET="your_api_secret"
TIMESTAMP=$(date +%s%3N)
NONCE=$(openssl rand -hex 16)
PATH="/api/ext/v1/orders/${ORDER_ID}"

BODY_HASH=$(echo -n "" | openssl dgst -sha256 -hex | awk '{print $NF}')
SIGNING_STRING="GET\n${PATH}\n${TIMESTAMP}\n${NONCE}\n${BODY_HASH}"
SIGNATURE=$(echo -ne "$SIGNING_STRING" | openssl dgst -sha256 -hmac "$API_SECRET" -hex | awk '{print $NF}')

curl -s "https://api.winnova.pro${PATH}" \
  -H "X-API-KEY: $API_KEY" \
  -H "X-API-TIMESTAMP: $TIMESTAMP" \
  -H "X-API-SIGNATURE: $SIGNATURE" \
  -H "X-API-NONCE: $NONCE"

Response

{
  "success": true,
  "data": {
    "order": {
      "id": "2c87c1ba-adde-41c8-ae3e-9fa90e922530",
      "user_id": "d9f8fb6e-5144-4377-b12a-3a56feb63a7c",
      "market_id": "550e8400-e29b-41d4-a716-446655440000",
      "outcome": "a",
      "amount": 50.00,
      "making_amount": 49.999,
      "taking_amount": 70.422,
      "odds": 0.71,
      "potential_profit": 20.42,
      "status": "matched",
      "side": "BUY",
      "order_type": "FOK",
      "order_source": "manual",
      "order_source_id": null,
      "clob_order_id": "0x452134a9...",
      "original_size": 50.001,
      "size_matched": 70.422,
      "clob_price": 0.71,
      "tx_hashes": [
        "0xc4aa72de..."
      ],
      "settlement_status": "won",
      "settlement_amount": 20.42,
      "settled_at": "2026-04-04T12:00:00Z",
      "submitted_at": "2026-04-04T10:00:00Z",
      "matched_at": "2026-04-04T10:00:01Z",
      "created_at": "2026-04-04T10:00:00Z",
      "updated_at": "2026-04-04T12:00:00Z"
    }
  }
}

Error Responses

Status 404 — order not found or not owned by you:

{
  "success": false,
  "code": "ORDER_NOT_FOUND",
  "error": "order not found"
}

Get Wallet Info

GET /api/ext/v1/wallet

Scope: orders:read

Returns the on-chain wallet addresses needed for raw CLOB order construction and clob_order_id pre-computation.

Response

{
  "success": true,
  "data": {
    "maker": "0x6509FE08D1d17A0fdEb26fFe8A73b851622BbbFa",
    "signer": "0x61BE2D6C64E7aDefF4307dE52B7533e83475716c",
    "chain_id": 137,
    "signature_type": 2,
    "ctf_exchange": "0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E",
    "neg_risk_exchange": "0xC5d563A36AE78145C45a50134d48A1215220f80a"
  }
}
FieldDescription
makerSafe wallet address (EIP-712 maker field)
signerEOA address (EIP-712 signer field)
chain_id137 (Polygon mainnet)
signature_type2 (PolyGnosisSafe, fixed)
ctf_exchangeContract address for non-NegRisk markets
neg_risk_exchangeContract address for NegRisk markets

These addresses are bound to the user account and do not change — safe to cache.


Place Raw CLOB Order

POST /api/ext/v1/orders/raw

Scope: orders:write

Bypasses server-side price × size calculation and passes CLOB parameters directly to Polymarket. Use this when you need full control over makerAmount/takerAmount or want to pre-compute clob_order_id before submission.

Request Body

FieldTypeRequiredDescription
market_idstring (UUID)YesWinNova market ID
outcomestringYes"a" or "b"
token_idstringYesCLOB token ID from token_id_a or token_id_b
maker_amountstringYesAmount paid, uint256 string (6 decimals, e.g. "2000000" = 2 USDC)
taker_amountstringYesAmount received, uint256 string (6 decimals)
sideintegerYes0 = BUY, 1 = SELL
fee_rate_bpsintegerYesFee rate in basis points — must match CLOB market fee
order_typestringNo"FOK" (default), "GTC", "GTD"
saltstringNoOrder salt [0, 10^12]; set a fixed value to pre-compute clob_order_id
noncestringNoDefault "0"
expirationstringNoUnix seconds, default "0" (never expires)
client_order_idstringNoIdempotency key, max 64 chars

Price constraint: price = maker_amount / taker_amount must be between 0 and 1.

Getting fee_rate_bps: Query the Polymarket CLOB API before placing the order:

curl "https://clob.polymarket.com/fee-rate?token_id=<token_id>"
# Response: {"base_fee": 1000}  → fee_rate_bps = 1000

Response

HTTP Status: 201 Created

{
  "success": true,
  "data": {
    "order_id": "5ef1b477-6eb2-46de-bd94-14e0431ddf60",
    "notification_id": ""
  }
}

Error Codes

CodeCause
ORDER_INVALID_SALTSalt outside [0, 10^12] range
ORDER_INVALID_MAKER_AMOUNTmaker_amount is not a valid non-negative integer string
ORDER_INVALID_TAKER_AMOUNTtaker_amount is not a valid non-negative integer string

Trading Limits

LimitDescription
Single order max50,000 USDC per order (enforced by signer-service; orders exceeding this fail)
Risk controlsPer-order / daily / monthly / per-minute frequency limits; breach returns 500 (ORDER_FAILED_PLACE_BET)
Bonus exemptionOrders using bonus funds (is_bonus) are exempt from risk control checks