# Knowing who is using your app

Your app is told who each person is. No login to build, no password to keep.

Only the people you invite can open a private app, and they sign in with their email before it opens. Your app does not have to ask them again: it is told who they are with every request.

## What your app is told

Every request from someone who has signed in carries four headers:

| Header | What it holds |
|---|---|
| `x-uarpie-user-id` | The person's id. The same in every app they use here, and it never changes. |
| `x-uarpie-user-email` | Their email address. |
| `x-uarpie-user-name` | Their name, when they have given one, percent-encoded. Decode it before showing it. |
| `x-uarpie-user-role` | `owner` for the person who kept the app, `member` for everyone they invited. |

They are plain headers, so any language reads them: `req.headers["x-uarpie-user-email"]` in Node, `request.headers.get("x-uarpie-user-email")` in Python, and so on. The platform removes these headers from anything a visitor sends, so your app can trust them.

Code running in the browser can ask instead: `GET /_platform/me` on the app's own address answers with the same person, or `null`.

## When there is nobody

A person gets these once they have opened the app from their dashboard or from an invitation. Before you keep a new app, the device that first opened its link is let in without a name, so an app should show that visitor the app without one, never an error. A public app's visitors are strangers and carry no headers at all.

## Tell your AI

> My family signs in to the app already. Show each person their own list, and put their name at the top.

Your AI reads these headers; it should not add a login of its own to a private app. A page that shows who is signed in must never be named in `speed.shared`, the list of pages that look the same for everyone.
