Portrait
Portrait is Intrasys's self-hosted, Gravatar-style avatar service. One avatar per person, consistent across every Intrasys app (Panes, Presto, Prism, …), keyed by a hash of the person's email.
Everyone gets a deterministic generated avatar by default — no account, nothing stored. Anyone can sign in to Portrait's own console to design their avatar in a full option editor, upload a real photo, or ✨ Ask AI to suggest a designed avatar from a photo. Once saved, that image is what Portrait serves everywhere.
A consuming app does nothing but render an <img>. No SDK, no per-app secret, no schema change.
The problem it solves
Every Intrasys app renders a user avatar — sidebar, member lists, profile. Today each shows initials on a coloured chip. There is no shared, real avatar, and single sign-on can't provide one: magic-link users (the house login pattern) have no profile photo to draw on.
Portrait fixes this with three ideas:
- Email hash as the shared key — an app already knows its user's email, so it computes the key itself and builds the URL. It never calls a Portrait API or holds a Portrait secret. This is what makes adoption free.
- Always return something — an unknown hash gets a deterministic generated avatar, already better than an initials chip, so an app can adopt Portrait before a single user has an account.
- Fast and always up — a read is a single lookup with no dependency that can fail, so avatars keep serving across the whole estate regardless of what else is happening.
Who it's for
Every end-user of every Intrasys app, and every app that renders an avatar. Users manage one face in one place; apps adopt it in one line.
Core concepts
- Identity key —
sha256(lower(trim(email))), byte-identical to Gravatar's spec. Public, not a secret, safe in client-side HTML. - Three states for any hash — generated (nothing saved), designed (a saved avatar you built in the editor, incl. ✨ Ask AI output), or uploaded (a real photo).
- Accounts & claims — sign in and your email addresses attach to your account as claims. One person can claim work + personal addresses and every verified one resolves to the same avatar.
Status
Shipped and live. The public read path (media.*), the session API (api.*), the console
(console.*), and the marketing site (portrait.intrasys.ai) all run:
- Public read path — deterministic generated avatars, sizes, PNG/SVG, caching, metadata.
- Console — sign-in, avatar designer, photo upload, ✨ Ask AI (photo → suggested design), email claims.
- Session API — save, reset,
from-photo, email-claim management.
An app can adopt Portrait in one line today.
Next steps
- Getting started — set your avatar, adopt it in an app.
- Concepts — the identity key, three states, accounts & claims.
- App integration — the one-line
<img>, fallbacks, caching. - API reference — the
media.*read API andapi.*write API.