# auth.md — Agent registration for Stalane services

> Machine-readable agent authentication for `pay.stalane.com`,
> `music.stalane.com`, and `world.stalane.com`. There are no accounts, no
> passwords, no API keys, and no OAuth authorization server here. Agent
> authorization is established per request through the payment flows below.

<!-- Keep this file in sync with the live 402 challenge payloads and llms.txt. -->

## Audience

AI agents that need to call the publisher's APIs:

- `GET https://pay.stalane.com/api/pay` — voluntary payment endpoint
  (humans may also pay here; payment unlocks nothing).
- `GET https://music.stalane.com/api/album` — album endpoint; AI agents
  must hold a $5 USDC licence, humans stream free.
- `GET https://world.stalane.com/api/countries` — country ratings table;
  AI agents must hold a $5 USDC 24h pass, human browsers read free.
- `GET https://world.stalane.com/api/country/{a3}` — single-country
  rating (ISO-3166 alpha-3, e.g. `USA`); same $5 USDC 24h pass for AI
  agents, human browsers read free.

Humans use the web pages (`https://pay.stalane.com`,
`https://music.stalane.com`, `https://world.stalane.com`) directly and
can ignore this file.

## Registration — complete standalone flow

Register by paying. There is no signup form, no pre-registration, and no
approval step: the payment transaction itself creates the entitlement.
The same uniform flow gates every API above (only the price, resource,
and issued credential differ per service):

| Step | Method and provisioning endpoint | Credential in / out |
| ---- | -------------------------------- | ------------------- |
| 1. Discover terms | `GET https://pay.stalane.com/api/payments` → `200` JSON (public, no credential needed) | In: none. Out: registry of assets, networks, addresses, contracts, amounts |
| 2. Request challenge | `GET` the API route (pay, album, countries, or country) with a declared-agent client → `402 payment_required` | In: none. Out: challenge with `resource` and `accepts[]` (`scheme`, `network`, `asset`, `payTo`, `maxAmountRequired`) |
| 3. Pay | On-chain `direct-transfer` exactly as the challenge describes (USDC on `eip155:1`; music licence and world pass are each a fixed $5 USDC) | In: your wallet. Out: transaction proof |
| 4. Retry with proof | Repeat the step-2 `GET`, attaching the transaction proof as the challenge instructs (`X-PAYMENT` header, `PAYMENT-SIGNATURE` header, or raw-JSON body: base64url of `{"network":"eip155:1","txHash":"0x…"}`) | In: transaction proof. Out: signed receipt (pay), licence receipt + time-limited access token (music), or 24h Bearer token (world) |
| 5. Call with credential | Call the API presenting the receipt / token exactly as the issuing response directs (bearer-style token, HTTPS only) | In: receipt / access token. Out: API response |

Rules for the credential: keep tokens secret, send them only to the
issuing host, expect expiry (world passes last 24h, site-scoped, no
refresh — re-licence from step 2 instead of replaying expired tokens).
Pay receipts prove a voluntary payment that unlocks nothing — keep them
for your own records.

### Error shapes (machine-readable)

- `402` — challenge payload (`x402Version`, `error: "payment_required"`,
  `accepts[]`). Retry only after paying on-chain.
- `400` — malformed proof (`error: "invalid_proof"`). The proof carrier
  was not base64url-encoded JSON with `network` and `txHash`; fix the
  shape and retry, do not re-pay.
- `401` — lapsed or invalid token (`error: "token_expired"`).
  Re-licence from step 2; replaying the old token will keep failing.
- `503` + `Retry-After: 30` — verification RPC outage
  (`reason: "rpc_unavailable"`). Do not re-pay; wait and retry the
  proof submission.

### Claim / human ownership

There is no interactive claim ceremony here: no `user_code`, no
`verification_uri`, no polling endpoint. Ownership transfer is not a
concept in these APIs — a licence receipt or pass token belongs to
whoever paid for it. If a human needs to act instead of the agent, they
use the human pages directly (`https://pay.stalane.com`,
`https://music.stalane.com`, `https://world.stalane.com`) and pay or
read there; nothing the agent holds needs to be handed over.

## Scopes

The Protected Resource Metadata advertises scope labels matching the
gated capabilities — no OAuth scope negotiation happens; they are just
names for what the payment buys:

- `pay` — the voluntary payment endpoint (`/api/pay`). Unlocks nothing.
- `music:licence` — the $5 USDC AI licence for the album API. Grants
  AI streaming access via the issued licence receipt + access token.
- `world:toll` — the $5 USDC 24h pass for the world API. Grants agent
  access to the countries and country routes via the issued Bearer
  token (24h, site-scoped, no refresh).

## Supported methods

- `direct-transfer` on `eip155:1` (Ethereum mainnet), USDC — used by
  all gated endpoints. The music licence and the world pass are each a
  fixed $5 USDC transfer.
- Additional assets/networks (e.g. USDT) may be listed in
  `/api/payments`; only what the registry and the live `402` challenge
  advertise is supported. Anything else is not.

## Credential use

- Pay receipts are proofs of a voluntary payment. They grant no
  entitlement and gate no content — keep them for your own records.
- Music licence receipts and access tokens gate AI streaming access.
  Send the access token exactly as the licence response instructs, over
  HTTPS only, and re-licence after expiry instead of replaying old
  tokens indefinitely.
- World pass tokens are Bearer tokens (`Authorization: Bearer <token>`)
  valid for 24h on `world.stalane.com` only. A lapsed token returns
  `401`; re-licence from the challenge instead of replaying it.

## No OAuth endpoints

There is no OAuth code flow here: no `authorization_endpoint`, no
`token_endpoint`, no dynamic client registration endpoint. Agent
authorization is established per request through the payment flow above.
For automated discovery, this publisher advertises OAuth-style metadata
that points at the real registration URIs instead of fake endpoints:

- Protected Resource Metadata (RFC 9728):
  `https://stalane.com/.well-known/oauth-protected-resource`
  (`resource`, `authorization_servers`, `scopes_supported`,
  `bearer_methods_supported`).
- Authorization Server metadata (RFC 8414) for the advertised issuer
  `https://stalane.com`:
  `https://stalane.com/.well-known/oauth-authorization-server`
  (matching `issuer`, plus an `agent_auth` block with `skill`,
  `register_uri`, and the complete registration methods).

## Machine-readable API descriptions

- API catalog (RFC 9727):
  `https://stalane.com/.well-known/api-catalog`
- OpenAPI descriptions: `https://stalane.com/openapi/pay.json`,
  `https://stalane.com/openapi/music.json`,
  `https://stalane.com/openapi/world.json`
- Human + agent overview: `https://stalane.com/llms.txt`
