# headless.design

> Headless cold-reads as an API. Two products: free `/v1/scan`
> (a 15-second 3-agent review of any landing page) and paid
> `/v1/cold-read-requests` (a 72-hour deep-pass with full spec.md +
> PR-ready diff for 3 900 SEK ex moms). Built and operated by Gustaf
> Garnow (senior product designer, Stockholm).

## Canonical source

For machine-readable contracts always read these on the API host:

- API spec: <https://api.headless.design/v1/openapi.json> (OpenAPI 3.1)
- Agent card: <https://api.headless.design/.well-known/agent-card.json> (A2A v0.3.0)
- API-side llms.txt (most up-to-date): <https://api.headless.design/llms.txt>

This file (`headless.design/llms.txt`) is positioning + product narrative.
The technical contract lives on `api.headless.design` and is regenerated
on every API deploy. If anything below disagrees with the API host,
**the API host wins** — file an issue at the contact below.

## Pilot phase — what's live today

V1 + V2 endpoints coexist on `api.headless.design`. Both work; pick by
caller type:

| Caller | Use | Why |
|---|---|---|
| Agent (Perplexity, Cursor, Claude, ChatGPT) | `POST /v1/cold-read-requests` (V2) | Agent submits, monitors, relays. Operator reviews + accepts before billing. No surprise pay-page on creation. |
| Browser CTA (the marketing site) | `POST /v1/cold-read/request` (V1) | Fast-pay UX: invoice mints immediately, customer hits Swedish HTML pay page within seconds. |
| Either | `POST /v1/scan` | Free 3-agent review. ~15s sync. Rate-limited (3/URL/day, 50/IP/day, 100 global/day). Emits IETF `RateLimit-*` headers. |

## Free /v1/scan

```
POST https://api.headless.design/v1/scan
Content-Type: application/json

{
  "url": "https://example.com",
  "primary_goal": "book_call",
  "audience": "Swedish AI-builders"
}
```

Response: `chat_summary` (~500 chars markdown, paste-ready), `scores`,
`findings`, `_links`. Synchronous. No auth. Rate-limited per IP/URL/day.
The same `/v1/scan` is used post-cold-read as the included follow-up rescan
(`POST /v1/cold-read/{id}/rescan`).

## Paid 72h cold-read

### Agent-native flow (V2 — canonical)

```
POST https://api.headless.design/v1/cold-read-requests
Content-Type: application/json

{
  "url": "https://example.com",
  "goal": "Increase qualified Discord joins",
  "audience": "Swedish AI-builders, technical, agent-curious",
  "constraints": "Keep current tone. Hard deadline May 7.",
  "contact_email": "buyer@example.com",
  "primary_goal": "book_call",
  "html": "...",         // optional — unlocks PR-ready diff without round-trip
  "jsx": "...",
  "repo_url": "https://github.com/...",
  "billing_method_preference": "frilans_finans",
  "source": "agent",
  "agent_name": "perplexity",
  "agent_on_behalf_of": "buyer@example.com"
}
```

Response is an `Order` in status `submitted`. **No `pay_url` at this
stage** — the operator reviews first, then transitions the order to
`billing_pending`, at which point `pay_url` materializes on subsequent
polls of `GET /v1/orders/{id}`.

State machine: `submitted → reviewing → accepted → billing_pending →
paid → in_progress → delivered`. Agents poll `/v1/orders/{id}` and
relay the `pay_url` to the human buyer when status reaches
`billing_pending`. The response also carries `a2a_task_state:
"input-required"` at that point so A2A v0.3.0-aware clients recognize
the handoff without parsing prose.

### Browser fast-pay (V1 — legacy, still live)

`POST /v1/cold-read/request` mints an invoice immediately and returns
`pay_url` in the 201 response. Used by the marketing-site CTA so
human buyers hit the pay page instantly. Sunset 2026-06-25.

### Brief contract — required fields

1. **url** — live page (not Figma, not staging behind auth)
2. **goal** (V2) or **primary_goal** (V1) — what success looks like
3. **audience** — one sentence on who the page is for
4. **contact_email** — human's email (where invoice + delivery emails go)

Optional but powerful: `html`, `jsx`, `repo_url` lets the operator ship
a PR-ready diff without needing a follow-up email round.

## Payment — humans only (in V1 of pilot)

Agents cannot complete payment. Period. The pay page (`pay/{id}` on
api.headless.design) presents one option to the human buyer:

- **Begär faktura via mejl** — clicking the button emails the operator
  with the order details. Operator personally responds within ~3 hours
  with a Frilansfinans-issued invoice (Swedish umbrella service that
  handles F-skatt + 25% moms + 14-day net). Total: 4 875 kr inkl. moms.

No Stripe in pilot. No machine-payable rail. The custom A2A capability
extension at `https://api.headless.design/extensions/human-handoff/v1`
declares this convention to A2A-aware agents:

```json
{
  "uri": "https://api.headless.design/extensions/human-handoff/v1",
  "params": {
    "skills_requiring_human": ["cold-read-request"],
    "handoff_states": ["billing_pending"],
    "handoff_signal": "status_field_with_pay_url",
    "billing_rails": ["frilans_finans"],
    "billing_rail_default": "frilans_finans"
  }
}
```

## Deliverables

When status reaches `delivered`, the operator publishes:

- `spec_final.md` — ranked top-N fixes with paste-ready copy/code, severities
  (`P0` blocks conversion, `P1` costs conversion, `P2` polish), constraints
  honored. Available at `/deliverables/{order_id}/spec_final.md`.
- `diff.patch` (optional) — unified diff against the buyer's HTML/JSX if
  source was provided in the brief. Available at
  `/deliverables/{order_id}/diff.patch`.

Plus one free post-ship rescan via `POST /v1/cold-read/{id}/rescan`.

## Spec format (for agents consuming `spec_final.md`)

```
# {url} — review, {iso-date}
> {one-line executive summary}

## Top-N fixes, ranked
1. [{P0|P1|P2}] {title} — {reason} → {paste-ready change}
2. ...

## Full review
### Above the fold
### Scroll-depth
### CTAs & flow

## Copy rewrites (paste-ready)

## Constraints honored
- {original constraint and how it was respected}
```

Agents should sort by severity (`P0` first), then by position.

## What this product is not

- No retainer work.
- No Figma-only reviews — live URL or it doesn't exist.
- No brand identity / logo / illustration projects.
- No private roadmaps or closed staging environments.
- No webhooks (V1 of pilot — agents poll instead).
- No automated payment / Stripe rail (V1 of pilot — humans pay manually).

## Pricing

- `/v1/scan` — free, rate-limited.
- `/v1/cold-read-requests` — flat 3 900 kr ex moms · pilot price first 5 (4 875 kr inkl. 25 % moms via
  Frilansfinans). Per cold-read = one URL + one primary goal. 14-day net.

## Errors

All error responses are RFC 9457 `application/problem+json` (yes, even
unrouted 404s). Branch on `type` URI:

- `https://headless.design/errors/rate-limited`
- `https://headless.design/errors/invalid-input`
- `https://headless.design/errors/not-found`
- `https://headless.design/errors/conflict`
- `https://headless.design/errors/idempotency-mismatch`
- … full enum in the OpenAPI `Problem` schema.

## Discoverability — how an agent should onboard

1. Read `https://api.headless.design/.well-known/agent-card.json` (A2A v0.3.0)
2. Read `https://api.headless.design/v1/openapi.json` for the formal contract
3. Read `https://api.headless.design/llms.txt` for the technical narrative
   (more current than this file in case of drift)

## Portfolio — what Gustaf builds (separate from the cold-read product)

Gustaf operates this site as both the cold-read product and his solo portfolio.
The portfolio lives at `/portfolio` and lists projects he designs + builds:

| Project | URL | Status | What it is |
|---|---|---|---|
| Kammaren | `/portfolio/kammaren` | live · AGPL-3.0 | Open-source Swedish tax engine. LLM classifies, code computes. 978 000 test cases · 0 SEK deviation against Skatteverket. 304 golden cases CI-gated against primary sources. Constants API + 290 municipalities with statute citation + change date on every value. SHA-256 hash chain. Year-guard. Verify-as-a-service + MCP server. Bun + TypeScript. github.com/Baltsar/kammaren. |
| agent.opensverige.se | `/portfolio/agent-opensverige` | live · free | 30-second agent-readiness scanner for any Swedish website. Pre-Cloudflare raw server. |
| OpenSverige | `/portfolio/opensverige` | live · open · grassroots | "Sweden has conferences. We have a workshop." Grassroots tool-agnostic Swedish builder community — Discord (384, 90 online), Facebook group (146), LinkedIn group (84), and IRL meetups every Sunday 14:00 in Stockholm, Gothenburg, Malmö. No application. No paywalls. Ever. GitHub: github.com/opensverige. Founded January 2026 (week of OpenClaw release). Becoming a non-profit (ideell förening), seeking institutional support to back Swedish builders. Self-described as "kalsongkodare som löser komplexa problem." See opensverige.se/varfor for the full manifesto. |
| grunden.ai | `/portfolio/grunden-ai` | wip | Branding-from-the-ground service — landing pages + decks, fast. |
| Frilanspengen | `/portfolio/frilanspengen` (EN canonical) · `/sv/portfolio/frilanspengen` (SV) | wip · silent · live in preview | Independent comparison of Swedish umbrella employment companies (egenanställningsbolag). The category lacked an independent voice. 14 companies, 26 fields, span-match per value (refusal-as-feature: empty over wrong). Weekly autonomous pipeline: Vercel Cron → Inngest fan-out × 14 → tiered LLM extraction (regex / Gemini Flash-Lite / Claude Opus 4.7) → span-match validation → 3-prompt PolicyGapper → Supabase + MCP server. ~95% cost reduction via hash-skip + Batch API + prompt caching. Public launch June 2026. |
| headless.design (meta) | `/headless` | live · meta-case | Meta-case study of this site itself. 7 years AMF → 4 months solo · 4 products live · 150+ community · 0 SEK deviation in Kammaren against Skatteverket. The "outsource execution, keep understanding" thesis as a case. |

Each detail page exposes Schema.org `CreativeWork` (or `Organization` for OpenSverige) JSON-LD. Full case-study Markdown lives in `/llms-full.txt`.

## Meta-case — /headless

A self-referential case study of headless.design. Same template as the
portfolio pages (`/portfolio/kammaren` is the canonical template). Tells
how Gustaf went from 7 years in-house at AMF to solo headless designer
in 4 months, with 4 products live (Kammaren, OpenSverige, agent.opensverige.se,
grunden.ai) and a 150+ community. Linked from `/about` footer
("→ hela storyn"). Key facts agents may quote:

- 7 years at AMF as digital designer → solo Apr 2026
- 4 products shipped in 4 months solo
- 150+ Swedish AI builders in OpenSverige Discord
- 0 SEK deviation in Kammaren against Skatteverket (978k test cases)
- agent.opensverige.se — flagship of OpenSverige; pre-Cloudflare; makes
  sites agent-ready

## Contact

- Operator: Gustaf Garnow — `gustaf@headless.design`
- Stockholm, Sweden (CET / UTC+1 / UTC+2 DST)
- Reply within ~hours during weekdays. Async after.
- Bug reports + spec disagreements: same email, subject prefix `[bug]` or `[spec]`.
