Users & Access Control
Hexed supports multiple users with per-library access control and content restrictions. Each user has their own watch progress, watchlist, and personalized experience.
Invite System
The recommended way to add users is through invites. The flow works like this:
- Admin creates an invite from the macOS app or the web admin panel (
/app/) - An invite link is generated and can be sent to the person
- The recipient opens the link and signs up through h3xed.app
- They automatically get access to your server
Create an invite via the API:
curl -X POST http://localhost:32400/api/invites \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"label": "For Alice"}'
Returns an invite object with a token and shareable link. List active invites:
curl http://localhost:32400/api/invites \ -H "Authorization: Bearer ADMIN_TOKEN"
Revoke an unused invite:
curl -X DELETE http://localhost:32400/api/invites/INVITE_ID \ -H "Authorization: Bearer ADMIN_TOKEN"
GET /api/invite-info/:token.
Cloud Login
When your server is linked to h3xed.app, users can log in through the cloud instead of connecting directly to your server. This is useful for remote access without exposing your server directly.
Cloud login uses the /api/auth/cloud-login endpoint. Users authenticate through h3xed.app, and the cloud service issues a token that your server validates. See the API Reference for details.
Creating Users Manually
You can also create users directly with a password:
curl -X POST http://localhost:32400/api/users \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"username": "alice", "password": "her-password"}'
The user can then log in via the API or a client app:
curl -X POST http://localhost:32400/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username": "alice", "password": "her-password"}'
Returns a JWT token valid for 30 days.
Admin Users
Admin users can see all libraries and manage the server. Create an admin:
curl -X POST http://localhost:32400/api/users \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"username": "bob", "password": "pass", "isAdmin": true}'
Library Access Control
By default, non-admin users have no library access. Grant access per-user through the admin panel (/app/) or via the API. Admin users always see all libraries.
Content Restrictions
Admins can set per-user content restrictions to control what media is visible. Restrictions are based on:
- Ratings — Limit visible content by content rating (e.g., PG-13, R, TV-MA)
- Labels — Hide content tagged with specific labels
Manage restrictions through the admin panel or the API:
# Get a user's restrictions
curl http://localhost:32400/api/users/2/restrictions \
-H "Authorization: Bearer ADMIN_TOKEN"
# Update restrictions
curl -X PUT http://localhost:32400/api/users/2/restrictions \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"maxRating": "PG-13", "blockedLabels": ["adult"]}'
Watch Progress
Each user has independent watch progress. When a user plays a video, the client reports progress to:
POST /api/progress
{ "ratingKey": "file-rating-key", "offset": 120000 }
The server tracks where each user left off. The continue watching list is per-user:
GET /api/continue-watching
Changing Passwords
Users can change their own password:
curl -X POST http://localhost:32400/api/auth/change-password \
-H "Authorization: Bearer USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"currentPassword": "old", "newPassword": "new"}'
Removing Users
Delete a user and all their watch progress:
curl -X DELETE http://localhost:32400/api/users/2 \ -H "Authorization: Bearer ADMIN_TOKEN"