NEW: Live arbitrage across 10+ prediction markets.Arbitrage →
← Index
APIOct 5, 2026

Polymarket Order Types (2026): GTC, GTD, FOK and FAK Explained

Polymarket Order Types (2026): GTC, GTD, FOK and FAK Explained

The Short Answer

Polymarket supports four order types, set in the orderType field: GTC (Good Till Cancelled) and GTD (Good Till Date) for limit orders that can rest on the book, and FOK (Fill or Kill) and FAK (Fill and Kill) for orders that must execute immediately. Post-only is a separate flag, postOnly: true, that works with GTC and GTD only. In the unified TypeScript SDK, placeLimitOrder() creates a GTC order, adding an expiration turns it into GTD, and placeMarketOrder() defaults to FAK. A GTD order expires one minute before its stated time, and that time must be at least three minutes in the future.

Key Takeaways

  • Every Polymarket order is a limit order. A market order is a limit order priced to match resting orders immediately.
  • GTC rests until it fills or you cancel it. GTD expires 60 seconds before its expiration, which must be at least 3 minutes away.
  • FOK fills the whole order or nothing, while FAK fills what it can and cancels the rest.
  • Post-only orders are rejected instead of taking liquidity, and the API accepts them only as GTC or GTD.
  • In the CLOB API, orderType and postOnly sit at the top level of the POST /order body, outside the signed order.

What order types does Polymarket support?

Order typeNameWhat happens to the unfilled amountRests on the book?
GTCGood Till CancelledStays open until it fills or you cancel itYes
GTDGood Till DateStays open until its expirationYes
FOKFill or KillThe whole order fills immediately, or none of it doesNo
FAKFill and KillFills what is available now, and the rest is canceledNo

Polymarket's documentation is blunt: "All orders on Polymarket are limit orders." A market order is a limit order priced to execute against the best resting orders, so the four types form two pairs. GTC and GTD decide how long an unfilled limit order stays open, and FOK and FAK decide what happens when an immediate order cannot fill completely. Post-only is a flag on a GTC or GTD order, not a fifth type.

How do limit and market orders behave on Polymarket?

A limit order names a price. If it crosses the spread, a buy at or above the lowest ask or a sell at or below the highest bid, it matches at once, and price improvement goes to the taker: a buy at $0.55 that meets a resting sell at $0.52 pays $0.52. Whatever does not fill stays open as GTC or GTD.

A market order takes its price from the current book and never rests, because "any amount that cannot fill is canceled." In the SDK, a market BUY takes amount in dollars and a SELL takes shares. maxPrice caps what a buy pays, minPrice floors what a sell accepts, and maxSpend sets an estimated all-in spend target that includes fees, which are otherwise charged on top.

SettingTypeScript SDKPython SDKCLOB API
Time in forceorderType: OrderType.FOKorder_type="FOK""orderType": "FOK"
GTD expirationexpirationexpirationorder.expiration
Post-onlypostOnly: truepost_only=True"postOnly": true
Price protectionmaxPrice, minPricemax_price, min_priceSet by the signed amounts

How does a GTD order's expiration work?

expiration is a Unix timestamp in seconds. GTC orders send "0", and so do FOK and FAK orders, because neither rests. A GTD order carries the time it should end, under two rules from Polymarket's docs:

  • It expires early. GTD orders "expire one minute before their stated expiration as a security threshold." For an effective lifetime of N seconds, set expiration to now plus 60 plus N.
  • It needs a minimum runway. The expiration must be at least 3 minutes in the future, which makes the shortest effective lifetime about two minutes.

The SDK enforces the second rule before it signs anything, with the error "Expiration must be at least 3 minutes in the future." Over the raw API, the CLOB rejects orders that expire too soon, and its invalid expiration error covers timestamps that are in the past or invalid. This places a 30-minute post-only GTD bid with @polymarket/client 0.12.0, the latest release on 3 October 2026:

import { createSecureClient, OrderResponseErrorCode, OrderSide } from '@polymarket/client';
import { privateKey } from '@polymarket/client/viem';

const client = await createSecureClient({
  signer: privateKey(process.env.POLYMARKET_PRIVATE_KEY as `0x${string}`),
});

const market = await client.fetchMarket({ slug: 'your-market-slug' });
const assetId = market.outcomes.yes.tokenId!;

// Effective lifetime of 30 minutes, plus the 60-second security threshold
const expiration = Math.floor(Date.now() / 1000) + 60 + 30 * 60;

const response = await client.placeLimitOrder({
  assetId,
  side: OrderSide.BUY,
  price: '0.52',
  size: '10',
  expiration,
  postOnly: true,
});

if (response.ok) {
  console.log(response.orderId, response.status);
} else if (response.code === OrderResponseErrorCode.POST_ONLY_WOULD_CROSS) {
  console.log('This price would take liquidity, so quote further from the ask.');
} else {
  console.error(response.code, response.message);
}

Leave out expiration and the same call places a GTC order. The SDK names the asset assetId, and the older tokenId parameter still works but is deprecated. On a rejection, response.code is a typed reason such as post_only_would_cross, so you can branch on it instead of parsing messages. Client setup is covered in the Polymarket SDK guide.

When should you use FOK or FAK?

Use FAK when a partial fill is acceptable, and FOK when the order only makes sense at full size, such as one leg of a two-sided trade. FAK still needs at least one match. If nothing on the book meets your price limit, the CLOB rejects it with "no orders found to match with FAK order." FOK rejects the whole order with "order couldn't be fully filled" when depth runs out.

One SDK detail catches people. placeMarketOrder() defaults to FAK, but estimateMarketPrice() models FOK unless told otherwise, and an FOK estimate throws when the book is too thin for the full amount. Pass the same orderType to both:

import { createSecureClient, OrderSide, OrderType } from '@polymarket/client';
import { privateKey } from '@polymarket/client/viem';

const client = await createSecureClient({
  signer: privateKey(process.env.POLYMARKET_PRIVATE_KEY as `0x${string}`),
});
const assetId = 'YOUR_TOKEN_ID';

const maxPrice = await client.estimateMarketPrice({
  assetId,
  side: OrderSide.BUY,
  amount: '25',
  orderType: OrderType.FOK,
});

const response = await client.placeMarketOrder({
  assetId,
  side: OrderSide.BUY,
  amount: '25',
  maxPrice,
  orderType: OrderType.FOK,
});

console.log(response.ok ? response.status : `${response.code}: ${response.message}`);

The estimate is a snapshot, so the book can move before the order lands. Passing it as maxPrice turns a moved book into a rejection instead of a worse fill. Trading involves risk: in a thin book, a market buy walks up the asks, so its average price can land well above the best quote.

Does Polymarket support post-only orders?

Yes. Polymarket added post-only orders in January 2026. Set postOnly: true on a GTC or GTD order, and it either rests on the book as a maker order or is rejected with "invalid post-only order: order crosses book." The API schema says post-only is "only supported for GTC and GTD orders," and the SDK throws before it submits a post-only FOK or FAK order.

Post-only also matters during maintenance. While the matching engine restarts, order requests return HTTP 425, and for two minutes after it returns, only cancels and post-only orders are accepted. Any other new order gets HTTP 503 with "code": "post_only_mode" and a retry delay in retry_after_seconds and the Retry-After header.

How do you set the order type in the CLOB API?

Over raw HTTP, an order is a signed EIP-712 struct inside a JSON body sent to POST https://clob.polymarket.com/order with the five L2 headers. The time in force is not part of the signature: orderType and postOnly are top-level fields, and expiration travels in the order object but sits outside the signed CLOB V2 struct.

FieldWhere it goesValues
orderTypeTop levelGTC (the default), GTD, FOK or FAK
postOnlyTop leveltrue or false (the default), GTC and GTD only
order.expirationOrder objectUnix seconds as a string, "0" unless the order is GTD
deferExecTop levelPolymarket's examples and the SDK send false

A post-only GTD order body looks like this, with your signed values in place of the placeholders:

{
  "deferExec": false,
  "order": {
    "builder": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "expiration": "YOUR_UNIX_SECONDS",
    "maker": "YOUR_DEPOSIT_WALLET_ADDRESS",
    "makerAmount": "5200000",
    "metadata": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "salt": 479249096354,
    "side": "BUY",
    "signature": "YOUR_ORDER_SIGNATURE",
    "signatureType": 3,
    "signer": "YOUR_DEPOSIT_WALLET_ADDRESS",
    "takerAmount": "10000000",
    "timestamp": "YOUR_UNIX_MILLISECONDS",
    "tokenId": "YOUR_TOKEN_ID"
  },
  "orderType": "GTD",
  "owner": "YOUR_API_KEY",
  "postOnly": true
}

makerAmount and takerAmount are six-decimal integers, so this BUY spends 5.20 USD for 10 shares at $0.52. signatureType 3 is a Deposit Wallet, where the maker and signer are both the wallet address. Batches go to POST /orders, which takes 1 to 15 of these entries, each with its own orderType. Check every result in the response, because one order can be accepted while another is rejected. Signing and the L2 headers are covered in the Polymarket CLOB API guide.

What do Polymarket order statuses mean?

StatusMeaning
liveThe order is resting on the book
matchedThe order matched immediately with resting liquidity
delayedThe order is marketable but waiting out a matching delay
unmatchedA marketable order placed on the book after the delay expired without a match

delayed comes from markets that hold marketable orders briefly: a taker delay on selected crypto and finance Up or Down markets, and a configured delay on some sports markets. The order is pending and cannot be canceled during the delay, and it is rejected if balance, allowance or risk checks fail when the delay ends. The unified SDK reports a raw unmatched status as ok: false with the code unmatched, so check open orders before resubmitting.

In our checks on 3 October 2026, Bitcoin 5-minute and 15-minute Up or Down markets returned itode: true, Polymarket's taker delay flag, from the public GET /clob-markets/{condition_id} endpoint, and soccer and esports markets reported secondsDelay: 1 in the Gamma API.

Why was my Polymarket order rejected?

CLOB messageSDK codeFix
order couldn't be fully filled. FOK orders are fully filled or killed.fok_not_filledCut the size, raise the limit or switch to FAK
no orders found to match with FAK orderfak_not_filledNothing met your price limit, so re-estimate
invalid post-only order: order crosses bookpost_only_would_crossMove the price off the opposite side
invalid expirationinvalid_expirationSet a GTD expiration at least 3 minutes ahead
post-only mode: only post-only orders and cancels are allowedpost_only_modeWait out the retry delay or send post-only
not enough balance / allowanceinsufficient_balance_or_allowanceAdd pUSD or set trading approvals
the market is not yet ready to process new ordersmarket_not_readyWait, then retry
Price (...) breaks minimum tick size ruleNoneRound the price onto the tick grid
Size (...) lower than the minimumNoneMeet the market's min_order_size

In the 0.12.0 source, tick and size errors have no dedicated SDK code and arrive as unknown with the original message, though the SDK checks the tick grid before signing. Rounding onto it is covered in the Polymarket tick size guide. An order timed out error, an HTTP 500 during bursts of orders from one account, never reached the book, and Polymarket says it can be safely resubmitted.

How do you place orders across venues?

Order vocabularies differ from venue to venue, so a bot that trades beyond Polymarket ends up maintaining several sets of rules. The Predictefy API builds orders server side across 15+ venues through one integration, and you sign each one in your own wallet or process, so Predictefy never holds your funds or keys. To rehearse an order flow before real money is involved, paper trading costs 0 credits on every plan.

Frequently Asked Questions

What order types does Polymarket support?

Four: GTC (Good Till Cancelled) and GTD (Good Till Date) for limit orders that can rest on the book, and FOK (Fill or Kill) and FAK (Fill and Kill) for orders that execute immediately. Post-only is a separate flag available on GTC and GTD orders.

What is the difference between FOK and FAK on Polymarket?

FOK fills the entire order immediately or cancels all of it. FAK fills whatever liquidity meets your price limit and cancels the rest, but it is rejected if nothing matches at all. The unified SDK uses FAK by default for market orders.

How long does a GTD order last on Polymarket?

Until one minute before its expiration timestamp, which Polymarket applies as a security threshold. The expiration must be at least three minutes in the future, so set it to the current time plus 60 seconds plus the lifetime you want.

Does Polymarket support post-only orders?

Yes. Set postOnly to true on a GTC or GTD order. If it would match immediately, the CLOB rejects it with "invalid post-only order: order crosses book" instead of filling it as a taker.

Does Polymarket have market orders?

Yes, although every Polymarket order is a limit order underneath. A market order is priced from the current book so it matches immediately, uses FOK or FAK, and never rests on the book.

Why does my Polymarket order say delayed?

The market applies a matching delay to marketable orders, such as the taker delay on some crypto Up or Down markets or the configured delay on sports markets. The order cannot be canceled during the delay, and it is matched, placed on the book or rejected when the delay ends.