Appearance
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
- Sign in at homecast.cloud
- Open Settings → API Tokens
- Click Create Token
- Name the token (e.g., "automation-script")
- Set home permissions — choose which homes the token can access and whether it gets
vieworcontrolaccess - 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:
| Parameter | Example | Description |
|---|---|---|
filter_by_home | ?filter_by_home=My Home | Only accessories in this home |
filter_by_room | ?filter_by_room=Bedroom | Only accessories in this room |
filter_by_type | ?filter_by_type=lightbulb | Only this accessory type |
filter_by_name | ?filter_by_name=Floor Lamp | Only 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.
| Property | Type | Description |
|---|---|---|
home | string | Home name (required) |
room | string | Room name (required) |
accessory | string | Accessory name (required) |
on | boolean | Power state |
brightness | integer | Brightness 0–100 |
hue | integer | Color hue 0–360 |
saturation | integer | Color saturation 0–100 |
color_temp | integer | Color temperature in mireds |
active | boolean | Active state (air purifiers, humidifiers) |
heat_target | float | Heating target temperature |
cool_target | float | Cooling target temperature |
hvac_mode | string | HVAC mode: off, heat, cool, auto |
lock_target | integer | Lock state: 1 (secured), 0 (unsecured) |
alarm_target | integer | Security alarm target state |
speed | integer | Fan speed 0–100 |
volume | integer | Speaker volume 0–100 |
mute | boolean | Speaker mute |
target | integer | Generic 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.pyHome 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 valuesview— 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
- GraphQL reference — Full schema with every query and mutation
- REST reference — Complete endpoint documentation
- Webhooks reference — Event delivery and signing
- Webhook automation — React to device events with push notifications
- AI assistant — Connect Claude or ChatGPT via MCP