Deriv API
Migration guide/Portfolio

Portfolio

Account
Auth Required

Retrieve information about the current portfolio of outstanding options, including all open positions for the authenticated account.

Quick comparison

AspectLegacyNewAction required
Endpoint
✅ Same
portfolioportfolioNone
Auth Required
✅ Same
YesYesNone
Symbol Field
⚠️ Changed
symbolunderlying_symbolUpdate field references
loginid Parameter
❌ Removed
OptionalRemovedRemove from requests
app_id Field
⚠️ Changed
integer | nullinteger onlyUpdate null handling
contract_type Filter
⚠️ Changed
Strict enum (36+ types)Any stringNone required

Breaking changes

1. Symbol field renamed

What Changed: The symbol field in each contract object has been renamed to underlying_symbol. This change affects how you access the trading symbol for each contract in the portfolio.

2. LoginId parameter removed

What Changed: The loginid parameter has been removed from the request structure in New. Account context must now be managed through the authorization flow.

3. app_id field can no longer be null

What Changed: The app_id field in each contract object can no longer be null. In Legacy, this field could be either an integer or null.

Migration: If your code handles null app_id values, update your logic to expect an integer value only.

Improvements in New

Core contract fields are now guaranteed

In New, 12 core contract fields (buy_price,contract_id,currency, etc.) are guaranteed to be present in each contract object. The app_id field remains optional.

Relaxed contract_type filter validation

The contract_type filter parameter now accepts any string value, instead of the previous strict enum of 36+ contract types. This allows for future contract types without requiring schema updates.

Request structure

Legacy Request Example

1{
2  "portfolio": 1,
3  "contract_type": ["CALL", "PUT"],  // Optional filter
4  "loginid": "CR1234567"  // ❌ Removed in New
5}

New Request Example

1{
2  "portfolio": 1,
3  "contract_type": ["CALL", "PUT"]  // Optional filter
4}

Response structure

Legacy Response Example

1{
2  "portfolio": {
3    "contracts": [
4      {
5        "app_id": null,       // Can be integer or null
6        "buy_price": 10.5,
7        "contract_id": 123456789,
8        "contract_type": "CALL",
9        "currency": "USD",
10        "date_start": 1699564800,
11        "expiry_time": 1699651200,
12        "longcode": "Win payout if Volatility 100 Index is strictly higher than entry spot at 15 minutes after contract start time.",
13        "payout": 20,
14        "purchase_time": 1699564800,
15        "shortcode": "CALL_R_100_20_1699651200_1699564800_S0P_0",
16        "symbol": "R_100",    // ❌ Renamed in New
17        "transaction_id": 987654321
18      }
19    ]
20  },
21  "echo_req": {
22    "portfolio": 1
23  },
24  "msg_type": "portfolio"
25}

New Response Example

1{
2  "portfolio": {
3    "contracts": [
4      {
5        "app_id": 12345,       // 🔄 Integer only (no null)
6        "buy_price": 10.5,
7        "contract_id": 123456789,
8        "contract_type": "CALL",
9        "currency": "USD",
10        "date_start": 1699564800,
11        "expiry_time": 1699651200,
12        "longcode": "Win payout if Volatility 100 Index is strictly higher than entry spot at 15 minutes after contract start time.",
13        "payout": 20,
14        "purchase_time": 1699564800,
15        "shortcode": "CALL_R_100_20_1699651200_1699564800_S0P_0",
16        "underlying_symbol": "R_100",  // 🆕 Renamed from symbol
17        "transaction_id": 987654321
18      }
19    ]
20  },
21  "echo_req": {
22    "portfolio": 1
23  },
24  "msg_type": "portfolio"
25}

Code examples

Legacy Implementation

1async function getPortfolio() {
2  const request = {
3    portfolio: 1,
4    contract_type: ["CALL", "PUT"]
5  };
6  
7  ws.send(JSON.stringify(request));
8  
9  // Handle response
10  ws.onmessage = (event) => {
11    const response = JSON.parse(event.data);
12    if (response.msg_type === "portfolio") {
13      const contracts = response.portfolio.contracts;
14      contracts.forEach(contract => {
15        console.log(`Symbol: ${contract.symbol}`);  // Legacy field name
16        console.log(`Contract ID: ${contract.contract_id}`);
17        console.log(`Buy Price: ${contract.buy_price}`);
18      });
19    }
20  };
21}

New Implementation

1async function getPortfolio() {
2  const request = {
3    portfolio: 1,
4    contract_type: ["CALL", "PUT"]
5  };
6  
7  ws.send(JSON.stringify(request));
8  
9  // Handle response
10  ws.onmessage = (event) => {
11    const response = JSON.parse(event.data);
12    if (response.msg_type === "portfolio") {
13      const contracts = response.portfolio.contracts;
14      contracts.forEach(contract => {
15        console.log(`Symbol: ${contract.underlying_symbol}`);  // New field name
16        console.log(`Contract ID: ${contract.contract_id}`);
17        console.log(`Buy Price: ${contract.buy_price}`);
18      });
19    }
20  };
21}