Rest commands for Fire TV

I was looking for a faster way to control the Fire TV 4k Max gen 2 which restricts the use of the sendevent and didn’t want to use another component to control it. (I know there are keyboard control options but this worked out better) I decided to try and figure out how the apps control the Fire Sticks. I am not a great coder so I am not sure I will be able to make an integration but I reversed engineered the apps and made a work around that works pretty well. If anyone can turn this into a integration please do. The hardest part was figuring out how the token gets sent when the pin is given. You may need to wake it up before requesting the pin but the details are as follows.

Using curl or postman or something you can easily send and receive post commands. Use the following to request the pin.

curl -k https://firetvip:8080/v1/FireTV/pin/display \
  -H "X-Api-Key: 0987654321" \
  -H "Content-Type: application/json" \
  -d '{"friendlyName": "ha\'s Fire TV"}'

Once the pin is displayed you will need to send it back to generate a token.

curl -k https://firetvip:8080/v1/FireTV/pin/verify \
  -H "X-Api-Key: 0987654321" \
  -H "Content-Type: application/json" \
  -d '{"pin":"xxxx"}'

This will output something like {"description":"Wj9PP8I"}. This is the token we will be using for the control.

There are 3 different urls depending on what you are doing.

  1. Media Controls:
ftv_key_media:
    url: 'https://firetvip:8080/v1/media?action={{state}}'
    method: POST
    headers:
      X-Api-Key: "0987654321"
      X-Client-Token: "Wj9PP8I"
      user-agent: "okhttp/4.10.0"
      Content-Type: "application/json"
    verify_ssl: false
    payload: "{{main}}"

The list of commands are:
Fast Forward:

  action:
  - service: rest_command.ftv_key_media
    data:
      state: 'scan'
      main: '{"direction":"forward", "keyAction":{"keyActionType":keyDown"}}'

Rewind:

  action:
  - service: rest_command.ftv_key_media
    data:
      state: 'scan'
      main: '{"direction":"back", "keyAction":{"keyActionType":keyDown"}}'

Play/Pause:

  action:
  - service: rest_command.ftv_key_media
    data:
      state: 'play'
  1. Main Controls
ftv_key_controls:
    url: 'https://firetvip:8080/v1/FireTV?action={{state}}'
    method: POST
    headers:
      X-Api-Key: "0987654321"
      X-Client-Token: "Wj9PP8I"
      user-agent: "okhttp/4.10.0"
    verify_ssl: false

The tested commands are:

Left = dpad_left
Right = dpad_right
UP = dpad_up
Down = dpad_down
Select = select
Home = home
Back = back
Menu = menu

(There may be more options but these are what I have confirmed so far)

  1. Apps can also be launched this way.
ftv_key_controls:
    url: 'https://firetvip:8080/v1/FireTV/app/{{app}}'
    method: POST
    headers:
      X-Api-Key: "0987654321"
      X-Client-Token: "Wj9PP8I"
      user-agent: "okhttp/4.10.0"
    verify_ssl: false

Tested App list (These are the ones tested there will be more):

Disney Plus = com.disney.disneyplus
Youtube = com.amazon.firetv.youtube
Netflix = com.netflix.ninja
Prime Video = com.amazon.cloud9
Amazon Music = com.amazon.bueller.music
Pandora = com.pandora.android.gtv
Hulu = com.hulu.plus
BBC = uk.co.bbc.iplayer
NowTV = com.bskyb.nowtv.beta
AppleTV = com.apple.atve.amazon.appletv
ITV = air.ITVMobilePlayer
Chan 4 = com.channel4.ondemand
Demand 5 = com.mobileiq.demand5
SkyNews = com.onemainstream.skynews.android

If you find more commands or apps please share them.

2 Likes

This is interesting, thanks for sharing will take a deep look soon

This is great stuff, and may help me solve another problem I have.

Note, you may need to “wake up” the server before it can be used. eg

curl -X POST -v http://10.0.0.52:8009/apps/FireTVRemote

Otherwise you might get connection refused because the app hasn’t started so isn’t listening on 8080.

But then I run into problems replicating your functions. I’m testing with curl to verify stuff works.

The pin/display and pin/verify functions work well, and I get an authorization code.

And this appears to work as well

curl -X POST -k https://10.0.0.52:8080/v1/media?action=play \
  -H "X-Api-Key: 0987654321" \
  -H "X-Client-Token: MYCODE" \
  -H "user-agent: okhttp/4.10.0"

But this gives an error:

curl -X POST -k https://10.0.0.52:8080/v1/media?action=scan \
  -H "X-Api-Key: 0987654321" \
  -H "X-Client-Token: MYCODE" \
  -H "user-agent: okhttp/4.10.0" \
  -d '{"direction":"forwards","keyAction":{"keyActionType":"keyDown"}}'
{"description":"Bad arguments supplied. Please check inputs."}

The MYCODE is correct 'cos I get an authn error if the token is wrong.

Am I doing something wrong?

1 Like

I realized I did make a mistake in the code. For the main controls it should be https://firetvip:8080/v1/FireTV?action={{state}}

For the media scan it should be {"direction":"forward","keyAction":{"keyActionType":"keyDown"}}
It should be forward without the s.

OK, so that’s a step forward; with FireTV?action= I’m able to send a dpad_right and see it move on the screen. Great :slight_smile:

And with the FireTV/app/com.amazon.tv.leanbacklauncher I can start the alternate launcher. So far so good!

But I’m still having trouble with media?action=scan…even with forward I still get the same error. :frowning:

curl -X POST -k https://10.0.0.52:8080/v1/media?action=scan \
  -H "X-Api-Key: 0987654321" \
  -H "X-Client-Token: XXXXXX" \
  -H "user-agent: okhttp/4.10.0" \
  -d '{"direction":"forward","keyAction":{"keyActionType":"keyDown"}}'
{"description":"Bad arguments supplied. Please check inputs."}

I also get the same if I send back.

That is the correct method. What if you added a space after the comma? Does it give you the same output. Which Fire TV do you have, it shouldn’t make a difference but it is possible we need to try something different.

As you suspected, adding a space doesn’t make any difference (but you can never tell if there’s a broken JSON parser so was definitely worth testing heheheh).

I have a Firestick 4k 1st gen running Fire OS 6.7.1.1 (N56711/5866)

I’ve tried to do some independent discovery, but my Android hacking skills aren’t that good; I’ve used apktool to decompile the mobile app and the server app, but can’t find the relevant code (I can’t even find the string "scan" - case insensitive - in the server side results); I’ve tried running it on a rooted phone with httptoolkit, but I’m guessing the TLS cert is pinned 'cos it fails to be intercepted (I can see the initial discovery and “wake up” calls, and I can see calls from other apps). At this point I’m reaching my skill limits!

I will test on my older unit tonight. I have a gen 2 at home. I tested a few commands on it but mostly programmed with a 4k max 2nd gen. The apps I used to find the codes are PCAPdroid and Fire Tv app or Fire Remote (lots of ads but doesn’t detect the ssl cert the PCAPdroid uses). Follow the steps to setup the local ssl cert and then you can test the codes from the remote app. They have a hard time detecting the fire stick when the connection is active but if you pair first and then start the process it works pretty good.

Decompiling tv.remote.control.firetv gave me the missing hint… it needs a content type :slight_smile:

curl -X POST -k https://10.0.0.52:8080/v1/media?action=scan \
  -H "X-Api-Key: 0987654321" \
  -H "X-Client-Token: XXXXXX" \
  -H "user-agent: okhttp/4.10.0" \
  -H "Content-Type: application/json; charset=utf-8" \
  -d '{"direction":"forward", "keyAction":{"keyActionType":"keyDown"}}'
{"description":"OK"}
1 Like

Ah, okay that makes sense. I didn’t even realize you were missing that and that I forgot to add it in the instructions. I added it to my instructions now.

1 Like