| title | Quickstart |
|---|---|
| description | Read the orderbook and submit your first signed order |
Use this sequence to integrate against Numo's orderbook for stablecoins pegged to fiat currencies.
markets-service is served from https://api.numofx.com. The examples below use $MARKETS_SERVICE_URL, so export it once:
export MARKETS_SERVICE_URL="https://api.numofx.com"Read endpoints are public and require no API key or no allowlisting for server-side clients.
Query markets-service first so you know which instruments are enabled in the matcher.
curl "$MARKETS_SERVICE_URL/v1/markets"For the USDC/cNGN market, look for:
market = "USDCcNGN-SPOT"contract_type = "spot"settlement_type = "spot"asset_addressandsub_id
Once you have the market symbol or the (asset_address, sub_id) pair, fetch the current orderbook and recent prints.
curl "$MARKETS_SERVICE_URL/v1/book?symbol=USDCcNGN-SPOT"
curl "$MARKETS_SERVICE_URL/v1/trades?symbol=USDCcNGN-SPOT&limit=50"markets-service is the public read surface for:
- market metadata
- top-of-book bids and asks
- recent trades and 24h stats
- order submission and cancellation
Orders are posted to markets-service, but the request must already contain a signed action payload that matches the contracts. See Authentication and signing for how to build action_json.data and produce the signature.
Do not copy 0 from an older example. The fee is paid by whichever order arrived later, so
resting on the book does not exempt you — see
Fees follow arrival order. A zero bound against
a live taker schedule reverts TM_FeeTooHigh on every fill you take.
curl -X POST "$MARKETS_SERVICE_URL/v1/orders" \
-H "Content-Type: application/json" \
-d '{
"order_id": "future-order-1",
"owner_address": "0xOWNER",
"signer_address": "0xSIGNER",
"subaccount_id": "10",
"recipient_id": "10",
"nonce": "1",
"side": "buy",
"asset_address": "0xDd9c2Ddf97a2Dc9B9d348DcD0ef776aF5291A1F9",
"sub_id": "1789567201",
"desired_amount": "0.1",
"limit_price": "1605",
"worst_fee": "4815000000000000000",
"expiry": 1893456000,
"action_json": {
"subaccount_id": "10",
"nonce": "1",
"module": "0xTRADE_MODULE",
"data": "0x...",
"expiry": "1893456000",
"owner": "0xOWNER",
"signer": "0xSIGNER"
},
"signature": "0x..."
}'markets-service rejects the order unless:
- the instrument is enabled
action_json.subaccount_idmatchessubaccount_idaction_json.noncematchesnonceaction_json.ownermatchesowner_addressaction_json.signermatchessigner_address
The matching loop in markets-service identifies crossed orders and emits a payload to execution-service.
execution-service then:
- validates the match payload shape
- ABI-encodes
TradeModule.OrderData - simulates
Matching.verifyAndMatch(...) - submits the transaction to the onchain matching contracts