> ## Documentation Index
> Fetch the complete documentation index at: https://docs.foresight.now/llms.txt
> Use this file to discover all available pages before exploring further.

# Place orders

> Batch-place up to **15** signed EIP-712 orders. **L2, permission `trade`.**

Matching is asynchronous: every accepted order returns `status: OPEN`.
Per-order rejections are returned inline in `results[]` — always inspect
each item. Request-level failures (batch > 15, auth) are HTTP errors.

See the **Signing orders** guide for the EIP-712 domain, struct, and the
integer-tick `maker_amount` / `taker_amount` math.




## OpenAPI

````yaml /api-reference/openapi-clob-v1.yaml post /v1/orders
openapi: 3.1.0
info:
  title: Foresight CLOB Trading API v1
  version: 1.0.0
  description: >
    Public-facing CLOB (central-limit order book) REST API for the Foresight

    prediction-market platform.


    This is a **different API from the legacy AMM Trade API** (`/trade/*`). The

    CLOB API trades signed limit/market orders against an order book instead of

    swapping against an automated market maker.


    ## Base URL


    ```

    https://api.foresight.now

    ```


    All routes below are prefixed with `/v1`.


    ## Auth tiers


    - **L0** — public, no credentials (all market-data routes).

    - **L1** — Privy JWT (`Authorization: Bearer <jwt>`); used for API-key
    management.

    - **L2** — Privy JWT **or** API-key headers (`fs-api-key` +
    `fs-api-secret`); used for trading and private reads.


    ## Market identity


    A market is identified by the pair **`condition_id`** (on-chain
    ConditionalTokens

    condition hash) + **`chain_id`** (blockchain network id). Internal database

    identifiers are never exposed.


    The CLOB currently runs on **BNB Smart Chain (BSC) mainnet — `chain_id:
    56`**.

    The collateral token on BSC has **18 decimals**. Always read the
    authoritative

    `decimals` from `GET /v1/markets/{condition_id}/tokens` rather than
    hard-coding

    it — amount math signed at the wrong scale is rejected at ingest.


    ## Async matching


    `POST /v1/orders` always returns `status: OPEN`. Matching runs in a
    background

    worker; matched / partial / failed transitions arrive on the private `user`

    WebSocket channel (`wss://api.foresight.now/v1/ws`).


    ## Error envelope


    Every non-2xx response is shaped as (all field names snake_case):


    ```json

    {
      "correlation_id": "abc-123",
      "code": "NOT_FOUND",
      "message": "Market not found",
      "status_code": 404,
      "timestamp": "2026-06-03T10:15:30.000Z",
      "path": "/v1/markets/0x.../book"
    }

    ```
servers:
  - url: https://api.foresight.now
    description: Production
  - url: http://localhost:3000
    description: Local development
security: []
tags:
  - name: Auth
    description: API-key lifecycle and WebSocket token issuance.
  - name: Market Data
    description: Public markets, orderbook, ticker, trades, tokens. L0 — no auth.
  - name: Orders
    description: Place, list, and cancel signed EIP-712 orders. L2.
  - name: Fills
    description: Authenticated wallet's fill history. L2.
  - name: Positions
    description: Authenticated wallet's CLOB positions. L2.
paths:
  /v1/orders:
    post:
      tags:
        - Orders
      summary: Place orders
      description: >
        Batch-place up to **15** signed EIP-712 orders. **L2, permission
        `trade`.**


        Matching is asynchronous: every accepted order returns `status: OPEN`.

        Per-order rejections are returned inline in `results[]` — always inspect

        each item. Request-level failures (batch > 15, auth) are HTTP errors.


        See the **Signing orders** guide for the EIP-712 domain, struct, and the

        integer-tick `maker_amount` / `taker_amount` math.
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PlaceOrdersRequest'
      responses:
        '200':
          description: Per-order results. Mixed success/error is normal.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlaceOrdersResponse'
        '422':
          description: Batch size exceeded or request validation failure.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        default:
          $ref: '#/components/responses/ErrorResponse'
      security:
        - PrivyJWT: []
        - ApiKey: []
          ApiSecret: []
components:
  parameters:
    IdempotencyKeyHeader:
      in: header
      name: fs-idempotency-key
      schema:
        type: string
      description: >-
        Optional idempotency key, scoped to the authenticated user and request
        body hash. Honored on `POST /v1/orders` only.
  schemas:
    PlaceOrdersRequest:
      type: object
      required:
        - orders
      properties:
        orders:
          type: array
          minItems: 1
          maxItems: 15
          items:
            $ref: '#/components/schemas/PlaceOrderItem'
    PlaceOrdersResponse:
      type: object
      properties:
        results:
          type: array
          description: >-
            One entry per submitted order, in request order. Each item is either
            a success or an inline error — always inspect each.
          items:
            oneOf:
              - $ref: '#/components/schemas/PlacedOrderResult'
              - $ref: '#/components/schemas/PlaceOrderError'
        _idempotent_replayed:
          type: boolean
          description: >-
            Present and `true` only when an `fs-idempotency-key` replayed a
            cached result.
    Error:
      type: object
      required:
        - correlation_id
        - code
        - message
        - status_code
        - timestamp
        - path
      properties:
        correlation_id:
          type: string
          description: Request correlation id; falls back to `"unknown"` when none is set.
        code:
          type: string
          example: NOT_FOUND
        message:
          type: string
        status_code:
          type: integer
          example: 404
        timestamp:
          type: string
          format: date-time
        path:
          type: string
          example: /v1/markets/0x.../book
    PlaceOrderItem:
      type: object
      required:
        - condition_id
        - chain_id
        - side
        - order_type
        - outcome
        - price
        - size
        - salt
        - signer
        - taker
        - token_id
        - maker_amount
        - taker_amount
        - expiration
        - nonce
        - fee_rate_bps
        - signature_type
        - signature
      properties:
        condition_id:
          type: string
        chain_id:
          type: integer
          example: 56
        side:
          type: string
          enum:
            - BUY
            - SELL
        order_type:
          type: string
          enum:
            - LIMIT
            - MARKET
            - GTD
          description: '`GTD` (good-til-date) requires a non-zero `expiration`.'
        outcome:
          type: integer
          enum:
            - 0
            - 1
          description: 0 = NO, 1 = YES.
        price:
          type: string
          example: '0.55'
          description: Decimal string in [0.01, 1.00], quantized to 2dp ticks.
        size:
          type: string
          example: '100'
          description: Decimal string >= 0.1.
        salt:
          type: string
          description: uint256 as decimal string.
        signer:
          type: string
          description: Must equal the authenticated wallet address (maker == signer).
        taker:
          type: string
          description: Counterparty restriction; zero address for open orders.
        token_id:
          type: string
          description: ERC-1155 position id from /tokens.
        maker_amount:
          type: string
          description: >-
            Raw token wei (BigInt string). See the signing guide — integer-tick
            math, BUY ceils / SELL floors.
        taker_amount:
          type: string
          description: Raw token wei (BigInt string).
        expiration:
          type: string
          description: Unix seconds; `0` = no expiry.
        nonce:
          type: string
        fee_rate_bps:
          type: integer
          example: 100
        signature_type:
          type: integer
          enum:
            - 0
            - 1
          description: 0 = EOA, 1 = EIP-1271.
        signature:
          type: string
          description: 0x-prefixed EIP-712 signature over the Order struct.
    PlacedOrderResult:
      type: object
      description: >
        A successfully accepted order. Always `status: OPEN` at POST time —

        matching is asynchronous and transitions arrive on the `user` WebSocket
        channel.
      properties:
        order_hash:
          type: string
        condition_id:
          type: string
        chain_id:
          type: integer
          example: 56
        status:
          type: string
          enum:
            - OPEN
          description: Always OPEN at POST time.
        side:
          type: string
          enum:
            - BUY
            - SELL
        outcome:
          type: integer
          enum:
            - 0
            - 1
        price:
          type: string
        size:
          type: string
        remaining_size:
          type: string
        fills:
          type: array
          description: >-
            Always empty at POST time. Read fills from the `user` WS channel or
            `GET /v1/fills`.
          items: {}
        book_added_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            Null at POST time; set by the matcher worker when the row reaches
            the book or a terminal state.
        created_at:
          type: string
          format: date-time
    PlaceOrderError:
      type: object
      description: A per-order rejection, returned inline in the `results` array.
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              example: WALLET_MISMATCH
            message:
              type: string
  responses:
    ErrorResponse:
      description: Error envelope.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    PrivyJWT:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Privy-issued JWT. Required for L1 routes; accepted on L2 routes.
    ApiKey:
      type: apiKey
      in: header
      name: fs-api-key
      description: >-
        API key id issued by `POST /v1/auth/api-keys`. Pair with
        `fs-api-secret`.
    ApiSecret:
      type: apiKey
      in: header
      name: fs-api-secret
      description: Plaintext secret returned once at API-key creation.

````