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

# Order execution flow

> End-to-end steps to submit a trade using the Investment Orders API

## Overview

This guide explains how to submit buy or sell orders for assets in a user's portfolio using the Investment Orders endpoint `POST /investments/orders`.

<Info>
  All order operations require M2M authentication with a bearer token and the `x-user-id` header to specify which user's orders to manage.
</Info>

### Key differences between order types

* **Buy orders**: Specify `amount` (monetary value to invest). You must verify the user has sufficient cash balance before submitting.
* **Sell orders**: Specify `quantity` (asset units to sell). You must verify the user has sufficient holdings before submitting.

### Prerequisites

* Access to API endpoints
* M2M bearer token with required scopes
* `x-user-id` header (user identifier, MongoDB ObjectId format)

***

## Buy order flow

Use this flow to purchase an asset for a user's portfolio.

<Steps>
  <Step title="Verify available cash">
    Before submitting a buy order, retrieve the user's cash balance to ensure sufficient funds are available.

    Call `GET /cash` to retrieve the available cash balance across all currencies.

    <CodeGroup>
      ```javascript Node.js theme={null}
      const BASE = 'https://api.wealthyhood.com';

      async function getCashBalance({ token, userId }) {
        const res = await fetch(`${BASE}/cash`, {
          method: 'GET',
          headers: {
            'Authorization': `Bearer ${token}`,
            'x-user-id': userId,
            'Accept': 'application/json'
          }
        });
        if (!res.ok) throw new Error(`Failed to get cash: ${res.status}`);
        return res.json();
      }
      ```

      ```bash cURL theme={null}
      curl -X GET 'https://api.wealthyhood.com/cash' \
        -H 'Accept: application/json' \
        -H 'Authorization: Bearer YOUR_M2M_TOKEN' \
        -H 'x-user-id: 64f0c51e7fb3fc001234abcd'
      ```
    </CodeGroup>

    <Tip>
      Compare the available cash balance in the target currency with the intended purchase amount before proceeding.
    </Tip>
  </Step>

  <Step title="Get asset buy preview">
    Get a preview of the asset buy transaction to show execution options, fees breakdown, and estimated quantity.

    Call `POST /investments/asset/preview` with the asset ISIN, amount, and side set to "buy".

    <CodeGroup>
      ```javascript Node.js theme={null}
      const BASE = 'https://api.wealthyhood.com';

      async function getAssetBuyPreview({ token, userId, isin, amount }) {
        const res = await fetch(`${BASE}/investments/asset/preview`, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${token}`,
            'x-user-id': userId,
            'Accept': 'application/json',
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            isin,
            amount,
            side: 'buy'
          })
        });
        if (!res.ok) throw new Error(`Failed to get preview: ${res.status}`);
        return res.json();
      }
      ```

      ```bash cURL theme={null}
      curl -X POST 'https://api.wealthyhood.com/investments/asset/preview' \
        -H 'Accept: application/json' \
        -H 'Content-Type: application/json' \
        -H 'Authorization: Bearer YOUR_M2M_TOKEN' \
        -H 'x-user-id: 64f0c51e7fb3fc001234abcd' \
        -d '{
          "isin": "US0378331005",
          "amount": 25.5,
          "side": "buy"
        }'
      ```
    </CodeGroup>

    <Tip>
      Display both express and smart execution options:

      * **Express (real-time)**: Faster execution but may incur additional fees
      * **Smart (market hours)**: Lower fees but executes during market hours

      Show the fees breakdown (`fees.express` vs `fees.smart`) and execution windows to help users make informed decisions.
    </Tip>
  </Step>

  <Step title="Submit the buy order">
    Call `POST /investments/orders` with optional query params:

    * **paymentMethod**: `cash` (default) or `gift`
    * **executeEtfOrdersInRealtime**: `true` only for users enabled for real-time ETF execution

    <CodeGroup>
      ```javascript Node.js theme={null}
      const BASE = 'https://api.wealthyhood.com';

      async function submitBuyOrder({ token, userId, isin, amount, paymentMethod = 'cash', executeEtfOrdersInRealtime }) {
        const url = new URL(`${BASE}/investments/orders`);
        if (paymentMethod) url.searchParams.set('paymentMethod', paymentMethod);
        if (typeof executeEtfOrdersInRealtime === 'boolean') {
          url.searchParams.set('executeEtfOrdersInRealtime', String(executeEtfOrdersInRealtime));
        }

        const res = await fetch(url.toString(), {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${token}`,
            'x-user-id': userId,
            'Accept': 'application/json',
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            side: 'buy',
            isin,
            amount
          })
        });
        if (!res.ok) throw new Error(`Order failed: ${res.status}`);
        return res.json();
      }
      ```

      ```bash cURL theme={null}
      curl -X POST 'https://api.wealthyhood.com/investments/orders?paymentMethod=cash' \
        -H 'Accept: application/json' \
        -H 'Content-Type: application/json' \
        -H 'Authorization: Bearer YOUR_M2M_TOKEN' \
        -H 'x-user-id: 64f0c51e7fb3fc001234abcd' \
        -d '{
          "side": "buy",
          "isin": "US0378331005",
          "amount": 25.5
        }'
      ```
    </CodeGroup>

    <Tip>
      Use `executeEtfOrdersInRealtime=true` only for eligible users and only for ETFs.
    </Tip>
  </Step>

  <Step title="Render the transaction in UI">
    The response is an `AssetTransaction` with display-ready fields such as `displayAmount`, `displayQuantity`, `executionWindow`, `fees`, and nested `orders`.

    * **Show execution window**: Use `executionWindow.type` (e.g., real-time or market-hours) and `expectedExecutionDate` when provided.
    * **Show fees**: Display `fees.commission.amount`, `fees.fx.amount`, etc., when present.
    * **Show order summary**: From `orders[0]`, read `isin`, `side`, `status`, and `displayQuantity`.

    <Check>
      Successful submission returns HTTP 200 with a populated transaction object.
    </Check>
  </Step>
</Steps>

***

## Sell order flow

Use this flow to sell an asset from a user's portfolio.

<Steps>
  <Step title="Verify portfolio holdings">
    Before submitting a sell order, retrieve the user's portfolio holdings to ensure sufficient quantity of the asset is available.

    Call `GET /portfolios/{id}` to retrieve holdings with asset details and quantities.

    <CodeGroup>
      ```javascript Node.js theme={null}
      const BASE = 'https://api.wealthyhood.com';

      async function getPortfolioHoldings({ token, userId, portfolioId }) {
        const res = await fetch(`${BASE}/portfolios/${portfolioId}`, {
          method: 'GET',
          headers: {
            'Authorization': `Bearer ${token}`,
            'x-user-id': userId,
            'Accept': 'application/json'
          }
        });
        if (!res.ok) throw new Error(`Failed to get holdings: ${res.status}`);
        return res.json();
      }
      ```

      ```bash cURL theme={null}
      curl -X GET 'https://api.wealthyhood.com/portfolios/64f0c51e7fb3fc001234abcd' \
        -H 'Accept: application/json' \
        -H 'Authorization: Bearer YOUR_M2M_TOKEN' \
        -H 'x-user-id: 64f0c51e7fb3fc001234abcd'
      ```
    </CodeGroup>

    <Tip>
      Verify that the portfolio holdings contain sufficient quantity of the asset (by ISIN) before proceeding with the sell order.
    </Tip>

    <Info>
      The holdings response includes an array of holdings, each with:

      * `asset.isin`: ISIN of the asset
      * `quantity`: Available quantity to sell
      * `asset.currentTicker.price`: Current price per unit
    </Info>
  </Step>

  <Step title="Get asset sell preview">
    Get a preview of the asset sell transaction to show execution options, fees breakdown, and estimated proceeds.

    Call `POST /investments/asset/preview` with the asset ISIN, quantity, and side set to "sell".

    <CodeGroup>
      ```javascript Node.js theme={null}
      const BASE = 'https://api.wealthyhood.com';

      async function getAssetSellPreview({ token, userId, isin, quantity }) {
        const res = await fetch(`${BASE}/investments/asset/preview`, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${token}`,
            'x-user-id': userId,
            'Accept': 'application/json',
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            isin,
            quantity,
            side: 'sell'
          })
        });
        if (!res.ok) throw new Error(`Failed to get preview: ${res.status}`);
        return res.json();
      }
      ```

      ```bash cURL theme={null}
      curl -X POST 'https://api.wealthyhood.com/investments/asset/preview' \
        -H 'Accept: application/json' \
        -H 'Content-Type: application/json' \
        -H 'Authorization: Bearer YOUR_M2M_TOKEN' \
        -H 'x-user-id: 64f0c51e7fb3fc001234abcd' \
        -d '{
          "isin": "IE00B4L5Y983",
          "quantity": 1.25,
          "side": "sell"
        }'
      ```
    </CodeGroup>

    <Tip>
      Display both express and smart execution options:

      * **Express (real-time)**: Faster execution but may incur additional fees
      * **Smart (market hours)**: Lower fees but executes during market hours

      Show the estimated proceeds (`orders.express` and `orders.smart` with `money` field) and fees breakdown.
    </Tip>

    <Warning>
      Aggregated sell orders for ETFs are rejected for real-time-enabled users. Check `hasETFOrders` in the preview response to determine if this applies.
    </Warning>
  </Step>

  <Step title="Submit the sell order">
    Call `POST /investments/orders` with optional query params:

    * **paymentMethod**: `cash` (default) or `gift`
    * **executeEtfOrdersInRealtime**: `true` only for users enabled for real-time ETF execution

    <CodeGroup>
      ```javascript Node.js theme={null}
      const BASE = 'https://api.wealthyhood.com';

      async function submitSellOrder({ token, userId, isin, quantity, paymentMethod = 'cash', executeEtfOrdersInRealtime }) {
        const url = new URL(`${BASE}/investments/orders`);
        if (paymentMethod) url.searchParams.set('paymentMethod', paymentMethod);
        if (typeof executeEtfOrdersInRealtime === 'boolean') {
          url.searchParams.set('executeEtfOrdersInRealtime', String(executeEtfOrdersInRealtime));
        }

        const res = await fetch(url.toString(), {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${token}`,
            'x-user-id': userId,
            'Accept': 'application/json',
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            side: 'sell',
            isin,
            quantity
          })
        });
        if (!res.ok) throw new Error(`Order failed: ${res.status}`);
        return res.json();
      }
      ```

      ```bash cURL theme={null}
      curl -X POST 'https://api.wealthyhood.com/investments/orders?paymentMethod=cash' \
        -H 'Accept: application/json' \
        -H 'Content-Type: application/json' \
        -H 'Authorization: Bearer YOUR_M2M_TOKEN' \
        -H 'x-user-id: 64f0c51e7fb3fc001234abcd' \
        -d '{
          "side": "sell",
          "isin": "IE00B4L5Y983",
          "quantity": 1.25
        }'
      ```
    </CodeGroup>

    <Warning>
      Aggregated sell orders for ETFs are rejected for real-time-enabled users. If the preview shows `hasETFOrders: true` and the user is real-time enabled, you should set `executeEtfOrdersInRealtime=false` or show an error message.
    </Warning>
  </Step>

  <Step title="Render the transaction in UI">
    The response is an `AssetTransaction` with display-ready fields such as `displayAmount`, `displayQuantity`, `executionWindow`, `fees`, and nested `orders`.

    * **Show execution window**: Use `executionWindow.type` (e.g., real-time or market-hours) and `expectedExecutionDate` when provided.
    * **Show fees**: Display `fees.commission.amount`, `fees.fx.amount`, etc., when present.
    * **Show order summary**: From `orders[0]`, read `isin`, `side`, `status`, and `displayQuantity`.

    <Check>
      Successful submission returns HTTP 200 with a populated transaction object.
    </Check>
  </Step>
</Steps>

***

## Error handling

* **400 Bad Request**: Validation or business rule violation (e.g., invalid amount, missing required field, invalid ISIN).
* **401/403**: Authentication/authorization failures.
* **404 Not Found**: Portfolio or related resource not found.

## See also

* API Reference → [Preview Asset Buy or Sell](/api-reference/investments/asset-preview)
* API Reference → [Submit Asset Order](/api-reference/order-execution/submit-order)
* API Reference → [Get Cash](/api-reference/cash/get-cash)
* API Reference → [Get Portfolio Holdings](/api-reference/portfolio/get-holdings)
