Step zero — from nothing to your first trade
Section titled “Step zero — from nothing to your first trade”- Create the account. Start at xo.market and obtain caller-owned XO CLOB access. XO access is partner-provided; the sources do not document its signup or KYC flow.
- Set up credentials. Create the API key, secret, and passphrase in your venue account’s API
settings. For the default model, your EVM wallet must own an XO smart account. Secure the wallet
seed phrase offline. Predictefy never sees the wallet private key; the credential triple transits
Predictefy only for a bounded submit and is never persisted.
Known limitation for social-login accounts (2026-08-23): an XO account created via social
login is a ZeroDev smart account whose embedded key produces a wrapped ERC-1271 signature —
but XO’s
POST /orderdocuments the wire signature as exactly 65 bytes, so a bare embedded-key signature is rejected by the venue’s smart-account check and the wrapped form does not fit the documented wire format. Until this is resolved with the venue, trade XO with a wallet-native account (the EOA holds the collateral and signs directly,signatureType0). Funded verification of the wrapped-signature path is in progress. - Fund it. Hold six-decimal Bridged USDC (XO) on chain
3223, approve the verified exchange, and leave collateral headroom above your first order. No numeric minimum or verified deposit route is published in the allowed sources. If funding crosses chains, queryGET /v1/bridge/quotefirst and use a venue-confirmed route if XO is unsupported. - Allow time. Budget 1–2 hours after CLOB access arrives; partner provisioning can take longer. Predictefy has not yet submitted an XO order; confirm your eligibility.
What you need first
Section titled “What you need first”- Production status: Building, submitting, and cancelling are all served, rebuilt on 2026-08-18 against the venue’s current order contract. The builder that shipped before that date signed the venue’s previous order struct against its previous exchange and was disarmed the same day; it has been replaced, and the reason to disarm went with it. Nothing has yet been submitted to XO, so the first live submit is the confirmation checkpoint — see the note below.
- Wallet and chain: An XO smart account on chain
3223is the default identity, and it is both the order’smakerand itssigner. A direct EOA is also accepted; see “Signature models”. - Venue account: Use caller-owned XO CLOB access that provides an API key, secret, and passphrase. The lane establishes no separate account-provisioning flow.
- Credentials: Your signing key stays client-side. The CLOB triple transits only submit, creates HMAC headers in-process, and is never persisted.
- Funding: Six-decimal Bridged USDC (XO) in the
makeraccount, approved to the verified exchange. There is no hosted helper, and the deposit route remains unverified by the funding registry. Fees are charged in collateral to themaker, so leave a little headroom above the order principal.
XO is a strict server-built lane and has no client-echo compatibility path. It is default off and
unregistered: its code and artifact bounds do not mean that any deployment has enabled it. Check
GET /v1/exec/venues; an absent XO row is the expected default.
Send asset (the catalog outcome id), or outcome + outcomeSide, with isBuy, price, size,
and the owner account. The indexed catalog lookup resolves the outcome first, and XO’s catalog
token_id becomes the signed tokenId verbatim.
Signature models
Section titled “Signature models”signatureType selects how the venue validates your signature. 3 is the default and is the XO
smart-account model: the account is both maker and signer, and the venue checks the signature
through ERC-1271 on that contract, so the 65 bytes you supply come from an owner key of the smart
account rather than from the maker address itself. signatureType: 0 is the direct-EOA model, where
maker and signer are your own wallet and the venue recovers the signature normally.
The venue’s documentation is not self-consistent here: its authentication and smart-account
guides both describe 3 as the only order-signing model the orderbook accepts today, while the
order-placement schema documents 0 for direct EOA integrations and lists it in the accepted enum.
The default is 3 because that is the model every page agrees on; 0 is available for callers who
want it, and is the contested one. The Polymarket proxy models (1 and 2) have no XO identity and
are rejected before any venue call.
Orders carry no fee rate. There is no fee field to set or sign; settlement applies the market
category’s rate to each filled leg. Predictefy reads that rate from the venue’s public fee endpoint
at build time and quotes it with the venue’s documented conviction curve —
fee = size × (rate / 10,000) × price × (1 − price), which peaks at a price of 0.5 and falls
toward the extremes. The quote assumes a complete fill, so it is an upper bound. The category rate is
currently 0, which makes the quote 0 by that formula rather than by assumption; a rate above the
exchange’s own on-chain maximum is refused rather than quoted.
expiresAt takes Unix seconds. An explicit 0 is the documented never-expiring GTC opt-in; a
future second builds GTD and must be within two years, so a millisecond stamp is rejected rather than
signed. Omitting it no longer means GTC: the order expires at the catalog market’s close date
when the row carries a future one, bounded by that same two-year horizon, so a resting order cannot
outlive the market it was written against. If the catalog has no usable close date, an omitted
expiresAt still builds GTC.
The returned artifact includes types, primaryType: "Order", domain, message, and
buildVersion: 2. The exact signed fields are salt, maker, signer, beneficiary, tokenId,
makerAmount, takerAmount, expiration, nonce, identifier, metadata, side, and
signatureType, in that order — thirteen fields; the signature is carried alongside them on the
wire but is not part of the hash. beneficiary, identifier, and metadata are always zero-filled
by server builds: a zero beneficiary pays the maker, and routing proceeds elsewhere is not a
decision this service takes on your behalf. The domain is XO Market CLOB, version 1, chain
3223, verifying contract 0x4bC5E872256D12E6017dfe466E04c867DC761B77. Collateral is six-decimal
Bridged USDC (XO), 0x80c12230ce677e6f304027a14780edd2a829ab0c. A missing or stale build version is
rejected on both idempotent build replay and submit, before any XO relay — artifacts built by the
previous builder carry buildVersion: 1 and are refused rather than relayed.
You sign the complete typed data in your own wallet and submit { executionId, signature, owner, apiKey, apiSecret, apiPassphrase }. Predictefy never receives a private key, never signs, and never
persists the credential triple or headers. XO account and funding routes are not implemented.
What the server verifies depends on the signature model, and the difference is real. State it before anything else, because “the server checks your signature” is only true for one of the two:
signatureType: 0(direct EOA). Full binding. The signature must recover to thesignerstored at build, against the server-stored digest. A signature that recovers to anyone else is rejected before any venue call.signatureType: 3(XO smart account — the default). The server cannot bind the signature to an address. The 65 bytes come from an owner key of your smart account, an address this service does not know and has no way to learn, so it checks only that the signature is well-formed. The authority is the venue, which passes the digest and signature to your smart account’s ERC-1271isValidSignature. That check, on-chain and at the venue, is what accepts or refuses the order.
In both models the server enforces that the owner you submit equals the maker/signer it wrote
at build, and it relays only the order it built and stored.
That is why a signature the server cannot bind is still not a route to anyone else’s funds. The
order it relays has maker == signer == your own account, pinned at build and re-checked on reload;
its beneficiary is the zero address, which pays the maker and nobody else; and the digest is
re-derived from the stored order before relay, so the bytes signed and the bytes sent are the same
order. A mismatched signature under 3 can at worst cause the venue to execute your own order —
or, far more likely, reject it.
After those checks Predictefy reads XO /time, creates the venue’s XO_* L2 HMAC headers
in-process, and posts the stored order to /order.
Cancel and status refresh
Section titled “Cancel and status refresh”Cancel and a client-credentialed status refresh are served: GET /v1/exec/venues reports
cancel: true for XO. They were armed on 2026-08-18, when XO’s own API documentation answered the
two questions that had kept them off — every authenticated XO route reads XO_* HMAC header names
(not the POLY_* forms this CLOB family uses elsewhere), and a cancel acknowledges with an explicit
list of the order ids it removed. They need only the CLOB base URL and your own credentials, never an
exchange address or an order struct.
Cancel follows the same non-custodial choreography as an order: POST /v1/exec/xo/orders/{id}/cancel mints a new cancel intent from server-stored truth, and you send that
new execution id to /submit with your own apiKey, apiSecret, and apiPassphrase. A cancel
carries no signature — XO authenticates it by HMAC alone — and it spends nothing. A status
refresh takes the same credential triple and reads your order back from the venue.
A status refresh is also the only way to see a partial fill. A resting order keeps its live
status from the first matched share to the last, so the fill shows up as a matched size against the
original size rather than as a status change. A submit acknowledgement reports the same thing in its
own units when an order matches part way and then rests.
Scope, stated plainly: both routes act on an execution Predictefy already holds — they take
an executionId, not a raw venue order id, so they reach XO orders recorded through this service and
not orders you placed elsewhere. Cancelling an order placed outside Predictefy is not a route this
service offers.
A cancel can legitimately fail, and the venue says so with a 200. XO acknowledges a cancel with
the ids it actually removed plus a per-id reason for the ones it did not, so a successful HTTP call
can still report failed with a reason such as already filled — the order matched before your
cancel arrived. That is a real outcome, not an error in your request. The mapping stays fail-closed
in both directions: canceled is reported only when the acknowledgement names your order among the
cancelled ids, and any answer we do not recognise is reported as failed with the venue’s own words.
