Home Assistant response_variable: read a Sume job id and status
Home Assistant rest_command returns status, content and headers in response_variable. Here is how to pull the Sume job id from it and branch on the status read.

What response_variable gives you
Home Assistant's RESTful Command page says a command returns a dictionary with three keys: status (the HTTP response code), content (the body, as text or JSON) and headers. An automation reads it by naming a response_variable on the action.
For a Sume submit that means status is the HTTP code and content is the parsed job envelope, so the job id sits at content.data.request_id. The SDK docs read the same field from the submit response.
Branch on the HTTP code first
A submit that was accepted returns a 2xx. Sume documents 402 for insufficient credits, 429 for rate_limited and queue_full, and 401 for a bad key, so a template that checks status before using content avoids treating an error body as a job.
| Status | Code | What to do |
|---|---|---|
| 401 | unauthorized | Fix the key; do not retry |
| 402 | insufficient_credits | Stop and notify; top up the balance |
| 429 | rate_limited | Wait for retry-after, then try again |
| 429 | queue_full | Wait for an existing job to finish or cancel one |
An automation that stores the id
The pattern below submits, checks the code, and keeps the id in a helper so a later automation can poll it. The action key name follows Home Assistant's own example (action: rest_command.<name>).
actions:
- action: rest_command.sume_image
data:
prompt: "A ceramic mug on a pale oak table"
response_variable: sume
- if:
- condition: template
value_template: "{{ sume.status in [200, 202] }}"
then:
- action: input_text.set_value
target:
entity_id: input_text.sume_job_id
data:
value: "{{ sume.content.data.request_id }}"
else:
- action: persistent_notification.create
data:
message: "Sume submit failed with {{ sume.status }}"
Poll with the hint, not a fixed loop
The status response carries next_poll_after_seconds and booleans terminal and result_ready. A second automation triggered by a time pattern can read the stored id, call the status command, and stop when terminal is true. Sume's docs say to poll on those booleans or on sume_status, and not to mix the queue-shaped status field with it.
When the job is completed, fetch GET /v1/jobs/{id}/result for the artifact URLs. The jobs docs list the full lifecycle.
Reading the finished result
Completed jobs carry artifacts, each with an id, a public URL on media.sume.com, a type and a content type. Once result_ready is true, a third rest_command can call the result route, and the same response_variable shape applies: content.data holds the job record and its result.
Treat anything other than completed as a different branch. A failed or canceled job answers the result route with 409 job_not_completed, so the status read is where you learn the outcome, and the job record holds the error. Keeping the three commands separate (submit, status, result) also keeps each one under Home Assistant's 10-second default timeout, which a single long wait would not.
Finally, remember that the job id you stored is the only handle on paid work already started. If an automation restarts, read the helper before submitting again, and if you must give up on a job, cancel it explicitly through the cancel route while it is still cancelable rather than just ignoring it.
Sources
Related posts
More in Developers
- Home Assistant rest_command 10-second timeout and Sume async jobs
rest_command times out at 10 seconds by default. Sume sync waits cap at 30. Submit with mode async, take the job id, and poll in a second command.
- How many characters is one minute of TTS audio? 1,200 s math
A vendor rule of thumb says a minute of speech is 750-800 characters. Here is what that means for a 1,200-second Sume TTS job and its 20,000-char cap.
- Idempotency-Key over 255 characters: hash long business keys
Sume accepts Idempotency-Key values up to 255 characters. Keep readable keys when short and fall back to a prefixed SHA-256 for long ones. Runnable Python.
- Idempotency-Key for a SaaS: customer, order and version
Derive a Format run's Idempotency-Key from customer id, order id, Format slug and a version you bump on purpose, so double clicks never make a second paid run.
Written by Sume