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

# Submit a market, limit, or stop order

> Submits an order to the command queue for processing. Returns a `command_id` you can use to track status.

**Order types:**
- `market` — executes immediately at best available price
- `limit` — executes when price reaches your level or better (requires `price`)
- `stop` — triggers a market order when price reaches stop level (requires `price`)

**Bracket orders:** optionally attach `take_profit` and/or `stop_loss` prices. These create child limit/stop orders that auto-cancel each other (OCO) when one fills.

**Validation:** checks account ownership, trading status, lockout, max contracts rule, and tick size before accepting.

Requires `x-idempotency-key` header to prevent duplicate submissions.



## OpenAPI

````yaml /api-reference/trade-openapi.json post /trade/order
openapi: 3.0.3
info:
  contact:
    name: Hyperprop
    url: https://hyperprop.com
  description: >
    # Hyperprop Trade API


    Authenticated trading API for prop firm evaluations. Execute trades, manage
    positions, and monitor account performance in real-time.


    ---


    ## Introduction


    The Hyperprop Trade API is a **high-performance trading engine** built from
    the ground up in **Rust** — the same language powering mission-critical
    systems at Discord, Cloudflare, and AWS. We chose Rust for one reason:
    **speed without compromise**.


    ### Why Rust?


    | Metric | Hyperprop (Rust) | Traditional APIs |

    |--------|------------------|------------------|

    | Engine processing | **< 1ms** | 5-20ms |

    | Typical end-to-end | **10-50ms** | 50-200ms |

    | Memory safety | **Guaranteed** | Runtime errors |

    | Concurrent users | **Thousands** | Hundreds |


    Our engine processes orders with **sub-millisecond internal latency**,
    handles thousands of concurrent WebSocket connections, and enforces trading
    rules in real-time — all while maintaining zero-copy memory efficiency.


    ### Architecture Highlights


    - **Zero-allocation hot path**: Order execution avoids memory allocation for
    maximum throughput

    - **Lock-free data structures**: Concurrent access without blocking

    - **Real-time rule enforcement**: P&L limits, drawdown checks, and position
    limits evaluated on every tick

    - **WebSocket-first design**: Instant event streaming with < 5ms delivery

    - **Async I/O**: Built on Tokio for efficient handling of 10,000+
    simultaneous connections


    ### What You Can Do


    - **Execute trades** with market, limit, and stop orders

    - **Monitor positions** with real-time P&L updates

    - **Stream events** via WebSocket for instant order fills, position changes,
    and rule violations

    - **Track multiple accounts** across different prop firms simultaneously


    ---


    ## Quick Start


    ```javascript

    // 1. Get your JWT token from your auth provider

    const token = 'your-jwt-token';


    // 2. Fetch your accounts

    const res = await fetch('/trade/accounts', {
      headers: { 'Authorization': `Bearer ${token}` }
    });

    const { data: accounts } = await res.json();


    // 3. Place a trade

    const order = await fetch('/trade/order', {
      method: 'POST',
      headers: { 
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        account_id: accounts[0].id,
        contract: 'ESH6',
        side: 'buy',
        quantity: 1
      })
    });

    ```


    ---


    ## Authentication


    All endpoints require a valid JWT token.


    **Header (recommended):**

    ```http

    Authorization: Bearer <your-jwt-token>

    ```


    **Query parameter (for WebSocket):**

    ```text

    /trade/ws?token=<your-jwt-token>

    ```


    ---


    ## Response Format


    All responses follow this structure:


    ### Success Response

    ```json

    {
      "success": true,
      "data": { ... },
      "error": null,
      "code": null
    }

    ```


    ### Error Response

    ```json

    {
      "success": false,
      "data": null,
      "error": "Human readable error message",
      "code": "ERROR_CODE"
    }

    ```


    ---


    ## Error Codes


    ### Authentication & Access


    | Code | HTTP Status | Description |

    |------|-------------|-------------|

    | `UNAUTHORIZED` | 401 | Invalid or missing JWT token |

    | `FORBIDDEN` | 403 | Account does not belong to you |

    | `NO_ACCOUNT` | 404 | No trading account found for user |

    | `NOT_FOUND` | 404 | Resource not found (order, position, command, etc.) |

    | `ENGINE_AT_CAPACITY` | 400 | Too many commands are already in flight; the
    order was NOT accepted. Retry after a short backoff — the same
    `x-idempotency-key` is safe to reuse because nothing was queued. |


    ### Trading


    | Code | HTTP Status | Description |

    |------|-------------|-------------|

    | `TRADING_DISABLED` | 403 | Account status prevents trading (passed or
    failed) |

    | `MARKET_NOT_ENABLED` | 403 | Account does not have access to this
    contract's exchange (e.g., trying to trade COMEX contract on a CME-only
    account) |

    | `INVALID_SIDE` | 400 | Side must be `buy` or `sell` |

    | `INVALID_CONTRACT` | 400 | Contract symbol is unknown or not active |

    | `INVALID_QUANTITY` | 400 | Quantity must be greater than 0 |

    | `MISSING_PRICE` | 400 | Limit/stop orders require a `price` field |

    | `INVALID_TAKE_PROFIT` | 400 | Take-profit price is invalid (<=0, bad tick,
    or wrong side relative to entry) |

    | `INVALID_STOP_LOSS` | 400 | Stop-loss price is invalid (<=0, bad tick, or
    wrong side relative to entry) |

    | `BRACKET_ATTACH_FAILED` | 400 | Bracket order validation failed (invalid
    TP/SL combination) |

    | `INVALID_REQUEST` | 400 | Missing or invalid request fields |


    ### Lockout


    | Code | HTTP Status | Description |

    |------|-------------|-------------|

    | `LOCKOUT_ACTIVE` | 403 | Account is currently locked — trading actions are
    blocked |

    | `INVALID_LOCKOUT_MODE` | 400 | Mode must be one of: `hours`,
    `trading_day`, `timed`, `session`, `trade_clock` |

    | `INVALID_LOCKOUT_DURATION` | 400 | Duration is invalid (e.g. hours <= 0,
    or unknown timed_duration value) |

    | `LOCKOUT_NOT_REMOVABLE` | 403 | Lockout cannot be removed by user — either
    it is timed (wait for expiry), trade_clock with open exposure, or
    admin-locked |


    ### Idempotency & Infrastructure


    | Code | HTTP Status | Description |

    |------|-------------|-------------|

    | `DUPLICATE_REQUEST` | 409 | Same `x-idempotency-key` was already used for
    this operation |

    | `RATE_LIMITED` | 429 | Too many requests — account exceeded the allowed
    rate for this action |

    | `REDIS_UNAVAILABLE` | 503 | Internal command queue unavailable — the
    command was not accepted; retry with backoff |

    | `INTERNAL_ERROR` | 500 | Unexpected server error (check logs) |


    ---


    ## Order Types


    | Type | Description | Required Fields |

    |------|-------------|-----------------|

    | `market` | Execute immediately at best price | account_id, contract, side,
    quantity |

    | `limit` | Execute when price reaches level | + price |

    | `stop` | Trigger market order at stop price | + price |


    ### Order Request Examples


    **Market Order:**

    ```json

    {
      "account_id": "550e8400-e29b-41d4-a716-446655440000",
      "contract": "ESH6",
      "side": "buy",
      "quantity": 2
    }

    ```


    **Limit Order:**

    ```json

    {
      "account_id": "550e8400-e29b-41d4-a716-446655440000",
      "contract": "ESH6",
      "side": "sell",
      "quantity": 1,
      "order_type": "limit",
      "price": 6050.25
    }

    ```


    **Stop Order:**

    ```json

    {
      "account_id": "550e8400-e29b-41d4-a716-446655440000",
      "contract": "ESH6",
      "side": "sell",
      "quantity": 1,
      "order_type": "stop",
      "price": 6000.00
    }

    ```


    ### Order Response

    ```json

    {
      "success": true,
      "data": {
        "id": "order-uuid",
        "user_id": "user-uuid",
        "account_id": "account-uuid",
        "contract": "ESH6",
        "side": "buy",
        "order_type": "market",
        "quantity": 2,
        "filled_quantity": 2,
        "limit_price": null,
        "stop_price": null,
        "status": "filled",
        "filled_price": 6045.50,
        "filled_at": "2024-01-15T10:30:00Z",
        "processed_at": "2024-01-15T10:30:00Z",
        "reject_reason": null
      }
    }

    ```


    ---


    ## Account Status


    The engine returns these status values via REST and WebSocket. The database
    stores equivalent aliases shown in the DB column.


    | API Status | DB Value | Can Trade | Description |

    |------------|----------|-----------|-------------|

    | `Active` | `not_started` | ✅ | Account created, not yet traded |

    | `InProgress` | `in_progress` | ✅ | Actively trading |

    | `Completed` | `passed` | ❌ | Profit target reached — account passed
    (flat-confirmed) |

    | `Violated` | `failed` | ❌ | Rule violation — auto-liquidated, trading
    disabled |

    | `Violated` | `expired` | ❌ | Account expired — treated same as failed |


    ---


    ## Position Schema


    ```json

    {
      "user_id": "user-uuid",
      "account_id": "account-uuid",
      "contract": "ESH6",
      "quantity": 2,
      "avg_entry_price": 6045.50,
      "unrealized_pnl": 125.00,
      "realized_pnl": 0.00,
      "opened_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:35:00Z"
    }

    ```


    - `quantity`: Positive = long, negative = short

    - `unrealized_pnl`: Current P&L if closed now

    - `realized_pnl`: Gross P&L from partial closes (does NOT include fees)


    ---


    ## Trade Schema


    ```json

    {
      "id": "trade-uuid",
      "user_id": "user-uuid",
      "account_id": "account-uuid",
      "order_id": "order-uuid",
      "contract": "ESH6",
      "side": "buy",
      "price": 6045.50,
      "quantity": 2,
      "realized_pnl": 0.00,
      "timestamp": "2024-01-15T10:30:00Z"
    }

    ```


    ---


    ## WebSocket


    Real-time streaming of trading events.


    ### Connection


    ```text

    wss://{host}/trade/ws?token=JWT_TOKEN

    wss://{host}/trade/ws?token=JWT_TOKEN&account_id=ACCOUNT_UUID

    ```


    Replace `{host}` with your current domain (e.g., `api.hyperprop.com` or
    `localhost:8080`).


    ### Commands


    | Command | Description |

    |---------|-------------|

    | `{"action": "subscribe", "account_id": "uuid"}` | Filter to specific
    account |

    | `{"action": "subscribe", "account_id": "*"}` | Receive all accounts
    (default) |

    | `{"action": "unsubscribe", "account_id": "uuid"}` | Stop receiving account
    events |

    | `{"action": "ping"}` | Keep-alive |


    ### Events


    **Welcome (on connect):**

    ```json

    {
      "type": "Welcome",
      "user_id": "user-uuid",
      "accounts": [
        {"id": "acc-1", "account_number": "HP-12345", "balance": 50000, "status": "Active"}
      ],
      "subscribed_to": "*",
      "open_positions": 1,
      "pending_orders": 0
    }

    ```


    **OrderSubmitted:**

    ```json

    {
      "type": "OrderSubmitted",
      "user_id": "user-uuid",
      "account_id": "account-uuid",
      "order": {
        "id": "order-uuid",
        "contract": "ESH6",
        "product": "CME",
        "symbol": "ES",
        "side": "buy",
        "order_type": "market",
        "quantity": 1,
        "status": "filled",
        "filled_price": 6045.50,
        "reason": "User submitted market order"
      }
    }

    ```


    **OrderFilled:**

    ```json

    {
      "type": "OrderFilled",
      "user_id": "user-uuid",
      "account_id": "account-uuid",
      "order": {
        "id": "order-uuid",
        "contract": "ESH6",
        "product": "CME",
        "symbol": "ES",
        "side": "buy",
        "order_type": "limit",
        "quantity": 1,
        "status": "filled",
        "filled_price": 6045.50,
        "reason": "Limit price reached"
      },
      "trade": { "id": "trade-uuid", "price": 6045.50, "quantity": 1, "realized_pnl": 0 }
    }

    ```


    **OrderCancelled:**

    ```json

    {
      "type": "OrderCancelled",
      "user_id": "user-uuid",
      "account_id": "account-uuid",
      "order": {
        "id": "order-uuid",
        "contract": "ESH6",
        "product": "CME",
        "symbol": "ES",
        "side": "buy",
        "order_type": "limit",
        "quantity": 1,
        "status": "cancelled",
        "reason": "User requested cancellation"
      }
    }

    ```


    **PositionUpdate:**

    ```json

    {
      "type": "PositionUpdate",
      "user_id": "user-uuid",
      "account_id": "account-uuid",
      "position": { "contract": "ESH6", "quantity": 1, "unrealized_pnl": 125.00, ... }
    }

    ```


    **AccountUpdate:**

    ```json

    {
      "type": "AccountUpdate",
      "user_id": "user-uuid",
      "account_id": "account-uuid",
      "current_balance": 50000.00,
      "equity": 50125.00,
      "high_water_mark": 50125.00,
      "unrealized_pnl": 125.00,
      "total_pnl": 125.00,
      "daily_pnl": 125.00,
      "current_drawdown": 0.00,
      "status": "InProgress",
      "violation_reason": null
    }

    ```


    **RuleViolation:**

    ```json

    {
      "type": "RuleViolation",
      "user_id": "user-uuid",
      "account_id": "account-uuid",
      "rule": "max_loss",
      "reason": "Max Loss exceeded: $2500 loss >= $2500 limit"
    }

    ```


    **Notification:**

    ```json

    {
      "type": "Notification",
      "user_id": "user-uuid",
      "account_id": "account-uuid",
      "level": "warning",
      "title": "Copy Trade Failed",
      "message": "Failed to copy BUY 1 ESH6 to follower account: Order would exceed max contracts limit (15 > 10)",
      "category": "copy_trade"
    }

    ```


    Notification levels: `info`, `warning`, `error`


    Notification categories:

    - `copy_trade` - Copy trading events (failed copies, sync issues)

    - `order` - Order-related notifications (rejections, modifications)

    - `risk` - Risk management alerts (approaching limits)

    - `system` - System notifications (maintenance, updates)


    ### Example Client


    ```javascript

    const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';

    const ws = new
    WebSocket(`${protocol}//${location.host}/trade/ws?token=${jwt}&account_id=${accountId}`);


    ws.onopen = () => console.log('Connected');


    ws.onmessage = (e) => {
      const msg = JSON.parse(e.data);
      
      switch (msg.type) {
        case 'Welcome':
          console.log('Accounts:', msg.accounts);
          break;
        case 'OrderFilled':
          console.log(`Filled: ${msg.order.side} ${msg.order.quantity} ${msg.order.contract} @ ${msg.trade.price}`);
          break;
        case 'PositionUpdate':
          console.log(`P&L: $${msg.position.unrealized_pnl.toFixed(2)}`);
          break;
        case 'AccountUpdate':
          console.log(`Equity: $${msg.equity.toFixed(2)}, Drawdown: $${msg.drawdown.toFixed(2)}`);
          break;
        case 'RuleViolation':
          alert(`⚠️ ${msg.reason}`);
          break;
        case 'Notification':
          // Display notification to user based on level
          const icon = msg.level === 'error' ? '❌' : msg.level === 'warning' ? '⚠️' : 'ℹ️';
          console.log(`${icon} ${msg.title}: ${msg.message}`);
          // Show toast/notification in UI
          break;
      }
    };


    // Switch accounts dynamically

    ws.send(JSON.stringify({ action: 'subscribe', account_id:
    'other-account-uuid' }));

    ```


    ---


    ## Trading Rules


    Each account has rules that are checked in real-time:


    | Rule | Type | Description |

    |------|------|-------------|

    | `profit_target` | $ | Target profit to pass evaluation |

    | `max_loss` | $ | Maximum total loss allowed |

    | `daily_loss` | $ | Maximum loss per day |

    | `max_drawdown` | % | Max drawdown from high water mark |

    | `daily_drawdown` | % | Max daily drawdown |

    | `max_contracts` | # | Maximum position size in mini-equivalent units |

    | `micro_conversion_ratio` | # | How many micros count as 1 unit toward
    `max_contracts` (default 10; e.g. 5 or 1 per firm plan) |


    When a rule is violated, positions are auto-liquidated and the account is
    marked as `Violated` or `Completed`.


    ---


    ## Contracts


    Supported CME futures contracts used by the engine:


    | Symbol | Name | Tick Size | Point Value |

    |--------|------|-----------|-------------|

    | ESH6 | E-mini S&P 500 | 0.25 | $12.50 |

    | NQH6 | E-mini Nasdaq | 0.25 | $5.00 |

    | YMH6 | E-mini Dow | 1.00 | $5.00 |

    | RTH6 | E-mini Russell | 0.10 | $5.00 |


    ---


    ## Data Persistence


    All trading data is persisted to ensure consistency and auditability:


    | Data | Storage | When |

    |------|---------|------|

    | **Order Snapshot** | Durable database | Latest state per `order_id`
    (upsert) |

    | **Order Events (Audit)** | Durable database | Every lifecycle transition
    (append-only) |

    | **Account State** | Durable database | On position close, rule violation,
    account completion |

    | **Positions** | In-memory | Real-time only (rebuilt from order history on
    restart) |


    ### Order Fields Persisted


    Every order includes:

    - `id`, `user_id`, `account_id`

    - `contract`, `product`, `symbol` (e.g., "ESH6", "CME", "ES")

    - `side`, `order_type`, `quantity`, `filled_quantity`

    - `limit_price`, `stop_price`, `filled_price`

    - `status`
    (pending_submit/new/working/pending/.../filled/cancelled/rejected)

    - `reason` (human-readable explanation)

    - `processed_at`, `engine_updated_at`, `filled_at`


    ---


    ## Rate Limits


    Rate limits are enforced **per trading account** using an in-memory token
    bucket algorithm. Each action category has its own independent bucket, so
    order submissions don't compete with cancellations.


    ### Limits by Action


    | Action | Burst Capacity | Refill Rate | Applies To |

    |--------|---------------|-------------|------------|

    | Order Submit | 10 | 10/sec | `POST /trade/order` |

    | Order Modify | 10 | 10/sec | `POST /trade/order/modify`,
    `/order/attach-bracket`, `/order/detach-bracket` |

    | Order Cancel | 20 | 20/sec | `POST /trade/order/cancel`,
    `/orders/cancel-all` |

    | Position Close | 5 | 2/sec | `POST /trade/position/close`,
    `/position/reverse`, `/close-all`, `/flatten` |

    | Copy Config | 10 | 2/sec | `POST /trade/copy/*` (create, update, toggle,
    delete) |

    | Lockout | 5 | 1/sec | `POST /trade/account/lockout`, `DELETE
    /trade/account/lockout` |


    Read endpoints (GET) are **not** rate limited.


    ### How It Works


    Each account starts with a full bucket (e.g., 10 tokens for order submit).
    Every request consumes 1 token. Tokens refill continuously at the specified
    rate. If the bucket is empty, the request is rejected with HTTP 429.


    ### Rate Limit Response (HTTP 429)


    ```json

    {
      \"success\": false,
      \"data\": null,
      \"error\": \"Rate limit exceeded for order submissions. Max 10 requests per second per account. Retry after 0.1 seconds.\",
      \"code\": \"RATE_LIMITED\"
    }

    ```


    ### Headers


    Successful requests do not include rate limit headers to minimize overhead.
    On 429 responses, inspect the error message for retry timing.


    ### Organization Overrides


    Organizations can have custom rate limits (e.g., higher limits for copy
    trading leaders). Contact the Hyperprop team for custom configurations.


    ### Important Notes


    - Limits are per **account**, not per user. A user with 5 accounts has 5
    independent buckets per action.

    - Different action categories have independent buckets. Exhausting order
    submit tokens does not affect cancellation tokens.

    - WebSocket events are **not** rate limited (server → client push).
  license:
    name: Proprietary
  title: Hyperprop Trade API
  version: 1.0.0
servers:
  - url: https://api.hyperprop.com
    description: Production
security: []
tags:
  - description: Trading account management - balances, equity, P&L, rules
    name: Account
  - description: Order submission, cancellation, and history
    name: Orders
  - description: Open positions and P&L tracking
    name: Positions
  - description: Real-time streaming of trading events
    name: WebSocket
  - description: >-
      Live engine metrics feeds. Metrics are kept in memory only and rendered by
      the operator dashboard at /trade/admin
    name: Metrics
paths:
  /trade/order:
    post:
      tags:
        - Orders
      summary: Submit a market, limit, or stop order
      description: >-
        Submits an order to the command queue for processing. Returns a
        `command_id` you can use to track status.


        **Order types:**

        - `market` — executes immediately at best available price

        - `limit` — executes when price reaches your level or better (requires
        `price`)

        - `stop` — triggers a market order when price reaches stop level
        (requires `price`)


        **Bracket orders:** optionally attach `take_profit` and/or `stop_loss`
        prices. These create child limit/stop orders that auto-cancel each other
        (OCO) when one fills.


        **Validation:** checks account ownership, trading status, lockout, max
        contracts rule, and tick size before accepting.


        Requires `x-idempotency-key` header to prevent duplicate submissions.
      operationId: submit_order
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrderRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubmitOrderAcceptedResponse'
          description: Order command accepted for async processing
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
          description: Invalid order parameters
        '401':
          content:
            application/json:
              example:
                code: UNAUTHORIZED
                data: null
                error: Invalid or missing JWT token
                success: false
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
          description: Authentication required
        '403':
          content:
            application/json:
              example:
                code: LOCKOUT_ACTIVE
                data: null
                error: >-
                  Account is locked out until 2026-03-12T16:00:00Z (mode: timed,
                  45 minutes remaining)
                success: false
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
          description: Trading not allowed
        '404':
          content:
            application/json:
              example:
                code: NOT_FOUND
                data: null
                error: Account not found
                success: false
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
          description: Account not found
        '429':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RateLimitResponse'
          description: Rate limit exceeded (max 10 order submissions/sec per account)
      security:
        - bearer: []
      x-codeSamples:
        - label: Market Order
          lang: JavaScript
          source: |-
            const response = await fetch('/trade/order', {
              method: 'POST',
              headers: {
                'Authorization': `Bearer ${token}`,
                'Content-Type': 'application/json'
              },
              body: JSON.stringify({
                account_id: 'your-account-uuid',
                contract: 'ESH6',
                side: 'buy',
                quantity: 2
              })
            });
            const { data } = await response.json();
            console.log('Order filled at:', data.order.filled_price);
        - label: Bracket Order (TP + SL)
          lang: JavaScript
          source: |-
            // Market order with Take Profit and Stop Loss
            const response = await fetch('/trade/order', {
              method: 'POST',
              headers: {
                'Authorization': `Bearer ${token}`,
                'Content-Type': 'application/json'
              },
              body: JSON.stringify({
                account_id: 'your-account-uuid',
                contract: 'ESH6',
                side: 'buy',
                quantity: 2,
                take_profit: 6100.00,  // Limit order to sell at 6100
                stop_loss: 6000.00     // Stop order to sell at 6000
              })
            });
            const { data } = await response.json();
            console.log('Entry order:', data.order.id);
            console.log('TP order:', data.take_profit_order?.id);
            console.log('SL order:', data.stop_loss_order?.id);
        - label: Limit Order
          lang: JavaScript
          source: |-
            const response = await fetch('/trade/order', {
              method: 'POST',
              headers: {
                'Authorization': `Bearer ${token}`,
                'Content-Type': 'application/json'
              },
              body: JSON.stringify({
                account_id: 'your-account-uuid',
                contract: 'ESH6',
                side: 'sell',
                quantity: 1,
                order_type: 'limit',
                price: 6100.00
              })
            });
        - label: Stop Loss Only
          lang: JavaScript
          source: |-
            // Market order with Stop Loss only (no Take Profit)
            const response = await fetch('/trade/order', {
              method: 'POST',
              headers: {
                'Authorization': `Bearer ${token}`,
                'Content-Type': 'application/json'
              },
              body: JSON.stringify({
                account_id: 'your-account-uuid',
                contract: 'ESH6',
                side: 'buy',
                quantity: 2,
                stop_loss: 6000.00
              })
            });
        - label: cURL - Bracket Order
          lang: cURL
          source: |-
            # Market order with TP and SL
            curl -X POST '/trade/order' \
              -H 'Authorization: Bearer YOUR_JWT_TOKEN' \
              -H 'Content-Type: application/json' \
              -d '{
                "account_id": "your-account-uuid",
                "contract": "ESH6",
                "side": "buy",
                "quantity": 2,
                "take_profit": 6100.00,
                "stop_loss": 6000.00
              }'
components:
  schemas:
    OrderRequest:
      description: |-
        Order submission request

        Submit a market, limit, or stop order for a specific trading account.

        ## Examples

        **Market Order (immediate execution):**
        ```json
        {
        "account_id": "550e8400-e29b-41d4-a716-446655440000",
        "contract": "ESH6",
        "side": "buy",
        "quantity": 2
        }
        ```

        **Limit Order (execute at specified price or better):**
        ```json
        {
        "account_id": "550e8400-e29b-41d4-a716-446655440000",
        "contract": "ESH6",
        "side": "sell",
        "quantity": 1,
        "order_type": "limit",
        "price": 6050.25
        }
        ```

        **Stop Order (trigger market order when price reached):**
        ```json
        {
        "account_id": "550e8400-e29b-41d4-a716-446655440000",
        "contract": "NQH6",
        "side": "sell",
        "quantity": 1,
        "order_type": "stop",
        "price": 21000.00
        }
        ```
      example:
        account_id: 550e8400-e29b-41d4-a716-446655440000
        contract: ESH6
        order_type: market
        price: null
        quantity: 2
        side: buy
        stop_loss: 6000
        take_profit: 6100
      properties:
        account_id:
          description: UUID of the trading account to place order on (required)
          example: 550e8400-e29b-41d4-a716-446655440000
          format: uuid
          type: string
        contract:
          description: Contract symbol (e.g., "ESH6" for E-mini S&P 500 March 2026)
          example: ESH6
          type: string
        order_type:
          description: 'Order type: "market" (default), "limit", or "stop"'
          example: market
          nullable: true
          type: string
        price:
          description: >-
            Price for limit/stop orders (required for limit/stop, ignored for
            market)
          example: 6050.25
          format: double
          nullable: true
          type: number
        quantity:
          description: Number of contracts to trade (positive integer)
          example: 2
          format: int32
          minimum: 1
          type: integer
        side:
          description: 'Order side: "buy" (go long) or "sell" (go short/close long)'
          example: buy
          type: string
        stop_loss:
          description: |-
            Stop loss price for bracket orders (optional).
            Creates a stop order to close position at this price.
            For buy orders: SL should be below entry price.
            For sell orders: SL should be above entry price.
          example: 6000
          format: double
          nullable: true
          type: number
        take_profit:
          description: |-
            Take profit price for bracket orders (optional).
            Creates a limit order to close position at this price.
            For buy orders: TP should be above entry price.
            For sell orders: TP should be below entry price.
          example: 6100
          format: double
          nullable: true
          type: number
      required:
        - account_id
        - contract
        - side
        - quantity
      type: object
    SubmitOrderAcceptedResponse:
      example:
        accepted: true
        command_id: 2f95ccde-3f33-4fa0-a84d-1a9bdf8575ff
        status: queued
      properties:
        accepted:
          type: boolean
        command_id:
          format: uuid
          type: string
        status:
          type: string
      required:
        - accepted
        - command_id
        - status
      type: object
    ApiErrorResponse:
      description: Standard API error response
      example:
        code: ERROR_CODE
        data: null
        error: Error message describing what went wrong
        success: false
      properties:
        code:
          description: Machine-readable error code
          example: NO_ACCOUNT
          nullable: true
          type: string
        data:
          description: Always null for errors
          nullable: true
        error:
          description: Human-readable error message
          example: No trading account found for this user
          nullable: true
          type: string
        success:
          description: Always false for errors
          example: false
          type: boolean
      required:
        - success
      type: object
    RateLimitResponse:
      description: |-
        Rate limit exceeded response (HTTP 429)

        Returned when an account exceeds the allowed request rate for an action.
        Includes standard rate limit headers as response fields.
      example:
        code: RATE_LIMITED
        data: null
        error: >-
          Rate limit exceeded for order submissions. Max 10 requests per second
          per account. Retry after 0.1 seconds.
        rate_limit:
          limit: 10
          remaining: 0
          reset: 1711800125
          retry_after: 0.1
        success: false
      properties:
        code:
          description: Machine-readable error code
          example: RATE_LIMITED
          nullable: true
          type: string
        data:
          description: Always null
          nullable: true
        error:
          description: Human-readable error message
          example: >-
            Rate limit exceeded for order submissions. Max 10 requests per
            second per account. Retry after 0.1 seconds.
          nullable: true
          type: string
        rate_limit:
          $ref: '#/components/schemas/RateLimitInfo'
        success:
          description: Always false
          example: false
          type: boolean
      required:
        - success
        - rate_limit
      type: object
    RateLimitInfo:
      description: >-
        Rate limit details included in 429 responses and success response
        headers
      example:
        limit: 10
        remaining: 0
        reset: 1711800125
        retry_after: 0.1
      properties:
        limit:
          description: Maximum burst capacity for this action category
          example: 10
          format: int32
          minimum: 0
          type: integer
        remaining:
          description: Tokens remaining (0 when rate limited)
          example: 0
          format: int32
          minimum: 0
          type: integer
        reset:
          description: Unix epoch seconds when the bucket will be full again
          example: 1711800125
          format: int64
          minimum: 0
          type: integer
        retry_after:
          description: >-
            Seconds until the next request will be accepted (only present on
            429)
          example: 0.1
          format: double
          type: number
      required:
        - limit
        - remaining
        - reset
        - retry_after
      type: object

````

## Related topics

- [Get order history from database (append-only lifecycle events)](/trade-api/orders/get-order-history-from-database-append-only-lifecycle-events.md)
- [Get active working orders](/trade-api/orders/get-active-working-orders.md)
- [Close a specific position by contract](/trade-api/positions/close-a-specific-position-by-contract.md)
- [Link a standalone order into the position's OCO group](/trade-api/orders/link-a-standalone-order-into-the-positions-oco-group.md)
- [Changelog](/changelog.md)
