# auth.md: writelikehuman.app

You are an agent. This service supports **agentic registration** (the [auth.md](https://github.com/workos/auth.md) profile, anonymous method): discover → register → exchange for an access_token → call the API → handle revocation.

You do not need to register to use this site: the rules (https://writelikehuman.app/rules.md), the pattern catalog, the checker (POST https://writelikehuman.app/check) and the MCP server (https://writelikehuman.app/mcp) are open, with limits of 30 checker or MCP calls a minute per IP. Register when you want your calls tied to an identity, or to sign requests with Web Bot Auth.

## Step 1: Discover

```http
GET /.well-known/oauth-protected-resource
GET /.well-known/oauth-authorization-server
```

The authorization server metadata has an `agent_auth` block: `identity_endpoint` https://writelikehuman.app/agent/identity, `identity_types_supported` ["anonymous"], token endpoint https://writelikehuman.app/oauth/token, revocation endpoint https://writelikehuman.app/oauth/revoke.

## Step 2: Pick a method

Only **anonymous** is enabled. There are no user accounts here, so `service_auth` and `identity_assertion` answer `service_auth_not_enabled` / `identity_assertion_not_enabled`.

## Step 3: Register

```http
POST /agent/identity
Content-Type: application/json

{ "type": "anonymous" }
```

Response (200):

```json
{
  "registration_id": "reg_...",
  "registration_type": "anonymous",
  "identity_assertion": "<service-signed JWT>",
  "assertion_expires": "…",
  "pre_claim_scopes": ["check", "mcp"],
  "post_claim_scopes": ["check", "mcp"],
  "claim_url": "https://writelikehuman.app/agent/identity/claim"
}
```

At most 10 registrations a day per IP.

## Step 4: Claim ceremony

Skip it. With no accounts there is nothing to claim: the scopes are already complete, and `POST /agent/identity/claim` answers `claim_not_required`.

## Step 5: Exchange the assertion

```http
POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&assertion=<identity_assertion>
```

Response: `{"access_token": "…", "token_type": "Bearer", "expires_in": 3600, "scope": "check mcp"}`. The assertion lasts 24 hours and can mint more tokens until then.

## Step 6: Use the access_token

`Authorization: Bearer <access_token>` on POST /check and POST /mcp. An invalid token answers 401 with `WWW-Authenticate: Bearer resource_metadata="https://writelikehuman.app/.well-known/oauth-protected-resource"`. `GET /agent` shows how the site sees you.

## Step 7: Revocation

```http
POST /oauth/revoke
Content-Type: application/x-www-form-urlencoded

token=<access_token or pass>
```

Access tokens also expire after an hour.

## Other ways in

- **OAuth client**: `POST /oauth/register` (RFC 7591) with `{"client_name": "…"}`, then `grant_type=client_credentials`; or the authorization code flow with PKCE (S256) at /oauth/authorize for a public client with `redirect_uris`.
- **Web Bot Auth**: sign requests (RFC 9421, Ed25519, tag `web-bot-auth`) and send `Signature-Agent` pointing at your key directory. The result is in the `X-Agent-Verified` response header.

## The early-bird pass

A free 30-day pass for agents. Send it as a Bearer token to /check (or MCP check_text) and each report comes back signed by writelikehuman.app, so anyone can verify that the text was checked here (keys at /.well-known/jwks.json). Free pass, not a sale: no price, no payment, no invoice.

```http
POST /ucp/v1/checkout-sessions
Content-Type: application/json

{"line_items": [{"item": {"id": "early-bird-pass"}, "quantity": 1}]}
```

Then `POST /ucp/v1/checkout-sessions/{id}/complete` with an empty body. The pass is in `pass.token`. Free pass, not a sale: no price, no payment, no invoice. Nothing is asked in return and no buyer data is collected. At most 10 signed checks a day per pass and 10 passes a day per IP.
