---
name: vizen-start
description: Entry point for building a Vizen shop through a personal API token — read the key passport, learn the map, and pick the right path BEFORE writing anything. Invoke first for any task touching /content-blocks, /html-documents, /design/bindings, categories or products. Question 0 — a finished site, template or export already exists? — routes to vizen-transfer; the rest to vizen-widgets, vizen-own-markup, vizen-chrome, vizen-catalog and vizen-troubleshoot.
---

# Start here

You are changing a **live shop** through a token. A mistake is visible to
shoppers immediately. Two things come before any write: know what the key can do,
and know which path the task actually needs.

## 0. Have a finished site, folder or export? Stop here

If the page or the whole site already exists — a folder with `index.html`, a
generator export, a React/Vite build, a Figma/Webflow/Tilda export — you are
**transferring, not building**: invoke `vizen-transfer` and skip the rest of
this skill. Folder = widget, one command per folder, real page DOM (scripts
and `position: fixed` work), nothing is cut and no path is rewritten:

```
node backend-3D/tools/html-transfer/transfer.mjs ./folder --page <slug>
```

## 0a. One page or the whole site? The layout decides

| What the owner wants | Where it goes |
|---|---|
| one page (landing, promo) | an html widget on that page — `--page <slug>` |
| something on **every** page: common CSS, fonts, `<head>`, a favicon, a script | the **LAYOUT's folder** — `--theme <id>`, `vizen-own-markup` §6.2 |
| header/footer for the whole site or for one section | groups bound to slots, on the shop, a section, or the layout — `vizen-chrome` |

Site-wide CSS belongs in the layout folder: the editor canvas loads only the
layout's `<head>`, it is the only stylesheet that survives the guarded zones,
and a header unbound from a section takes its styles with it. Why in full —
`vizen-own-markup` §6.2.

A layout is a group with `group_type:"theme"`; the shop's default one is the
earliest by id ("Основной"). Find them with `GET /content-blocks` and filter
the answer yourself — the API has no filter. In the guarded zones (`/cart`,
`/checkout`, `/account`, `/wishlist`, `/orders`, `/deals`, `/dashboard`) no
author script runs — layout code included; markup and styles stay.

## 1. Read the key passport

```
GET /v1/account/token
```

It is the only reliable statement of your rights: public endpoints answer 200
without `catalog:read` too, using an anonymous projection, so "200 on /products"
proves nothing.

From the passport, before the first write:

- `writes_to_live: true` → say out loud to the owner that visitors will see the
  change immediately, and wait for confirmation;
- `store.currency` → compare with the prices you are about to write; a mismatch
  is rejected, and the currency cannot be changed with a token;
- `warnings[]` → pass to the owner verbatim.

Then `GET /` for the map, and `GET /llms.txt` for the reading order.

## 2. Ask three questions before the first write

**Question 0 — before the three questions: does a finished site, template or
export already exist?** Trigger words: "transfer", "migrate", "we already have
a site", "export", "ZIP", a folder or a repo in the task. If yes, the path is
`vizen-transfer` — move it as it is; rebuilding a finished design costs the
whole build (one shop: three generations of documents and 31 releases before
1:1). The three questions below are for building from scratch.

**Trigger words: "unique", "not like the rest of the shop", "our own storefront",
"wow", "fully custom design".** When you hear them, stop and ask. These forks are
invisible in both the task and the documentation, and getting one wrong costs the
whole build — measured: one run threw away 12% of its steps this way.

| Question | Path A | Path B |
|---|---|---|
| **Header, menu, footer** | platform widgets — fast, `sticky` works, look is bounded by props | own markup in an HTML block — full freedom, needs a chrome kit and a binding |
| **"unique", "not like the rest"** | usually neither extreme: keep the widget and put your own class on its wrapper (`props.wrapperClass`), then restyle from your own CSS | replace the block with own markup only when the structure itself has to change |
| **Product lists** | platform `productListing` — filters, paging, sorting; look is fixed | own markup — any design, and prices are live too (`vz-for="p in products"`). What you give up is the machinery: no filters, no paging |
| **Product card** | change it for one product | change it for every product of a section — `category_children` inherits down the whole tree |
| **Needed more than once?** | one page — an html widget | many pages, different content — a **component** (`vizen-own-markup` §6.3): one folder, values per insertion |

Say the cost of the second answer out loud. An owner who hears "your prices will
stop updating" decides differently than one who does not.

## 3. Pick the skill

| The task is about | Skill |
|---|---|
| a finished site, folder, build or export to move as it is | `vizen-transfer`, area `GET /docs/transfer` |
| configuring platform blocks, their props and limits | `vizen-widgets` |
| own HTML/CSS/JS, vz- keys, modals, global CSS | `vizen-own-markup` |
| the same markup on many pages with different content | `vizen-own-markup` §6.3, area `GET /docs/components` |
| site-wide CSS/fonts/scripts, favicon, a second design for one section | `vizen-own-markup` (§6.2, the layout folder), `vizen-chrome` (§2a) |
| the cart, checkout, account pages — their header and footer | `vizen-chrome` §2a, system pages |
| making any block look unique — own class on the wrapper, or one wrapper axis | `vizen-own-markup` (§4), area `GET /docs/own-markup` §5 |
| header, menu, footer, layouts, second chrome kit | `vizen-chrome` |
| products, categories, filters, images, import | `vizen-catalog` |
| prices, discounts, promo codes, combo sets | `vizen-catalog`, then `GET /docs/promotions` |
| "I set it, got 200, nothing changed" | `vizen-troubleshoot` |
| closing the site while it is being built — it can be UNPUBLISHED behind a short numeric PIN, invisible to crawlers | area `GET /docs/resource-access` |

## 4. Two rules that apply everywhere

**Look up before you write.** Field names, enum values and defaults come from
`GET /docs/widgets` and `GET /docs/vz-keys.json`, not from memory. Both are
generated from the real code, so they cannot drift from the platform.

**Validate before you write.** `POST /docs/validate` takes the exact `sections`
list you were about to PUT and answers per path: `applied`, `ignored` or
`unknown`, with the allowed values when the miss is in those. It writes nothing
and touches no shop data, so there is no reason not to call it.

```
POST /docs/validate   {"sections":[ … ]}
```

Use it because the failures it catches are **silent**: a setting written beside
`kind` instead of under `props` is stored and renders nothing; a value outside an
enum is accepted and the default is drawn; `"12"` where a number belongs reads
back as the default. Every one of those answers 200.

**Verify by looking, not by status code.** Even after a clean validation, re-read
the object and open the page. The validator knows the schema; it does not know
whether the id you referenced exists or whether the result looks right.

## 5. Never

- print the token — not in answers, files, markup or reports;
- write to the cabinet, cart or checkout flows;
- use `git` at all: you work through the API only.
