Users & access
h3xed has two layers of people. Accounts are the separate humans you share a server with — each gets their own login and the libraries you choose. Profiles are sub-users under a single account, like Netflix, with their own watch state and optional kids restrictions. On top of that, friends, watch party, and co-op let you connect with other people's servers.
Inviting people to your server
The recommended way to give someone their own access is an invite. From the admin panel (/app/) or the desktop app:
- Create an invite and choose which libraries it grants
- Send the person the invite link
- They open it and sign up (or sign in) with an h3xed.app account
- Your server shows up in their app automatically, with the libraries you shared
Invites can be created, listed, and revoked from the API as well:
# Create an invite
curl -X POST http://YOUR_SERVER:32400/api/invites \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"label": "For Alice"}'
# List active invites
curl http://YOUR_SERVER:32400/api/invites \
-H "Authorization: Bearer ADMIN_TOKEN"
# Revoke an unused invite
curl -X DELETE http://YOUR_SERVER:32400/api/invites/INVITE_ID \
-H "Authorization: Bearer ADMIN_TOKEN"
GET /api/invite-info/:token.
Cloud sign-in
When your server is linked to h3xed.app, people sign in with their h3xed.app account and reach your server through the secure relay — no need to expose it directly or hand out a local password. On a LAN-only server, you create local accounts with passwords instead.
Library access
Each account sees only the libraries you've shared with it — choose them when you create the invite, or adjust them later per account from the admin panel. Admin accounts always see everything and can manage the server.
Profiles
Within a single account, set up profiles so everyone sharing that login gets their own space — separate Continue Watching, watchlist, and watch history. Add a profile from the picker, give it a name and avatar, and optionally set a PIN so switching into it requires the code.
# List profiles on the account
curl http://YOUR_SERVER:32400/api/profiles \
-H "Authorization: Bearer USER_TOKEN"
# Create a profile (optionally managed, with a PIN)
curl -X POST http://YOUR_SERVER:32400/api/profiles \
-H "Authorization: Bearer USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Kids", "isManaged": true, "pin": "1234"}'
# Switch the active profile
curl -X POST http://YOUR_SERVER:32400/api/profiles/PROFILE_ID/switch \
-H "Authorization: Bearer USER_TOKEN"
Managed (kids) profiles
Mark a profile as managed to turn it into a kids profile with content restrictions. A managed profile can be limited by:
- Library access — which libraries the profile can see at all
- Rating ceilings — a maximum rating on the ladder (e.g.
PG-13orTV-14); everything at or below is allowed, everything above is hidden - Label rules — allow-only or deny lists on your tags and labels
Restrictions are enforced on every read, and they fail closed — unrated items stay hidden under a rating rule unless you explicitly allow them. Manage them from the admin panel, or via the API:
# Get a profile's restrictions
curl http://YOUR_SERVER:32400/api/users/PROFILE_ID/restrictions \
-H "Authorization: Bearer ADMIN_TOKEN"
# Set a PG-13 ceiling, deny an "adult" label, allow unrated off
curl -X PUT http://YOUR_SERVER:32400/api/users/PROFILE_ID/restrictions \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"ratingCeilings": ["PG-13"],
"excludedLabels": ["adult"],
"allowUnrated": false
}'
Restrictions also support explicit allowedRatings / excludedRatings and an allowedLabels allow-list if you want finer control than a single ceiling. A managed profile holding its own PIN can't escape into the unrestricted parent profile.
Friends
Friends connect accounts across servers. Send a friend request, accept incoming ones, and see which friends are around with presence. You can block an account to cut off requests and visibility. Friends are who you invite into a watch party, and who you can link servers with for co-op.
Watch party
A watch party plays the same title in sync for everyone in the room. Host one from the web app or Apple TV, then either invite friends directly or share the room's 6-character code so anyone can join from their own device. Playback — play, pause, and seek — stays in step across the room.
Co-op servers
Co-op links your server with a friend's so their libraries appear merged into your app, right alongside your own. Each owner still governs their own content — you set what you share, they set what they share, and managed-profile restrictions still apply to merged content. Duplicate titles across the two servers are de-duplicated so the merged view stays clean.
Watch progress
Watch progress is per profile. The client reports playback position as you watch, and the server keeps a per-profile Continue Watching list:
POST /api/progress
{ "ratingKey": "file-rating-key", "offset": 120000 }
GET /api/continue-watching
Removing access
Remove an account, delete a profile, or revoke an invite from the admin panel. Deleting a profile or account also removes its watch state.
# Delete an account or profile by id curl -X DELETE http://YOUR_SERVER:32400/api/users/USER_ID \ -H "Authorization: Bearer ADMIN_TOKEN"