# Snabbsite

Snabbsite is a website builder for small businesses. A connected agent can read
a customer's website, write drafts, publish, manage domains and create new
websites, within the scopes its owner approved.

## Registration types

- `anonymous` — supported, as the claim ceremony below. The agent starts with
  no identity and receives nothing until a human claims the pairing.

Not supported: `identity_assertion` and `service_auth`. We do not accept an
agent-attested identity, and we never mint a credential before a human has
signed in and confirmed it. There is no pre-claim token.

## The claim ceremony

1. `POST https://snabbsite.com/v1/cli/pair/start` with `{ "scopes": [...], "client": "<your name>" }`.
   The reply carries `userCode`, `deviceCode`, `verificationUrl` and the
   NORMALISED scope list, which may already be narrower than you asked for.
2. Show the human the `userCode` and `verificationUrl` in one message. Do not
   ask them for anything else.
3. The human signs in at `https://snabbsite.com/dashboard/connect`, types the code, and sees
   every scope you requested with a tick box beside it. They may untick any of
   them. They cannot add one you did not request.
4. `POST https://snabbsite.com/v1/cli/pair/poll` with `{ "deviceCode": "..." }` every two
   seconds. On approval it returns `token` ONCE, plus the scopes actually
   granted. Poll again and you get `claimed` and nothing else.

The human may have no website yet. That is a normal, supported answer: the
approval then covers the whole company, `websiteId` comes back `null`, and
creating the first website is a thing you can do with `workspace:write`.

An account is never created for the human. If they have none, send them to
`https://snabbsite.com` to sign up first, and start the ceremony after that.

## Using the credential

Send it to the MCP endpoint as a bearer token:

```
https://snabbsite.com/api/mcp
Authorization: Bearer sajt_live_...
```

Protected resource metadata (RFC 9728):
`https://snabbsite.com/.well-known/oauth-protected-resource/api/mcp`

An OAuth 2.1 client may skip the ceremony entirely and authorize against that
metadata instead. Both paths end at the same connection and the same gate.

## Scopes

`site:read` is added to every connection. Request the narrowest set
that does your job; the default an owner sees is `edit`, which is
`site:read` plus `content:write`.

| Scope | What it grants |
| --- | --- |
| `site:read` | Read the business profile, pages, sections, brand and visitor statistics. Always granted. |
| `content:write` | Create and edit DRAFT pages, sections and posts. Nothing reaches the live site. |
| `publish` | Publish the draft to the live site. |
| `ai:generate` | Generate text and images. Spends the owner's credits. |
| `crm:read` | Read leads, bookings and contacts. This is personal data. |
| `crm:write` | Update customer records and bookings. Never deletes one. |
| `settings:write` | Change the business profile, brand, visitor assistant and visibility settings. |
| `domain:read` | Read the site's web addresses and their DNS status. |
| `domain:write` | Connect, verify and select a web address the business already owns. Never buys one. |
| `access:write` | Invite or remove people from a website. Every call needs the owner's confirmation. |
| `communications:write` | Send quotes, invoices and invitations. Every call needs the owner's confirmation. |
| `commerce:write` | Create and update services, offers and invoices. |
| `workspace:write` | Create a new website, or propose a new company for the owner to confirm. |

Some calls need the owner's confirmation even when the scope is granted:
publishing, sending a document, changing who has access, and creating a company.
Those return a pending action with a link for the human to approve.

## Terms

- Pricing: https://snabbsite.com/pricing
- Terms: https://snabbsite.com/terms
- Privacy: https://snabbsite.com/privacy
- Integration problems: support@snabbsite.com
