Skip to content

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.

API endpoints

bash
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 ​

FieldParametersReturnsDescription
homes—[HomeKitHome]All accessible homes
cachedHomes—[CachedHome]Cached homes with relay status
roomshomeId[HomeKitRoom]Rooms in a home
zoneshomeId[HomeKitZone]Zones in a home
serviceGroupshomeId[HomeKitServiceGroup]Service groups
sceneshomeId[HomeKitScene]Scenes in a home

Types ​

graphql
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 ​

FieldParametersReturnsDescription
accessorieshomeId?, roomId?[HomeKitAccessory]List accessories
accessoryaccessoryId, homeId?HomeKitAccessoryGet single accessory
characteristicGetaccessoryId, characteristicType, homeId?CharacteristicValueRead a characteristic

Mutations ​

FieldParametersReturnsDescription
setCharacteristicaccessoryId, characteristicType, value, homeId?SetCharacteristicResultSet a device characteristic
setServiceGrouphomeId, groupId, characteristicType, valueSetServiceGroupResultControl all devices in a group
executeScenesceneId, homeId?ExecuteSceneResultExecute a HomeKit scene

Types ​

graphql
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.

Relay needs Apple Home edit access

Creating, updating, or deleting automations requires the relay Mac's Apple ID to have edit access in Apple Home ("Add & Edit Accessories", called "Allow Editing" on older iOS). Without it, mutations fail with an Insufficient privileges error — see Troubleshooting.

Queries ​

FieldParametersReturnsDescription
automationshomeId[HomeKitAutomation]List automations in a home

Mutations ​

FieldParametersReturnsDescription
createAutomationhomeId, name, trigger (JSON), actions (JSON)HomeKitAutomationCreate a new automation
updateAutomationautomationId, homeId?, name?, trigger? (JSON), actions? (JSON), enabled?HomeKitAutomationUpdate an automation
deleteAutomationautomationId, homeId?AutomationResultDelete an automation
setAutomationEnabledautomationId, enabled, homeId?HomeKitAutomationEnable or disable

Types ​

graphql
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 ​

FieldParametersReturnsDescription
accessTokens—[AccessTokenInfo]List all tokens

Mutations ​

FieldParametersReturnsDescription
createAccessTokenname, homePermissions, expiresAt?CreateAccessTokenResultCreate a token
revokeAccessTokentokenIdRevokeAccessTokenResultRevoke a token

Webhooks ​

Queries ​

FieldParametersReturnsDescription
webhooks—[WebhookInfo]List all webhooks
webhookwebhookIdWebhookInfoGet single webhook
webhookEventTypes—[WebhookEventTypeInfo]Available event types
webhookDeliveryHistorywebhookId, offset?, limit?DeliveryHistoryResultDelivery history

Mutations ​

FieldParametersReturnsDescription
createWebhookname, url, eventTypes?, homeIds?, roomIds?, accessoryIds?, collectionIds?, maxRetries?, rateLimitPerMinute?, timeoutMs?CreateWebhookResultCreate a webhook
updateWebhookwebhookId, name?, url?, eventTypes?, homeIds?, roomIds?, accessoryIds?, collectionIds?, maxRetries?, rateLimitPerMinute?, timeoutMs?UpdateWebhookResultUpdate a webhook
deleteWebhookwebhookIdDeleteWebhookResultDelete a webhook
pauseWebhookwebhookIdUpdateWebhookResultPause deliveries
resumeWebhookwebhookIdUpdateWebhookResultResume deliveries
rotateWebhookSecretwebhookIdRotateSecretResultRotate signing secret
testWebhookwebhookIdTestWebhookResultSend test delivery

Types ​

graphql
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 ​

FieldParametersReturnsDescription
authorizedApps—[AuthorizedAppInfo]OAuth apps with access

Mutations ​

FieldParametersReturnsDescription
revokeAuthorizedAppclientIdRevokeAuthorizedAppResultRevoke app access

Examples ​

Read all accessories in a home ​

graphql
{
  homes {
    id
    name
    rooms {
      id
      name
      accessories {
        id
        name
        category
        reachable
        services {
          type
          characteristics {
            type
            value
          }
        }
      }
    }
  }
}

Set a device characteristic ​

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

Create an access token ​

graphql
mutation {
  createAccessToken(
    name: "My Script"
    homePermissions: "{\"home-uuid\": \"control\"}"
  ) {
    success
    rawToken
    error
  }
}

Create a webhook ​

graphql
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 ​

FieldParametersReturnsDescription
pushTokens—[PushTokenInfo]List registered push notification devices
notificationPreferences—[NotificationPreferenceInfo]List all notification preferences (global, per-home, per-automation)
notificationHistorylimit, offset, automationId[NotificationLogInfo]Notification delivery history (30-day retention)

Mutations ​

FieldParametersReturnsDescription
registerPushTokentoken!, platform!, deviceFingerprint!, deviceNameRegisterPushTokenResultRegister or update an FCM/APNs push token
unregisterPushTokendeviceFingerprint!BooleanRemove a push token
setNotificationPreferencescope!, scopeId, pushEnabled!, emailEnabled!, localEnabled!SetNotificationPreferenceResultSet notification preferences at a scope
deleteNotificationPreferencescope!, scopeIdBooleanDelete a preference override (revert to parent scope)
sendTestNotificationmessageBooleanSend a test notification to all your devices

Types ​

graphql
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:

  1. Automation (scope: "automation", scopeId: "<automationId>")
  2. Home (scope: "home", scopeId: "<homeId>")
  3. Global (scope: "global", scopeId: null)
  4. Defaults — push: on, email: off, local: on

Example ​

graphql
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.