Partner API

Trading on behalf

Place, change and close orders FOR a mapped user through the same order path the trader uses. Leverage, spread, lot rules, margin and every guard apply; every action is written to the client's history as done by your key. MetaTrader accounts are not traded here (409 mt_account).

GET/api/external/v1/users/{external_id}/orders

#The user's pending orders

Auth X-Api-Key accounts:read Partner API

Scope accounts:read. ?account_id= narrows to one of the user's accounts.

Path parameters

external_id string required

Your client id (1-191 letters, digits, . _ @ : + -). Stored on the client as external_user_id.

Query parameters

account_id integer optional

Responses

200

The pending orders (status pending).

404

not_found / user_not_found / account_not_found / symbol_not_found.

curl "https://api.your-brand.com/api/external/v1/users/cust_10042/orders" \
  -H "X-Api-Key: $OCTOLIT_PARTNER_KEY"
Response 200
{
  "orders": [
    {
      "id": 1042,
      "account_id": 55,
      "symbol": "EURUSD",
      "status": "open",
      "side": "buy",
      "order_type": 1,
      "amount": "100.00",
      "trade_amount": "string",
      "units": 10000,
      "lot_size": 1.5,
      "leverage": 100,
      "open_price": "string",
      "stop_loss": "string",
      "take_profit": "string",
      "profit": "19.00",
      "commission": "0.00",
      "swap": "-0.12",
      "market": "string",
      "opened_at": "2026-11-11T09:30:00Z",
      "closed_at": "2026-11-11T10:05:12Z",
      "closed_by": "string",
      "created_at": "2026-11-11T09:30:00.000000Z"
    }
  ]
}
POST/api/external/v1/users/{external_id}/orders

#Place an order for the user

Auth X-Api-Key trading:act Partner API

Scope trading:act. Places a market / limit / stop order on one of the user's trading accounts through the SAME order path the trading platform uses (the account's leverage, spread, lot rules, margin and every CRM guard apply; the position is the user's). The brand's partner API switch and the user's trading state are checked (403 brand_disabled, company_inactive, brand_inactive, client_inactive, trading_inactive). Every action is written to the client's history as done by this API key. Idempotent per key by client_order_id (body or Idempotency-Key header): a repeat returns 200 replayed with the first answer.

Path parameters

external_id string required

Your client id (1-191 letters, digits, . _ @ : + -). Stored on the client as external_user_id.

Headers

Idempotency-Key string optional

Used as client_order_id when the body has none.

Request body · application/json

client_order_id string optional

Your id of this order (idempotency per key, letters digits _ - : .); or send the Idempotency-Key header. 0-64 characters.

trading_account_id integer required

One of the user's trading accounts.

symbol_id integer optional

The symbol id (or symbol).

symbol string optional

The symbol name

side enum required
buysell
type enum required
marketlimitstop
units number optional

Size in units (or lots).

lots number optional

Size in lots (converted with the symbol's contract size).

leverage integer optional

One of the leverages the account offers; default the symbol's.

sl number | null optional
tp number | null optional
price number optional

Required for limit / stop.

Responses

200

replayed - the same client_order_id was placed before.

201

placed - the order / position.

403

insufficient_scope, ip_not_allowed, api_disabled, company_inactive, brand_disabled, sso_disabled, trending_disabled (trading on behalf also: brand_inactive, client_inactive, trading_inactive, trading_denied).

404

not_found / user_not_found / account_not_found / symbol_not_found.

422

invalid_request (details.errors) or a refusal of the order path: order_refused, insufficient_margin, invalid_size, invalid_levels, invalid_price, invalid_leverage, market_closed, symbol_not_allowed, too_many_orders (details.reason / details.errors). Also 409 mt_account (an MT4 / MT5 account is not traded here), 503 no_price / balance_unavailable.

curl -X POST "https://api.your-brand.com/api/external/v1/users/cust_10042/orders" \
  -H "X-Api-Key: $OCTOLIT_PARTNER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "client_order_id": "ord-2026-0001",
  "trading_account_id": 55,
  "symbol_id": 42,
  "symbol": "EURUSD",
  "side": "buy",
  "type": "market",
  "units": 10000,
  "lots": 0.1,
  "leverage": 100,
  "sl": 1.08,
  "tp": 1.1,
  "price": 1.085
}'
Response 200
{
  "code": "placed",
  "client_order_id": "ord-2026-0001",
  "order": {
    "id": 1042,
    "account_id": 55,
    "symbol": "EURUSD",
    "status": "open",
    "side": "buy",
    "order_type": 1,
    "amount": "100.00",
    "trade_amount": "string",
    "units": 10000,
    "lot_size": 1.5,
    "leverage": 100,
    "open_price": "string",
    "stop_loss": "string",
    "take_profit": "string",
    "profit": "19.00",
    "commission": "0.00",
    "swap": "-0.12",
    "market": "string",
    "opened_at": "2026-11-11T09:30:00Z",
    "closed_at": "2026-11-11T10:05:12Z",
    "closed_by": "string",
    "created_at": "2026-11-11T09:30:00.000000Z"
  },
  "position": {
    "id": 1042,
    "account_id": 55,
    "symbol": "EURUSD",
    "status": "open",
    "side": "buy",
    "order_type": 1,
    "amount": "100.00",
    "trade_amount": "string",
    "units": 10000,
    "lot_size": 1.5,
    "leverage": 100,
    "open_price": "string",
    "stop_loss": "string",
    "take_profit": "string",
    "profit": "19.00",
    "commission": "0.00",
    "swap": "-0.12",
    "market": "string",
    "opened_at": "2026-11-11T09:30:00Z",
    "closed_at": "2026-11-11T10:05:12Z",
    "closed_by": "string",
    "created_at": "2026-11-11T09:30:00.000000Z"
  }
}
Response 201
{
  "code": "placed",
  "client_order_id": "ord-2026-0001",
  "order": {
    "id": 1042,
    "account_id": 55,
    "symbol": "EURUSD",
    "status": "open",
    "side": "buy",
    "order_type": 1,
    "amount": "100.00",
    "trade_amount": "string",
    "units": 10000,
    "lot_size": 1.5,
    "leverage": 100,
    "open_price": "string",
    "stop_loss": "string",
    "take_profit": "string",
    "profit": "19.00",
    "commission": "0.00",
    "swap": "-0.12",
    "market": "string",
    "opened_at": "2026-11-11T09:30:00Z",
    "closed_at": "2026-11-11T10:05:12Z",
    "closed_by": "string",
    "created_at": "2026-11-11T09:30:00.000000Z"
  },
  "position": {
    "id": 1042,
    "account_id": 55,
    "symbol": "EURUSD",
    "status": "open",
    "side": "buy",
    "order_type": 1,
    "amount": "100.00",
    "trade_amount": "string",
    "units": 10000,
    "lot_size": 1.5,
    "leverage": 100,
    "open_price": "string",
    "stop_loss": "string",
    "take_profit": "string",
    "profit": "19.00",
    "commission": "0.00",
    "swap": "-0.12",
    "market": "string",
    "opened_at": "2026-11-11T09:30:00Z",
    "closed_at": "2026-11-11T10:05:12Z",
    "closed_by": "string",
    "created_at": "2026-11-11T09:30:00.000000Z"
  }
}
GET/api/external/v1/users/{external_id}/orders/lookup

#Find the order / position this key placed with a client_order_id

Auth X-Api-Key accounts:read Partner API

Scope accounts:read. ?client_order_id= - 404 not_found when this key never placed it.

Path parameters

external_id string required

Your client id (1-191 letters, digits, . _ @ : + -). Stored on the client as external_user_id.

Query parameters

client_order_id string required

Responses

200

The order (pending) or position (open / closed) with that id.

404

not_found / user_not_found / account_not_found / symbol_not_found.

422

invalid_request with details.errors = { field: reason }.

curl "https://api.your-brand.com/api/external/v1/users/cust_10042/orders/lookup?client_order_id=ord-2026-0001" \
  -H "X-Api-Key: $OCTOLIT_PARTNER_KEY"
Response 200
{
  "client_order_id": "ord-2026-0001",
  "order": {
    "id": 1042,
    "account_id": 55,
    "symbol": "EURUSD",
    "status": "open",
    "side": "buy",
    "order_type": 1,
    "amount": "100.00",
    "trade_amount": "string",
    "units": 10000,
    "lot_size": 1.5,
    "leverage": 100,
    "open_price": "string",
    "stop_loss": "string",
    "take_profit": "string",
    "profit": "19.00",
    "commission": "0.00",
    "swap": "-0.12",
    "market": "string",
    "opened_at": "2026-11-11T09:30:00Z",
    "closed_at": "2026-11-11T10:05:12Z",
    "closed_by": "string",
    "created_at": "2026-11-11T09:30:00.000000Z"
  }
}
PATCH/api/external/v1/users/{external_id}/orders/{id}

#Change a pending order (price, stop loss, take profit)

Auth X-Api-Key trading:act Partner API

Scope trading:act. Body { "price": 1.0850, "sl": 1.08, "tp": null, "client_order_id": "..." } - a field left out keeps its value, null clears it. 409 not_pending when the order was filled already. Answers 200 modified / 200 unchanged.

Path parameters

external_id string required

Your client id (1-191 letters, digits, . _ @ : + -). Stored on the client as external_user_id.

id integer required

The pending order's id.

Request body · application/json

price number | null optional

Pending orders only.

sl number | null optional
tp number | null optional
client_order_id string optional

0-64 characters.

Responses

200

The order after the change.

403

insufficient_scope, ip_not_allowed, api_disabled, company_inactive, brand_disabled, sso_disabled, trending_disabled (trading on behalf also: brand_inactive, client_inactive, trading_inactive, trading_denied).

404

not_found / user_not_found / account_not_found / symbol_not_found.

409

email_taken, brand_fixed, limit_reached, already_linked, no_brand, no_app_domain.

422

invalid_request with details.errors = { field: reason }.

curl -X PATCH "https://api.your-brand.com/api/external/v1/users/cust_10042/orders/1042" \
  -H "X-Api-Key: $OCTOLIT_PARTNER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "price": 1.085,
  "sl": 1.08,
  "tp": 1.1,
  "client_order_id": "ord-2026-0001"
}'
Response 200
{
  "code": "placed",
  "client_order_id": "ord-2026-0001",
  "order": {
    "id": 1042,
    "account_id": 55,
    "symbol": "EURUSD",
    "status": "open",
    "side": "buy",
    "order_type": 1,
    "amount": "100.00",
    "trade_amount": "string",
    "units": 10000,
    "lot_size": 1.5,
    "leverage": 100,
    "open_price": "string",
    "stop_loss": "string",
    "take_profit": "string",
    "profit": "19.00",
    "commission": "0.00",
    "swap": "-0.12",
    "market": "string",
    "opened_at": "2026-11-11T09:30:00Z",
    "closed_at": "2026-11-11T10:05:12Z",
    "closed_by": "string",
    "created_at": "2026-11-11T09:30:00.000000Z"
  },
  "position": {
    "id": 1042,
    "account_id": 55,
    "symbol": "EURUSD",
    "status": "open",
    "side": "buy",
    "order_type": 1,
    "amount": "100.00",
    "trade_amount": "string",
    "units": 10000,
    "lot_size": 1.5,
    "leverage": 100,
    "open_price": "string",
    "stop_loss": "string",
    "take_profit": "string",
    "profit": "19.00",
    "commission": "0.00",
    "swap": "-0.12",
    "market": "string",
    "opened_at": "2026-11-11T09:30:00Z",
    "closed_at": "2026-11-11T10:05:12Z",
    "closed_by": "string",
    "created_at": "2026-11-11T09:30:00.000000Z"
  }
}
DELETE/api/external/v1/users/{external_id}/orders/{id}

#Cancel a pending order

Auth X-Api-Key trading:act Partner API

Scope trading:act. Answers 200 cancelled / 200 already_cancelled; 409 not_pending once filled.

Path parameters

external_id string required

Your client id (1-191 letters, digits, . _ @ : + -). Stored on the client as external_user_id.

id integer required

The pending order's id.

Responses

200

Cancelled.

403

insufficient_scope, ip_not_allowed, api_disabled, company_inactive, brand_disabled, sso_disabled, trending_disabled (trading on behalf also: brand_inactive, client_inactive, trading_inactive, trading_denied).

404

not_found / user_not_found / account_not_found / symbol_not_found.

409

email_taken, brand_fixed, limit_reached, already_linked, no_brand, no_app_domain.

curl -X DELETE "https://api.your-brand.com/api/external/v1/users/cust_10042/orders/1042" \
  -H "X-Api-Key: $OCTOLIT_PARTNER_KEY"
Response 200
{
  "code": "placed",
  "client_order_id": "ord-2026-0001",
  "order": {
    "id": 1042,
    "account_id": 55,
    "symbol": "EURUSD",
    "status": "open",
    "side": "buy",
    "order_type": 1,
    "amount": "100.00",
    "trade_amount": "string",
    "units": 10000,
    "lot_size": 1.5,
    "leverage": 100,
    "open_price": "string",
    "stop_loss": "string",
    "take_profit": "string",
    "profit": "19.00",
    "commission": "0.00",
    "swap": "-0.12",
    "market": "string",
    "opened_at": "2026-11-11T09:30:00Z",
    "closed_at": "2026-11-11T10:05:12Z",
    "closed_by": "string",
    "created_at": "2026-11-11T09:30:00.000000Z"
  },
  "position": {
    "id": 1042,
    "account_id": 55,
    "symbol": "EURUSD",
    "status": "open",
    "side": "buy",
    "order_type": 1,
    "amount": "100.00",
    "trade_amount": "string",
    "units": 10000,
    "lot_size": 1.5,
    "leverage": 100,
    "open_price": "string",
    "stop_loss": "string",
    "take_profit": "string",
    "profit": "19.00",
    "commission": "0.00",
    "swap": "-0.12",
    "market": "string",
    "opened_at": "2026-11-11T09:30:00Z",
    "closed_at": "2026-11-11T10:05:12Z",
    "closed_by": "string",
    "created_at": "2026-11-11T09:30:00.000000Z"
  }
}
PATCH/api/external/v1/users/{external_id}/positions/{id}

#Change the stop loss / take profit of an open position

Auth X-Api-Key trading:act Partner API

Scope trading:act. Body { "sl": 1.08, "tp": 1.10, "client_order_id": "..." } - a field left out keeps its value, null clears it. 409 pending_order for an order not filled yet (use the orders routes).

Path parameters

external_id string required

Your client id (1-191 letters, digits, . _ @ : + -). Stored on the client as external_user_id.

id integer required

The open position's id.

Request body · application/json

price number | null optional

Pending orders only.

sl number | null optional
tp number | null optional
client_order_id string optional

0-64 characters.

Responses

200

modified / unchanged - the position after the change.

403

insufficient_scope, ip_not_allowed, api_disabled, company_inactive, brand_disabled, sso_disabled, trending_disabled (trading on behalf also: brand_inactive, client_inactive, trading_inactive, trading_denied).

404

not_found / user_not_found / account_not_found / symbol_not_found.

409

email_taken, brand_fixed, limit_reached, already_linked, no_brand, no_app_domain.

422

invalid_request with details.errors = { field: reason }.

curl -X PATCH "https://api.your-brand.com/api/external/v1/users/cust_10042/positions/1042" \
  -H "X-Api-Key: $OCTOLIT_PARTNER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "price": 1.085,
  "sl": 1.08,
  "tp": 1.1,
  "client_order_id": "ord-2026-0001"
}'
Response 200
{
  "code": "placed",
  "client_order_id": "ord-2026-0001",
  "order": {
    "id": 1042,
    "account_id": 55,
    "symbol": "EURUSD",
    "status": "open",
    "side": "buy",
    "order_type": 1,
    "amount": "100.00",
    "trade_amount": "string",
    "units": 10000,
    "lot_size": 1.5,
    "leverage": 100,
    "open_price": "string",
    "stop_loss": "string",
    "take_profit": "string",
    "profit": "19.00",
    "commission": "0.00",
    "swap": "-0.12",
    "market": "string",
    "opened_at": "2026-11-11T09:30:00Z",
    "closed_at": "2026-11-11T10:05:12Z",
    "closed_by": "string",
    "created_at": "2026-11-11T09:30:00.000000Z"
  },
  "position": {
    "id": 1042,
    "account_id": 55,
    "symbol": "EURUSD",
    "status": "open",
    "side": "buy",
    "order_type": 1,
    "amount": "100.00",
    "trade_amount": "string",
    "units": 10000,
    "lot_size": 1.5,
    "leverage": 100,
    "open_price": "string",
    "stop_loss": "string",
    "take_profit": "string",
    "profit": "19.00",
    "commission": "0.00",
    "swap": "-0.12",
    "market": "string",
    "opened_at": "2026-11-11T09:30:00Z",
    "closed_at": "2026-11-11T10:05:12Z",
    "closed_by": "string",
    "created_at": "2026-11-11T09:30:00.000000Z"
  }
}
POST/api/external/v1/users/{external_id}/positions/{id}/close

#Close an open position at market

Auth X-Api-Key trading:act Partner API

Scope trading:act. Body { "client_order_id": "..." } (optional, or the Idempotency-Key header). Answers 200 closed / 200 already_closed.

Path parameters

external_id string required

Your client id (1-191 letters, digits, . _ @ : + -). Stored on the client as external_user_id.

id integer required

The open position's id.

Responses

200

The closed position.

403

insufficient_scope, ip_not_allowed, api_disabled, company_inactive, brand_disabled, sso_disabled, trending_disabled (trading on behalf also: brand_inactive, client_inactive, trading_inactive, trading_denied).

404

not_found / user_not_found / account_not_found / symbol_not_found.

422

invalid_request with details.errors = { field: reason }.

curl -X POST "https://api.your-brand.com/api/external/v1/users/cust_10042/positions/1042/close" \
  -H "X-Api-Key: $OCTOLIT_PARTNER_KEY"
Response 200
{
  "code": "placed",
  "client_order_id": "ord-2026-0001",
  "order": {
    "id": 1042,
    "account_id": 55,
    "symbol": "EURUSD",
    "status": "open",
    "side": "buy",
    "order_type": 1,
    "amount": "100.00",
    "trade_amount": "string",
    "units": 10000,
    "lot_size": 1.5,
    "leverage": 100,
    "open_price": "string",
    "stop_loss": "string",
    "take_profit": "string",
    "profit": "19.00",
    "commission": "0.00",
    "swap": "-0.12",
    "market": "string",
    "opened_at": "2026-11-11T09:30:00Z",
    "closed_at": "2026-11-11T10:05:12Z",
    "closed_by": "string",
    "created_at": "2026-11-11T09:30:00.000000Z"
  },
  "position": {
    "id": 1042,
    "account_id": 55,
    "symbol": "EURUSD",
    "status": "open",
    "side": "buy",
    "order_type": 1,
    "amount": "100.00",
    "trade_amount": "string",
    "units": 10000,
    "lot_size": 1.5,
    "leverage": 100,
    "open_price": "string",
    "stop_loss": "string",
    "take_profit": "string",
    "profit": "19.00",
    "commission": "0.00",
    "swap": "-0.12",
    "market": "string",
    "opened_at": "2026-11-11T09:30:00Z",
    "closed_at": "2026-11-11T10:05:12Z",
    "closed_by": "string",
    "created_at": "2026-11-11T09:30:00.000000Z"
  }
}