Skip to content

Sharing

Looking for the user guide?

See Sharing Access for a step-by-step guide to inviting members and creating share links.

Homecast provides two sharing systems: home members (invite users to your entire home) and entity access (share specific devices, rooms, or collections via link).

Home Members

Invite other Homecast users to access your home. Each member gets a role that controls what they can do.

Roles

RoleView devicesControl devicesManage members
OwnerYesYesYes
AdminYesYesYes
ControlYesYesNo
ViewYesNoNo
  • view members can see all device states but cannot toggle, adjust, or execute scenes
  • control members can read and control devices but cannot invite or remove other members
  • admin members have full control plus member management
  • owner is the home owner (the account whose relay provides the home)

Invitation flow

  1. Owner/admin calls inviteHomeMember with email and role
  2. If the email matches an existing user, the invitation appears in their pendingInvitations
  3. The invited user calls acceptPendingInvitation or rejectPendingInvitation
  4. If the email doesn't match any user, the invitation stays pending. When someone signs up with that email, the invitation is automatically linked.
  5. Accepted members see the home in mySharedHomes and can interact based on their role

GraphQL operations

graphql
# Invite a member
mutation {
  inviteHomeMember(homeId: "home-uuid", email: "user@example.com", role: "control") {
    success
    error
  }
}

# List members
{ homeMembers(homeId: "home-uuid") { id email role isPending name createdAt } }

# Change role
mutation { updateHomeMemberRole(homeId: "home-uuid", email: "user@example.com", role: "view") { success } }

# Remove member
mutation { removeHomeMember(homeId: "home-uuid", email: "user@example.com") { success } }

# View pending invitations (as the invitee)
{ pendingInvitations { id homeId homeName role inviterName createdAt } }

# Accept/reject
mutation { acceptPendingInvitation(invitationId: "invitation-uuid") { success } }
mutation { rejectPendingInvitation(invitationId: "invitation-uuid") { success } }

Enforcement

Permissions are enforced across all APIs. view members can see all device states but control actions (toggling, adjusting, running scenes) are blocked. control and above can read and write.

Entity Access

Share specific entities (devices, rooms, collections) via link. Supports public, passcode-protected, and user-specific access.

Entity types

TypeDescription
accessorySingle device
accessory_groupGroup of devices
roomAll devices in a room
room_groupMultiple rooms
collectionCustom device grouping
collection_groupMultiple collections
homeEntire home
groupGeneric group

Access types

TypeDescription
publicAnyone with the link can access
passcodeRequires a passcode to access
userOnly the specified Homecast user can access

Access roles

RolePermissions
viewRead-only — see device state
controlRead and write — toggle, adjust, execute

Create a share

graphql
# Public share with view access
mutation {
  createEntityAccess(
    entityType: "room"
    entityId: "room-uuid"
    accessType: "public"
    role: "view"
    homeId: "home-uuid"
  ) {
    success
    entityAccess { id }
    shareHash
    shareUrl
  }
}

# Passcode-protected share with control access
mutation {
  createEntityAccess(
    entityType: "accessory"
    entityId: "acc-uuid"
    accessType: "passcode"
    passcode: "1234"
    role: "control"
    homeId: "home-uuid"
    name: "Guest Access"
  ) {
    success
    shareHash
    shareUrl
  }
}

# User-specific share
mutation {
  createEntityAccess(
    entityType: "collection"
    entityId: "coll-uuid"
    accessType: "user"
    userEmail: "friend@example.com"
    role: "control"
    homeId: "home-uuid"
  ) {
    success
  }
}

Share URLs

Share links follow the format: https://homecast.cloud/s/{hash}

The hash encodes the entity type, entity ID, and an HMAC signature. Users visiting the link see a read-only or interactive view depending on the role.

Share control endpoints

For control role shares, devices can be controlled via simple URL paths:

PathDescription
/s/{hash}/onTurn on
/s/{hash}/offTurn off
/s/{hash}/toggleToggle power state
/s/{hash}/lockLock
/s/{hash}/unlockUnlock
/s/{hash}/brightness/{value}Set brightness (0–100)
/s/{hash}/hue/{value}Set hue (0–360)
/s/{hash}/saturation/{value}Set saturation (0–100)
/s/{hash}/temp/{value}Set color temperature
/s/{hash}/position/{value}Set position (0–100)
/s/{hash}/color/{hue}/{saturation}Set color

These endpoints accept both GET and POST requests.

Access schedules

Entity access supports time-based schedules via the accessSchedule field (JSON string). This allows temporary or recurring access windows.

Manage shares

graphql
# List shares for an entity
{ entityAccess(entityType: "room", entityId: "room-uuid") {
    id accessType role name userEmail hasPasscode createdAt
} }

# Get sharing summary
{ sharingInfo(entityType: "room", entityId: "room-uuid") {
    isShared hasPublic publicRole passcodeCount userCount shareHash shareUrl
} }

# Update a share
mutation { updateEntityAccess(accessId: "access-uuid", role: "view") { success } }

# Delete a share
mutation { deleteEntityAccess(accessId: "access-uuid") { success } }

# List all entities I've shared
{ mySharedEntities { id entityType entityId accessType role createdAt } }

Public entity access (no auth required)

graphql
# View shared entity
{ publicEntity(shareHash: "abc123", passcode: "1234") {
    entityType entityId entityName homeName accessories { id name }
} }

# Get full accessory data
{ publicEntityAccessories(shareHash: "abc123") {
    id name services { type characteristics { type value } }
} }

# Control a device via shared access
mutation {
  publicEntitySetCharacteristic(
    shareHash: "abc123"
    accessoryId: "acc-uuid"
    characteristicType: "on"
    value: true
  ) {
    success
  }
}