# Agent-originated customers, with a human who agreed.

Agents already arrive at your signup page looking like fraud. Through Suffect, each one is a real human's account: your terms accepted by version and hash, a budget behind it, and a signed record you keep.

- [Read the spec](/spec)
- [For site operators](/bot)

## What a signup looks like today

- A hosted browser fills your own signup form as the human's tool, after that human approved your terms and a budget with a passkey.
- Every request is signed as Suffect (RFC 9421, Ed25519), the User-Agent ends in `SuffectRunner/0.1 (+https://suffect.com)`, and the requests your server handles carry a `Suffect-Attestation` header naming the human's signed record.
- A CAPTCHA or a two-factor step goes to the human, never solved. The account's email is an alias Suffect runs for that human, or their own address by their choice.

## Publish one file

A manifest at `https://your-domain/.well-known/suffect.json`, served from your own domain over HTTPS, tells Suffect what you sell, which documents a human must accept and how an account is created.

The hash is the sha256 of the document's text as the spec normalizes it; the spec package computes it, and the conformance check compares it with your live page.
```json
{
  "suffect": "0.2",
  "provider": {
    "name": "Example API",
    "domain": "example.com"
  },
  "terms": [
    {
      "kind": "terms_of_use",
      "url": "https://example.com/terms",
      "version": "2026-06-01",
      "sha256": "9f3c0a7e5b1d4c2a8e6f0b3d7c9a1e5f2b4d6c8a0e1f3b5d7c9a2e4f6b8d0c1e",
      "requires": [
        "age_18",
        "authority_if_entity"
      ],
      "notices": [
        "one_account_per_person"
      ]
    },
    {
      "kind": "privacy_policy",
      "url": "https://example.com/privacy",
      "version": "2026-05-02",
      "sha256": "41d7b2c9e8f1a3d5c7b9e2f4a6c8d0b1e3f5a7c9d2b4e6f8a0c1d3e5f7b9a2c4"
    }
  ],
  "pricing": {
    "currency": "USD",
    "plans": [
      {
        "id": "developer",
        "name": "Developer",
        "price": 0,
        "period": "month"
      }
    ],
    "url": "https://example.com/pricing"
  },
  "signup": {
    "level": 3,
    "endpoint": "https://api.example.com/suffect/signups",
    "auth": "suffect_jws",
    "contact_fields": [
      "email",
      "name",
      "country"
    ],
    "idempotency": true
  }
}
```

## What you publish, what you get

What you publish is read from the manifest, never negotiated; `suffect-spec check` prints the level a manifest earns.
| You publish | You get |
| --- | --- |
| nothing | agent-originated signups through Suffect's runner, the same as a human using your site; where Suffect has written a playbook for your site, the sheet names your documents by version and hash |
| a manifest with your terms and pricing | exact consent sheets worded from your own manifest, your hashes held to your pages, fewer disputes |
| a signup endpoint in the manifest | one-call signups, signed consent records stored with each account, no bot-defense collisions |
| MPP or x402 rails | per-request access for agents that do not want an account, paid from the human's budget (planned: Suffect's 402 and MPP rails are not built yet) |

## The signup endpoint

- With a signup endpoint in the manifest, Suffect posts one JSON request to it: the human's signed consent record, a five-minute attestation, the plan requested, the contact fields your manifest lists, and the credential scopes.
- You verify the attestation and the record's two proofs against `https://suffect.com/.well-known/jwks.json` and check that the record names your current terms.
- You answer 201 with the account id and the credential; 409 when the human already has an account; 422 when the terms version is stale.
- A reference endpoint in Hono ships with the spec package, and `suffect-spec check your-domain` runs the conformance steps before you publish.

## Verify every request from Suffect

- `Signature-Input` and `Signature`: an RFC 9421 signature, Ed25519, five minutes of life, a fresh nonce, the key id being the key's JWK thumbprint.
- `Signature-Agent: "https://api.suffect.com"`: the origin that publishes the key directory at `/.well-known/http-message-signatures-directory` and the Signature Agent Card at `/.well-known/signature-agent-card`.
- `Suffect-Attestation`: the same five-minute JWS a manifest signup carries; `GET https://api.suffect.com/v1/consents/by-hash/{sha256}` with it as the `Authorization` returns the record it names.

> The production service is not open yet (see [where things stand](/#questions)); the spec is at 0.2 and the conformance check runs today against any domain.

## Publish a manifest

About ten minutes of your time: the terms you already publish, named by version and hash, in one JSON file.

- [Read the spec](/spec)
- [The runner, for site operators](/bot)

---

Canonical: https://suffect.com/vendors. Every page of this site has a Markdown twin at the same path plus `.md`; the index is https://suffect.com/llms.txt.
