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

# Batch create orders

> Batch create orders.

 Create multiple orders in a single batch. Each order is processed
 sequentially through the matching engine.



## OpenAPI

````yaml post /api/v1/orders/batch-create
openapi: 3.0.3
info:
  title: Monaco Protocol API
  description: REST API for the Monaco Protocol hybrid CLOB exchange.
  version: 1.0.0
servers:
  - url: https://apimonaco.xyz
    description: Production (Sei mainnet)
security: []
tags:
  - name: AccountsService
  - name: ApplicationsService
  - name: AuthService
  - name: BuildercodeRewardsService
  - name: ComplianceService
  - name: CopyTradingService
  - name: DelegatedAgentsService
  - name: FaucetService
  - name: FeesService
  - name: HealthService
  - name: ManagedMarketsService
    description: |-
      Wallet-authenticated maker assignments. The signed session must match both
       configured maker user and application. Owner IDs are process fences, never auth.
       Only wallet sessions are supported; delegated-agent sessions receive 403.
  - name: MarginAccountsService
    description: |-
      Current public isolated-margin semantics:
       - a user has one parent margin account per application scope
       - opening orders create or reuse isolated position buckets under that parent
       - parent account creation is handled internally by margin workflows
  - name: MarketService
  - name: OrderbookService
  - name: OrdersService
  - name: PositionsService
    description: |-
      Current public isolated-margin semantics:
       - positions link to a parent margin account and, when applicable, a bucket id
       - opening orders create or reuse isolated position buckets under the parent
       - users can open another isolated position by reusing the parent account with a different market bucket
  - name: PulseService
  - name: SweeperService
  - name: TraderCodeService
  - name: TradesService
  - name: WithdrawalsService
paths:
  /api/v1/orders/batch-create:
    post:
      tags:
        - OrdersService
        - Orders
      summary: Batch create orders
      description: |-
        Batch create orders.

         Create multiple orders in a single batch. Each order is processed
         sequentially through the matching engine.
      operationId: batch_create_orders
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BatchCreateOrdersRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BatchCreateOrdersResponse'
        '400':
          description: Invalid request
        '401':
          description: Authentication required
        '429':
          description: >-
            Order rate limit exceeded — each batch item counts against the
            per-account budget (and the account family's shared budget) and the
            whole request is rejected; retry after the interval in
            details.retryAfter
        '500':
          description: Internal server error
      security:
        - monacoSignature: []
        - monacoHttpSignature: []
components:
  schemas:
    BatchCreateOrdersRequest:
      required:
        - orders
      type: object
      properties:
        orders:
          maxItems: 100
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/BatchCreateOrderItem'
      additionalProperties: false
    BatchCreateOrdersResponse:
      type: object
      properties:
        totalRequested:
          example: 5
          type: integer
          description: Number of orders requested to create
          format: int32
          nullable: true
        totalSucceeded:
          example: 4
          type: integer
          description: Number of orders successfully created
          format: int32
          nullable: true
        totalFailed:
          example: 1
          type: integer
          description: Number of creations that failed
          format: int32
          nullable: true
        results:
          type: array
          items:
            $ref: '#/components/schemas/BatchCreateResult'
          nullable: true
    BatchCreateOrderItem:
      required:
        - tradingPairId
        - orderType
        - side
        - quantity
      type: object
      properties:
        tradingPairId:
          example: 456e7890-e12b-12d3-a456-426614174000
          type: string
          description: Trading pair UUID
          format: uuid
        orderType:
          example: LIMIT
          type: string
          description: 'Order type: LIMIT or MARKET'
        side:
          example: BUY
          type: string
          description: 'Order side: BUY or SELL'
        price:
          example: '35000.00'
          type: string
          description: Limit price as decimal string (required for LIMIT orders)
          nullable: true
        quantity:
          example: '0.5'
          type: string
          description: Order quantity as decimal string
        tradingMode:
          example: SPOT
          type: string
          description: 'Trading mode: SPOT or MARGIN (default: SPOT)'
          nullable: true
        slippageToleranceBps:
          example: 50
          maximum: 10000
          type: integer
          description: Maximum slippage tolerance in basis points (market orders only)
          format: int32
          nullable: true
        useMasterBalance:
          example: false
          type: boolean
          description: Use master account balance for sub-account orders
          nullable: true
        expirationDate:
          example: '2026-06-01T00:00:00Z'
          type: string
          description: Order expiration date (ISO 8601, must be in the future)
          nullable: true
        timeInForce:
          example: GTC
          type: string
          description: >-
            Time in force: GTC, IOC, or FOK. LIMIT orders only; rejected on
            MARKET orders.
          nullable: true
        marginAccountId:
          example: 123e4567-e89b-12d3-a456-426614174000
          type: string
          description: Margin account UUID for margin orders
          format: uuid
          nullable: true
        riskBucketId:
          example: 123e4567-e89b-12d3-a456-426614174001
          type: string
          description: >-
            Existing isolated risk bucket UUID for risk-bucket-scoped margin
            orders
          format: uuid
          nullable: true
        riskBucketCollateral:
          example: '1000'
          type: string
          description: >-
            Decimal collateral allocated as an order budget in a new isolated
            risk bucket. Fills commit their required margin and paid-fee funding
            to position backing; unfilled or unused order funds do not protect
            the position from liquidation. Use position margin adjustment to add
            liquidation protection. The API creates the bucket ID and the
            matching engine persists it through the durable log.
          nullable: true
        positionSide:
          example: LONG
          deprecated: true
          enum:
            - LONG
            - SHORT
          type: string
          description: >-
            DEPRECATED compatibility field. Order side is authoritative. When
            supplied, BUY requires LONG and SELL requires SHORT; NONE is
            rejected.
          nullable: true
        leverage:
          example: '5'
          type: string
          description: >-
            Leverage multiplier as a decimal string. Required for normal margin
            orders; optional and ignored for reduce-only orders.
          nullable: true
        reduceOnly:
          example: false
          type: boolean
          description: Whether the margin order is reduce-only
          nullable: true
        strategyKey:
          example: my-strategy
          type: string
          description: Strategy key used to group risk buckets for delegated/margin orders
          nullable: true
        marginMode:
          example: CROSS
          enum:
            - ISOLATED
            - CROSS
          type: string
          description: >-
            Risk bucket mode for margin orders. Defaults to ISOLATED. Values:
            ISOLATED, CROSS. On an isolated-only market
            (TradingPairData.isolated_only) a CROSS order that is not
            reduce-only is rejected with HTTP 400 / gRPC INVALID_ARGUMENT
            carrying the structured error code CROSS_MARGIN_NOT_ALLOWED. One
            margin mode per market and margin account: while the account holds
            the pair in its other risk bucket (an open position, or a resting
            order that is not reduce-only), an order that is not reduce-only is
            rejected with HTTP 400 / gRPC INVALID_ARGUMENT carrying the
            structured error code MARGIN_MODE_CONFLICT; reduce-only orders
            always pass, so a pair already held in both modes can be reduced on
            either side until one closes.
          nullable: true
        postOnly:
          example: false
          type: boolean
          description: >-
            Post-only: reject instead of matching if this limit order would
            cross the book — rejected with HTTP 400 / gRPC INVALID_ARGUMENT
            carrying the structured error code POST_ONLY_WOULD_CROSS (REST
            error-envelope 'code' field; gRPC google.rpc.ErrorInfo reason; batch
            per-item error.code). Matching the 'post-only order would cross'
            message substring is a legacy fallback. LIMIT orders with GTC only;
            rejected on MARKET orders and IOC/FOK.
          nullable: true
        clientOrderId:
          example: quote-btc-1130-a
          type: string
          description: >-
            Client-assigned correlation handle, echoed back on order reads
            (detail and list) and on order WebSocket events. At most 64
            characters from [A-Za-z0-9._:-]; surrounding whitespace is trimmed
            before storage, and a blank or whitespace-only value is treated as
            absent. Uniqueness is enforced only among your orders that are
            RESTING on the book: an item reusing a value another of your resting
            orders still holds fails that item alone — the batch itself returns
            2xx / OK and the offending item's result slot carries error.code
            CLIENT_ORDER_ID_CONFLICT; no transport-level 409 / ALREADY_EXISTS is
            raised. An order that never rests — MARKET, IOC/FOK, or a LIMIT that
            fills completely on arrival — does not take the handle, and the
            value is released the moment any order reaches a terminal state. It
            is therefore NOT an idempotency key: resubmitting after a lost
            response can execute a second time. Reconcile a lost response
            against the order WebSocket stream, which carries this value on the
            submit acknowledgement and on fills, including for orders that never
            rest; order history is replica-backed and can omit an order that did
            land. The stream is not replayable and has no sequence number to
            backfill from, and its fan-out is non-persistent Core NATS: the
            service can re-establish an ended upstream subscription without
            closing your socket, so events can be missed while your connection
            still looks healthy. A matching event is therefore positive proof
            the order was accepted, but silence is NEVER evidence it was not,
            and no client-observable condition makes it so. Absent positive
            evidence the outcome is unresolved: hold and escalate rather than
            resubmitting. Rejections split in two: an item rejected before
            acceptance (malformed, post-only would cross, handle conflict, a
            plain MARKET submit with no liquidity, rejected during pricing)
            fails only that item — a per-item error in an otherwise-successful
            response — emits no event and is never written to order history (an
            item rejected AFTER acceptance is persisted with status REJECTED, so
            only the pre-acceptance class is absent); an accepted LIMIT with IOC
            or FOK that cannot fill, or an accepted MARKET order whose apparent
            liquidity is invalidated by maker-risk revalidation, reports
            matchResult.status REJECTED in its result slot and emits OrderPlaced
            then OrderRejected, both carrying this value. Neither the batch's
            2xx nor a populated result slot therefore means the order executed.
            Where no surface is conclusive, do not resubmit.
          nullable: true
        idempotencyKey:
          maxLength: 64
          minLength: 1
          pattern: ^[A-Za-z0-9._:-]+$
          type: string
          description: >-
            Optional submission identity, distinct from clientOrderId. Use 1-64
            characters from [A-Za-z0-9._:-], without whitespace. Scoped to your
            authenticated user/subaccount and application, shared by create and
            batch-create items. Retrying the same key and normalized order
            payload within 15 minutes of the original acceptance returns the
            original committed submission result, even after a fill or
            cancellation, without executing again. A full response cache does
            not prevent new keyed submissions: durable responses may be evicted
            while exact key history remains retained. If response capacity is
            protected by pending durability or persistence, a new key is refused
            with ORDER_SUBMISSION_CAPACITY_EXCEEDED. A retry whose original
            response cannot currently be retrieved returns
            ORDER_SUBMISSION_UNAVAILABLE and never executes again. Both are HTTP
            503 / gRPC UNAVAILABLE, or per-item errors in batches. Retry the
            same key and payload; for previously accepted keys, stay within 15
            minutes of the original acceptance. A capacity refusal does not
            accept or reserve a new key. Different payload returns
            IDEMPOTENCY_KEY_CONFLICT (HTTP 409 / gRPC ALREADY_EXISTS; per-item
            error in batches). Validation failures before acceptance do not
            reserve the key. The window does not extend on retries; after it
            expires the key may execute a new order, so never retry an
            unresolved submission after 15 minutes. Generate a fresh key for
            each intended new order and retain it across transport retries.
            Without a key, a timeout or 5xx leaves the outcome unknown and must
            not be blindly retried.
          nullable: true
        selfTradePreventionMode:
          example: CANCEL_TAKER
          enum:
            - CANCEL_MAKER
            - CANCEL_TAKER
            - CANCEL_BOTH
            - SKIP
          type: string
          description: >-
            Per-order self-trade-prevention override: how the engine resolves
            this order matching against one of your own resting orders (your
            whole wallet family, subaccounts included; the incoming order's mode
            governs the step and resting orders' modes are never consulted).
            CANCEL_MAKER cancels each of your resting orders encountered and
            keeps matching. CANCEL_TAKER fills third-party liquidity up to the
            first self-touch, then cancels the incoming order's remainder — a
            zero-fill CANCELLED outcome is possible. CANCEL_BOTH additionally
            cancels the encountered resting orders. SKIP trades around your
            resting orders; a remainder that would rest crossing one of your
            surviving orders is cancelled instead of resting. Omitted, your
            wallet's configured default applies, else the platform default
            CANCEL_MAKER. STP cancellations carry terminalReason
            SELF_TRADE_PREVENTION and stpCounterpartyOrderId on reads and
            WebSocket events. With time_in_force FOK: CANCEL_MAKER cancels your
            makers first and then fills or kills; CANCEL_TAKER and SKIP cancel
            the whole order when self is in the fill path; CANCEL_BOTH fails
            only this item with a per-item SELF_TRADE_NOT_ALLOWED error — the
            batch itself still returns 2xx / OK. An unknown value likewise fails
            only this item, with error.code INVALID_SELF_TRADE_PREVENTION_MODE.
            The requested value is echoed back as selfTradePreventionMode on
            order reads, absent when omitted here.
          nullable: true
      additionalProperties: false
    BatchCreateResult:
      type: object
      properties:
        orderId:
          example: 123e4567-e89b-12d3-a456-426614174000
          type: string
          description: Created order UUID
          format: uuid
          nullable: true
        matchResult:
          $ref: '#/components/schemas/MatchResult'
        error:
          $ref: '#/components/schemas/BatchCreateError'
    MatchResult:
      type: object
      properties:
        tradesCount:
          example: 2
          type: integer
          description: Number of trades generated by this order
          format: int32
          nullable: true
        totalFilled:
          example: '0.2'
          type: string
          description: Total quantity filled
          nullable: true
        remainingQuantity:
          example: '0.3'
          type: string
          description: Remaining unfilled quantity
          nullable: true
        averageFillPrice:
          example: '35100.00'
          type: string
          description: Volume-weighted average fill price
          nullable: true
        status:
          example: PARTIALLY_FILLED
          type: string
          description: Resulting order status after matching
          nullable: true
        actualSlippageBps:
          example: 15
          type: integer
          description: Actual slippage incurred in basis points
          format: int32
          nullable: true
        maxSlippageBps:
          example: 50
          type: integer
          description: Maximum slippage tolerance that was set
          format: int32
          nullable: true
        executionPriceRange:
          $ref: '#/components/schemas/ExecutionPriceRange'
    BatchCreateError:
      type: object
      properties:
        code:
          example: INSUFFICIENT_BALANCE
          type: string
          description: >-
            Machine-readable error code. ORDER_SUBMISSION_CAPACITY_EXCEEDED
            refuses a new keyed submission when response-cache capacity is
            protected by pending durability or persistence.
            ORDER_SUBMISSION_UNAVAILABLE means the original response is
            temporarily unavailable or keyed admission is busy; it never
            authorizes duplicate execution. Retry the same key and payload; the
            15-minute limit applies only to previously accepted keys.
          nullable: true
        message:
          example: Insufficient balance to place order
          type: string
          description: Human-readable error message
          nullable: true
    ExecutionPriceRange:
      type: object
      properties:
        bestPrice:
          example: '2045.00'
          type: string
          description: Best execution price achieved
          nullable: true
        worstPrice:
          example: '2052.00'
          type: string
          description: Worst execution price in the fill
          nullable: true
  securitySchemes:
    monacoSignature:
      type: apiKey
      description: >-
        Ed25519 session-key request signing. Every authenticated request carries
        three headers: `X-Monaco-PublicKey` (64-char lowercase-hex session
        public key), `X-Monaco-Timestamp` (Unix milliseconds, within 30s of
        server time), and `X-Monaco-Signature` (hex ed25519 signature). The
        signature is over `METHOD\npath?query\ntimestamp_ms\nSHA256_hex(body)`,
        where the body hash is the SHA-256 of the empty byte string when there
        is no body. Obtain the session keypair from `POST
        /api/v1/auth/challenge` followed by `POST /api/v1/auth/verify`.
      name: X-Monaco-Signature
      in: header
    monacoHttpSignature:
      type: apiKey
      description: >-
        RFC 9421 Ed25519 session-key request signatures. Send Signature-Input,
        Signature, and Content-Digest together; never combine them with
        X-Monaco-* credentials. The monaco signature covers @method, @path,
        @query, and content-digest in that order, with created (Unix seconds
        within 30s of server time), keyid (registered lowercase-hex session
        public key), and alg=ed25519 parameters. Content-Digest uses RFC 9530
        sha-256 over the exact body bytes, including the empty body. Query
        coverage retains ordering and percent encoding. Timestamp freshness does
        not reject repeated identical requests; use endpoint idempotency where
        supported. Existing legacy signing remains supported during server-first
        migration; SDK RFC 9421 signing is opt-in. See
        https://docs.0xmonaco.com/reference/http-message-signatures for the
        complete profile and trust model.
      name: Signature
      in: header

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.