Concepts
Sharing and invites
Every app has two independent access controls: `isPublic` (discoverable) and `requiresAuth` (gated). Share by email — invitees who aren't on Ellivate yet get a signup link that lands them in your app on first load.
Two independent axes
Every app has two toggles that control access. They're independent — all four combinations are valid, and confusing them was the source of a real data-leak bug on our end, so Ellivate keeps them strictly separated:
| isPublic | requiresAuth | Meaning |
|---|---|---|
| false | true | Private + gated — default. Invite-only. Unlisted, sign-in required. |
| true | true | Public + gated — Notion-workspace pattern. Listed on your profile, but users must sign in to open. |
| true | false | Public + open — demo / showcase. Anyone can open, no sign-in. |
| false | false | Private + open — rare. Unlisted but anyone with the URL can open. |
The right default for most apps is private + gated. Flip toggles from the dashboard's app detail page.
Sharing with specific people
From the app detail page, click Share. Paste a list of email addresses (commas, semicolons, spaces, newlines — any separator works). For each email:
- Already an Ellivate user — the app lands in their dashboard on their next load. They can open it immediately.
- Not yet on Ellivate — Ellivate emails them an invite from
invites@ellivate.aiwith a link to sign up and an App Store link for the iOS app. They sign up with the invited email and the app shows up in their dashboard on first load. No manual claim step.
What the invitee sees
The invite URL looks like ellivate.ai/invite/<token>. Clicking it shows one of three states:
- Anonymous visitor → "[Inviter] invited you to [App]. Sign up with [email] to open it." CTA: Create an Ellivate account.
- Signed in as the invited email → "[App] is waiting for you." CTA: Open my dashboard.
- Signed in as a different email → " [App] is waiting for you. @[Inviter] sent it to [invited-email]." CTA: Add [invited-email] to your account. Verifies the inbox via a 6-digit code; on success the invite snaps into the dashboard.
The token IS the authorization — anyone holding the URL is meant to see who invited them to what. Gating the invite page behind sign-in would defeat the whole growth loop.
Sign in with Apple and “Hide My Email”
If you sign up with Apple and pick “Hide My Email”, your primary address is an opaque @privaterelay.appleid.com alias that nobody can type into a share dialog. The dashboard prompts you to add a real contact email — the address your friends know you by. Verification happens through a 6-digit code, same as adding any secondary email. Once verified, share lookups match against either your primary or your contact email, so friends inviting you to tools find you regardless of which one they typed.
The same flow runs from the invite landing page: if your friend already sent you something to that real email, accepting it on the invite page is what adds it to your account in the first place — no extra setup.
Share modes — what invitees see when they open the app
Sharing also involves a data mode, set at the app level. Two options:
Join owner's data
Invitees join the owner's existing share group. Everyone sees the same shared:-scoped data.
- Use for: household grocery lists, team retrospectives, shared playlists, any case where the invitees are collaborating on the same dataset.
- Don't use for: task trackers where each user should have their own tasks; habit trackers where everyone tracks independently.
Own copy
Each invitee gets their own share group — just them and the owner. The owner sees each invitee's data separately. Invitees don't see each other's data.
- Use for: solo tools the owner wants to distribute — a trip planner where each friend fills in their own trip, a reading tracker where each person logs their own books.
- Don't use for: apps where users should see each other's contributions.
Canonical URL
Every app has one canonical URL: <your-username>.ellivate.ai/<app-slug>. That's what builders share; that's what visitors bookmark. Dashboard-runner URLs like app.ellivate.ai/app/<id> are internal plumbing — they work when someone clicks "Open" from their dashboard, but they're not the canonical share URL.
Revoking access
From the app's share dialog, remove an invitee. They lose access on their next load. Their contributed data (if any, under personal: or their own share group) is retained but inaccessible through the app — they can be re-added later and the data reconnects.
Public apps and anonymous visitors
On public + open apps, anonymous visitors can read public:-scoped keys. They cannot read shared: or personal:, and the SDK returns null on those reads so your UI can show an empty state cleanly.
An anonymous visitor who later signs in stays "empty" until the owner shares the app with their email. Public apps aren't a blanket read pass — they just remove the sign-in requirement.
What's next
- Guide: share an app — walkthrough of the share dialog.
- Persistence & scopes — what each data scope means.