Deriv API
Migration guide/Contract update

Contract update

Trading
Auth Required

Update contract parameters like take profit and stop loss. The loginid parameter removed, response object now required, and new display_order_amount field added.

Quick comparison

AspectLegacyNewAction required
Endpoint
✅ Same
contract_updatecontract_updateNone
Auth Required
✅ Same
YesYesNone
loginid Parameter
❌ Removed
OptionalRemovedRemove from requests
contract_update in Response
⚠️ Changed
OptionalRequiredSimplify error handling
display_order_amount Field
🆕 New
Not presentAddedUse for display formatting

Breaking changes

1. loginid parameter removed

What Changed: The loginid parameter has been removed in New. This parameter was previously used to specify which account to update contracts for when multiple tokens were provided during authorization.

Migration: Remove the loginid field from your contract_update requests. Account selection is now handled through the authorization token.

2. contract_update object now required in response

What Changed: The contract_update object is now a required field at the root level of the response. In Legacy, only echo_req andmsg_type were required.

Migration: You can now rely on the contract_update object always being present in successful responses. Remove any conditional checks for its existence.

3. New display_order_amount field added

What Changed: A new display_order_amount string field has been added to both stop_loss andtake_profit objects in the response. This provides a pre-formatted display string for the order amount.

Migration: You can optionally use this new field for displaying order amounts in the UI instead of formatting the order_amount number yourself.

Request structure

Legacy Request Example

1{
2  "contract_update": 1,
3  "contract_id": 123456789,
4  "limit_order": {
5    "stop_loss": 15.00,
6    "take_profit": 25.00
7  },
8  "loginid": "CR123456"
9}

New Request Example

1{
2  "contract_update": 1,
3  "contract_id": 123456789,
4  "limit_order": {
5    "stop_loss": 15.00,
6    "take_profit": 25.00
7  }
8}

Note: The loginid parameter must be removed in New.

Response structure

Legacy Response Example

1{
2  "contract_update": {
3    "stop_loss": {
4      "display_name": "Stop loss",
5      "order_amount": 15.00,
6      "order_date": 1234567890,
7      "value": "1234.56"
8    },
9    "take_profit": {
10      "display_name": "Take profit",
11      "order_amount": 25.00,
12      "order_date": 1234567890,
13      "value": "1256.78"
14    }
15  },
16  "echo_req": { "contract_update": 1, "contract_id": 123456789 },
17  "msg_type": "contract_update"
18}

New Response Example

1{
2  "contract_update": {
3    "stop_loss": {
4      "display_name": "Stop loss",
5      "display_order_amount": "15.00 USD",
6      "order_amount": 15.00,
7      "order_date": 1234567890,
8      "value": "1234.56"
9    },
10    "take_profit": {
11      "display_name": "Take profit",
12      "display_order_amount": "25.00 USD",
13      "order_amount": 25.00,
14      "order_date": 1234567890,
15      "value": "1256.78"
16    }
17  },
18  "echo_req": { "contract_update": 1, "contract_id": 123456789 },
19  "msg_type": "contract_update"
20}

Note: The contract_update object is now required in responses, and includes the new display_order_amount field.

Code examples

Legacy Implementation

1async function updateContract(contractId, loginId = null) {
2  const request = {
3    contract_update: 1,
4    contract_id: contractId,
5    limit_order: {
6      stop_loss: 15.00,
7      take_profit: 25.00
8    }
9  };
10  
11  // Add loginid if provided (for multi-account)
12  if (loginId) {
13    request.loginid = loginId;
14  }
15
16  ws.send(JSON.stringify(request));
17
18  ws.onmessage = (event) => {
19    const response = JSON.parse(event.data);
20    if (response.msg_type === 'contract_update') {
21      // contract_update may be undefined
22      if (response.contract_update) {
23        const sl = response.contract_update.stop_loss;
24        const tp = response.contract_update.take_profit;
25        // Format order_amount manually
26        console.log('Stop Loss:', sl?.order_amount);
27        console.log('Take Profit:', tp?.order_amount);
28      }
29    }
30  };
31}
32
33updateContract(123456789, 'CR123456');

New Implementation

1async function updateContract(contractId) {
2  const request = {
3    contract_update: 1,
4    contract_id: contractId,
5    limit_order: {
6      stop_loss: 15.00,
7      take_profit: 25.00
8    }
9    // loginid removed - account selection via auth token
10  };
11
12  ws.send(JSON.stringify(request));
13
14  ws.onmessage = (event) => {
15    const response = JSON.parse(event.data);
16    if (response.msg_type === 'contract_update') {
17      // contract_update is always present
18      const sl = response.contract_update.stop_loss;
19      const tp = response.contract_update.take_profit;
20      // Use new display_order_amount for formatted display
21      console.log('Stop Loss:', sl.display_order_amount);
22      console.log('Take Profit:', tp.display_order_amount);
23    }
24  };
25}
26
27updateContract(123456789);

Migration checklist

Remove loginid parameter

Remove the loginid field from all contract_update requests

Simplify response handling

The contract_update object is now guaranteed in successful responses

Consider using display_order_amount

New pre-formatted field available for stop_loss and take_profit display