
# Authentication & payment

Baton serves two kinds of caller — autonomous agents and developers — and there are **two ways in**, told apart by *what is funded*. Each bundles three things: who you are (**identity**), how you pay (**payment**), and how you make calls (**calls**). Identity and payment are separate questions — but in practice they pair up as the two paths below. There is one stable customer identity underneath either path, so you can use both and keep a single ledger and history.

## A — Wallet

- **Identity:** your wallet. To *read* your account and history without re-signing every request, hold a session via **wallet-JWT**: request a challenge, sign it with an EIP-191 `personal_sign` (not the EIP-712 signature payment uses), and exchange it for a short-lived bearer token. This is **authentication only — not a way to pay**; there is no wallet balance to debit.
- **Payment:** **x402 per-call.** You sign a USDC or EURC payment authorization (an EIP-712 signature over EIP-3009) and send it with each call. The wallet that signs *is* your identity. No account, no balance to manage.
- **Calls:** the **HTTP API** with an `X-Payment` header — one call carries the payload and the payment. This is the lodestone; see [x402 wire format](/docs/x402) and [the lodestone](/docs/lodestone).

```bash
# wallet-JWT (reads only): challenge → sign → verify → bearer token
curl "https://api.relaystation.ai/v1/auth/challenge?wallet=0x..."
curl -X POST https://api.relaystation.ai/v1/auth/verify \
  -H "Content-Type: application/json" \
  -d '{"walletAddress":"0x...","nonce":"...","signature":"0x..."}'
# → { "token": "...", ... }  — send as: Authorization: Bearer <token>
```

The token comes back in the body, not a cookie — agent-friendly. Use it to read `/v1/account` and your history; to *pay*, you still sign an x402 authorization per call.

## B — Google / GitHub sign-in (OAuth)

- **Identity:** an **OAuth account + API key.** Sign in at [app.relaystation.ai](https://app.relaystation.ai) with Google or GitHub, and mint an API key (prefixed `rs_live_`).
- **Payment:** a **Stripe-funded balance** — top up with a **card or crypto**; each call debits the balance. No recurring charge, no minimum.
- **Calls:** the **HTTP API** (send the key as `Authorization: Bearer rs_live_...`) **or** an **MCP client**. An MCP client authenticates either by **OAuth approval** — connect the server as a connector and approve in your browser — **or** by pasting your `rs_live_` key. OAuth is **not dashboard-only**: it authorizes programmatic MCP access too, so an agent on an MCP client can act as your account without handling a raw key.

## One identity, two ways

There are **two ways to fund** — x402 per-call, or a Stripe-funded balance. That's it. x402 is a **payment** path, not a third kind of login, and there is no "funded wallet" you deposit into. Whichever path you use, your customer identity and ledger are the same — you can move between them without losing history.
