Invites & Onboarding

Mockups for emailed, pre-provisioned invites and the server-driven feature tour that runs after a new person signs in — on web, Android, and Apple. The current flow hands someone an 8-character code and drops them on an empty home screen; this replaces both halves.

Mockup · not implemented Theme: midnight-cinema Web · Android · iOS/tvOS
01 — Admin

Sending an invite

The existing Invite Codes tab stays exactly as it is for the casual "drop a code in Discord" case. A second tab, Invitations, is for inviting a specific person: the admin scopes their access up front, and the invitee only sets a password.

/admin/users → Invitations
Users
Defaults
Invitations
Invite Codes

Invitations

Email a personal link. Access is set here, so they only choose a password.

Recipient Access Status Sent
dana@example.com
Invited by quick
Household · All libraries Accepted 2 days ago
marco@example.com
Invited by quick
Household · All libraries Sent · expires in 6d 18 hours ago
kid@example.com
Invited by quick
Kids · Movies, Cartoons Sent · expires in 2d 5 days ago
old@example.com
Invited by quick
Guests · Movies Expired 3 weeks ago
1 Status is honest about lifetime: Sent → Accepted / Expired / Revoked. An admin can always see who has a live link outstanding.
2 Resend mints a fresh token and invalidates the old one — a forwarded or leaked link stops working the moment the invite is resent.
3 Accepted rows link straight to the created user, so the invite list doubles as an audit trail of how each account got here.
Dialog — Invite someone

Invite someone

They get an email with a link. Their username is their email address, so all they pick is a password.

marco@example.com
This becomes both the destination and their sign-in username.
Household ▾
User ▾
All libraries ▾
Group permissions still apply on top; the stricter of the two wins.
Hey — set yourself up whenever. The 4K stuff is all under Movies.
Appears in the email above the button. Plain text.
Create their first profile automatically
Named from the part before the @. They can rename it later.
Show the feature tour on first sign-in
Walks through favorites, watchlists, requests, watch together, quality, subtitles, and notifications — skipping anything this server has turned off.
Link expires in 7 days · single use
4 Email address is the username. Nothing to invent, nothing to forget, and it matches how every other service they use behaves. Existing username accounts are untouched — login accepts either.
5 If SMTP isn't configured, the dialog swaps the send button for "Copy invite link" and says so plainly, rather than silently failing to send.
02 — Email

What lands in their inbox

Rendered with the existing internal/mail layout, so it matches the notification and verification emails already going out. No images, no tracking pixel, works link-free in a plain-text client.

Invitation email
Subject: Quick invited you to Silo
SILO

You've been invited

Quick set up an account for you on their Silo server.

"Hey — set yourself up whenever. The 4K stuff is all under Movies."

Set your password
Sign in withmarco@example.com
AccessAll libraries
Link expiresIn 7 days

Or paste this into your browser:
https://silo.example.com/invite/9f2c8a4e1b7d63f0

This link works once and expires in 7 days.
If you weren't expecting this, ignore it — no account is created until you use the link.
6 No account exists until the link is used. An unopened invite leaves no row in users, so a mistyped address can't create a dead account or squat a username.
7 The email states the sign-in address explicitly — it's the one thing they'll need again on the phone app, and it's the one thing they'd otherwise guess wrong.
03 — Claim

Setting a password

One field. Everything else was decided when the invite was sent, so this screen has nothing to ask. It reuses the existing auth-shell and journey-progress treatment from Login and Signup.

/invite/9f2c8a4e1b7d63f0
Invite
2
Password
3
Household
Invited by Quick

Welcome to Silo

Choose a password and you're in. You'll sign in with your email address.

marco@example.com
••••••••••••
Strong · at least 8 characters
••••••••••••

Already set this up? Sign in

8 An expired or used link doesn't dead-end. It renders a plain "This invite has expired — ask Quick to send a new one" card with a sign-in link, not a 404.
9 Submitting creates the account, redeems the token, and logs them straight in. They land on the tour, not back at a login form.
04 — Household

Setting up the household

Right after the password, before the tour: profiles for everyone on the couch. This is step 3 of the journey indicator on the claim screen. Kids get a content ceiling and library limits; grandparents get big defaults and no clutter; the parent gets a PIN so nobody wanders into their profile. All of it maps onto the profile model that already exists — is_child, max_content_rating, PIN, and per-profile library restrictions.

Onboarding · who's watching?
Invite
Password
3
Household

Who's watching?

Everyone gets their own history, watchlist, and recommendations. Add the whole household now or later — this is your account either way.

MYou · PIN
Marco
All libraries
S
Sofia
All libraries
EKids · PG
Emma
Movies, Cartoons
+
Add profile
 
Dialog — Add a profile (kid preset shown)

Add a profile

Profiles share your account — they're not separate logins.

Emma
+
Kids profile
Simplified home screen, no requests, and the ceilings below.
PG ▾
Movies, Cartoons ▾
Require a PIN to open
Usually for the parents' profiles, not the kids' — it keeps the kids out of yours.
Everything here is editable later in Settings → Profiles.
10 Profiles are not logins. They all share the invited account — one password, one email, many viewers. That's the existing Silo model (several profiles per user_id); this screen just surfaces it at the right moment instead of leaving it buried in settings.
11 The kids toggle is a preset, not a lecture. Flipping it on reveals the rating ceiling and library picker with sensible defaults (PG, kid-flagged libraries preselected when the admin marked any). Grandparents don't need a ceiling — for them you just make a plain profile and skip all of this.
12 PIN guidance matters more than the PIN field. The common mistake is pinning the kid's profile; the useful move is pinning the adults'. One line of copy fixes a support thread.
13 "Just me for now" is a real path. It creates nothing extra, and the tour's household stop reminds them it exists. No modal nagging on every launch.
14 Each new profile starts its own taste-seed state, so Emma's picker shows kid-appropriate titles filtered by her rating ceiling — the existing taste-seed endpoint already scopes to the active profile.
05 — Tour

The first-run tour, on web

This is the part that actually sells Silo. The steps come from the server, so a server with requests disabled never shows a requests stop — and a stop added later shows up without a client release. Two presentations: a full card for concept stops, a spotlight for "here's where it lives."

Tour · step 1 of 8 — welcome
Welcome · 2 minutes

Silo isn't quite like the others

You've probably used Plex or Jellyfin. Most of this will feel familiar — but a handful of things work differently here, and they're the reason this server exists. Quick look?

Watch together
Synced rooms, no extensions
Requests
Ask for what's missing
Real recommendations
From your taste, not popularity
Tour · step 3 of 8 — playback quality (writes a real setting)
Playback · step 3 of 8

Pick a quality ceiling now, change it anywhere

Silo won't burn your data plan guessing. Set a ceiling and it sticks — per device, if you want. You can override it for a single library or a single show later.

Video quality
On this device
Auto
1080p
4K
Auto-skip intros and recaps
Jump straight into the episode

Saved as you go. Settings → Playback has the rest.

Tour · step 6 of 8 — spotlight on the sidebar

Watchlist and Favorites live here

Favorites teach recommendations what you like. The watchlist is the "get to it eventually" pile — and Silo tells you when something on it lands.

Tour · step 8 of 8 — finish
All set

That's the tour

Everything here is in Settings, and you can replay this any time from Settings → Personalize.

Quality ceiling1080p
SubtitlesEnglish · on for foreign audio
NotificationsEmail · watchlist arrivals
Favorites picked7 titles
Next: pick a few favorites so recommendations aren't cold.
15 Steps that change a setting write it immediately through the existing settings API. The tour isn't a slideshow with a "now go configure it yourself" ending — by step 8 their account is genuinely set up.
16 Skip is always one click away and always honored. Completion is stored per profile on the server, so skipping on the phone doesn't re-prompt on the TV.
17 This flows into the existing taste-seed picker rather than replacing it — the tour ends by handing off to the screen that's already there.
06 — Mobile

Android and Apple

Same server manifest, native presentation. The phone apps get a full-screen pager because spotlights don't survive a 390pt viewport; tvOS gets a focus-driven variant with no text entry.

9:41▮▮▮
SILO
Server
2
Pass
3
Family

Welcome to Silo

Invited by Quick · silo.example.com

marco@example.com
••••••••••••
Tapping the email linkUniversal link / App Link opens the app with server + token already filled. No "which server?" prompt.
9:41▮▮▮

Who's watching?

Everyone gets their own history and recommendations.

MYou · PIN
Marco
S
Sofia
EKids · PG
Emma
+
Add
Household setupSame step 3 as web. Tapping a tile edits it; the kid preset carries rating ceiling + libraries.
9:41▮▮▮
Watch together

Same movie,
different couches

Start a room, send the link. Play, pause, and seek stay in sync for everyone — no browser extension, no screen share, and it works from the phone or the TV.

Full-screen pagerSwipeable. One idea per page, illustration slot at the top, skip always reachable.
9:41▮▮▮
Subtitles

Set them once, everywhere

Language and appearance follow your profile across every device.

English ▾
Only for foreign audio
Skip subtitles when it's already in English
Interactive stopNative controls in a sheet, writing the same profile setting the web tour writes.
tvOS / Android TV — focus-driven, no keyboard
Step 2 of 5

Your watchlist follows you here

Anything you add on your phone shows up on this screen, and Silo tells you when something on it arrives.

18 TV gets a shortened manifest — the server marks steps that need text entry or a settings write as unsuitable for a 10-foot UI, and the TV client requests the reduced set.
07 — Mechanics

How the pieces connect

Invite lifecycle
Admin · web
Sends the invite

POST /api/v1/admin/invitations — email, group, role, libraries, note. Server stores only a SHA-256 of the token; the raw token exists in the email and nowhere else.

Server
Sends mail through the shared sender

internal/mail — same SMTP config, layout, and diagnostics as notifications. If email is off, the endpoint returns the link for the admin to copy instead of failing.

Invitee
Opens the link

GET /api/v1/invitations/{token} — unauthenticated, returns only what the claim screen renders: inviter name, email, expiry. Rate-limited alongside the other auth endpoints.

Invitee
Sets a password

POST /api/v1/invitations/{token}/accept — creates the user with the pre-bound access, marks the invite accepted in the same transaction, and returns a normal session token pair. Same shape as signup, so clients reuse their session plumbing.

Invitee
Sets up the household

POST /api/v1/profiles per added profile — the existing endpoint, which already carries name, avatar, PIN, is_child, rating ceiling, and per-profile library restrictions. No new backend surface for this step.

Client
Asks what to show

GET /api/v1/onboarding/flow?surface=web — ordered steps for this server and this profile, with features that are off already filtered out.

Client
Records progress

POST /api/v1/onboarding/progress — per profile, so finishing on the web means the phone doesn't ask again.

Step manifest — clients render what they know, ignore the rest

Every step carries a kind the client switches on. A client that doesn't recognize a kind skips it silently — that's what lets the server add a stop without waiting for three app store releases.

Step kindWhat it doesGated on
welcomeFraming card. Static copy from the server.Always
feature_cardExplains one capability. Title, body, optional illustration key.Per feature
setting_choiceRenders a control and writes a real profile setting.Setting key exists
spotlightHighlights a named UI anchor. Web and tablet only.Surface supports it
handoffEnds the tour by routing somewhere — e.g. the taste-seed picker.Always
Shown — feature enabled on this server
Skipped — feature off, or surface can't render it
19 The tour is not invite-only. Everyone who hasn't seen it gets it, including accounts that predate this work and anyone who signed up with a code. The invite just makes the entrance nicer.
20 Copy lives on the server, which means fixing an awkward sentence is a server deploy — not three PRs and a review queue at Apple.