webull: get_options has stopped working today, returns a json error
Hello,
Looks like the endpoint for get_options has stopped working today. It now returns this json error when trying to unpack the response using json():
requests.exceptions.JSONDecodeError: [Errno Expecting value] : 0
The response code itself is 200, so it seems like it’s getting something back. Also, the other endpoints work just fine still(at least the ones I’ve tried). Has this one changed at all?
The specific endpoint that is causing trouble is this one:
def options(self, stock): return f'{self.base_options_url}/quote/option/{stock}/list'
Can anyone else verify that the endpoint is not working as expected?
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 38 (9 by maintainers)
I have got some workaround.
curl -XPOST https://quotes-gw.webullfintech.com/api/quote/option/strategy/list -H “content-type:application/json” -d ‘{“tickerId”:913244796,“count”:-1,“direction”:“all”,“expireCycle”:[3,2,4],“type”:0,“quoteMultiplier”:100}’
The result is a HUGE json in which we can find the complete option expire date list and each option’s tickerID. We need the tickerID in the next HTTPS request.
{ “strikePrice”: “27”, “volume”: “0”, “latestPriceVol”: “0”, “expireDate”: “2022-06-03”, “tickerId”: 1032363507, “belongTickerId”: 913244796, “activeLevel”: 27, “cycle”: 2, “weekly”: 1, “executionType”: “A”, “direction”: “call”, “derivativeStatus”: 0, “currencyId”: 247, “regionId”: 6, “exchangeId”: 189, “symbol”: “SQQQ220603C00027000”, “unSymbol”: “SQQQ”, “quoteMultiplier”: 100, “quoteLotSize”: 100 }
GET this endpoint with a list of option ticker IDs.
curl “https://quotes-gw.webullfintech.com/api/quote/option/quotes/queryBatch?derivativeIds=1032283511,1032363508,1032363507”
Thanks everyone for the work done here. I’m reopening this until the fix is integrated into this package and doesn’t require a custom workaround by users of the package.
It does appear that they POST them through https://quotes-gw.webullfintech.com/api/quote/option/strategy/list instead, with a payload of:
I can probably play with this a little later and see if I can make any headway.
Dear All.
Thanks for the discussion here.
After some time investigating, I realized that the webapp endpoint for option is updated. This is probably a good reason for intermittent success on the old endpoint. My guess is that they did not stop it completely, but some servers have it stopped working, so with some load balancing, if you are responded by servers that have deprecated the endpoint would result in the empty response or the json error.
It is likely that the old endpoint will be stopped completely, so I updated the endpoint. The response is not completely the same some some variables have been changed. I tried to respond it in the same format so the code might look a bit messy. I tried calling the new endpoint 30+ times and found it working 100%. The new endpoint is a bit fat though, so it’s taking webull’s server a bit longer for each request.
I am happy it’s solved. Sorry for the delayed response. I am a bit busy with job interviews and I try to shy away from my investing recently since the market is doing so bad. Thanks to Yashwant who has been encouraging me on LinkedIn and on the buymecoffee app. If you like I do, you can post some kind words to me too. 😂🙏🙏🙏
Sorry about the ignorance. The random reqid does fix the issue. It seems like Webull is demanding the headers as well. I think the package has been updated, and pushed to pypi as well. Thank you for the investigation!
This returns an unauthorized user error:
'msg': 'unauthorized user', 'code': '417'EDIT: Nevermind, I got this to work by placing it in the headers area of the webull class. Prior to that I was doing a hacky job just for testing. Placing it in the correct spot seems to apply the trade token. Currently this is working for me. Thanks.
Per your suggestion I’m using a random value for the reqid. Perhaps this will avoid unwanted eyeballs if we don’t all use the same reqid for every request. Here’s my code - there’s probably a better way of doing it though.
ok solved, you need almost all of the headers in the request device-type,os,ph,hl,platform,reqid,osv all of there are required now
That’s working for me too. I think I was missing the “json” field and that’s why it was failing. Thanks BobLiu20, jjqqkk, and grm083.
It is working well for me.
The first request https://quotes-gw.webullfintech.com/api/quote/option/strategy/list must be called with http/2, otherwise webull server returns 500 error.
The python code in this library is not able to make http/2 connection coz requests is not ready for http/2 yet. We may import httpx for that POST request.
Curl makes http/1.1 POST and changes to http/2 seemlessly (curl -v to verify). I need a very quick fixup and let my bot work today. So I am using subprocess to fork curl and get the JSON data through stdout.