API Order Failures

The problem is that you are attempting to reauthorize using the same access token.

In order to renew your access token, you must call the /auth/renewaccesstoken endpoint. It will have a different address than the original token.

Thanks @Arthur !

Just so I’m clear … Are you suggesting to use /auth/renewaccesstoken to get a new token when the original token expires in 80 minutes?

Currently we are calling “https://demo.tradovateapi.com/v1/auth/accesstokenrequest” to get a new token after 80 minutes have passed on the current token – should we instead call /auth/renewaccesstoken to get the new token even after the previous token has expired?

Here’s the flow you should have:

  • acquire access token with /auth/accessTokenRequest
  • run your application normally until…
  • your token’s expiration is approaching.
  • send a request to /auth/renewAccessToken. The response looks like the /auth/accessTokenRequest's.
  • now you have a new token, continue running until the token is almost expired and repeat.

There are several ways that you could achieve this. Since you’re using WebSockets, you can check on each incoming message whether or not your token is approaching expiration. Once you get the new token, make sure that you store it properly so that it is usable by both apps.

Yes, the access token comes with an expirationTime property. You should call renewAccessToken before the expiration time elapses, because once your token expires, you will not be able to submit any requests to the server.

@Alexander @Arthur

Thank you! I hope the below summary of how our app works is helpful in directing us further:

  • the app currently gets a new token from this endpoint > https://live.tradovateapi.com/v1/auth/accesstokenrequest.
  • Once it gets the token from the above endpoint, it uses the same token until it expires (“expirationTime”)
  • Once the token expires, it goes gets a new token from the same endpoint again > https://live.tradovateapi.com/v1/auth/accesstokenrequest.
  • The app will wait for the new token – it doesn’t use old expired token during this time. This way, we make sure the apps are using only one token for the entire duration of its validity (80 minutes).

We are seeing 408s/401s/1006s when the token still has several minutes of validity left.

Do you see any issues with this approach?
Might this approach be causing the 408s, 401s and 1006 (websocket) issues we have been facing?

Appreciate if you could help troubleshoot and guide us regarding the changes we should make. Thank you!

Hi @Alexander ,

We have taken note of your message above posted at 4:10 pm CT yesterday. Thank you!

When you get a chance, could you please provide your thoughts on my later message above posted at 7:12 pm CT? We want to make sure to understand if you see any issue with our current design before going back to make any necessary changes.

Thanks again, as always!

Hey @fin1, I meant to reply directly to your latest message. The bullet list flow of how the app should run is accurate, you should try to adopt that model. Re-acquiring an access token with /auth/accesstokenrequest is not advised, you should always use the /auth/renewaccesstoken if you already have one.

Hi @Alexander ,

I made the changes per your suggestion. However, I continue to see 408 errors.

I am sending the errors in a text file to support@tradovate.com as recommended by your phone agent this morning.

Appreciate if you could help review the logs at your end and advise next steps.

Thanks again! Appreciate your help.

OK, we will get to the bottom of this. I have some more theories for you to test.

408 errors are the result of too many concurrent connections. At some point:

  • you are attempting to call request access token while you already have an active connection, or
  • you are maybe logging into the Trader app while you are running the application?
  • If multiple instances of the application are ever running this could also cause the error.
  • The 408 usually also means you’ve been booted off by a more recent connection. Possibly you’ve cached an old access token in a callback and it is attempting to use the stale token to make a request? That could describe the subsequent 401 behavior as well.

@fin1, I was reviewing your logs and I was noticing you call DELETE on some part of the API. Could you explain what you use that part for?

Thanks @Alexander . Those are for canceling pending stop entry orders. We send them based on the original trade setup no longer being true in light of new price action.

What endpoint do those DELETE entries call? You should just call /order/cancelOrder documented here.

Thanks @Alexander . Yes, that is the exact endpoint we are calling with POST action.

Hi @Alexander ,

Just checking if you might have specific insights based on your review of my account logs on your server. Appreciate if you could help guide on what is exactly causing the issues. Thanks again!

The combination 408 and 401 point to you using an expired access token at some point in conjunction with requesting a new access token. You need to make sure that you only use the access token renewal endpoint after you’ve retrieved your initial token via /auth/accesstokenrequest That’s about as much as I can tell you about the situation, unfortunately.

It seems quite likely to me that somewhere an old token has been cached, or a new token is requested when a non-expired token already exists. A previously valid token will yield 401s once a newer token has been created (beyond max concurrent conns), and the new token being requested via accesstokenrequest acts like a fresh login - it will boot the oldest connection beyond your max concurrent connections which results in the 408 error. That’s essentially what our logs say happened based on these results and their accompanying messages - you used an expired token and exceeded your max allowed concurrent connections.

This flow is incorrect. You cannot renew a token from the same endpoint you use to create one.

All of the information you need to solve this issue has been laid out for you in this thread by @Alexander and me. There is nothing more to add, short of writing the actual code for you. I would suggest going back to the previous posts and making sure your code follows the correct order flow.

But just to make sure it is crystal clear:

  1. Create an access token: /auth/accesstokenrequest
  2. Store expirationTime and run renewal procedure before this time transpires
  3. Renew access token: /auth/renewaccesstoken
  4. Repeat from step 2

@Alexander @Arthur

We had made those changes you recommended previously. Please see below the details of changes and observations after the changes - please let us know what else we can do to move forward. Thanks.

  1. Auth token endpoint is called only once when the app is deployed and started

  2. We set internal TTL for the token to 70 minutes, 10 minutes less than actual validity.

  3. when it passes the TTL, we renew the token by calling renew token api endpoint.

  4. Steps 2 and 3 are repeated.

As stated in our previous message, we are not seeing 401s, but we are seeing 408s when the current token still has 20+ minutes validity on our side - we are logging first 10 characters of the token on every usage/outbound api call and it shows only one token.

Can something else be causing 408s? Our app is deployed in AWS Lambda which scales based on the volume. We appreciate your insight in this regard.

Thanks.

I have a new theory - if you are generating the device ID from the environment (AWS Lambda’s env), and if AWS creates multiple instances (which I’m pretty sure it does, esp on scaling) it will treat each instance as a separate device. That could potentially cause the 408s.