Skip to content

Sites and onboarding

A site is the unit of installation in Sill: one site is one registered domain. Adding a site at app.sill.so mints a per-site site_key, runs a four-step onboarding flow (domain → skills → install + verify → complete), and — once domain ownership is proven — exposes that site’s signed agent card, MCP server, and ARD ai-catalog.json at Sill’s edge, all verifiable against the public JWKS.

Sites are managed in the dashboard at https://app.sill.so/. The Sites overview lists every site on your account; the Add site button opens the onboarding shell. The shell is a single-screen, four-step state machine — there are no separate routes for each step, and progress is persisted on the server so closing the tab and returning resumes where the merchant left off.

The site lifecycle is the same in both Discovery and Transactional modes; Transactional adds further gates on top of a verified site (signed mandates, policy, payment authorization), but the site itself is created and verified the same way.

On a new account’s first entry into the shell, Sill renders a one-screen welcome before step 1. It states what Sill does in three lines — identity (know every AI agent that visits), intent (control what each one can do), and proof (keep a signed record) — and sets a time expectation. A single Get started action falls through to step 1.

The welcome intentionally does not ask which platform the merchant runs. Platform detection is authoritative and runs automatically at the install step — Sill never asks what it can detect. Returning to the shell after the first entry skips the welcome and resumes directly at the right step.

Prefill path — welcome is skipped. If the merchant typed a domain on the marketing site before signing in (the sill.so hero), Sill skips the welcome entirely and auto-creates a pending_proof site during account creation. The shell opens directly at step 2 (Skills). The Domain step only appears as a fallback: if auto-creation fails (validation error, duplicate domain) or when the merchant adds a second site from the Sites overview.

flowchart LR
  W[Welcome<br/>one screen, first entry only] --> A[1 - Domain<br/>add site]
  A --> B[2 - Skills<br/>pick capabilities]
  B --> C[3 - Install + verify<br/>five install-method tabs]
  C --> D[4 - Complete<br/>You are live]
  D -.stale status detected.-> C

The install step’s five tabs are labeled Script tag, WordPress, WooCommerce, Shopify, and Cloudflare. All five are always visible in a tabs-on-top layout; the tab Sill recommends for the detected setup is pre-selected and carries a RECOMMENDED badge, but every tab stays one click away — detection is a hint, never a gate.

Step 1 (Domain) — the first shell step after the welcome screen (or the first screen on any return visit).

The merchant types a bare domain (e.g. example.com; the https:// prefix is implied and any path is stripped). On submit the dashboard calls POST /v1/sites, which creates the site row at status pending_proof and returns the site, its site_key, and its site_key_hash. Domain validation is a lightweight format check; deeper checks happen during install + verify, not here.

On the happy path (marketing hero → sign-in), this step is skipped — the site was auto-created during account creation and the shell opens at step 2. If auto-creation failed and the domain was carried over as a fallback, it pre-fills the input here. The pre-fill is consumed once and validated against the same domain format check as manual input; an invalid value simply pre-fills nothing.

If the domain is already on your account, the dashboard surfaces a calm “resuming your existing setup” toast and jumps straight to the right step for that site, rather than erroring out.

Terminal window
curl -X POST https://api.sill.so/v1/sites \
-H "authorization: Bearer <session>" \
-H "content-type: application/json" \
-d '{"domain":"example.com","name":"Example"}'
{
"site": {
"site_id": "01J...ULID...",
"account_id": "01J...ULID...",
"domain": "example.com",
"name": "Example",
"status": "pending_proof",
"site_key": "sk_...",
"site_key_hash": "<43-char base64url SHA-256>",
"policy_version": "discovery-v1",
"edge_sync_status": "synced",
"created_at": "2026-06-22T12:00:00Z"
},
"site_key_shown_once": true
}

The raw site_key is returned once at create time; treat it as a secret embedded in the snippet. The site_key_hash (base64url(sha256(site_key)), 43 characters) is the public, URL-safe identifier used by the hash-form snippet at the edge — see Embed script.

Step 2 exposes the seven skill slots (Browse catalog, Check availability, Place order, Order status, Track shipment, Request refund, Recommend) and — when platform detection succeeds — a detection-driven suggestion panel. The starting state depends on what Sill detected:

  • A detected commerce platform (Shopify, WooCommerce, WordPress with a store): the detection-narrow effect pre-selects the read-only skills that fit the site (browse_catalog, check_availability, order_status, track_shipment, recommend where the catalog or order surface backs them). Transactional skills (place_order, request_refund) stay off until a payment path is connected, gated by the amber-Lock affordance.
  • A non-store, undetected, or unknown site: nothing is pre-selected. Every skill starts off; the merchant enables exactly what they want. Transactional skills stay locked to a payment path in the same way.

Detection is a hint, never a gate: whether or not the detection-narrow effect fired, the merchant can flip any skill on or off.

Skill toggles persist per site as the merchant flips them. There is no merchant-facing “Analyze my site” button; any deeper extraction runs server-side and best-effort, and never blocks the flow.

The suggestion panel exposes an Apply all control that turns on every suggested skill in one click. Once every suggested skill is already enabled, the button becomes non-interactive and reads All applied — the change is idempotent and the label stays honest.

Step 3 (Install + verify) — five install-method tabs, always visible, with a shared proof-check state. The detection-recommended tab is pre-selected and carries a lime RECOMMENDED badge; every tab stays clickable.

Before the install work, Sill surfaces a See it first card: one tap deep-links into the Live Agent view and plays a phased walkthrough of an AI agent reading the site and attempting a checkout — identified, governed, and signed. It runs on demo data until the embed is live, and no real charge is ever made. The card lets the merchant experience the outcome before committing to the install.

The merchant then picks an install method (or accepts the recommended pre-selection), places the Sill snippet, and proves domain ownership. The five install tabs are:

  • Script tag — the universal path. Paste a one-line <script> into the site’s HTML. Rich per-visit browser-side observation for JS-executing agents. Static-only crawlers cannot see a script-tag-only install: the pointer is injected into the DOM at runtime, so a static fetch of /.well-known/agent-card.json returns nothing on this path — the Cloudflare, WordPress, and WooCommerce tabs close that gap. See Embed script for the snippet, sizing, and load behavior.
  • WordPress — the Sill WordPress plugin (v1.1) is the recommended path. Download the per-site-keyed .php file from the Install tab and upload it once through the WordPress admin. The plugin serves both well-known surfaces same-origin: /.well-known/agent-card.json (a proxy of the signed card served from Sill’s edge) and /.well-known/sill-proof.txt. That means a plugin-only install completes ownership proof — no snippet paste required. Pasting the universal <script> tag (Appearance → Theme File Editor → footer.php, a block theme’s Editor → Template parts → Footer, or an existing code-snippet plugin) remains available as a manual alternative. See Agent readiness for details.
  • WooCommerce — an explicit two-step flow. Step 1 is the WordPress plugin (or, as a fallback, the same script snippet) plus verify — this proves ownership of the domain. Step 2 connects the store’s REST API keys so agents can read orders and recommendations, and — once Stripe is connected — place governed orders.
  • Shopify — OAuth connect to the merchant’s Shopify store. On a Shopify site the OAuth grant itself proves ownership, so a separate proof panel is not shown on this tab.
  • Cloudflare — a one-token flow for sites already proxied through Cloudflare (orange-cloud). Paste a Cloudflare API token; Sill deploys a Worker on the merchant’s domain that serves both /.well-known/agent-card.json and /.well-known/sill-proof.txt from the merchant’s own origin, and forwards crawler-class agent requests to the traffic log. The Worker serves the static well-known card even when the origin platform reserves /.well-known/ (as Shopify does), which is why the Cloudflare tab is what Sill recommends for a Cloudflare-proxied site whose origin platform could not be identified.

Verification is mandatory. There is no skip-verify affordance: the proof check itself advances the flow. The proof channels are described in detail in Domain verification — in short:

  • HTTP challenge (script-tag / WordPress / WooCommerce) — Sill’s origin server-fetches the merchant’s published HTML and looks for the snippet (with the per-site data-proof-token) embedded in the served page. Finding it records a P1 proof and flips the site to discovery_active. The browser/runtime does NOT transmit the proof token; the attribute exists only so the origin’s homepage scan can confirm domain ownership by finding it in the merchant-served HTML.
  • .well-known fallback — when the homepage scan misses (single-page apps, JS-rendered HTML), the merchant can host a static file under /.well-known/ instead. The Sill WordPress plugin and the Cloudflare Worker both serve /.well-known/sill-proof.txt automatically, so a plugin- or Worker-only install proves ownership without an extra step.
  • Shopify OAuth domain-match (Shopify tab) — the OAuth callback’s verified shop domain matches the site, which records a P2 proof and (with a P1 alongside) enables Transactional gates.

The canonical snippet is built by the dashboard and looks like:

<!-- paste before </body> -->
<script async src="https://cdn.sill.so/embed.js"
data-site-key="sk_…"
data-proof-token="pf_…"></script>

The data-proof-token is per-site and opaque — public-by-design once installed. It is the ownership-proof token Sill’s origin looks for in the served HTML; it is not a bearer credential, and the embed runtime in the browser does not read or send it.

Proof status — what ownership proof authorizes

Section titled “Proof status — what ownership proof authorizes”

The proof-status panel sits inline with the install work on this step (on the snippet tabs; on the Shopify tab the OAuth grant is itself the proof, so a separate panel is not shown). It surfaces the current proof state, the .well-known fallback affordance when the homepage scan misses, and — most importantly — the reason proof matters: proof of ownership is what authorizes Sill to publish signed statements about this domain. That is the signed agent card at https://edge.sill.so/v1/agent-card/{site_key}.json, the signed ARD catalog at https://edge.sill.so/v1/catalog/{site_key}.json, and the site’s signed audit records. Without proof, anyone could claim the site; with it, the signatures downstream carry the domain’s authority.

The WooCommerce tab presents the install as two clear steps:

  • Step 1 — install the plugin (or paste the script) + verify. The recommended path is the Sill WordPress plugin, which serves both well-known surfaces same-origin and clears ownership without a snippet paste; the universal script tag remains as a fallback. This step proves ownership of the domain.
  • Step 2 — connect the REST API. Paste a consumer key and secret from the store’s WooCommerce admin. This lets agents read orders and product recommendations, and — once Stripe is also connected — place governed orders through the merchant’s WooCommerce store.

Both steps are required. The WooCommerce keys are a second proof, added on top of the domain proof from Step 1 — they do not replace it. Order reads need verify plus connect; either alone is insufficient. The panel says this explicitly under the form so a “Connected” confirmation is not read as making verify optional.

Exits — invite a developer, or finish later

Section titled “Exits — invite a developer, or finish later”

The two exits from this step live below the install and proof work, separated from it by a horizontal rule so they cannot be mistaken for part of the primary path:

  • Invite your developer — a collapsed disclosure that expands into an invite form. Sending the invite adds the developer to the workspace with admin role (site key rotation and proof are owner- or admin-gated) and sends them an email that names this site’s domain and deep-links to this exact install step. Nothing sensitive is emailed; the developer retrieves the snippet and site key in the dashboard after signing in.
  • Finish later — a subdued link that exits the shell to the Sites overview. Verification still gates going live; the hatch stops verification from gating looking around. The Sites overview keeps the merchant’s place via the v2 setup guide (below).

Step 4 fetches the fresh server-side status before rendering — not the cached client snapshot — so the “you’re live” hero only ever appears when the server says the site is discovery_active or transactional_active. If the merchant lands here on a still-pending_proof site (stale URL, race, forced navigation), Sill shows a safety-net face that says “One step left — verify” and routes back to step 3 instead of falsely claiming success.

Beneath the hero, Sill runs a post-install readiness check against the merchant’s live site — the same probe class a third-party checker would run. It fetches /.well-known/agent-card.json and the in-page <link rel="agent-card"> pointer and reports what each discovery surface returned: static card-lookup, in-page pointer, crawler traffic logging. Ownership (the proof-check on step 3) is the gate that turns the site live; the readiness check is additive and non-blocking, so a transient probe miss never traps the merchant on step 4. When the static card is missing (typical of a script-tag-only install), the panel surfaces the honest fix — usually “switch to the plugin, Worker, or app tab” — instead of leaving the merchant to discover the gap on an external checker.

The success face also surfaces a condensed advert for the rest of the protocol stack with a “Notify me” interest-capture for the items that are not yet live (see Protocols for the canonical state of each).

Sites move through a small, deliberate set of states:

statusWhat it meansDashboard card label
pending_proofSite exists, site_key minted, no proof recorded yet (tier T0).NOT YET VERIFIED
discovery_activeA first valid P1 (HTTP challenge) proof was recorded (tier T1). Audit writes enabled.AWAITING TRAFFIC then DISCOVERY · LIVE
transactional_activeAdditionally has a P2 (OAuth domain-match) proof (tier T2/T3). Mandate + connector dispatch enabled.DISCOVERY · LIVE (Transactional gates separately surfaced)
suspendedOps action only.(hidden from list)

The Sites overview also splits discovery_active into two card faces based on whether any agent traffic has been seen:

  • Awaiting traffic — verified, but last_seen_at is null. The card prompts the merchant to view the install snippet.
  • Live — verified and at least one beacon has arrived. The card shows stats and a calm DISCOVERY · LIVE label. If beacons stop arriving for more than 24 hours, a NO RECENT BEACONS band invites the merchant to re-check the install (the site_key may have rotated).

A Shopify site that auto-installed via ScriptTag but has not yet received an agent visit shows a third intermediate face: AWAITING FIRST AGENT VISIT — Sill installed the embed; recording starts on the first agent visit.

The Sites overview renders an actions-first setup guide targeted at the account’s most-progressed site — no manual check-off, no observation-only milestones. Each step is auto-derived from server state the dashboard can already read; a step Sill can’t yet confirm renders as not-done rather than being guessed.

The five steps are:

  1. Install and verify — done when the site’s status is discovery_active or transactional_active.
  2. Set your guardrails — done when the active policy is merchant-authored (a version other than the seeded baseline). Deep-links to Guardrails.
  3. Connect your store — done when a Shopify or WooCommerce connector reports connected. The step guidance names the webhook-custom-skills path for non-store sites so a SaaS on WordPress isn’t told it must have a cart.
  4. Enable governed checkout — done when a settle rail is available (Stripe connected, or Shopify connected, since Shopify checkout settles via Shopify).
  5. Get escalation alerts — done when a Slack webhook is configured and enabled. Email alerts are the default channel; Slack is the upgrade, not the only option.

The guide is dismissible; non-commerce sites that will never complete steps 3–4 can dismiss it once and it stays dismissed. There is deliberately no per-step “skip” — that would reintroduce manual check-off state. The four detection reads for steps 2–5 fire in one parallel batch, only when the card is visible, not dismissed, and step 1 is already done.

Returning to the dashboard mid-onboarding jumps to the right step based on the site’s status:

  • pending_proof → step 2 (Skills). The merchant has a site but no proof yet.
  • discovery_active / transactional_active → step 4 (Complete). The site is live; show the success hero.
  • Anything else (null, suspended) → step 1 (Domain).

Switching the active site via the dashboard’s top bar re-runs this mapping so the flow does not inherit the previous site’s step.

Removal is a two-stage modal:

  1. Stop recording (available today) — soft-delete. The embed snippet stops being recognized, the site disappears from the active list, and past audit records remain on Sill’s servers and are exportable from the Audit log’s “Show deleted sites” toggle. Re-adding the same domain creates a new site (new site_id, new chain).
  2. Erase content (in a later release) — cryptographic erasure: destroy the per-site key used to encrypt records, leaving the ciphertext undecryptable. Rendered disabled today with the explicit “available in a later release” label.

The hard-delete path is intentionally not offered: the audit chain’s integrity is a product property, not a UI convenience.

Does Sill require a DNS or CNAME record to verify a site? No. Proof of ownership runs through the install snippet (HTTP challenge or .well-known fallback) or through Shopify OAuth domain-match. There is no DNS change to make. See Domain verification.

Can I add a subdomain as a separate site? Yes — a site is bound to exactly one registered domain string, and shop.example.com and example.com are distinct sites with distinct site_keys, distinct agent cards, distinct ARD catalogs, and distinct audit chains.

What changes between Discovery and Transactional onboarding? Onboarding itself is the same four steps. Transactional adds a P2 proof (OAuth domain-match) and connector configuration on top of a discovery_active site; the path is covered in the Transactional overview. Both Discovery and Transactional are live on the Stripe rail; Shopify live-mode is not yet enabled.

Is the site_key a secret? The raw site_key returned at create time is embedded in the script-tag snippet and should be treated like any other identifier scoped to the site. The site_key_hash is the public, URL-safe form used by the hash-form snippet at cdn.sill.so/embed.js?site=<hash>.

Can I rotate the site_key? Yes. The dashboard exposes a key-rotation action; re-rotating invalidates the previous key after the merchant re-installs the snippet with the new value. A site whose key was rotated but whose snippet was not updated will show the NO RECENT BEACONS band after the freshness window elapses.

  • Domain verification — the proof channels (HTTP challenge, .well-known, Shopify OAuth) in depth.
  • Embed script — the snippet, hash-form URL, and load behavior.
  • Agent card — what gets published at the edge once a site is verified.
  • ARD catalog — the signed ai-catalog.json per site.
  • Verify a signature — how a third party verifies any Sill-signed surface against the public JWKS.
  • Quickstart — the end-to-end “add a site, install the snippet, see your first agent” walkthrough.
  • Transactional overview — what changes once a site is gated for signed mandates and payment authorization.

External references: the agent card is A2A-compatible; the MCP server speaks the Model Context Protocol; the per-site signed manifests use RFC 8785 JCS canonicalization with ed25519 signatures over a JWS / EdDSA envelope; site identity uses did:web over the merchant’s verified domain.