Hulu True Deeplinking

Has anyone had any luck with true deep linking Hulu. I’m not just talking about starting a media player and switching the source to Hulu. That’s easy and readily achievable. What I’m looking for is the ability to direct Hulu to a specific network, like The Weather Channel, as part of an automation or script.

I’m currently running 4 Roku TV’s as media players and have a subscription to Hulu. The typical start up sequence is:

  1. Turn on Media Player
  2. Set source to Hulu and delay until Hulu is ready
  3. Select the user from the Hulu Menu. We have 2, plus there is an option to add a user.
  4. This is where it gets wonky. Select the correct Network. In my case I want a specific network, not a particular show or series.

I can do the first 3 steps using the remote.send_command service calls, but the desired channel is not typically in the same sequence of key commands from day to day. Meaning if the sequence was Left, Left, Down, Select, Down, Select EVEREY DAY this would be an acceptable solution, but it isn’t. With 4 TV’s and one Hulu account the Recently Watched and Live TV list order changes daily.
Therefore I would like to do something like this:

hulu_direct_to_history:
  alias: Hulu Direct to History Channel
  sequence:
    - service: media_player.play_media
      enabled: TRUE
      target:
        entity_id: media_player.kitchen_roku_tv
      data:
        media_content_id: 2285
        media_content_type: app
        extra:
          content_id: the-history-channel-bf84c00e-26c4-4c19-b4f2-e113fd4ebbc8
          media_type: live

However this fails. The content ID was acquired using the Hulu website on my PC. I can log in, select a network and watch whatever is on at the time. Using the information found on the Roku integration page, the URL is parsed down to a content_id of:

the-history-channel-bf84c00e-26c4-4c19-b4f2-e113fd4ebbc8

from the full URL of:

https://www.hulu.com/network/the-history-channel-bf84c00e-26c4-4c19-b4f2-e113fd4ebbc8

I suspect that the Roku TV’s post a similar content ID to the one the web page uses, but in every case where I get the data from the website, parse it and send it with the above code, it fails.

I’ve tried:

        extra:
          content_id: the-history-channel-bf84c00e-26c4-4c19-b4f2-e113fd4ebbc8
          media_type: live

        extra:
          content_id: the-history-channel
          media_type: live

        extra:
          content_id: bf84c00e-26c4-4c19-b4f2-e113fd4ebbc8
          media_type: live

        extra:
          content_id: network/the-history-channel-bf84c00e-26c4-4c19-b4f2-e113fd4ebbc8
          media_type: live

None work. :<(

Does anyone have a suggestion or alternative solution? Any help would be appreciated.

Any luck here? I’m trying to do the same on Apple TV.

Unfortunately, no. I dug around with WireShark but could never get anything I could code to link an action directly to a specific channel. Super disappointing since it seems like it should be do-able especially since I can click a link on Hulu on my pc and jump right to that channel.

This seems to be working for me using

action: media_player.play_media
target:
  entity_id:
    - media_player.office_apple_tv
data:
  media_content_id: hulu://watch/73df1fcf-09ed-4717-a9d2-14d3138afd7e
  media_content_type: url

so basically remove the host/query params of the web url and change the scheme to hulu://. changing watch to series opens the series page instead of playing the media. Still early in testing, but hope this helps!

After some playing with curl, I found that the Roku ECP url will accept networkID as a parameter – you can get these from the Hulu URL when you navigate to a network’s details page, e.g. for CNN:

https://www.hulu.com/network/77c1d69b-93a6-45d8-b7d1-6d39cde0e820

Unfortunately as of HA core 2025.7.2 the official Roku integration does not support network_id as a parameter. I’ve opened a PR to fix this, but in the meantime you can use the rest_command integration to send the HTTP request to the Roku directly:

configuration.yaml

rest_command:
  turn_on_hulu_cnn:
    url: "http://{ip-address-of-your-roku}:8060/launch/2285?networkId=77c1d69b-93a6-45d8-b7d1-6d39cde0e820"
    method: post

Note with the rest_command approach you have to hardcode the target roku’s IP and the network id, so you’ll need a new entry per each (roku device, channel) combination

1 Like

I’m gonna test this over the next few days. Initially, it looks good. I’ll mark as a solution after testing. Thanks for posting!!

So, unfortunately, this didn’t work for me. I added the following lines to my rest commands file:

turn_on_kitchen_hulu_abc25:
  url: "http://192.168.1.14:8060/launch/2285?networkId=wjxx-7d9d2a8c-e1b7-499e-8818-de5db36902b0"
  method: post
#
turn_on_kitchen_hulu_cbs47:
  url: "http://192.168.1.14:8060/launch/2285?networkId=wjax-f272b9c5-f82d-4545-bd53-288a590d0027"
  method: post
#
turn_on_kitchen_hulu_discovery:
  url: "http://192.168.1.14:8060/launch/2285?networkId=discovery-15c4547b-7457-44d2-8cf3-e6aefa2ac09d"
  method: post
#
turn_on_kitchen_hulu_fox30:
  url: "http://192.168.1.14:8060/launch/2285?networkId=wfox-cffc1048-87d6-4144-8f30-197095dcffde"
  method: post
#
turn_on_kitchen_hulu_nbc12:
  url: "http://192.168.1.14:8060/launch/2285?networkId=wtlv-d148cfd1-5645-44ef-b114-bc81e16cf580"
  method: post

I got the network ID while opening the channel on my pc. Here’s that screenshot:


And finally I called the rest command from a mushroom template chip. That code looks like this:

type: custom:mushroom-chips-card
chips:
  - type: template
    tap_action:
      action: perform-action
      target: {}
      perform_action: rest_command.turn_on_kitchen_hulu_nbc12
    content: NBC Live
    picture: /local/roku_icons/nbc.png
    entity: media_player.kitchen_roku_tv
#
type: custom:mushroom-chips-card
chips:
  - type: template
    tap_action:
      action: perform-action
      target: {}
      perform_action: rest_command.turn_on_kitchen_hulu_cbs47
    content: CBS Live
    picture: /local/roku_icons/cbs.png

When I tap the mushroom chip(s) on my dashboard, it restarts Hulu and goes to displaying whatever is first in the LIVE NOW bar onscreen (waiting for the user to press PLAY). As best as I can tell, I have put all the correct pieces in place as described, but can’t get it to go directly to the selected channel.
Just for clarity, the kitchen device is a Roku TV with Hulu built in as an app. The rest commands do connect and interact with the device, but not with the desired outcome. I have populated 5 individual mushroom chips for the major local networks and Discovery Network channel, and all tap actions do the exact same thing, even though the underlying rest commands differ. Also note that I’ve tried the tap action with and without the entity defined. See the last line in the two chip card YAML.
Any thoughts jeigrei?

Hm, those network ids look different from the ones I was seeing (could be a regional or app version thing?) – have you tried setting the network Id to just the UUID? e.g. instead of

wjxx-7d9d2a8c-e1b7-499e-8818-de5db36902b0

just

7d9d2a8c-e1b7-499e-8818-de5db36902b0

Tried your suggestion today. Unfortunately I get the exact same response. Just out of curiosity, how do you get your network ID’s? Are you using a browser where you can see the URL or are you using some other method? Also, I am initiating the rest command from a Lovelace mushroom card tap action. It shouldn’t matter how it gets called, correct? I could try moving the action portion to a script and use the mushroom tap action to call the script. (I really don’t think it will make a difference, but can try.)
In any case, I do appreciate your efforts and will continue to tinker with this.

I just had to figure this out. If you bring up Live TV in a browser (I could only get Google Chrome to work-- not Brave or Safari), you can go into a live video, make it fit the screen to where you get a stream or watch ID in the URL-- but this is NOT the ID to use…

The ID in the URL will be for whatever specific show / episode is currently playing, it is NOT the network ID, and that ID in the URL will change whenever the next show comes on.

To get the right network ID… make sure the video is big (not picture in picture), right click on the live video and go to view page source.

Copy the whole HTML into notepad and save it.

Upload it to ChatGPT (or whatever AI) and ask it to parse out the channel names and the IDs. Example of what will be in the HTML… (for me all 90 channels and their info / IDs were in the HTML)

“25a56912-f488-49b1-a50f-a61138270395”:{“color”:“#000000”,“name”:“Bloomberg”}

I had ChatGPT create a .json file of all the channel names and IDs so my scripts can use this as a dictionary…

example:

{    
    "Bloomberg": "25a56912-f488-49b1-a50f-a61138270395",
    "Bravo": "d132a0bf-f84d-4d37-8de6-6f3cd4531e5b",
    "TBS": "d3c92930-65e7-4f65-8064-818db30cdea1",
    "Comedy Central": "d738418f-6492-4bbc-96a3-9c4ce8d5d32b",
    "Golf Channel": "efa36fda-b813-49e6-8600-65e19d1f6be8",
    "TNT": "fc29059f-629e-4702-8eac-2f721e834b45",
    ...
}

After a few hours with Claude and ChatGPT, i think i figured out the DeepLinking on Roku logged into Hulu Live. Get the networkId from your browser logged into Hulu. Best to go to Hubs at the top, find the network, then in the address bar hulu.com/network/{{networkId}}.

rest_command:
  hulu_live_channel:
    url: "http://{{ roku_ip }}:8060/launch/2285?networkId={{ networkId }}"
    method: post

action: rest_command.hulu_live_channel
data:
  roku_ip: "192.168.1.XX"
  networkId: "920e4e9c-7cd6-40f2-b24f-0f0baf4d3eb2"