---
name: site-management
description: Een site op Spaicely beheren als hij gebouwd is: versies uploaden en live zetten, terugzetten, een deel van een pagina wijzigen, de site op zijn domein zetten, DNS en mail doorsturen, mensen en rollen, goedkeuren, overdragen, het hostingpakket en het verlengen van domeinen. Gebruik dit altijd als je aan een bestaande site of een bestaand account bij Spaicely werkt, niet alleen bij het bouwen.
---

# Een site op Spaicely beheren

Hoe een site online komt en blijft. Wat een goede site bevat, staat in de skill `site-building`; een naam zoeken in `domain-search`. Elke tool, parameter en elk HTTP-endpoint staat op https://spaicely.com/developers/ en, voor AI's, in https://spaicely.com/llms-full.txt.

## Beginnen

- Roep eerst `account.whoami` aan. Die zegt voor wie je werkt, welke scopes je hebt en per site je rol en wat je mag. Nog geen site? `sites.create` maakt er een; vraag de persoon eerst om de naam.
- Je rechten zijn nooit ruimer dan de rol van de persoon. Weigert een tool, zeg dan wat er ontbreekt (rol, scope of pakket) in plaats van het via een andere weg te proberen.
- Staat een tool die hier genoemd wordt niet in je lijst, dan is je lijst oud: vraag de persoon de Spaicely-connector opnieuw te verbinden (in claude.ai: Instellingen > Connectors; in Claude Code: `/mcp`).
- Vraag de persoon eerst bij alles wat verandert wat bezoekers zien, geld kost of niet terug te draaien is. Sommige tools vragen in Claude Code zelf om toestemming.
- **Wat je zelf mag**, kiest de persoon per soort handeling (`ai_permissions` in `account.whoami`): `self`, `ask` of `never`. Standaard staan kopen, mensen, mail, het register, verwijderen en factuurgegevens op `ask`. Zo'n aanroep antwoordt met `approval_required` en een `url`: geef de persoon die link en herhaal de aanroep niet. De persoon keurt goed in Spaicely; wij voeren de aanroep dan precies uit zoals jij hem stuurde, en `approvals.status` met het `approval`-id geeft het antwoord. Een soort op `never` wordt geweigerd; dat kan alleen de persoon aanpassen, op https://app.spaicely.com/ai.

## Een versie online zetten

Een versie is altijd de hele site, nooit een set wijzigingen. Niets is zichtbaar voordat hij gepubliceerd is.

1. **Uploaden**, op een van twee manieren:
   - `sites.deploy` met elk bestand: `path` vanaf de hoofdmap van de site, `sha256` in hex en `size` in bytes. Voor een afbeelding die al op het web staat geef je `source_url` in plaats daarvan (https, hooguit 20 per aanroep). Het antwoord noemt `missing`; stuur precies die met `sites.files.put` (hooguit 50 bestanden en 2 MB per aanroep, tekst als `utf8`, de rest als `base64`).
   - Met de site als map op schijf: `sites.upload_url`, dan `tar -czf site.tar.gz -C <map> . && curl -T site.tar.gz <url>`. De URL werkt één keer, 10 minuten; `index.html` moet in de hoofdmap van het archief staan.
2. **Publiceren** met `sites.publish` en het versienummer, nadat de persoon akkoord gaf. Bezoekers gaan in één keer over, nooit naar een mengsel. Het duurt tot een halve minuut; `sites.versions` laat zien wanneer hij live staat.
3. **Het rapport lezen.** `sites.versions` geeft per versie de bespaarde bytes en `hints`, elk met een `fix`. Los op wat van toepassing is en publiceer opnieuw.

Goed om te weten:

- We bewaren de bestanden precies zoals ze geüpload zijn; bezoekers krijgen een geoptimaliseerde kopie (kleinere HTML, CSS en JavaScript, opnieuw gecomprimeerde afbeeldingen tot 2560 pixels).
- Alles onder `_private/` blijft van het CDN af; alleen een downloadformulier geeft het uit. `_redirects` wordt doorverwijzingen op het CDN en wordt zelf niet geserveerd (zie `site-building`).
- Heeft iemand anders gepubliceerd nadat jouw versie begon? Dan worden jouw wijzigingen op de zijne gezet en gaat dat live. Een conflict komt terug per pad: lees het live bestand met `sites.files.get`, doe je wijziging daarop opnieuw en upload weer.
- **Terug naar de vorige versie**: `sites.publish` met `rollback: true`. Een oudere versie: `sites.publish` met haar nummer.
- Lees een pagina die iemand anders maakte eerst met `sites.files.get` (de live versie, of `deployment` voor een andere) en laat staan wat er staat. `sites.files.list` toont de bestanden, met `prefix` voor één map.

## Eén deel van een pagina wijzigen

Een pagina kan blokken markeren die een rol los mag wijzigen:

```html
<!-- spaicely:edit news -->
<p>Vanaf 1 november ook op zondag open.</p>
<!-- /spaicely:edit -->

<!-- spaicely:append agenda -->
<li>12 november: proeverij</li>
<!-- /spaicely:append -->
```

- `edit` mag helemaal veranderen; `append` neemt alleen toevoegingen voor of na wat er staat. Namen: kleine letters, cijfers, `-` en `_`. Blokken gaan niet in elkaar.
- `sites.files.list` noemt de blokken per pagina. `sites.region.update` met `path`, `region` en `content` maakt een nieuwe versie die alleen in dat blok van live verschilt (`mode` replace, prepend of append; `index` als een naam vaker voorkomt). Publiceer daarna.
- Zet deze markeringen waar de persoon verwacht dat anderen iets bijhouden (nieuws, openingstijden, agenda), zodat een redacteur nooit de hele pagina nodig heeft.

## Mensen en rollen

- **Op het hele account**: `account.members`. Eigenaren regelen betalen, domeinen en mensen; leden werken aan alle sites. Uitnodigen gaat per e-mail (de link werkt 7 dagen).
- **Op één site**: `access.list` toont wie welke rol heeft; `access.update` geeft, wijzigt of haalt (`role: "none"`) er een weg. Alleen de eigenaar. De persoon heeft een Spaicely-login met dat adres nodig.
- Rollen: `admin` (alles behalve eigenaarszaken), `maintainer` (alle bestanden, formulieren en DNS), `designer` en `editor` (alleen wat hun `rules` toestaan), `viewer` (meekijken). `can_publish` laat een maintainer of editor publiceren.
- Regels beperken een designer of editor tot handelingen op paden, eventueel tot gemarkeerde blokken: `[{"actions": ["update"], "paths": ["blog/**", "index.html"], "regions": ["news"]}]`.
- **Goedkeuren** (pakketten Pro en Winkel): wie bestanden mag wijzigen maar niet publiceren, roept `sites.review.request` aan met een `note`. Wie mag publiceren krijgt een mail; goedkeuren is `sites.publish`, terugsturen is `sites.review.reject` met een toelichting. Bij pakket Site vraagt de persoon iemand die mag publiceren.

## Een domein voor de site

- Een domein registreren of verhuizen: zie `domain-search` (`domains.register`, `domains.transfer`; een partner stelt er een voor aan de klant met `domains.propose`). De klant is altijd houder.
- **Koppelen**: `sites.domains.connect` met het domein zelf, zonder www. Spaicely leest de records die het domein nu heeft; roep na ongeveer een halve minuut opnieuw aan voor `records_to_confirm`. Laat ze de persoon zien: behouden records (mail, verificaties) gaan mee, records met reden `site` worden vervangen, reden `certificate` is een CAA-record dat het certificaat zou blokkeren. Roep dan aan met `confirm: true` (`skip` met de nummers die je weglaat).
- De persoon zet daarna bij de registrar de nameservers op de twee uit het antwoord (`kiki.bunny.net` en `coco.bunny.net`). Domeinen die bij Spaicely geregistreerd zijn hebben die al. DNSSEC bij de oude aanbieder moet eerst uit. We kijken elke vijf minuten, halen dan het certificaat en mailen de persoon; `www` stuurt bezoekers door naar het domein zelf.
- `domains.status` toont hoe het ervoor staat: records om te bevestigen, nameservers, DNSSEC, certificaat en de records die wij serveren.
- **DNS-records**: `domains.dns.update` voegt A, AAAA, CNAME, TXT, MX, SRV en CAA toe of haalt ze weg (`name` ten opzichte van het domein, `@` voor het domein zelf; weghalen met het id uit `domains.status`). Waar het domein en www naartoe wijzen blijft bij de site. Een domein van het account zonder site krijgt zo ook Spaicely-DNS.
- Ondertekeningssleutels (DKIM) van een ongewone dienst kunnen bij het koppelen gemist worden: de persoon stuurt dan één mail vanaf een adres op het domein naar `dkim@spaicely.com` met de code uit `dkim_mail` als onderwerp.
- `sites.domains.disconnect` laat de site niet meer op het domein antwoorden; mailrecords blijven staan.

## Mail doorsturen

Mail aan `info@<domein>` kan door naar een postvak dat de persoon al heeft, zoals Gmail. Antwoorden als `info@` kan nog niet.

1. `mail.forward.enable` op een domein dat aan een betaalde site gekoppeld is. Die zet MX, verificatie, DKIM, SPF en DMARC. Ontvangt het domein al mail ergens anders, dan stopt dat: de aanroep weigert zonder `replace_existing_mail: true`, dus vraag het eerst.
2. `mail.forward.add` met `address` (`info`, of `*` voor elk adres zonder eigen regel) en hooguit 5 `destinations`. Elke nieuwe bestemming krijgt een bevestigingsmail; er gaat niets heen voordat daarop geklikt is.
3. `mail.forward.status` toont de adressen, de stand van elke bestemming en mail die de laatste 30 dagen als mogelijke spam is tegengehouden; `mail.forward.release` stuurt er alsnog een door, alleen als de persoon hem herkent.

Elk adres kost EUR 1,50 per maand excl. btw op het pakket van de site; Site staat er 1 toe, Pro 5, Winkel 10. `mail.forward.remove` en `mail.forward.disable` stoppen het.

## Pakket, betalen en verlengen

- **Hosting**: `sites.subscription` toont pakket, status en verlengdatum. Met `plan` (`site`, `pro` of `shop`; EUR 9, 19 en 39 per maand excl. btw) start hij de hosting, met een `checkout_url` voor de persoon, of wisselt hij meteen van pakket. Zonder pakket wordt een nieuwe site na 14 dagen weggehaald. Kaart, facturen en opzeggen staan op `portal_url`. Alleen eigenaren van het betalende account.
- **Factuurgegevens**: `account.billing` (zakelijk of niet, btw-nummer, adres). Elke aankoop heeft ze nodig; een btw-nummer wordt gecontroleerd bij VIES. `account.invoices` geeft onze facturen met elk een link.
- **Consumenten** (een account dat geen bedrijf is) moeten akkoord gaan dat een bestelling meteen begint, wat hun herroepingsrecht beperkt. Geef `start_now: true` alleen als ze dat zelf gezegd hebben.
- **Domeinen**: verlengen gaat standaard automatisch, 14 dagen voor de verloopdatum, van de kaart of het mandaat waarmee het domein betaald is (`domains.auto_renew`; zonder opgeslagen betaalmethode heeft het antwoord een `setup_url`). `domains.renew` geeft een betaallink om nu te verlengen.
- Ook voor eigenaren van het houderaccount: `domains.holder` (houdergegevens; een andere naam of organisatie loopt via ons), `domains.lock` (verhuisslot), `domains.nameservers` (`ours: true`, of andere voor een domein zonder site) en `domains.transfer_code` (de code gaat per mail naar de persoon en de houder, nooit naar jou).

## Partners

- Een partner (een webontwerper of bureau) bouwt op zijn eigen partneraccount, of werkt met een rol aan de site van de klant.
- `sites.handover` mailt de klant een link (14 dagen) om een af site op zijn eigen account te nemen; `role` is wat de partner houdt, `payer` wie daarna betaalt. `sites.handover.revoke` trekt hem in zolang de klant niet geaccepteerd heeft.
- `domains.propose` stelt een domein voor bij de site van een klant; de klant controleert de houdergegevens en gaat eerst per mail akkoord.

## In de gaten houden

- `sites.stats` geeft verzoeken, bytes, `not_found` en CDN-regio's per dag, over 7, 30 of 90 dagen, zonder cookies. Veel `not_found` betekent kapotte links: zoek ze op en maak een doorverwijzing of herstel de link.
- `scripts.list` toont de stand van elk formulier; `shop.orders` de laatste bestellingen.
- Een site verwijderen (`sites.delete`, alleen de eigenaar, met de naam die de persoon intypte) haalt elke versie, elk formulier en de winkel voorgoed offline. De domeinen blijven van hem.

## Zonder MCP

De Spaicely CLI doet hetzelfde vanuit een terminal of CI: `spaicely login`, `spaicely deploy` (vergelijkt met live, uploadt, publiceert eventueel), `spaicely publish`, `spaicely rollback`, `spaicely versions`, `spaicely domains ...`, `spaicely dns ...`, en `spaicely call <tool>` voor elke andere tool. Installeren en voorbeelden: https://spaicely.com/developers/#command-line.
