If you run an Emby server for family and friends, you know the routine: someone asks for access, you open the dashboard, invent a username, set a password, pick libraries, check the parental settings, and then you do it again next week. It does not scale, and every hand-made account is a chance to forget a policy or grant too much.
Registration is an Emby plugin that puts a public sign-up page on your own Emby address. People create their own account with an access code you give them, and you keep control through approval, family codes, anti-bot protection and a template user that defines what a new account can see. This tutorial walks through a practical setup: codes, approval, templates and the anti-bot basics.
A quick note before we start: this is for legal, self-hosted media you own or are licensed to use. Invite people you trust, and keep the server's rules clear.
Prerequisites
- Emby Server 4.10.1 or newer.
- Your Emby server must be reachable by the people who will register, either directly or through a reverse proxy.
- A MediaLab Works account with a license for this server (monthly, yearly, lifetime, or part of the Emby bundle). There is a free 30-day trial if you want to test first. One license per Emby server.
- Access to the Emby dashboard. The plugin's admin page is opened from a browser, because the Emby app blocks plugin pages.
Step 1 — Install the plugin and activate the license
- Sign in to your MediaLab Works account, open Licenses and download the plugin DLL. The download is available on an active subscription, a lifetime license within its update window, or during the trial.
- Copy the DLL into the Emby plugins folder and restart Emby Server:
- Linux (package):
/var/lib/emby/plugins/ - Docker: the
pluginsfolder inside your Emby config volume - Windows:
%AppData%\Emby-Server\programdata\plugins\
- Linux (package):
- Open Emby Dashboard → Plugins, click the plugin, paste your license key and save. The plugin contacts the license server, binds the key to this Emby server and shows the license as Active.
The license is checked once a day and at every Emby start. Without internet the plugin keeps working for 7 days after the last successful check. Without a valid license the plugin is stopped: automatic tasks do not run and the public sign-up page shows "unavailable", but existing accounts, codes and settings are untouched.
Step 2 — Configure the basics
Open Dashboard → Plugins → Registration. The configuration page has a short list of settings:
| Setting | What it does |
|---|---|
| Template user | New accounts copy libraries and policies from this user. |
| Approval required | Accounts are disabled until you approve them in the plugin page. |
| Access codes | Create codes: uses left, expiry, family code (optional). |
| Anti-bot | On by default; also limits attempts per IP. |
| Public URL | The address where the form is served, e.g. https://emby.example.com/registration. |
Set the Public URL first. This is the address people will open, so it has to match what your reverse proxy actually serves. If you are behind a proxy, make sure the registration path is allowed there — a form that is not reachable is almost always a proxy rule, not the plugin.
Step 3 — Create a template user
This is the step that saves you the most work later. A template user is a normal Emby account whose libraries, parental settings and policies are copied to every new account created through the sign-up page.
Create an account in Emby that represents "a new user on this server": the libraries they should see, the parental settings you want as the default, and nothing more than that. Then select it as the Template user in the plugin settings.
Because the copy happens at account creation, changing the template later does not rewrite existing accounts — it only affects new ones. Keep that in mind if your library layout changes.
Step 4 — Decide between approval mode and instant accounts
Approval required keeps every new account disabled until you approve it in the plugin page. The person can fill in the form, but nobody gets in until you say yes. For a server that is open to a wider circle, this is the safer default: you see the request, you decide.
With approval off, the account is created and usable immediately. That is convenient for a small group of people you already know, but it puts the access code in charge of who gets in.
Either way, the account is created disabled at request time and the password is handled by Emby; the plugin does not store passwords.
Step 5 — Hand out access codes
Access codes are the gate. In the plugin settings you create codes with:
- Uses left — a single-use code for one person, or a multi-use code for a group.
- Expiry — the code stops working after that point.
- Family code (optional) — groups related accounts so you can see and manage them together.
A practical pattern: one single-use code per person for individual invites, and a family code for a household so the accounts stay linked in your overview. If a code is rejected, check the uses left and the expiry on the plugin page first — those are the two usual causes.
Once the code exists, send the sign-up link together with the code. The person picks a username and password on the public form, branded with your server name.
Step 6 — Keep the bots out
The anti-bot challenge is on by default, and the plugin also limits attempts per IP. Leave it on. If you want the stronger challenge, you can enter your own Cloudflare Turnstile keys; that option is off by default and only active when you provide keys. When it is on, the visitor's browser loads the Turnstile widget and your server verifies the answer by sending the secret key, the token and the visitor's IP address to challenges.cloudflare.com.
One privacy detail worth knowing: on form submit, the plugin checks the password against Have I Been Pwned – Pwned Passwords by sending only the first 5 characters of the password's SHA-1 hash (k-anonymity, with padding). The password and the full hash never leave your server. You can turn this off, and if the service is down, registration continues.
Step 7 — Get the link in front of people
The public sign-up page works in any browser, on desktop and phone. On the login screen, the "Create account" button is Emby Web only: the plugin adds a script to dashboard-ui/index.html, and it is re-applied after Emby updates. Native Emby apps (Android, iOS, Android TV, Samsung, LG, Roku, Apple TV) cannot show that button, so send those people the link directly.
For TVs, the page detects TV browsers and shows a QR code for the phone. QR codes are generated on the server.
Daily use
- Create an access code and send the sign-up link plus the code.
- The person picks a username and password; with approval on, you confirm the account in the plugin page.
- Family codes let you see and manage related accounts together.
Tips and troubleshooting
- The form is not reachable. Make sure the path is allowed by your reverse proxy and that the Public URL matches it.
- A code is rejected. Check uses left and expiry on the plugin page.
- The login-screen button disappeared. It is re-applied after Emby updates; if it cannot be restored, the log is sent only if automatic log sending is on.
- Email. Nothing is sent until you configure SMTP. After that, applicants get a confirmation and the decision (approved or rejected) plus the access message you compose, which may contain a generated password. Admin notifications are off by default. STARTTLS is the default.
- Telegram notifications are optional and off by default. If enabled, admin messages include the request data (name, username, email, phone, IP, Cloudflare country).
- Data on disk. Requests are stored in
data/registrations.json(mode 600). Rejected, expired or deleted requests are purged after 30 days; pending requests expire after 7 days and the disabled account is deleted. When a user is deleted, their personal data in the plugin is wiped immediately. Data is not deleted on uninstall unless you tick that option. - Secrets. The SMTP password, Telegram token, Turnstile secret and form HMAC key are encrypted at rest in
secrets.enc.json(AES-256-GCM) and never sent to the browser.
Conclusion
A public sign-up page with access codes turns a recurring admin chore into a one-time setup: a template user defines the defaults, approval mode keeps you in the loop, and codes plus the anti-bot challenge decide who gets to ask. If you want to go further, the plugin also works with the Cashier plugin for paid plans and with Quick Connect for phone sign-in.
The full reference is in the user guide, and you can find the plugin on the Registration product page. More self-hosting material lives in our knowledge base and FAQ; if something does not fit your setup, contact us.