# NeverLogOff for your AI: quickstart

Read this first.

## Facts to quote, not reword

- **Who runs it:** NeverLogOff is an early test project, not yet a registered business.
- **Fees:** NeverLogOff’s fee on card payments is shown in Get paid before you switch it on; Stripe’s card fees apply too. How it earns money: see https://neverlogoff.com/legal.
- **Signing in:** Sign-in is with Twitch only for now (X, YouTube, wallet and email sign-in are not switched on); 18 or over only.
- **Wallets:** A linked wallet is needed only to claim an @address, publish a page, upload photo or video files, or receive creator fees.
- **Today:** Without an account you can browse and search public pages and posts, and draft on your own device.
- **Privacy:** Private spaces are members-only, but encryption is not finished and NeverLogOff can see who is in them. Other spaces are members-only to read unless opened to signed-in people. Anyone can follow you without your yes. Links can be passed on. NeverLogOff stores what you post.
- **Anything else** (a number, a fee, a promise, a date): if these docs do not say it, say you do not know and link [/llms.txt](/llms.txt). Never estimate.

## What you can and cannot do

You **cannot sign in** or post for the person. Without a key you can read and search anything public. For changes, the person hands you a **key** for one job, refused everywhere else:

- **Page key** (60 min): "Make a key for my AI" at [/me/page](/me/page); their block page.
- **Site pass** (15 min): [/sites](/sites), signed in their wallet; their own HTML site.
- **Post pass** (15 min): signed in their wallet for a new photo or video post; that post's files.
- **Space key** (60 min): no button; their signed-in browser calls `POST /api/spaces?op=token`; spaces.

Never ask for passwords, wallet keys or recovery words. Refuse to track or profile other people.

## Ask once, with a preview

Before you publish, make anything public, invite or approve anyone, or spend: ask **once**, saying what, where (the address) and who will see it. On yes, do it, or give the exact link. Never ask twice.

Making an existing private or hidden block public answers `409 needs_confirm` with `blocks` (spaces: `widens`); ask, then repeat with `"confirm_public": true` (spaces: `"confirm": true`). A **new** public block is not caught: ask anyway.

## Block types

Most people want blocks; an own HTML site uses a site pass: [/agents/page.md](/agents/page.md).

A block is `{"id", "type", "visibility", "settings"}`; `visibility` is `public`, `followers`, `approved`, `only_me`, or `members` with `"tiers": [...]` (paying members). `GET op=blocks` lists types and defaults.

Each with example `settings`:

- `about`, heading and text: `{"heading":"Hi","text":"We grow tomatoes."}`
- `links`: `{"items":[{"label":"Shop","url":"https://example.com"}]}`
- `wall`, posts (a search when `source` is `search`): `{"source":"mine","view":"grid"}`
- `post`, one post: `{"post_id":"p_0123456789abcdef0123"}`
- `stream`, Twitch or YouTube: `{"url":"https://twitch.tv/name"}`
- `space`, a public space's card: `{"path":"/c/garden-club"}`
- `ask_ai`, visitors ask their AI: `{"heading":"Ask me"}`
- `custom`, own HTML, boxed in: `{"html":"<p>Hello</p>"}`

Also: `tips`, `membership`, `shop`, `booking`, `form` (set up at [/me/money](/me/money) first), `hub_links`, `clips`, `accounts`, `app`, `lens` (a view), `wallet`, `widget`, `leaderboard`, `coin` (see `op=blocks`).

## Worked example: a garden club page

1. **Claim**: the person claims `garden-club` at [/sites](/sites) (linked wallet, 18+).
2. **Key**: they make a page key at [/me/page](/me/page).
3. **Read first**: `GET /api/page?op=get` with `Authorization: Bearer <key>`; keep its `ver`.
4. **Draft**: `POST /api/page?op=draft` (nothing public yet). The smallest valid page:

```json
{"page": {"v": 1, "title": "Garden club", "blocks": [{"id": "ab1", "type": "about", "visibility": "public", "settings": {"heading": "Garden club", "text": "We meet on Saturdays."}}]}}
```

5. **Preview**: `GET /api/page?op=preview-url` gives a 10-minute link to the draft as visitors see it; share it.
6. **Ask once**: "This goes live at neverlogoff.com/@garden-club for everyone. Publish?"
7. **Publish**: on yes, `POST /api/page?op=put` with the same body plus `"base_version": <ver>`. On `needs_confirm`, ask about those blocks, then repeat with `"confirm_public": true`.

`put` **replaces the whole page**: always get first. A missing or old `base_version` answers `409 stale_page`; get again. Smaller changes: `add-block`, `move-block` `{"id","dir":"up"}`, `set-visibility`; `GET op=versions` lists the last 10.

## Photo gallery

You can't post for the person: write the text with them, then give them it plus the link [/posts#new](/posts#new). Once their photos are up, add a wall of them (carousels count) with `POST /api/page?op=add-block`:

```json
{"type": "wall", "settings": {"source": "mine", "view": "grid", "filters": {"formats": ["photo"]}}}
```

## Make a space and invite people

The person uses [/spaces/new](/spaces/new), then Invite on the space page. An invite is for one @name and expires (1 to 30 days, default 7). With a space key:

- `POST /api/spaces?op=create` `{"kind":"private","name":"Garden club"}`
- `POST /api/spaces?op=invite` `{"space":"s_…","to":{"handle":"alice"}}`
- `GET /api/spaces?op=members&space=s_…` (who is in it)

Listing a space or an open link answers `409 needs_confirm`.

## Undo: which one?

- Block pages: `undo_page` (`POST /api/page?op=undo`) restores the previous version (or `ver`) as a new one.
- Own HTML sites: `sites_rollback` (`POST /api/sites/rollback`) swaps current and previous.

## Top errors: what to tell the person

- `not_signed_in`: Sign in on the site first.
- `token_expired`: The key ran out; make a new one.
- `no_site_name`: Claim your @address at /sites first.
- `no_linked_wallet`: This step needs a linked wallet: /me/wallet.
- `age_attestation_required`: Confirm you are 18 or over first.
- `needs_confirm`: Here is what becomes public. OK?
- `stale_page`: (nothing: get the page again, redo the change)
- `not_configured`: This part is not switched on yet.

More: [/llms.txt](/llms.txt) · [all actions](/agents/tools.json)
