# Krawl Agent Authentication

This document tells autonomous agents how to obtain and use credentials for the
Krawl research API at `https://api.krawl.sh`. It follows the WorkOS `auth.md`
convention (https://workos.com/auth-md) and the `agent_auth` discovery model.

Krawl supports three credential paths, in increasing order of setup cost:

1. **Anonymous pay-per-use** — no account. Pay per request with x402 (USDC on Base).
2. **Demo key** — a free, rate-limited `X-API-Key`, issued instantly with no signup.
3. **Managed key** — a durable `krawl_live_...` key tied to a billing plan.

## Discover

Discovery metadata lives at well-known URLs:

- Protected-resource metadata (RFC 9728):
  `https://api.krawl.sh/.well-known/oauth-protected-resource`
- Authorization-server metadata (RFC 8414), including the `agent_auth` block:
  `https://api.krawl.sh/.well-known/oauth-authorization-server`
- Machine-readable agent profile: `https://krawl.sh/agent.json` (or `https://krawl.sh/?mode=agent`)
- OpenAPI spec: `https://api.krawl.sh/openapi.json`

An unauthenticated request to a protected endpoint returns `401` (or `402` when
x402 is enabled) with a `WWW-Authenticate` header pointing back here.

## Pick a method

| `identity_type` | Method | When to use |
|-----------------|--------|-------------|
| `anonymous` | x402 micropayment (`credential_types_supported: ["x402"]`) | One-off calls, no account, willing to pay USDC per request |
| `anonymous` | demo key | Quick evaluation, low volume, free |
| `identity_assertion` | managed API key | Production use, higher quota, billing |

The `agent_auth` block in the AS metadata advertises these via
`identity_types_supported` and the per-type `credential_types_supported`.

## Register

Programmatic registration of a demo credential — no human, no signup:

```
POST https://api.krawl.sh/auth/demo-key
Content-Type: application/json
```

Response:

```json
{ "api_key": "krawl_demo_xxx", "quota": { "deep_per_month": 5 }, "expires_in": "~24h" }
```

This endpoint is the `register_uri` advertised in the AS metadata `agent_auth`
block. For a managed key, a human registers a plan at `https://krawl.sh` and
(optionally) an admin mints keys via `POST /auth/keys` with an `X-Admin-Key`.

## Claim

Demo keys are returned directly in the registration response — there is no
separate claim step. The `claim_uri` therefore points back at the demo-key
endpoint; an `OPTIONS` preflight against it resolves (it is not a 404). For
managed keys, the key string shown at issuance is the claim.

## Use the credential

Send the key in the `X-API-Key` header:

```bash
curl -N https://api.krawl.sh/research \
  -H "X-API-Key: krawl_demo_xxx" \
  -H "Content-Type: application/json" \
  -d '{"query": "state of AI agents in 2025", "mode": "deep"}'
```

Or pay anonymously with x402 — omit the key, receive `402` with
`PaymentRequirements`, sign an EIP-3009 USDC authorization, and retry with a
base64 `X-PAYMENT` header. See `https://krawl.sh/agent.json` (`authentication.x402`).

The same credentials authenticate the MCP server at `https://api.krawl.sh/mcp`.

## Errors

| Status | Meaning | Action |
|--------|---------|--------|
| `401` | Missing/invalid/revoked key | Re-register via `register_uri` or supply a valid key |
| `402` | Payment required (x402) | Read `accepts[]`, sign payment, retry with `X-PAYMENT` |
| `403` | Admin-only operation | Use an `X-Admin-Key` |
| `429` | Rate limit / quota exceeded | Back off; upgrade plan or wait for quota reset |

Error bodies are JSON with an `error_code`, `message`, and optional `retry_after`.

## Revocation

A key holder can revoke their own key (self-service):

```
DELETE https://api.krawl.sh/auth/keys
X-API-Key: krawl_live_xxx
```

This is the `revocation_uri` advertised in the AS metadata. Revocation is
immediate; subsequent requests with the revoked key return `401`.

---

Spec anchors: `agent_auth`, `register_uri`, `claim_uri`, `revocation_uri`,
`identity_assertion`, `id-jag`, `WWW-Authenticate`. Reference:
https://workos.com/auth-md
