Bots EndpointBot Trades
Update Trade
Update trade fields including status, PnL, and error information
Update an existing bot trade. This endpoint allows you to update trade status, profit/loss, error information, and other trade metadata. When updating status to "closed", the system automatically updates open exit transactions and recalculates trade status.
Endpoint
PATCH /api/bots/:slug/trades/:tradeIdAuthentication
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 update |
Slug Validation
The slug must match the regex pattern: /^[a-zA-Z0-9_-]+$/
Request Body
{
status?: string; // Trade status
closedAt?: string; // ISO timestamp when trade closed
netPnl?: string; // Net profit/loss as decimal string
errorMessage?: string; // Error message if trade failed
errorAt?: string; // ISO timestamp when error occurred
metadata?: Record<string, unknown>; // Additional metadata
expirationDate?: string; // Expiration date for options/derivatives
}Request Body Schema
| Field | Type | Required | Description |
|---|---|---|---|
status | string | No | Trade status (e.g., "open", "closed", "error") |
closedAt | string (ISO timestamp) | No | When the trade was closed |
netPnl | string | No | Net profit/loss as decimal string |
errorMessage | string | No | Error message if trade failed |
errorAt | string (ISO timestamp) | No | When the error occurred |
metadata | object | No | Additional metadata |
expirationDate | string | No | Expiration date for options/derivatives |
Validation Rules
- At least one field must be provided
closedAtanderrorAtare converted from ISO timestamp strings to Date objects- When
statusis set to"closed":- All open exit transactions are automatically updated to
"filled"status - Trade status is recalculated based on transaction states
closedAtis set from calculation if not providednetPnlis calculated and set if not provided
- All open exit transactions are automatically updated to
Allowed Fields
Only the following fields can be updated:
statusclosedAtnetPnlerrorMessageerrorAtmetadataexpirationDate
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": "closed",
"signalAt": "2024-01-15T10:30:00.000Z",
"openedAt": "2024-01-15T10:30:05.000Z",
"closedAt": "2024-01-15T15:30:00.000Z",
"netPnl": "525.50",
"metadata": {}
}
}Response Schema
| Field | Type | Description |
|---|---|---|
success | boolean | Always true for successful requests |
trade | object | Updated trade object |
Error Responses
400 Bad Request
Invalid JSON:
{
"error": "Invalid JSON in request body",
"code": "BAD_REQUEST"
}No valid fields to update:
{
"error": "No valid fields to update",
"code": "BAD_REQUEST"
}Missing slug or tradeId:
{
"error": "Bot slug and trade ID are required",
"code": "BAD_REQUEST"
}Invalid slug format:
{
"error": "Invalid slug format. Only alphanumeric characters, hyphens, and underscores are allowed.",
"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
async function updateBotTrade(
botSlug: string,
tradeId: string,
apiKey: string,
updates: {
status?: string;
closedAt?: string;
netPnl?: string;
errorMessage?: string;
errorAt?: string;
metadata?: Record<string, unknown>;
expirationDate?: string;
}
) {
const response = await fetch(
`https://api.example.com/api/bots/${botSlug}/trades/${tradeId}`,
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
"x-api-key": apiKey,
},
body: JSON.stringify(updates),
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(`Failed to update trade: ${error.error}`);
}
return await response.json();
}
// Example: Close a trade
const result = await updateBotTrade(
"my-bot",
"111e4567-e89b-12d3-a456-426614174001",
"your-api-key",
{
status: "closed",
closedAt: new Date().toISOString(),
netPnl: "525.50"
}
);
console.log(`Trade ${result.trade.id} updated to status: ${result.trade.status}`);Python
from typing import Optional, Dict, Any
from datetime import datetime
import requests
def update_bot_trade(
bot_slug: str,
trade_id: str,
api_key: str,
updates: Dict[str, Any]
) -> Dict[str, Any]:
"""
Update a bot trade.
Args:
bot_slug: Bot identifier
trade_id: UUID of trade to update
api_key: Bot API key
updates: Dictionary of fields to update
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}"
headers = {
"Content-Type": "application/json",
"x-api-key": api_key
}
response = requests.patch(url, json=updates, headers=headers)
response.raise_for_status()
return response.json()
# Example: Close a trade
result = update_bot_trade(
bot_slug="my-bot",
trade_id="111e4567-e89b-12d3-a456-426614174001",
api_key="your-api-key",
updates={
"status": "closed",
"closedAt": datetime.now().isoformat(),
"netPnl": "525.50"
}
)
print(f"Trade {result['trade']['id']} updated to status: {result['trade']['status']}")Use Cases
Close Trade with PnL
// Close trade and set profit/loss
await updateBotTrade("my-bot", tradeId, apiKey, {
status: "closed",
closedAt: new Date().toISOString(),
netPnl: "525.50"
});Record Trade Error
# Record an error that occurred during trade execution
update_bot_trade(
bot_slug="my-bot",
trade_id=trade_id,
api_key=api_key,
updates={
"status": "error",
"errorMessage": "Order rejected by broker: Insufficient funds",
"errorAt": datetime.now().isoformat()
}
)Automatic Status Recalculation
// When closing a trade, the system automatically:
// 1. Updates all open exit transactions to "filled"
// 2. Recalculates trade status
// 3. Sets closedAt if not provided
// 4. Calculates netPnl if not provided
await updateBotTrade("my-bot", tradeId, apiKey, {
status: "closed"
// closedAt and netPnl will be calculated automatically
});