Send variable to script over REST API - help needed

I have created a TTS script in my configuration that needs 3 variables to run properly. When calling this script in my automations, I simply do:

    - service: script.google_home_notification
      data:
        exclude_bedroom_when_sleeping: "yes"
        language: "en"
        message: "this is a test"

Works like a charm. However, I also want to be able to call this script via the REST API but I can’t seem to get the URL (see below) correct, I keep on getting 400: Bad Request back. When I do a POST to a script without variables, that works fine, it executes without any problem.

curl --location --request POST 'MYURL/api/services/script/turn_on' \
--header 'Authorization: Bearer MYTOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
	"entity_id": "script.google_home_notification",
	"exclude_bedroom_when_sleeping":"yes",
	"language":"en",
	"message":"this is a test"		
}'

I tried variations that included data, data_template, service_data, etc… with our without the entity_id included, but all without any success. Also a - way too long - search on Google and here in the community didn’t get me any closer. I’m guessing this will be a small stupid error but just can’t find it… help :grinning:

1 Like

Did you solve your problem yet?
I almost got the same problem and found a workaround. The problem still exists in some apps though.
I setup my call with Postman (your curl looks similar) and always get a 400 Bad Request with a “Bad status line ‘invalid HTTP method’” message.

This was my initial request after digging through the forums and google.

curl --location --request POST 'MYURL/api/services/script/sunrise' \
--header 'Authorization: Bearer MYTOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{"entity_id": "script.1615844466946"}'

I changed it to this:

curl --location --request POST 'MYURL/api/services/script/1615844466946' \
--header 'Authorization: Bearer MYTOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{"entity_id": "script.1615844466946"}'

This still fails in Postman, but works in WSL/Terminal and (with the same parameters in Tasker (Android)).

HomeAssistant logs on a failing request via Postman:

Logger: aiohttp.server
Source: /usr/local/lib/python3.8/site-packages/aiohttp/web_protocol.py:393
First occurred: 8:50:06 (1 occurrences)
Last logged: 8:50:06

Error handling request
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/aiohttp/web_protocol.py", line 314, in data_received
    messages, upgraded, tail = self._request_parser.feed_data(data)
  File "aiohttp/_http_parser.pyx", line 546, in aiohttp._http_parser.HttpParser.feed_data
aiohttp.http_exceptions.BadStatusLine: 400, message="Bad status line 'invalid HTTP method'"

Also found a bug report on the underlying library, didnt dig to deep into it yet.
Server throws ‘aiohttp.http_exceptions.BadStatusLine’ · Issue #3287 · aio-libs/aiohttp · GitHub
All I got from it is that there was/is an issue with an additional line feed send after the post data, but that should be fixed already. Would still like to be able to send POST request via Postman, so I hope anyone got a solution for this?

Did you already found a solution?

The solution is… POST a JSON object containing the following keys(i Will write in YAML here for semplicity)

entity_id: script.your_script
variables:
   message: Your beautiful message

Be aware: You cannot create a restful notification target calling this script because every notification adds a message Key on the root of the object so It Will become:

message: This will be merged automatically
entity_id: script.your_script
variables:
   message: Your beautiful message

…and this JSON will results in a 400 bad request from the api. I solved calling a python_script in place of a script.

RESTful notification target → python_script wrapper → my original target script.

Hope It helps

2 Likes

@aventrax thanks for this. It was what I needed to tie everything together. It’s maybe not really needed, but I’m just going to drop the JSON dictionary format here for total clarity. This was the final piece of the puzzle for me to allow the passing of Home Assistant script variables via the REST API.

Chat-GPT o1 helps me a huge amount with Home Assistant scripts, but couldn’t get this one right.

Here’s my JSON for passing a timer variable to an oven script:

{'entity_id': 'script.cook_oven', 'variables': {'cooking_timer': 60}}

Everything needs to be packed in a “variables” key but I’m not sure if that is stated anywhere other than @aventrax’s post.