# The page model

Every field on a page, its type and limits, and which endpoint sets it.

A page is one JSON document. `POST /api/agent/pages` takes the fields under `page`; `PATCH /api/profiles/{id}` takes any subset of the same fields; `GET /api/profiles/{id}` returns them all plus the read-only ones.

| Field | Type | Notes |
| --- | --- | --- |
| `username` | string, 3–30, `[a-z0-9-]` | The subdomain. Set at creation; not changed over the API. |
| `displayName` | string ≤ 60 | Shown as the heading. Empty falls back to `@username`. |
| `bio` | string ≤ 300 | One or two sentences. Also the page's meta description. |
| `avatar` | storage key or `null` | From `POST /api/upload`. Never a URL — see [Images](https://tapmy.link/documentation/agents/images.md). |
| `avatarFocus` | `{ x, y }` percent or `null` | Where the round crop is anchored; centre when absent. |
| `templateId` | one of ten ids | See [Templates](https://tapmy.link/documentation/agents/templates.md). Default `editorial`. |
| `layout` | `list` or `grid` | `grid` shows link cards two abreast, best with images. Default `list`. |
| `headerAlign` | `left`, `center`, `right` or `null` | `null` uses the template's own alignment. |
| `theme.accent` | `#rrggbb` | Accent colour for buttons and marks. Optional. |
| `theme.backgroundImage` | storage key or `null` | Kind `background` from the upload route. |
| `theme.backgroundFocus` | `{ x, y }` percent or `null` | Where the full-bleed crop is anchored. |
| `theme.overlay` | number 0–1 | Darkening over the background image so text stays legible. |
| `pageLocale` | locale code | Language of the page's own UI strings. See [Languages](https://tapmy.link/documentation/agents/languages.md). |
| `isPublished` | boolean | Off means the address answers 404 to everyone but the owner. |
| `utm` | boolean | Append `utm_source=tapmy` etc. to outgoing links. Default off: it rewrites someone else's URL. |
| `blocks` | array ≤ 80 | The content. See [Blocks](https://tapmy.link/documentation/agents/blocks.md). |

## Read-only fields

| Field | Meaning |
| --- | --- |
| `id` | The page id used in `/api/profiles/{id}`. |
| `moderationStatus` | `ok`, `review` or `banned`. A banned page cannot be edited (`403 banned`). |
| `createdAt`, `updatedAt` | ISO timestamps. |

## Full example

```json
{
  "displayName": "Studio Kōri",
  "bio": "Ceramics from a small studio in Kyoto. Shop opens the first Sunday of each month.",
  "templateId": "whisper",
  "layout": "grid",
  "headerAlign": "center",
  "theme": { "accent": "#2B4C7E" },
  "pageLocale": "en",
  "isPublished": true,
  "blocks": [
    { "type": "link", "label": "Shop", "url": "https://kori.example/shop", "path": "shop", "featured": true },
    { "type": "link", "label": "Workshops", "url": "https://kori.example/workshops", "note": "Two Saturdays a month" },
    { "type": "socialRow", "items": [ { "platform": "instagram", "url": "https://instagram.com/studiokori" } ] }
  ]
}
```

---
Part of the [Tapmy.link agent documentation](https://tapmy.link/documentation/agents.md). Canonical: https://tapmy.link/documentation/agents/page-model.md
