# headless.design

> Cold-read API for landing pages that convert. Free 15-second scan at POST /v1/scan, paid 72-hour deep-dive at POST /v1/cold-read/request (3 900 SEK ex moms). A "cold-read" is a senior outside-eyes audit — spec.md + PR-ready diff — published with permission and verified post-ship by a free re-scan.

Solo operator: Gustaf Garnow, Stockholm. Built with three adversarial Claude agents — designer, copywriter, strategist — whose conflict is the product. Premium tier adds a Playwright + Sonnet-vision pipeline and a human review from Gustaf.

## Status — pilot phase

This API is in pilot. V2 lands within ~10 days and renames the cold-read
endpoints to canonical lifecycle paths (`POST /v1/cold-read-requests` +
`GET /v1/orders/{id}`). Old paths will keep working as 308 bridges with
RFC 8594 `Sunset` headers for 60 days. Build against the V1 paths below
today; expect a re-read of `llms.txt` once V2 ships.

## Discovery

- [Manifest](https://api.headless.design/v1/manifest): Who built this and why
- [OpenAPI 3.1 spec](https://api.headless.design/v1/openapi.json): Machine-readable contract
- [Health check](https://api.headless.design/v1/ping): Liveness probe
- [Agent card](https://api.headless.design/.well-known/agent-card.json): A2A v0.3.0 discovery card (canonical filename per spec §5.6.1)
- Legacy [`agent.json`](https://api.headless.design/.well-known/agent.json) 307-redirects to `agent-card.json` until 2026-06-25

## Endpoints

### Free / Frilansfinans-paid (existing)

- [POST /v1/scan](https://api.headless.design/v1/scan): Free scan. Input: `{ url, primary_goal, audience? }`. Returns `scores` + `findings` + `chat_summary`. Synchronous, ~15s. Emits `RateLimit-Limit`/`Remaining`/`Reset` headers per IETF draft.
- [POST /v1/cold-read/request](https://api.headless.design/v1/cold-read/request): Create paid invoice. Returns `pay_url` + `status_url` + `_links`. Optional fields: `html`, `jsx`, `repo_url` for PR-ready diff. Supports `Idempotency-Key` header.
- [GET /v1/cold-read/{id}](https://api.headless.design/v1/cold-read/): Poll cold-read status. Stable enum: `pending_payment | paid | processing | draft_ready | done | expired`.
- POST /v1/cold-read/{id}/rescan: One-shot follow-up scan after the cold-read ships. Available on `_links` when `status=done` and `rescan_used=false`.
- GET /deliverables/{id}/spec_draft.md | spec_final.md | diff.patch: Raw artifact downloads. Unguessable invoice ID in path gates access.

### Pay-per-call (MPP / Tempo, agent-completable)

These endpoints accept signed Tempo credentials via `Authorization: Payment <credential>`. Without a credential they return HTTP 402 + `WWW-Authenticate: Payment` challenge. Agents speaking [MPP](https://mpp.dev) sign on Tempo (mainnet chainId 4217 or Moderato testnet 42431), retry, get 200 + `Payment-Receipt` header. No human in the loop.

- POST /v1/quick-fix: $0.10 USDC. One diagnosis + rewrite + rationale for a single UI element. Claude Haiku 4.5, no URL fetch. Same defenses as /audit (replay-guard, rate-limit, daily LLM-budget circuit breaker).
- POST /v1/audit: $0.50 USDC. 5 ranked findings (P0/P1/P2) + executive summary. 5x output budget vs quick-fix.
- POST /v1/scan-paid: $0.33 USDC. Same scanner output as the free /v1/scan, but **no per-wallet rate-limit**. For production agents that need reliable throughput. "Free for humans, paid for agents" — your wallet is the rate-limit.
- POST /v1/agents/submit: Free, marketplace seeding. Submit your own agent-callable endpoint for review.

## Delivery model — Tvåfas

Cold-read delivery is two-phase:
- `draft_ready` (~60 min after mark-paid): AI-generated spec.md available at `draft_url`. Customer gets an email + `_links.draft_result` is live. Status is still non-terminal.
- `done` (within 72h): Gustaf has QA'd every line. `final_url` + `diff_url` go live, replacing `draft_url` as the canonical deliverable. Second email ships.

Agents should relay the draft URL to the human as soon as `draft_ready` lands, then re-relay the final URL when status flips to `done`.

## For agents

This API is designed to be called by AI agents on behalf of a human, with
two hard constraints:

1. **Agents cannot pay.** `/v1/cold-read/request` returns a `pay_url` that
   serves a Swedish HTML pay page. Payment goes via Frilansfinans e-invoice
   (B2B canonical) or Swish to a private number (privatperson-only). There
   is no machine-callable payment rail in V1. The agent's job is to relay
   the URL to the human and resume polling.
2. **Free `/v1/scan` is fully agent-completable.** Use it freely.

Agents should:

1. Pass a `client` object on /v1/cold-read/request: `{ type: "agent", name: "cursor", on_behalf_of: "user@example.com" }`.
2. Include `html` or `jsx` (or `repo_url`) on /v1/cold-read/request when available — unlocks the PR-ready diff without a follow-up email round.
3. Relay `pay_url` back to the human. Mention Frilansfinans for B2B (real invoice with VAT + F-skatt) and Swish only as a privatperson shortcut.
4. Poll `status_url` at the interval in `poll_interval_sec` (60s default).
5. Follow `_links` state machine — each status returns only the actions valid for that state. `draft_ready` exposes `draft_result`, `done` adds `result`, `diff`, and (once) `rescan`.
6. Use the `chat_summary` field verbatim when relaying scan results into a chat conversation — it's formatted for that purpose (~500 chars markdown).

## Errors

All errors follow RFC 9457 `application/problem+json`. Branch on the `type`
URI (e.g. `https://headless.design/errors/rate-limited`), not on prose.
Even unrouted paths return `problem+json` 404 — no plain-text leakage.

## Pricing

- `/v1/scan`: free (rate limits — 3 per URL/day, 50 per IP/day, 100 global/day)
- `/v1/cold-read`: 3 900 SEK ex moms.
  - Frilansfinans path (B2B canonical): 4 875 SEK inkl. 25 % moms, faktura med F-skatt + moms-reg-nr, 14-dagars netto.
  - Swish path (privatperson): 3 900 SEK direkt, ingen moms, inget kvitto för bokföring.

## Contact

- Gustaf Garnow — gustaf@headless.design
- Based in Stockholm, Sweden
- Does custom work for founders serious about conversion
