---
title: Account Context and Settings
description: Inspect authority and limits, verify account-email changes and read linked Nano addresses.
navigationTitle: Account Context and Settings
---

# Account context and settings

`GET /api/v1/me` accepts either an owner session or Publishing key and returns `{credential,profile,readiness,actions,limits}`. Owner sessions additionally receive `{account:{id,email,pendingEmail}}` and the keys/finance/settings action URLs. Publishing-key responses omit private email and finance and never expose the full receiving address.

`credential.type` is `owner_session` or `publishing_key`; expiry is ISO time or null, and Publishing credentials include `scope: "posts:publish"`. Readiness has `canPublish` and `{code,field?,action}` blockers. `profile-incomplete` identifies name/handle setup; `payout-address-required` links to the owner address action. Limits include five active keys, 2 MiB images, 250-character bio, 80-character location, two social links, price min/max/precision and the supported language values. Fix blockers through the appropriate credential family.

## Change and confirm email

Email is optional. A wallet owner can use all ordinary account and publication flows without it. Adding or confirming email preserves the original UUID and the current wallet session; Nano login remains available after verification.

Email notifications require a confirmed current email and an enabled email preference. Confirmation unlocks email settings; it does not enable delivery or send earlier events automatically. Enable delivery afterward through [notification preferences](https://docs.subnano.ai/v1/api/engagement#notification-and-privacy-settings). In-app notifications remain available without email.

These owner-only calls check that the exact session is still active. Publishing keys cannot call them. Responses and confirmation material are private and must never enter logs or caches.

| Method and path                     | Body                                        | Persisted result                                                             |
| ----------------------------------- | ------------------------------------------- | ---------------------------------------------------------------------------- |
| `GET /api/v1/account/email`         | None                                        | `email`, `pendingEmail`, `status` (not_configured, pending or verified)      |
| `POST /api/v1/account/email`        | `{email}`                                   | `status` (confirmation_sent or already_pending), `pendingEmail`              |
| `POST /api/v1/account/email/resend` | None                                        | `status:resent`, `pendingEmail`                                              |
| `POST /api/v1/account/email/verify` | `{email,code}` or `{email,confirmationUrl}` | Current email/status; email sessions may also receive a renewable token pair |

The request normalizes email to lowercase and trims whitespace; it supports at most 320 characters and a 64-character local part. Repeating the current/pending email returns `already_pending`. Read GET after response loss. Resend without a pending change returns `400 data.code: "no_pending_email"`. Invalid/in-use email errors use `400` and `data.code: "invalid_email"` or `"email_in_use"`.

Verification requires exactly one six-to-eight-digit code or the complete email-change confirmation URL from the authorized mailbox. It must match the configured Supabase origin, `/auth/v1/verify`, `type=email_change`, and this owner's pending change. The server checks the token without exposing it or following redirects. Wrong/expired/foreign confirmation returns `422`; other URLs are rejected. Provider double-confirmation may leave status `pending` after the first mailbox confirms; complete each required mailbox confirmation and read status until `verified`. A lost final success replays as verified for the same final email. For an email session, atomically save any returned `accessToken`, `refreshToken` and Unix-seconds `expiresAt`. Wallet confirmation returns status without replacing the wallet token pair; keep the existing wallet session and its normal refresh lifecycle.

Email request/resend follow the existing provider/abuse policy; production limits include five change attempts/hour and three resends/15 minutes. Verification allows ten attempts/minute. SMTP, templates, CAPTCHA and session policy must be checked before launch. [Authentication](https://docs.subnano.ai/v1/api/authentication) covers renewing a session independently of email changes.

## Account lifecycle

These endpoints accept an active owner Bearer session. Publishing keys cannot call them. Browser cookie requests require the same-origin `Origin` header.

`POST /api/account/delete` takes `{handle}` with the exact current handle. The session must have been created in the last five minutes. `401 data.code: "fresh-session-required"` requires a new login, `422` requires the matching handle, and `409 data.code: "unsettled-payouts"` requires resolving unpaid or unreconciled payouts first.

**Deletion removes all owned uploads, including purchased ZIPs and Post images. Previous buyers and callers using settled proofs lose file access immediately after deletion commits.** See the [attachment retention guide](https://docs.subnano.ai/v1/api/attachments#edit-publish-and-retain).

Success returns `{deleted:true,mediaCleanupPending:boolean}`. The account loses its personal data and credentials, its Posts are unpublished, and all native and wallet sessions are revoked. Private purchases, payouts, transactions and original bookkeeping evidence stay for at least five years. Public receipt displays hide the deleted identity. A confirmed email receives a queued confirmation. `mediaCleanupPending:true` means not all owned uploads are verified gone. Cleanup is retried and can wait for safety holds or active writers.

`POST /api/account/logout-everywhere` returns `{loggedOut:true,scope:"global"}` after revoking every native refresh token and wallet session. Clear the local credentials after success. Failure returns `401` for an inactive session or `503` when revocation cannot complete. An issued native access JWT can remain cryptographically valid until expiry; active-session checks reject it after revocation.

## Linked addresses and privacy

`GET /api/v1/nano-addresses` with owner Bearer returns only owned rows: `{id,address,user_id,created_at,updated_at}`. These are read-only linked addresses, distinct from the saved payout address. The ordinary API cannot reassign wallet ownership.

[Engagement settings](https://docs.subnano.ai/v1/api/engagement#notification-and-privacy-settings) expose existing email/in-app/push preference booleans and creator/supporter leaderboard visibility. OS or browser push permission and administrator/operator controls remain outside ordinary account authority.

## Optional legacy email bootstrap

New integrations should use the owner-session email endpoints above after [Nano login](https://docs.subnano.ai/v1/api/authentication#nano-login-without-email). The existing `/api/v1/account/email/bootstrap` family remains a compatibility path for attaching email to a freshly proven wallet without a Bearer header. It is optional; login and publishing are already available before email setup.

All four calls are POSTs with private `loginSecret` in JSON, without cookies. The continuation lasts 15 minutes after the original claim and retries do not extend it. Start takes `{loginSecret,email}`; `/status` and `/resend` take `{loginSecret}`; `/verify` takes `{loginSecret,email,code}` or `{loginSecret,email,confirmationUrl}`. The proof must belong to that same account's pending mailbox. Status returns `{status,userId,email,pendingEmail,bootstrapExpiresAt}` with `awaiting_email`, `pending`, `confirmation_sent`, `verified` or `configuration_blocked`. A verified wallet continuation has `nextAction:authenticated` and returns no replacement pair: keep the wallet pair. Read status after any uncertainty; fresh Nano login recovers the same account after a lost or expired continuation.

`EMAIL_CONFLICT` (`409`) cannot reassign another wallet or mailbox. `INVALID_CONFIRMATION` (`422`) needs the correct owner's proof. `BOOTSTRAP_UNAVAILABLE` (`503`/`429`) needs bounded retry/status read with the same secret. `NANO_BOOTSTRAP_EXPIRED` (`410`/`401`) needs a new wallet proof. `configuration_blocked` and `EMAIL_CONFIGURATION_BLOCKED` are not email completion; provider configuration must be repaired. Pending/configuration-blocked optional email does not remove an otherwise valid wallet session's owner authority.

These calls share 120 requests/minute per ingress IP; each hashed secret/action allows 30/minute, except verification at 10/minute. HTTP `429` can include `data.retryAfter` seconds. Keep secrets and mailbox proof out of URLs and logs.
