Skip to content

API reference

Trade execution

Place an order through your connected broker in two steps: prepare, then execute with a confirmation token.

Two steps

Placing an order takes two calls to the same endpoint, so that nothing is sent to your broker by accident.

  1. Prepare

    Send the order with "action": "prepare". The API validates it, works out the protective levels and returns a confirmationToken. No order exists yet.

  2. Execute

    Within 5 minutes, send "action": "execute" with that token. The order goes to your live Alpaca account and the response carries the broker's order.

You need a live key with the trading:execute scope, a Partner plan and an Alpaca account connected to ENTON (see OAuth service).

Prepare or execute a trade

POST/api/v1/trading/execute
API keyscope trading:execute

Two calls place one order. The first, with "action": "prepare", validates the order and returns a confirmation token without placing anything. The second, with "action": "execute" and that token, sends the order to your connected broker. Orders always go to the live account.

It also needs:

  • A live key. Test keys get 403.
  • A Partner plan on the account. Any other plan gets 403.
  • A broker connected to your ENTON account (Alpaca, through OAuth).

Known issue

Requests that pass the API-key checks currently fail with 401. This endpoint forwards to an internal route that expects a signed-in session, and the forwarded request does not carry one. The failed call still counts against your rate limit and monthly quota. This page will say so when it is fixed.

Request

JSON body

FieldDescription
actionstringrequiredWhich step this call is.one of "prepare", "execute"
symbolstringPrepare only, required. Ticker, for example "AAPL". Upper-cased for you.
sidestringPrepare only, required.one of "buy", "sell"
quantitynumberPrepare only, required. Shares, more than 0 and at most 10,000.at most 10000 · more than 0
orderTypestringPrepare only.one of "market", "limit" · default "market"
limitPricenumberPrepare only. Required when orderType is "limit".
protectionobjectPrepare only. Stop-loss and take-profit distances as fractions of the entry price.
protection.stopLossnumber0.01 (1%) to 0.50 (50%).default 0.05 · 0.01 to 0.5
protection.takeProfitnumber0.01 (1%) to 1.00 (100%).default 0.1 · 0.01 to 1
confirmationTokenstringExecute only, required. The token from prepare. It expires 5 minutes after it was issued.

Response

"action": "prepare"

200 The prepared order and its confirmation token. Nothing has been sent to the broker.

FieldDescription
actionstring"prepare".one of "prepare"
preparedOrderobjectThe order as it will be placed.
preparedOrder.symbolstringTicker.
preparedOrder.sidestring"buy" or "sell".
preparedOrder.quantitynumberShares.
preparedOrder.orderTypestring"market" or "limit".
preparedOrder.limitPricenumberLimit price, for limit orders.
preparedOrder.estimatedCostnumberQuantity times the reference price.
preparedOrder.protectionOrdersobjectProtective levels.
preparedOrder.protectionOrders.stopLossnumberStop price.
preparedOrder.protectionOrders.takeProfitnumberTake-profit price.
preparedOrder.protectionOrders.stopLossPercentnumberThe fraction you sent, or 0.05.
preparedOrder.protectionOrders.takeProfitPercentnumberThe fraction you sent, or 0.10.
preparedOrder.confirmationTokenstringPass this to execute.
preparedOrder.expiresAtstringWhen the token stops working.date-time
preparedOrder.messagestringStatus text.
Example response
{
  "action": "prepare",
  "preparedOrder": {
    "symbol": "AAPL",
    "side": "buy",
    "quantity": 10,
    "orderType": "market",
    "estimatedCost": 1754.3,
    "protectionOrders": {
      "stopLoss": 166.66,
      "takeProfit": 192.97,
      "stopLossPercent": 0.05,
      "takeProfitPercent": 0.1
    },
    "confirmationToken": "<confirmation token>",
    "expiresAt": "2026-10-23T14:07:11.000Z",
    "message": "Order prepared successfully"
  }
}

"action": "execute"

200 The broker order, as the broker reported it.

FieldDescription
actionstring"execute".one of "execute"
successbooleanWhether the broker accepted the order.
orderobjectThe order.
order.orderIdstringThe broker's order id.
order.symbolstringTicker.
order.sidestring"buy" or "sell".
order.quantitynumberShares ordered.
order.orderTypestringOrder type.
order.statusstringBroker status, for example "accepted" or "filled".
order.filledPricenumberAverage fill price, once filled.
order.filledQuantitynumberShares filled so far.
order.submittedAtstringSubmission time.
order.filledAtstringFill time, once filled.
protectionOrdersobjectStatus of the stop-loss and take-profit orders. Each is { "status": "pending" } until the broker reports otherwise.
messagestringStatus text.
metadataobjectRequest metadata.
metadata.responseTimeintegerMilliseconds this request took, measured by the API.
metadata.environmentstringAlways "live".one of "live"
Example response
{
  "action": "execute",
  "success": true,
  "order": {
    "orderId": "<broker order id>",
    "symbol": "AAPL",
    "side": "buy",
    "quantity": 10,
    "orderType": "market",
    "status": "accepted",
    "submittedAt": "2026-10-23T14:03:02.000Z"
  },
  "protectionOrders": {
    "stopLoss": {
      "status": "pending"
    },
    "takeProfit": {
      "status": "pending"
    }
  },
  "message": "Order executed successfully",
  "metadata": {
    "responseTime": 1820,
    "environment": "live"
  }
}

Errors

StatusWhenerror
403The key has neither "trading:execute" nor "*".Insufficient permissions. Required scope: trading:execute
403The key is a test key.Test API keys cannot execute real trades. Use a live API key for trading.
403The account is not on the Partner plan.Live trading requires a Partner subscription ($99/mo). Upgrade at enton.ai/pricing.
400action is missing or another value.Invalid action. Must be "prepare" or "execute"
400Prepare without one of them.Missing required fields: symbol, side, quantity
400side is another value.Invalid side. Must be "buy" or "sell"
400quantity is 0 or less, or over 10,000.Invalid quantity. Must be between 1 and 10,000
400orderType is another value.Invalid orderType. Must be "market" or "limit"
400orderType is "limit" without limitPrice.Limit price is required for limit orders
400protection.stopLoss is out of range.Stop loss percentage must be between 0.01 (1%) and 0.50 (50%)
400protection.takeProfit is out of range.Take profit percentage must be between 0.01 (1%) and 1.00 (100%)
400Execute without a token.Missing confirmationToken. First call with action:"prepare" to get a token.
500Anything unexpected, including a body that is not valid JSON.Failed to process trade. Please try again.

Errors use the standard error body. Any request can also get the authentication errors (401) and the rate-limit error (429).

Examples

Step 1: prepare

curl -X POST "https://enton.ai/api/v1/trading/execute" \
  -H "Authorization: Bearer $ENTON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "prepare",
    "symbol": "AAPL",
    "side": "buy",
    "quantity": 10,
    "orderType": "market",
    "protection": {
      "stopLoss": 0.05,
      "takeProfit": 0.1
    }
  }'

Step 2: execute

curl -X POST "https://enton.ai/api/v1/trading/execute" \
  -H "Authorization: Bearer $ENTON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "execute",
    "confirmationToken": "<token from step 1>"
  }'

Notes

  • A confirmation token is signed, expires 5 minutes after prepare, and is accepted only for the account it was issued to.
  • Execute places a real order on your live brokerage account. Prepare places nothing.