Bots EndpointBot Trades
Add Transactions
Add transactions to an existing bot trade
Add one or more transactions to an existing bot trade. This is useful for adding exit transactions after a trade has been created, or adding additional entry transactions. The trade status is automatically recalculated after adding transactions.
Endpoint
POST /api/bots/:slug/trades/:tradeId/transactionsAuthentication
All requests require bot API key authentication via the x-api-key header.
headers: {
'x-api-key': 'your-bot-api-key'
}Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | Yes | Bot identifier (alphanumeric, hyphens, underscores only) |
tradeId | string | Yes | UUID of the trade to add transactions to |
Slug Validation
The slug must match the regex pattern: /^[a-zA-Z0-9_-]+$/
Request Body
{
transactions: Array<{
transactionGroup: "entry" | "exit";
exitType?: string; // Required for exit transactions
trimLevel?: number; // Required for trim exits
symbol: string;
assetType: string;
side: string;
type: string;
quantity: number;
transactionDate: string; // ISO timestamp
stopPrice?: string;
price?: string;
optionType?: string;
strikePrice?: string;
expirationDate?: string;
status?: string;
filledAt?: string;
filledPrice?: string;
filledQuantity?: string;
avgFillPrice?: string;
broker?: string;
brokerAccountNumber?: string;
brokerOrderId?: string;
brokerParentOrderId?: string;
notes?: string;
metadata?: Record<string, unknown>;
}>;
}Request Body Schema
| Field | Type | Required | Description |
|---|---|---|---|
transactions | array | Yes | Array of transaction objects (must not be empty) |
transactions[].transactionGroup | "entry" | "exit" | Yes | Whether this is an entry or exit transaction |
transactions[].exitType | string | Yes* | Exit type (required if transactionGroup is "exit") |
transactions[].trimLevel | number | Yes** | Trim level (required if exitType is "trim") |
transactions[].symbol | string | Yes | Transaction symbol |
transactions[].assetType | string | Yes | Asset type (e.g., "stock", "option") |
transactions[].side | string | Yes | Side of transaction ("buy" or "sell") |
transactions[].type | string | Yes | Order type (e.g., "market", "limit", "stop") |
transactions[].quantity | number | Yes | Quantity/shares |
transactions[].transactionDate | string (ISO timestamp) | Yes | Transaction date/time |
transactions[].stopPrice | string | No | Stop price for stop orders |
transactions[].price | string | No | Limit price for limit orders |
transactions[].optionType | string | No | Option type ("call" or "put") |
transactions[].strikePrice | string | No | Strike price for options |
transactions[].expirationDate | string | No | Expiration date for options |
transactions[].status | string | No | Transaction status (e.g., "open", "filled") |
transactions[].filledAt | string (ISO timestamp) | No | When transaction was filled |
transactions[].filledPrice | string | No | Fill price |
transactions[].filledQuantity | string | No | Filled quantity |
transactions[].avgFillPrice | string | No | Average fill price |
transactions[].broker | string | No | Broker code |
transactions[].brokerAccountNumber | string | No | Broker account number |
transactions[].brokerOrderId | string | No | Broker order ID |
transactions[].brokerParentOrderId | string | No | Broker parent order ID (for bracket orders) |
transactions[].notes | string | No | Notes |
transactions[].metadata | object | No | Transaction metadata (defaults to {}) |
* Required when transactionGroup is "exit"
** Required when exitType is "trim"
Validation Rules
Transaction Level:
transactionsmust be a non-empty arraytransactionGroupmust be exactly"entry"or"exit"- If
transactionGroupis"exit",exitTypeis required - If
exitTypeis"trim",trimLevelis required and must be a number symbol,assetType,side,typemust be non-empty stringsquantitymust be a numbertransactionDatemust be a valid ISO timestamp string
Trade Validation:
- Trade must exist and belong to the specified bot
Response
Success Response (200 OK)
{
"success": true,
"trade": {
"id": "111e4567-e89b-12d3-a456-426614174001",
"botId": "123e4567-e89b-12d3-a456-426614174000",
"symbol": "AAPL",
"tradeType": "long",
"status": "open",
"signalAt": "2024-01-15T10:30:00.000Z",
"openedAt": "2024-01-15T10:30:05.000Z",
"lastUpdateAt": "2024-01-15T11:00:00.000Z"
},
"transactionsAdded": 2
}Response Schema
| Field | Type | Description |
|---|---|---|
success | boolean | Always true for successful requests |
trade | object | Updated trade object (status may be recalculated) |
transactionsAdded | number | Number of transactions added |
Notes
- After adding transactions, the trade status is automatically recalculated
- The
lastUpdateAtfield is updated to reflect the addition - Trade status may change based on the new transaction states
Error Responses
400 Bad Request
Invalid JSON:
{
"error": "Invalid JSON in request body",
"code": "BAD_REQUEST"
}Empty transactions array:
{
"error": "transactions array required and cannot be empty",
"code": "BAD_REQUEST"
}Invalid transaction group:
{
"error": "transactions[0].transactionGroup must be 'entry' or 'exit'",
"code": "BAD_REQUEST"
}Missing exit type:
{
"error": "transactions[0].exitType is required for exit transactions",
"code": "BAD_REQUEST"
}Missing required field:
{
"error": "transactions[0].symbol is required and must be a string",
"code": "BAD_REQUEST"
}401 Unauthorized
Missing API key:
{
"message": "API key required. Include x-api-key header."
}403 Forbidden
Invalid API key:
{
"message": "Invalid API key for this bot"
}404 Not Found
Bot not found:
{
"error": "Bot with slug 'my-bot' not found",
"code": "NOT_FOUND"
}Trade not found:
{
"error": "Trade not found",
"code": "NOT_FOUND"
}500 Internal Server Error
{
"error": "Internal server error",
"code": "INTERNAL_SERVER_ERROR"
}Code Examples
TypeScript
interface Transaction {
transactionGroup: "entry" | "exit";
exitType?: string;
trimLevel?: number;
symbol: string;
assetType: string;
side: string;
type: string;
quantity: number;
transactionDate: string;
// ... other optional fields
}
async function addTransactionsToTrade(
botSlug: string,
tradeId: string,
apiKey: string,
transactions: Transaction[]
) {
const response = await fetch(
`https://api.example.com/api/bots/${botSlug}/trades/${tradeId}/transactions`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": apiKey,
},
body: JSON.stringify({ transactions }),
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(`Failed to add transactions: ${error.error}`);
}
return await response.json();
}
// Example: Add take profit exit after trade is created
const result = await addTransactionsToTrade(
"my-bot",
"111e4567-e89b-12d3-a456-426614174001",
"your-api-key",
[
{
transactionGroup: "exit",
exitType: "take_profit",
symbol: "AAPL",
assetType: "stock",
side: "sell",
type: "limit",
price: "160.00",
quantity: 100,
transactionDate: new Date().toISOString(),
status: "open"
}
]
);
console.log(`Added ${result.transactionsAdded} transactions. Trade status: ${result.trade.status}`);Python
from typing import List, Dict, Any
from datetime import datetime
import requests
def add_transactions_to_trade(
bot_slug: str,
trade_id: str,
api_key: str,
transactions: List[Dict[str, Any]]
) -> Dict[str, Any]:
"""
Add transactions to an existing bot trade.
Args:
bot_slug: Bot identifier
trade_id: UUID of trade to add transactions to
api_key: Bot API key
transactions: List of transaction dictionaries
Returns:
Response dictionary with updated trade
Raises:
requests.HTTPError: If the request fails
"""
url = f"https://api.example.com/api/bots/{bot_slug}/trades/{trade_id}/transactions"
payload = {
"transactions": transactions
}
headers = {
"Content-Type": "application/json",
"x-api-key": api_key
}
response = requests.post(url, json=payload, headers=headers)
response.raise_for_status()
return response.json()
# Example: Add take profit exit after trade is created
result = add_transactions_to_trade(
bot_slug="my-bot",
trade_id="111e4567-e89b-12d3-a456-426614174001",
api_key="your-api-key",
transactions=[
{
"transactionGroup": "exit",
"exitType": "take_profit",
"symbol": "AAPL",
"assetType": "stock",
"side": "sell",
"type": "limit",
"price": "160.00",
"quantity": 100,
"transactionDate": datetime.now().isoformat(),
"status": "open"
}
]
)
print(f"Added {result['transactionsAdded']} transactions. Trade status: {result['trade']['status']}")Use Cases
Add Take Profit Order
// Add take profit exit after entry is filled
await addTransactionsToTrade("my-bot", tradeId, apiKey, [
{
transactionGroup: "exit",
exitType: "take_profit",
symbol: "AAPL",
assetType: "stock",
side: "sell",
type: "limit",
price: "160.00",
quantity: 100,
transactionDate: new Date().toISOString()
}
]);Add Stop Loss Exit
# Add stop loss exit
add_transactions_to_trade(
bot_slug="my-bot",
trade_id=trade_id,
api_key=api_key,
transactions=[{
"transactionGroup": "exit",
"exitType": "stop",
"symbol": "NVDA",
"assetType": "stock",
"side": "sell",
"type": "stop",
"stopPrice": "400.00",
"quantity": 100,
"transactionDate": datetime.now().isoformat()
}]
)Add Trim Exit
// Add partial exit (trim) at 50% position
await addTransactionsToTrade("my-bot", tradeId, apiKey, [
{
transactionGroup: "exit",
exitType: "trim",
trimLevel: 1,
symbol: "TSLA",
assetType: "stock",
side: "sell",
type: "limit",
price: "250.00",
quantity: 50, // 50% of 100 share position
transactionDate: new Date().toISOString()
}
]);Add Multiple Exit Orders
# Add bracket order exits (stop loss + take profit)
add_transactions_to_trade(
bot_slug="my-bot",
trade_id=trade_id,
api_key=api_key,
transactions=[
{
"transactionGroup": "exit",
"exitType": "stop",
"symbol": "AAPL",
"assetType": "stock",
"side": "sell",
"type": "stop",
"stopPrice": "145.00",
"quantity": 100,
"transactionDate": datetime.now().isoformat()
},
{
"transactionGroup": "exit",
"exitType": "take_profit",
"symbol": "AAPL",
"assetType": "stock",
"side": "sell",
"type": "limit",
"price": "160.00",
"quantity": 100,
"transactionDate": datetime.now().isoformat()
}
]
)