> ## Documentation index
> Fetch the complete documentation index at: https://docs.predictefy.com/llms.txt
> Use it to discover every available page before exploring further.

# XO

> The build request schema, signing scheme, and bounds for XO.

## Step zero — from nothing to your first trade

1. **Create the account.** Start at [xo.market](https://xo.market) and obtain caller-owned XO CLOB
   access. XO access is partner-provided; the sources do not document its signup or KYC flow.
2. **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 /order` documents 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, `signatureType` 0). Funded
   verification of the wrapped-signature path is in progress.
3. **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, query `GET /v1/bridge/quote`
   first and use a venue-confirmed route if XO is unsupported.
4. **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

- **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 `3223` is the default identity, and it is both
  the order's `maker` and its `signer`. 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 `maker` account, 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 the `maker`, 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.

:::caution[No XO order has ever been submitted through Predictefy]
Every claim on this page is verified against the venue's own API documentation and, for the signing
contract, against the deployed exchange on chain `3223` — the EIP-712 domain our builder computes is
byte-identical to the contract's own `domainSeparator()`, and the contract's read-only order-hashing
view returns the exact digest we ask you to sign. What has **not** happened is a live credentialed
call: no XO order has been placed through this service, so the first live submit is the point at
which the wire contract is confirmed rather than derived. Treat an early failure as new information
about the venue, not as a regression.
:::

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

`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.

### Fees

**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 the `signer`
  stored 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-1271
  `isValidSignature`. 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

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.

:::caution[What an XO cancel can and cannot do]
Cancelling removes the order from XO's **order book**. It does **not** invalidate the signed order
on-chain: the deployed exchange ships no cancel function, and self-service nonce bumping is
restricted to the venue operator, so there is no maker-side on-chain invalidation to offer. The
residual exposure is bounded by the exchange's fill functions being operator-only — the only party
that could still fill a removed order is the operator you removed it from. Treat a cancel as
"withdrawn from the book", not "revoked".
:::

:::caution[XO liquidity and eligibility]
A read-only scan found only **2 active markets in 3,000 catalog rows**. Treat fill probability and
depth as thin until a live book proves otherwise. Venue access and jurisdiction restrictions are an
operator/compliance matter; source-ready code is not permission to enable or trade from every region.
:::
