Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

403 response code for any POST request to Interactive Brokers Client Portal Web API

I try use Interactive Brokers Client Portal Web API:

  • I succesfully start gateway and login.
  • I succesfully make GET requests to various end-points.
  • When I make POST request to any end-points, I receive 403 response code.

For example, I try update currently selected account:

// it is need for change User-Agent as recommended*
chrome.webRequest.onBeforeSendHeaders.addListener(function (details) {
    for (var i = 0; i < details.requestHeaders.length; ++i) {
        if (details.requestHeaders[i].name === 'User-Agent') {
            details.requestHeaders[i].value = 'Console';
            break;
        }
    }
    return {requestHeaders: details.requestHeaders};
}, {urls: ['<all_urls>']}, ['blocking', 'requestHeaders']);

// it is code of make of POST request
var data = {};
data['acctId'] = 'U1234567';
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://localhost:5000/v1/portal/iserver/account', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(data));
xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) {
        sendResponse({Status: xhr.status + '_' + xhr.responseText}); // I have "403_" response
    }
};

*: Making POST request from console app results in Error 403 - Access denied

Headers of my request:

Cookie: SBID=xskr4cf7kflki7wrzzy; XYZAB_AM.LOGIN=29c2d567b3a3f23d8d02bdd5ef78d0c8c2694438; XYZAB=29c2d567b3a3f22d8d12bdd5ef78d0c8c2694438; api=673d21e86cf499f04b985446a90a844b; ibkr.nj=286565962.20480.0000
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,uk;q=0.6
Accept-Encoding: gzip, deflate, br
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: none
Origin: chrome-extension://jnblchdcckkmedocgchlfmfhbaihjdnl
Accept: */*
Content-Type: application/json
User-Agent: Console
Content-Length: 21
Connection: close
Host: localhost:5000

Body of my request:

{"acctId":"U1234567"}
like image 426
Nikolas Avatar asked Nov 16 '22 01:11

Nikolas


2 Answers

I resolved this issue by populating the User-Agent and sending an empty string as the POST payload to ensure the Content-Length header was being set, ex. calls made to the /tickle endpoint.

like image 68
Sullivan Avatar answered Dec 21 '22 22:12

Sullivan


As described above, we can resolve this by adding 'User-Agent': 'Console' to the header. You can use Python requests to send the header alongwith as below.

import requests

headers = {'User-Agent': 'Console', 'content-type': 'application/json'}

response = requests.post(url, data=data, headers=headers, verify='path to .pem file or False if SSL is not needed')

where url is the string containing the post URL and data is the json data you need to submit to POST request.

like image 24
Wenuka Avatar answered Dec 21 '22 22:12

Wenuka