GraphQL API
Endpoint: GET/POST https://api.homecast.cloud/graphql
Authenticate with an access token (hc_...) or OAuth Bearer token. Enable Developer Mode in Settings → Account, then find your endpoints in Settings → API Access.

curl -X POST https://api.homecast.cloud/graphql \
-H "Authorization: Bearer hc_your_token" \
-H "Content-Type: application/json" \
-d '{"query": "{ homes { id name } }"}'Field name convention
All field names are camelCase in GraphQL (e.g., accessTokens, homeId).
Homes & Rooms
Queries
| Field | Parameters | Returns | Description |
|---|---|---|---|
homes | — | [HomeKitHome] | All accessible homes |
cachedHomes | — | [CachedHome] | Cached homes with relay status |
rooms | homeId | [HomeKitRoom] | Rooms in a home |
zones | homeId | [HomeKitZone] | Zones in a home |
serviceGroups | homeId | [HomeKitServiceGroup] | Service groups |
scenes | homeId | [HomeKitScene] | Scenes in a home |
Types
type HomeKitHome {
id: String!
name: String!
role: String # owner, admin, control, view
}
type CachedHome {
homeId: String!
name: String!
role: String
isConnected: Boolean
memberCount: Int
}
type HomeKitRoom {
id: String!
name: String!
homeId: String!
}
type HomeKitScene {
id: String!
name: String!
homeId: String!
}Accessories & Control
Queries
| Field | Parameters | Returns | Description |
|---|---|---|---|
accessories | homeId?, roomId? | [HomeKitAccessory] | List accessories |
accessory | accessoryId, homeId? | HomeKitAccessory | Get single accessory |
characteristicGet | accessoryId, characteristicType, homeId? | CharacteristicValue | Read a characteristic |
Mutations
| Field | Parameters | Returns | Description |
|---|---|---|---|
setCharacteristic | accessoryId, characteristicType, value, homeId? | SetCharacteristicResult | Set a device characteristic |
setServiceGroup | homeId, groupId, characteristicType, value | SetServiceGroupResult | Control all devices in a group |
executeScene | sceneId, homeId? | ExecuteSceneResult | Execute a HomeKit scene |
Types
type HomeKitAccessory {
id: String!
name: String!
homeId: String!
roomId: String!
category: String
reachable: Boolean!
services: [HomeKitService!]!
}
type HomeKitService {
id: String!
type: String!
name: String
characteristics: [HomeKitCharacteristic!]!
}
type HomeKitCharacteristic {
type: String!
value: JSON
description: String
format: String
unit: String
minValue: Float
maxValue: Float
minStep: Float
validValues: [String]
canRead: Boolean!
canWrite: Boolean!
}
type SetCharacteristicResult {
success: Boolean!
value: JSON
error: String
}Automations
Manage HomeKit automations — time-based triggers, device state events, sunrise/sunset, and more. Automations sync bidirectionally with the Apple Home app.
Queries
| Field | Parameters | Returns | Description |
|---|---|---|---|
automations | homeId | [HomeKitAutomation] | List automations in a home |
Mutations
| Field | Parameters | Returns | Description |
|---|---|---|---|
createAutomation | homeId, name, trigger (JSON), actions (JSON) | HomeKitAutomation | Create a new automation |
updateAutomation | automationId, homeId?, name?, trigger? (JSON), actions? (JSON), enabled? | HomeKitAutomation | Update an automation |
deleteAutomation | automationId, homeId? | AutomationResult | Delete an automation |
setAutomationEnabled | automationId, enabled, homeId? | HomeKitAutomation | Enable or disable |
Types
type HomeKitAutomation {
id: String!
name: String!
isEnabled: Boolean!
trigger: AutomationTrigger!
actions: [AutomationAction!]!
lastFireDate: String
homeId: String
}
type AutomationTrigger {
type: String! # "timer" or "event"
fireDate: String # ISO8601 (timer)
recurrence: String # JSON-encoded DateComponents (timer)
timeZone: String # IANA timezone (timer)
events: [AutomationEvent!] # Events that activate the trigger
endEvents: [AutomationEvent!] # Events that deactivate (e.g., motion stops)
recurrences: String # JSON-encoded array of DateComponents
executeOnce: Boolean # Fire once then disable
activationState: String # enabled, disabled, disabledNoHomeHub, etc.
}
type AutomationEvent {
type: String! # "characteristic", "significantTime", "location", etc.
accessoryId: String
accessoryName: String
characteristicType: String
triggerValue: String # JSON-encoded
significantEvent: String # "sunrise" or "sunset"
offsetMinutes: Int
# Location fields
latitude: Float
longitude: Float
radius: Float
# Presence fields
presenceType: String
presenceEvent: String
}
type AutomationAction {
accessoryId: String!
accessoryName: String!
characteristicType: String!
targetValue: String # JSON-encoded
}
type AutomationResult {
success: Boolean!
automationId: String!
error: String
}JSON string parameters
The trigger and actions parameters in mutations are JSON strings, not objects. Serialize them with JSON.stringify() before passing.
Access Tokens
Queries
| Field | Parameters | Returns | Description |
|---|---|---|---|
accessTokens | — | [AccessTokenInfo] | List all tokens |
Mutations
| Field | Parameters | Returns | Description |
|---|---|---|---|
createAccessToken | name, homePermissions, expiresAt? | CreateAccessTokenResult | Create a token |
revokeAccessToken | tokenId | RevokeAccessTokenResult | Revoke a token |
Webhooks
Queries
| Field | Parameters | Returns | Description |
|---|---|---|---|
webhooks | — | [WebhookInfo] | List all webhooks |
webhook | webhookId | WebhookInfo | Get single webhook |
webhookEventTypes | — | [WebhookEventTypeInfo] | Available event types |
webhookDeliveryHistory | webhookId, offset?, limit? | DeliveryHistoryResult | Delivery history |
Mutations
| Field | Parameters | Returns | Description |
|---|---|---|---|
createWebhook | name, url, eventTypes?, homeIds?, roomIds?, accessoryIds?, collectionIds?, maxRetries?, rateLimitPerMinute?, timeoutMs? | CreateWebhookResult | Create a webhook |
updateWebhook | webhookId, name?, url?, eventTypes?, homeIds?, roomIds?, accessoryIds?, collectionIds?, maxRetries?, rateLimitPerMinute?, timeoutMs? | UpdateWebhookResult | Update a webhook |
deleteWebhook | webhookId | DeleteWebhookResult | Delete a webhook |
pauseWebhook | webhookId | UpdateWebhookResult | Pause deliveries |
resumeWebhook | webhookId | UpdateWebhookResult | Resume deliveries |
rotateWebhookSecret | webhookId | RotateSecretResult | Rotate signing secret |
testWebhook | webhookId | TestWebhookResult | Send test delivery |
Types
type WebhookInfo {
id: String!
name: String!
url: String!
secretPrefix: String!
status: String! # active, paused, disabled
eventTypes: [String!]!
homeIds: [String!]!
roomIds: [String!]!
accessoryIds: [String!]!
collectionIds: [String!]!
maxRetries: Int!
rateLimitPerMinute: Int
timeoutMs: Int!
consecutiveFailures: Int!
lastTriggeredAt: String
lastSuccessAt: String
lastFailureAt: String
createdAt: String
}OAuth Apps
Queries
| Field | Parameters | Returns | Description |
|---|---|---|---|
authorizedApps | — | [AuthorizedAppInfo] | OAuth apps with access |
Mutations
| Field | Parameters | Returns | Description |
|---|---|---|---|
revokeAuthorizedApp | clientId | RevokeAuthorizedAppResult | Revoke app access |
Examples
Read all accessories in a home
{
homes {
id
name
rooms {
id
name
accessories {
id
name
category
reachable
services {
type
characteristics {
type
value
}
}
}
}
}
}Set a device characteristic
mutation {
setCharacteristic(
accessoryId: "acc-uuid"
characteristicType: "brightness"
value: "50"
homeId: "home-uuid"
) {
success
value
error
}
}Create an access token
mutation {
createAccessToken(
name: "My Script"
homePermissions: "{\"home-uuid\": \"control\"}"
) {
success
rawToken
error
}
}Create a webhook
mutation {
createWebhook(
name: "State logger"
url: "https://my-server.com/webhook"
eventTypes: ["state.changed"]
homeIds: ["home-uuid"]
) {
success
webhook {
id
name
secretPrefix
}
error
}
}Push Notifications
Manage push notification tokens, preferences, and view notification history. Cloud plan only.
Queries
| Field | Parameters | Returns | Description |
|---|---|---|---|
pushTokens | — | [PushTokenInfo] | List registered push notification devices |
notificationPreferences | — | [NotificationPreferenceInfo] | List all notification preferences (global, per-home, per-automation) |
notificationHistory | limit, offset, automationId | [NotificationLogInfo] | Notification delivery history (30-day retention) |
Mutations
| Field | Parameters | Returns | Description |
|---|---|---|---|
registerPushToken | token!, platform!, deviceFingerprint!, deviceName | RegisterPushTokenResult | Register or update an FCM/APNs push token |
unregisterPushToken | deviceFingerprint! | Boolean | Remove a push token |
setNotificationPreference | scope!, scopeId, pushEnabled!, emailEnabled!, localEnabled! | SetNotificationPreferenceResult | Set notification preferences at a scope |
deleteNotificationPreference | scope!, scopeId | Boolean | Delete a preference override (revert to parent scope) |
sendTestNotification | message | Boolean | Send a test notification to all your devices |
Types
type PushTokenInfo {
id: String!
platform: String! # "web", "macos", "ios"
deviceName: String
deviceFingerprint: String!
createdAt: String!
lastUsedAt: String
}
type NotificationPreferenceInfo {
id: String!
scope: String! # "global", "home", "automation"
scopeId: String # null for global, home/automation ID otherwise
pushEnabled: Boolean!
emailEnabled: Boolean!
localEnabled: Boolean!
}
type NotificationLogInfo {
id: String!
automationId: String
homeId: String
title: String
message: String!
channelsSent: String! # comma-separated: "push", "email", "push,email"
channelsFailed: String
rateLimited: Boolean!
createdAt: String!
}Preference resolution
Preferences follow a hierarchy — the most specific scope wins:
- Automation (
scope: "automation",scopeId: "<automationId>") - Home (
scope: "home",scopeId: "<homeId>") - Global (
scope: "global",scopeId: null) - Defaults — push: on, email: off, local: on
Example
mutation {
registerPushToken(
token: "fcm-token-here"
platform: "web"
deviceFingerprint: "browser-uuid"
deviceName: "Chrome on macOS"
) {
success
error
}
}See API Errors for error response formats and common issues.