# PeopleProof HTTP contract (provisional name)

Prelaunch: only future-use interest registration. No studies, panel, results, prices, launch date, payments or MCP server. Results first. Payment only after your agent validates them. Receipt alone and silence are not acceptance.

1. GET /service.json. `real_intention_capture=false` means only explicitly marked tests are accepted. The privacy controller must be configured before real capture.
2. Generate a cryptographically random 32-byte capability locally, encoded as unpadded base64url (43 characters). Keep it secret. Generate a separate UUIDv4 Idempotency-Key. Never put capabilities in URLs. HTTPS required in production.
3. POST /v1/intentions with `Authorization: Bearer <capability>`, `Idempotency-Key: <UUIDv4>`, `Content-Type: application/json` and a JSON object following /openapi.json.

Explicitly synthetic example body (exclude from demand):
```json
{"need_summary":"Synthetic comparison of travel planning concepts","audience":"People planning a short trip","use_case":"agent_build","horizon":"unknown","recurrence":"unknown","budget":"unknown","currency":"unknown","integration":"HTTP","source":"directed_test","authorized":true,"prelaunch_ack":true,"is_test":true}
```
A genuine authorized need must use is_test=false when capture is enabled. No confidential/personal/sensitive data, names, emails or URLs in free text; no secrets, files or callbacks. Optionally include `notification_email` (ASCII address, maximum 254 characters, local part maximum 64) with `notification_consent:true` only with the email owner’s explicit consent to one availability notice. Omit both to opt out. Empty email with absent/false consent is also valid. Consent without email, invalid email or email without true consent returns 422. No marketing, no email is sent now, and the privacy gate applies equally to emails. The email and consent share the existing private record’s 30-day lifetime and DELETE withdrawal. Receipts are capability-protected and may contain the email; never publish them. Budget is optional/unknown and never spending authority. No extra fields. See OpenAPI for enums and text limits. Free text checks cannot guarantee no personal data.

201 = created. 200 = same capability/key/normalized payload replayed, same record ID. Capability is never returned by server. 409 = this capability was used with different key/data. Different capabilities cannot retrieve another record through its key/payload. New capability creates a separate record; not buyer deduplication. Retain the same capability/key/data on uncertain retry. One intention per capability. After deletion/expiry, reusing the capability can create a new record (no permanent tombstone).

4. GET /v1/receipt with Authorization returns only your record. DELETE /v1/receipt with Authorization returns 204; later GET returns 404. No list API. Records expire in 30 days, purge runs hourly and on API use. Capability loss cannot be recovered; anyone holding it can read/delete. Protect agent-host histories too.

Limits: body 4096 bytes measured during streaming. No compressed bodies. 60 authenticated requests/IP/hour, 120/capability/hour. Invalid requests after authentication count. 429 includes Retry-After. Same-origin browser access only, no CORS. Agents may omit Origin; if present it must exactly match service origin. Query strings rejected.

Errors: 400 malformed JSON/UTF-8/query; 401 malformed/missing bearer; 403 origin; 404 absent/expired/deleted; 405 method; 409 conflict; 413 body; 415 media/encoding; 422 validation/idempotency; 429 rate limit; 503 privacy/setup/temporary failure. Error body is `{ "error": "message" }`.

MCP: NOT IMPLEMENTED in this Cloudflare build. /mcp returns 501. MCP preference is demand only, not a connector. The separate Python prototype is not this deployment. /llms.txt is a reading index, not guaranteed discovery.

Full HTML docs: /docs/. Privacy/controller status: /privacy/.
