Skip to main content
POST
/
order
Create order
curl --request POST \
  --url https://clob.forka.st/order \
  --header 'Content-Type: application/json' \
  --data '
{
  "orderType": "GTC",
  "order": {
    "tokenId": "0x51524f4c595f5945535f544f4b454e5f4944",
    "conditionId": "0x504f4c595f434f4e444954494f4e5f4944",
    "expiration": "1767225599",
    "maker": "0xAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAa",
    "signer": "0xAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAa",
    "taker": "0x0000000000000000000000000000000000000000",
    "makerAmount": "75000000",
    "takerAmount": "100000000",
    "side": "BUY",
    "referrer": "0x9aE9d1b7b5C0F4a8C6D3E1f2A9B7C8D6E4F5A3B2",
    "affiliate": "0x0000000000000000000000000000000000000000",
    "affiliatePercentage": 0,
    "metadata": {
      "strategy": "manual_limit"
    },
    "nonce": "42",
    "feeRateBps": "200",
    "salt": "176543219998812345678901234",
    "signatureType": 0,
    "signature": "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
  },
  "owner": "0xAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAa"
}
'
{
  "success": false,
  "error_code": "FOK_ORDER_NOT_FILLED_ERROR",
  "error_msg": "order couldn't be fully filled, FOK orders are fully filled/killed",
  "order_id": null,
  "order_hashes": []
}
Submit a new order to the Forkast central limit order book. Orders are accepted for matching immediately; validation happens synchronously and the response tells you whether the request was persisted.
All order placement calls require the L2 authentication headers: FORKAST_ADDRESS, FORKAST_SIGNATURE, FORKAST_TIMESTAMP, FORKAST_API_KEY, and FORKAST_PASSPHRASE. Review how to obtain them in the Authentication overview or use the managed console at auth.forka.st.
When the global circuit breaker is enabled, this endpoint returns 409 with {"error":"system_paused"}. Individually paused books still reply with 409 and {"error":"condition_paused"}. Make sure the owner field matches the FORKAST_ADDRESS header; otherwise the API returns 400 and {"error":"owner_address_mismatch"}.

Placement status values

Order submissions respond with a status field that reflects the immediate lifecycle state:
StatusMeaning
liveOrder accepted and resting on the book.
matchedOrder matched instantly against existing liquidity.
delayedOrder is marketable but matching is deferred temporarily.
unmatchedOrder was marketable but could not be matched after the delay period.

Request body

Root fields

FieldTypeRequiredDescription
ownerstringYesPolygon address that owns the API key. Must match the FORKAST_ADDRESS header.
orderTypestringYesTime-in-force policy for the order (FOK, FAK, GTC, GTD).
orderobjectYesFull order payload described below.
For GTD orders you must supply an order.expiration in the future. GTC, FAK, and FOK may omit expiration; the engine simply ignores the value when it is not needed.

order object

FieldTypeRequiredDescription
tokenIdstringYesIdentifier of the token/outcome being traded.
conditionIdstringYesMarket condition identifier tied to the token.
expirationstringConditionalUnix timestamp (seconds) when the order becomes invalid. Required for GTD, optional otherwise.
makerstringYesAddress that holds the asset being offered.
signerstringYesAddress that produced the signature authorizing the order.
takerstringYesCounterparty address. Use the zero address for open orders.
makerAmountstringYesQuantity provided by the maker, denominated with fixed precision.
takerAmountstringYesQuantity expected from the taker. Must stay within allowed tick sizes.
sidestringYesEither BUY or SELL.
referrerstringYesReferrer identifier (use the zero address when unused).
affiliatestring|nullNoAffiliate beneficiary address; provide null when not used.
affiliatePercentageinteger|nullNoAffiliate share in basis points.
metadataobject|nullNoOptional JSON metadata stored with the order.
noncestringYesMonotonic value chosen by the maker to guard against reuse.
feeRateBpsstringYesMaker fee rate in basis points.
saltstringYesUnique entropy for replay protection. Reuse causes duplicate rejection.
signatureTypenumberYes0 = EOA, 1 = proxy signer, 2 = Gnosis Safe signer.
signaturestringYesHex-encoded signature produced over the order payload.
All fixed-precision numeric values (makerAmount, takerAmount, nonce, feeRateBps, expiration) must be sent as strings to avoid precision issues during parsing. side must be the uppercase string BUY or SELL. owner must match the FORKAST_ADDRESS header supplied with the request.

Order types

TypePartial fills?Rests on the book?Auto expiration?
FOK (Fill-Or-Kill)❌ No❌ No✅ Immediately if not 100% filled
FAK (Fill-And-Kill / IOC)✅ Yes❌ No✅ Any remaining size cancels right away
GTC (Good-Til-Cancelled)✅ Yes✅ Yes, until cancelled❌ No
GTD (Good-Til-Date)✅ Yes✅ Yes, until the given timestamp✅ At the specified expiration time
For GTD, the engine enforces a one-minute safety buffer. If you need the order to expire in 90 seconds, set expiration = now + 90 + 60.

Execution and follow-up

  • A successful placement returns 201 Created with success: true, even for FAK/FOK orders that may cancel remaining size after partial execution.
  • orderId is the ULID generated for storage. Use GET /data/order/{id} to check final status and filled amounts.
  • orderHashes currently returns an empty array; on-chain settlement hashes will populate this field in the future.
  • Need to retire a resting order? Call DELETE /order.
Order status values returned by GET /data/order/{id} are:
StatusMeaning
openOrder is resting on the book.
partially_filledOrder remains on the book with some fills.
filledOrder fully executed.
cancelledOrder removed. For IOC/FAK, partial fills still return cancelled with non-zero filled amounts.

Error codes

When validation fails, the response sets success to false (or true for warnings) and includes an errorCode alongside errorMsg. Current error codes follow the live engine responses:
errorCodesuccesserrorMsg (default)Notes
INVALID_ORDER_MIN_TICK_SIZEtrueorder is invalid. Price breaks minimum tick size rulesPrice implied by maker/taker amounts is outside the permitted [0, 1_000_000] window.
INVALID_ORDER_MIN_SIZEtrueorder is invalid. Size lower than the minimumMaker or taker amount is non-positive or below minimum size.
INVALID_ORDER_DUPLICATEDtrueorder is invalid. Duplicated. Same order has already been placed, can’t be placed againReserved for future duplicate protection.
INVALID_ORDER_NOT_ENOUGH_BALANCEtruenot enough balance / allowanceReserved for balance/allowance enforcement.
INVALID_ORDER_EXPIRATIONtrueinvalid expirationMissing, past, or negative expiration.
INVALID_ORDER_ERRORtruecould not insert orderGeneric validation failure.
EXECUTION_ERRORtruecould not run the executionInternal engine/database failure while inserting.
ORDER_DELAYEDfalseorder match delayed due to market conditionsReserved for delayed matching path.
DELAYING_ORDER_ERRORtrueerror delaying the orderReserved for delayed matching errors.
FOK_ORDER_NOT_FILLED_ERRORfalseorder couldn’t be fully filled, FOK orders are fully filled/killedReturned when a fill-or-kill order cannot fill 100%.
MARKET_NOT_READYfalsethe market is not yet ready to process new ordersReserved for markets warming up.
Even when success is true, errorCode and errorMsg may be populated to surface warnings without rejecting the order.

Body

application/json
owner
string
required

Polygon address that owns the API key. Must match the FORKAST_ADDRESS header.

Example:

"0xAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAa"

orderType
enum<string>
required

Execution policy for the order.

Available options:
FOK,
FAK,
GTC,
GTD
Example:

"GTC"

order
object
required

Response

Order accepted but the matching engine returned a business error (payload will have success: false).

success
boolean
required

Indicates whether the order was accepted.

Example:

true

error_msg
string
required

Human-readable status for the placement.

Example:

""

order_hashes
string[]
required

Settlement hashes for immediate matches (empty if none).

Example:
[]
error_code
string | null

Machine-readable error code when placement fails (ex: FOK_ORDER_NOT_FILLED_ERROR, EXECUTION_ERROR).

Example:

null

order_id
string | null

ULID of the submitted order when accepted.

Example:

"01JABCD4XY7M5Q1PQW8ZMN9ABC"