> ## Documentation Index
> Fetch the complete documentation index at: https://pmxt-sync-hosted-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Build Order

> Build an order *without* placing it. Returns the order's typed-data payload (for the wallet to sign) plus a `built_order_id` to pass to `submitOrderHosted` once it's signed.

Use this when you want a human to approve each trade before it submits — for example, surfacing the order details in a wallet popup. For everything else, use `createOrderHosted`, which builds + signs + submits in one call.

<Info>
  **Available on:** Polymarket, Opinion, Limitless. Other venues raise `NotSupported` in hosted mode — for those, run a [local PMXT service](/guides/self-hosted).
</Info>

<Note>
  **Before your first call:** deposit USDC on Polygon at [pmxt.dev/dashboard/wallet](https://pmxt.dev/dashboard/wallet) (one-time setup). For the programmatic flow, see [escrow lifecycle](/guides/escrow-lifecycle).
</Note>

<Tip>
  Use any EVM private key. Your USDC sits in a non-custodial PreFundedEscrow on Polygon — for Polymarket, Opinion, and Limitless. PMXT cannot move funds without your EIP-712 signature.
</Tip>


## OpenAPI

````yaml /api-reference/openapi-hosted-trading.json post /v0/trade/build-order
openapi: 3.0.0
info:
  title: PMXT Hosted Router API
  description: Hosted-only endpoints for cross-venue search, matching, arbitrage, and SQL.
  version: 49fbcd4
servers:
  - url: https://trade.pmxt.dev
    description: Hosted trading (v0)
security:
  - bearerAuth: []
tags:
  - name: Trading (Hosted)
    description: >-
      Hosted trading endpoints. Build / submit / cancel orders via
      `trade.pmxt.dev/v0/*`. Hosted-mode is the default when `pmxt_api_key` is
      set.
  - name: Orders & Positions (Hosted)
    description: >-
      Hosted account reads. Open orders, fills, balances, and positions via
      `trade.pmxt.dev/v0/*`. Requires `pmxt_api_key` + `wallet_address`.
  - name: MatchedMarkets
    description: Cross-venue matched market and event clusters.
  - name: SQL
    description: Direct read-only SQL access to the catalog (Enterprise).
paths:
  /v0/trade/build-order:
    post:
      tags:
        - Trading
      summary: Build Order
      description: >-
        Build an order *without* placing it. Returns the order's typed-data
        payload (for the wallet to sign) plus a `built_order_id` to pass to
        `submitOrderHosted` once it's signed.


        Use this when you want a human to approve each trade before it submits —
        for example, surfacing the order details in a wallet popup. For
        everything else, use `createOrderHosted`, which builds + signs + submits
        in one call.
      operationId: buildOrderHosted
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BuildOrderHostedRequest'
      responses:
        '200':
          description: Built order with typed data to sign.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BuildOrderHostedResponse'
        '401':
          description: Invalid or missing PMXT API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HostedErrorResponse'
        '403':
          description: Insufficient escrow balance to back the requested order size.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HostedErrorResponse'
        '404':
          description: Outcome not found in the catalog.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HostedErrorResponse'
        '422':
          description: Invalid order parameters (e.g. price out of range, denom mismatch).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HostedErrorResponse'
        '503':
          description: Catalog unavailable -- temporary upstream failure.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HostedErrorResponse'
      x-codeSamples:
        - lang: python
          label: Polymarket
          source: >
            # Current hosted venues are funded once on Polygon — see
            /guides/escrow-lifecycle.

            # Hosted writes need: pmxt_api_key + wallet_address + private_key
            (signs EIP-712 locally).

            # Pass an outcome straight from client.fetch_markets() — no UUID
            lookup needed.

            import pmxt


            client = pmxt.Polymarket(
                pmxt_api_key="YOUR_PMXT_API_KEY",
                wallet_address="0xYourWallet",    # EVM address — its Polygon USDC funds the escrow
                private_key="0x...",    # any EVM key controlling that address
            )

            market = client.fetch_markets({"query": "trump 2028"})[0]

            yes = next(o for o in market.outcomes if o.label.lower() == "yes")

            order = client.build_order(
                outcome=yes,
                side="buy",
                type="limit",
                amount=10,
                price=0.55,
            )

            print(order.id, order.status)
        - lang: javascript
          label: Polymarket
          source: >
            // Current hosted venues are funded once on Polygon — see
            /guides/escrow-lifecycle.

            // Hosted writes need: pmxtApiKey + walletAddress + privateKey
            (signs EIP-712 locally).

            // Pass an outcome straight from client.fetchMarkets() — no UUID
            lookup needed.

            import { Polymarket } from "pmxtjs";


            const client = new Polymarket({
              pmxtApiKey: "YOUR_PMXT_API_KEY",
              walletAddress: "0xYourWallet",  // EVM address — its Polygon USDC funds the escrow
              privateKey: "0x...",  // any EVM key controlling that address
            });


            const markets = await client.fetchMarkets({ query: "trump 2028" });

            const market = markets[0];

            const yes = market.outcomes.find((o) => o.label.toLowerCase() ===
            "yes")!;

            const order = await client.buildOrder({
              outcome: yes,
              side: "buy",
              type: "limit",
              amount: 10,
              price: 0.55,
            });

            console.log(order.id, order.status);
        - lang: python
          label: Opinion
          source: >
            # Current hosted venues are funded once on Polygon — see
            /guides/escrow-lifecycle.

            # Hosted writes need: pmxt_api_key + wallet_address + private_key
            (signs EIP-712 locally).

            # Pass an outcome straight from client.fetch_markets() — no UUID
            lookup needed.

            import pmxt


            client = pmxt.Opinion(
                pmxt_api_key="YOUR_PMXT_API_KEY",
                wallet_address="0xYourWallet",    # EVM address — its Polygon USDC funds the escrow
                private_key="0x...",    # any EVM key controlling that address
            )

            market = client.fetch_markets({"query": "trump 2028"})[0]

            yes = next(o for o in market.outcomes if o.label.lower() == "yes")

            order = client.build_order(
                outcome=yes,
                side="buy",
                type="limit",
                amount=10,
                price=0.55,
            )

            print(order.id, order.status)
        - lang: javascript
          label: Opinion
          source: >
            // Current hosted venues are funded once on Polygon — see
            /guides/escrow-lifecycle.

            // Hosted writes need: pmxtApiKey + walletAddress + privateKey
            (signs EIP-712 locally).

            // Pass an outcome straight from client.fetchMarkets() — no UUID
            lookup needed.

            import { Opinion } from "pmxtjs";


            const client = new Opinion({
              pmxtApiKey: "YOUR_PMXT_API_KEY",
              walletAddress: "0xYourWallet",  // EVM address — its Polygon USDC funds the escrow
              privateKey: "0x...",  // any EVM key controlling that address
            });


            const markets = await client.fetchMarkets({ query: "trump 2028" });

            const market = markets[0];

            const yes = market.outcomes.find((o) => o.label.toLowerCase() ===
            "yes")!;

            const order = await client.buildOrder({
              outcome: yes,
              side: "buy",
              type: "limit",
              amount: 10,
              price: 0.55,
            });

            console.log(order.id, order.status);
components:
  schemas:
    BuildOrderHostedRequest:
      type: object
      description: >-
        Hosted build-order request. Identify the target outcome by passing
        `venue` + `venue_outcome_id` from `client.fetch_markets()` (the SDK does
        this automatically when you pass `outcome=` to `create_order` or
        `build_order`).
      required:
        - side
        - amount
        - user_address
      properties:
        venue:
          type: string
          enum:
            - polymarket
            - opinion
            - limitless
          description: >-
            Venue the outcome trades on. Inferred automatically from your client
            class in the SDKs.
        venue_outcome_id:
          type: string
          description: >-
            The outcome's identifier (e.g. Polymarket `tokenId`, Opinion outcome
            hash, or Limitless token address). Returned by
            `client.fetch_markets()`.
        side:
          type: string
          enum:
            - buy
            - sell
          description: >-
            Direction of the order. `buy` opens or adds to a long position on
            the outcome; `sell` closes or reduces it.
        order_type:
          type: string
          enum:
            - market
            - limit
          default: market
          description: >-
            `market` fills immediately at the best available price (subject to
            `slippage_pct`); `limit` rests on the venue's order book at `price`
            until matched or cancelled.
        amount:
          type: number
          minimum: 0
          description: >-
            Order size. For `market` buys, in USDC dollars (the budget you want
            to spend). For `market` sells and all `limit` orders, in outcome
            shares.
        denom:
          type: string
          enum:
            - shares
            - usdc
          default: shares
          description: >-
            Unit `amount` is denominated in. `shares` = outcome shares; `usdc` =
            USDC dollars. Market buys require `usdc`; market sells and limit
            orders require `shares` (the server validates this combination).
        price:
          type: number
          minimum: 0
          maximum: 1
          nullable: true
          description: >-
            Required for `limit` orders. Probability in [0, 1] -- e.g. `0.55`
            means buying / selling shares at 55 cents each. Ignored for `market`
            orders.
        slippage_pct:
          type: number
          minimum: 0
          maximum: 100
          nullable: true
          description: >-
            Maximum acceptable slippage as a percent. Use aggressive defaults
            (`30` for buys, `99.9` for sells) until the upstream economic
            validator tightens -- lower values frequently trip precision checks.
            Ignored for market orders, which pin worst-price to the domain
            extreme; the server defaults to `20` when omitted.
        user_address:
          type: string
          description: >-
            EVM wallet address that will sign the resulting typed data. Must
            match the wallet whose USDC funded the PMXT PreFundedEscrow on
            Polygon.
    BuildOrderHostedResponse:
      type: object
      description: >-
        Hosted build-order response. The caller must sign `typed_data` locally
        (and `pull_typed_data` if present) and POST the signatures back via
        `submitOrderHosted` before the order expires.
      required:
        - built_order_id
        - side
        - typed_data
        - quote
      properties:
        built_order_id:
          type: string
          description: >-
            Opaque server-side key used by `submitOrderHosted` to look up the
            build context.
        side:
          type: string
          enum:
            - buy
            - sell
          description: Echo of the order side from the request.
        typed_data:
          type: object
          description: >-
            EIP-712 typed-data payload to sign locally with the wallet key
            matching `user_address`. Return the signature in
            `SubmitOrderHostedRequest.signature`.
        pull_typed_data:
          type: object
          nullable: true
          description: >-
            Optional secondary EIP-712 payload for venues that require a
            separate pull-authorization (notably Polymarket neg-risk markets and
            sell orders). Sign with the same wallet and return in
            `SubmitOrderHostedRequest.pull_signature`. `null` when not required.
        quote:
          type: object
          description: 'Pre-trade quote: expected average fill price, slippage, and fees.'
          properties:
            best_price:
              type: number
              description: >-
                Top-of-book price on the side you are trading against (best ask
                for buys, best bid for sells), in probability units [0, 1].
            expected_avg_price:
              type: number
              description: >-
                Volume-weighted average fill price across the order-book levels
                that would be consumed, in probability units.
            expected_slippage_pct:
              type: number
              description: >-
                Expected slippage from `best_price` to `expected_avg_price`,
                expressed as a percent.
            estimated_cost_or_proceeds:
              type: number
              description: >-
                Estimated USDC dollars to be spent (for buys) or received (for
                sells), net of fees.
            fillable:
              type: boolean
              description: >-
                `true` when the venue currently has enough resting liquidity to
                fill the requested size at-or-better than the implied worst
                price.
            liquidity:
              type: number
              description: >-
                Total resting liquidity on the relevant book side, in USDC
                dollars.
            fee_amount:
              type: number
              description: Estimated PMXT + venue fee for the order, in USDC dollars.
            tick_size:
              type: string
              description: >-
                Minimum price increment on the venue's order book, as a decimal
                string (e.g. `"0.01"`).
        resolved:
          type: object
          nullable: true
          description: >-
            Venue-side fields resolved from the supplied outcome — token ids,
            contract addresses, etc. Useful when you want to cross-reference the
            order against the venue's own API. `null` if resolution failed.
          properties:
            venue:
              type: string
              enum:
                - polymarket
                - opinion
                - limitless
              description: Venue the order will execute on.
            token_id:
              type: string
              description: >-
                Venue-native outcome identifier (Polymarket ERC-1155 `tokenId`,
                Opinion outcome hash, or Limitless token address).
            neg_risk:
              type: boolean
              description: >-
                `true` when the market uses Polymarket's neg-risk contract
                (which requires the secondary `pull_typed_data` signature).
            tick_size:
              type: number
              description: >-
                Minimum price increment on the venue's order book, in
                probability units (e.g. `0.01`).
            opinion_market_id:
              type: integer
              nullable: true
              description: >-
                Opinion-native integer market id. `null` for Polymarket and
                Limitless orders.
    HostedErrorResponse:
      type: object
      description: >-
        Error envelope returned by `trade.pmxt.dev/v0/*` endpoints. Mirrors the
        `ErrorDetail` shape used inside `BaseResponse.error` from the sidecar
        spec.
      required:
        - error
      properties:
        error:
          type: object
          description: Structured error envelope. Always present on non-2xx responses.
          properties:
            message:
              type: string
              description: Human-readable explanation safe to surface to end users.
            code:
              type: string
              description: >-
                Stable hosted-mode error code. Use this (not `message`) for
                branching in client code.
              enum:
                - HOSTED_TRADING_ERROR
                - INSUFFICIENT_ESCROW_BALANCE
                - ORDER_SIZE_TOO_SMALL
                - INVALID_API_KEY
                - OUTCOME_NOT_FOUND
                - CATALOG_UNAVAILABLE
                - BUILT_ORDER_EXPIRED
                - INVALID_SIGNATURE
                - NO_LIQUIDITY
                - MISSING_WALLET_ADDRESS
                - ORDER_NOT_FOUND
                - INVALID_ORDER
            retryable:
              type: boolean
              description: >-
                `true` when the same request may succeed if retried (e.g.
                transient catalog outage); `false` when the caller must change
                inputs first.
            exchange:
              type: string
              nullable: true
              description: >-
                Source venue that produced the error (e.g. `polymarket`,
                `opinion`, `limitless`), when the failure originated upstream of
                PMXT. `null` for PMXT-side errors.
            detail:
              type: object
              additionalProperties: {}
              nullable: true
              description: >-
                Free-form structured diagnostics (e.g. required minimum size,
                escrow balance available). Shape varies per `code`.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Required when calling the hosted API directly (curl, requests, fetch).
        SDK users pass credentials via constructor params instead.

````