Skip to content

Create a TDA Refresh Token

William Studer edited this page Jun 10, 2023 · 13 revisions

The official directions are on TDA's developer site here:

  • Simple Auth for Local Apps - this is confusing, especially the part where you generate yourself a valid OAuth refresh token that is needed in order to use the Java Client API.

Others have found a random Redditor's directions easier to follow than the official TDA docs:

My Own Method

My own directions that I've successfully used a few times leverage Docker and Curl to make the process easier:

You need to have Docker running. Start a simple NGINX container on http localhost: docker run --name mynginx1 -p 80:80 -d nginx

In your TDA Application settings, make sure your redirect URL is set to http://127.0.0.1. Notice that this is NOT https. tda_callback_url

You will have your client ID (sometimes referred to as consumer key) as something like: DFTTFRYTNJQGV7BXYZTAARGH0ZMMA91C.

When generating the client token, in the first and only first GET request, you have to append @AMER.OAUTHAP to it. In every case I can see, e.g. the second POST request and when using the API itself, you do NOT use this @AMER.OAUTHAP stuff.

  1. 1st request - do it in the browser (substituting your own client id in the parameter): https://auth.tdameritrade.com/auth?response_type=code&redirect_uri=http%3A%2F%2F127.0.0.1&client_id=DFTTFRYTNJQGV7BXYZTAARGH0ZMMA91C%40AMER.OAUTHAP

You will get taken to a TDA Login page where you type in your user name and password. Sometimes you have to authenticate with a phone number, too, depending on your settings.

If successful, it will send a redirect to localhost, which will fail. That is okay, because you only needed to obtain the code query parameter that was appended to the url. Copy that code parameter that you get back. You need it for the next request.

url_redirect

Notice how we URL encoded the parameters?

  1. 2nd request with NGINX running in Docker and after you've logged into TDA. You need to use the code you got in the previous redirect. Make sure it's URL encoded in the next post call using curl.

curl -X POST --header "Content-Type: application/x-www-form-urlencoded" -d "grant_type=authorization_code&refresh_token=&access_type=offline&code=<THE_CODE_FROM_PREVIOUS_CALL_HERE>&client_id=DFTTFRYTNJQGV7BXYZTAARGH0ZMMA91C&redirect_uri=http%3A%2F%2F127.0.0.1" "https://api.tdameritrade.com/v1/oauth2/token"

Obviously replace the CODE section above with the url encoded code parameter you got back in the first request. And also use your own client ID (a.k.a. consumer key).

Note that in this call using Curl, we did not append @AMER.OAUTHAP to the client id (consumer key)? I have no idea why TDA uses it sometimes but not always, but it definitely confuses a lot of developers.

This will redirect back to your NGINX server running on localhost, and should contain a json payload which includes the refresh token that is good for 90 days.

curl_tda

Every time you run this process successfully and generate a new refresh token, your old refresh token(s) are invalidated. So you can't just keep creating multiple new ones and expect them to all work concurrently. You will basically only have one token per app and redirect URL at a time (as far as I can tell).

In order to test the refresh token you've generated, you could quickly run the TDA Client Example with your token and client ID set in the appropriate properties file.

Clone this wiki locally