Skip to content

Build Home Automation Scripts

Homecast exposes REST and GraphQL APIs for programmatic control of your HomeKit devices. This guide walks through creating a token, reading state, controlling devices, and building a complete automation script.

Get an API token

  1. Sign in at homecast.cloud
  2. Open SettingsAPI Tokens
  3. Click Create Token
  4. Name the token (e.g., "automation-script")
  5. Set home permissions — choose which homes the token can access and whether it gets view or control access
  6. Copy the token — it starts with hc_ and is only shown once

Store tokens securely

Treat your token like a password. Store it in environment variables or a secrets manager, never in source code.

Read your home state

The REST API returns a hierarchical view of your homes, rooms, and accessories.

bash
curl https://api.homecast.cloud/rest/state \
  -H "Authorization: Bearer hc_your_token_here"
python
import requests

resp = requests.get(
    "https://api.homecast.cloud/rest/state",
    headers={"Authorization": "Bearer hc_your_token_here"}
)
state = resp.json()
javascript
const resp = await fetch("https://api.homecast.cloud/rest/state", {
  headers: { Authorization: "Bearer hc_your_token_here" }
});
const state = await resp.json();

The response is a nested structure:

json
{
  "homes": [
    {
      "id": "home-uuid",
      "name": "My Home",
      "rooms": [
        {
          "id": "room-uuid",
          "name": "Living Room",
          "accessories": [
            {
              "id": "acc-uuid",
              "name": "Floor Lamp",
              "type": "lightbulb",
              "reachable": true,
              "services": [
                {
                  "type": "lightbulb",
                  "characteristics": [
                    { "type": "on", "value": true },
                    { "type": "brightness", "value": 75 }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

Filter the response

Use query parameters to narrow results:

ParameterExampleDescription
filter_by_home?filter_by_home=My HomeOnly accessories in this home
filter_by_room?filter_by_room=BedroomOnly accessories in this room
filter_by_type?filter_by_type=lightbulbOnly this accessory type
filter_by_name?filter_by_name=Floor LampOnly accessories matching this name
bash
curl "https://api.homecast.cloud/rest/state?filter_by_type=lightbulb&filter_by_room=Bedroom" \
  -H "Authorization: Bearer hc_your_token_here"

Control a device

Send a POST to /rest/state with an array of updates:

bash
curl -X POST https://api.homecast.cloud/rest/state \
  -H "Authorization: Bearer hc_your_token_here" \
  -H "Content-Type: application/json" \
  -d '[{
    "home": "My Home",
    "room": "Living Room",
    "accessory": "Floor Lamp",
    "on": true,
    "brightness": 80
  }]'
python
resp = requests.post(
    "https://api.homecast.cloud/rest/state",
    headers={
        "Authorization": "Bearer hc_your_token_here",
        "Content-Type": "application/json"
    },
    json=[{
        "home": "My Home",
        "room": "Living Room",
        "accessory": "Floor Lamp",
        "on": True,
        "brightness": 80
    }]
)
result = resp.json()
print(f"Updated: {result['updated']}, Failed: {result['failed']}")
javascript
const resp = await fetch("https://api.homecast.cloud/rest/state", {
  method: "POST",
  headers: {
    Authorization: "Bearer hc_your_token_here",
    "Content-Type": "application/json"
  },
  body: JSON.stringify([{
    home: "My Home",
    room: "Living Room",
    accessory: "Floor Lamp",
    on: true,
    brightness: 80
  }])
});
const result = await resp.json();

Update properties

Each update object must include home, room, and accessory (by name). All other fields are optional — only include the properties you want to change.

PropertyTypeDescription
homestringHome name (required)
roomstringRoom name (required)
accessorystringAccessory name (required)
onbooleanPower state
brightnessintegerBrightness 0–100
hueintegerColor hue 0–360
saturationintegerColor saturation 0–100
color_tempintegerColor temperature in mireds
activebooleanActive state (air purifiers, humidifiers)
heat_targetfloatHeating target temperature
cool_targetfloatCooling target temperature
hvac_modestringHVAC mode: off, heat, cool, auto
lock_targetintegerLock state: 1 (secured), 0 (unsecured)
alarm_targetintegerSecurity alarm target state
speedintegerFan speed 0–100
volumeintegerSpeaker volume 0–100
mutebooleanSpeaker mute
targetintegerGeneric target position 0–100 (blinds, garage doors)

The response:

json
{
  "updated": 1,
  "failed": 0,
  "changes": ["Floor Lamp: on=true, brightness=80"],
  "errors": [],
  "message": "Updated 1 accessories"
}

Run a scene

Execute a HomeKit scene by name:

bash
curl -X POST https://api.homecast.cloud/rest/scene \
  -H "Authorization: Bearer hc_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{"home": "My Home", "name": "Good Night"}'
python
resp = requests.post(
    "https://api.homecast.cloud/rest/scene",
    headers={
        "Authorization": "Bearer hc_your_token_here",
        "Content-Type": "application/json"
    },
    json={"home": "My Home", "name": "Good Night"}
)

Go deeper with GraphQL

The GraphQL API at /graphql provides typed queries and mutations for everything the REST API does, plus user management, webhooks, sharing, and more.

bash
curl -X POST https://api.homecast.cloud/graphql \
  -H "Authorization: Bearer hc_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "{ homes { id name rooms { id name accessories { id name category services { type characteristics { type value } } } } } }"
  }'

Set a characteristic via GraphQL:

graphql
mutation {
  setCharacteristic(
    accessoryId: "acc-uuid"
    characteristicType: "brightness"
    value: "50"
    homeId: "home-uuid"
  ) {
    success
    value
  }
}

See the GraphQL reference for the complete schema.

Real-time updates

Use webhooks to get notified when device state changes. See the webhook automation guide for setup.

Example: lights-off automation

A complete script that turns off all lights after midnight:

python
#!/usr/bin/env python3
"""Turn off all lights if it's past midnight."""

import requests
from datetime import datetime

TOKEN = "hc_your_token_here"
API = "https://api.homecast.cloud/rest"
HEADERS = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}

def main():
    hour = datetime.now().hour
    if hour >= 0 and hour < 5:
        # Get all lights
        resp = requests.get(f"{API}/state?filter_by_type=lightbulb", headers=HEADERS)
        state = resp.json()

        updates = []
        for home in state["homes"]:
            for room in home["rooms"]:
                for acc in room["accessories"]:
                    # Check if light is on
                    for svc in acc.get("services", []):
                        for char in svc.get("characteristics", []):
                            if char["type"] == "on" and char["value"] is True:
                                updates.append({
                                    "home": home["name"],
                                    "room": room["name"],
                                    "accessory": acc["name"],
                                    "on": False
                                })

        if updates:
            resp = requests.post(f"{API}/state", headers=HEADERS, json=updates)
            result = resp.json()
            print(f"Turned off {result['updated']} lights")
        else:
            print("All lights already off")

if __name__ == "__main__":
    main()

Run this with cron to check every 15 minutes:

bash
*/15 * * * * /usr/bin/python3 /path/to/lights_off.py

Home permissions

API tokens can be scoped to specific homes with specific access levels:

json
{
  "home-uuid-1": "control",
  "home-uuid-2": "view"
}
  • control — Read state and set values
  • view — Read state only (set requests will be rejected)
  • null (no permissions set) — Full access to all homes

See the Authentication reference for details on all auth models.

Next steps