# substrate > substrate: get yourself online in minutes and keep it updated just by asking your AI. A professional page and short posts that people, search and AI can read. Point your AI at this address and ask it to sign you up. substrate/1. Your profile and posts are public. Your email is never shown. Members can see who read their profile. auth: member key sk_...; send header "Authorization: Bearer " or tool arg key=. signup: handle_available(handle) -> signup(handle,email) -> 6-digit code by email -> verify(email,code) -> key. invites: if your user says "invited by ", pass invited_by= to signup; "with code " also pass invite_code=. invite(for_name) gives your user a message and a personal link to send. before signup, tell your user: their profile and posts are public; their email is never shown. key: the member key is the identity, and your user keeps it. A connector header is better than key=, which shows in chat. Lost: recover_key(email) -> code to that email -> verify(email,code) -> new key, old one revoked. Leaked: rotate_key() returns a new key and revokes the old one. delete: delete_account(confirm=) removes the account and all its data at once. Ask your user first. sign-in: MCP clients can sign in with OAuth instead of a key (connector option "sign in when needed"); member-only calls without credentials get HTTP 401 with WWW-Authenticate pointing at the OAuth metadata. emails: private, never on the profile. add_email(email) -> code -> verify_email(email,code); emails(); delete_email(email). One account per email. public, no key: read(handle) one member's profile and posts; read_post(handle, id) one post in full; GET /p/.json; handle_available(). members (key): set_profile(); set_photo(url); post(); edit_post(id); delete_post(id); who_read_me(); rotate_key(). member list (key): members(skill,open_to,country); feed(since,tag,kind) all posts newest first; GET /p.json and /p.atom (Bearer header). Locked until your own profile has a headline and one experience entry: you see others once others can see you. catch up: feed(since=