Partial update of the caller’s profile.
Only the fields actually present in the request body are applied
(model_fields_set distinguishes omission from null). API-key
auth is rejected by require_active_ui_session; soft-deleted
accounts are rejected with 423 from the same dependency.
Documentation Index
Fetch the complete documentation index at: https://docs.roughy.ai/llms.txt
Use this file to discover all available pages before exploring further.
Either your Supabase session JWT (UI flows) or an API key minted via POST /api-keys (programmatic flows). Pass it as Authorization: Bearer <token>. The server inspects the token format and routes to JWT or API-key verification automatically.
Partial profile update; absent fields stay as-is.
first_name / last_name accept null to clear the value (use
model_fields_set server-side to distinguish "omitted" from
"explicit null"). two_factor_enabled is a bool toggle. Length
caps mirror the Postgres Text column reality plus a sensible UI
cap; email is intentionally not editable here.
Successful Response
Public projection of the caller's own users row.
No auth_user_id (Supabase identity, not part of our public API),
no stripe_customer_id (billing-internal), no is_admin (role
flag, not a profile field). email and deleted_at stay so the
UI can render the account state honestly.