Appearance
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
| Role | View devices | Control devices | Manage members |
|---|---|---|---|
| Owner | Yes | Yes | Yes |
| Admin | Yes | Yes | Yes |
| Control | Yes | Yes | No |
| View | Yes | No | No |
viewmembers can see all device states but cannot toggle, adjust, or execute scenescontrolmembers can read and control devices but cannot invite or remove other membersadminmembers have full control plus member managementowneris the home owner (the account whose relay provides the home)
Invitation flow
- Owner/admin calls
inviteHomeMemberwith email and role - If the email matches an existing user, the invitation appears in their
pendingInvitations - The invited user calls
acceptPendingInvitationorrejectPendingInvitation - If the email doesn't match any user, the invitation stays pending. When someone signs up with that email, the invitation is automatically linked.
- Accepted members see the home in
mySharedHomesand 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
| Type | Description |
|---|---|
accessory | Single device |
accessory_group | Group of devices |
room | All devices in a room |
room_group | Multiple rooms |
collection | Custom device grouping |
collection_group | Multiple collections |
home | Entire home |
group | Generic group |
Access types
| Type | Description |
|---|---|
public | Anyone with the link can access |
passcode | Requires a passcode to access |
user | Only the specified Homecast user can access |
Access roles
| Role | Permissions |
|---|---|
view | Read-only — see device state |
control | Read 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:
| Path | Description |
|---|---|
/s/{hash}/on | Turn on |
/s/{hash}/off | Turn off |
/s/{hash}/toggle | Toggle power state |
/s/{hash}/lock | Lock |
/s/{hash}/unlock | Unlock |
/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
}
}