# Authentication

Free endpoints and free MCP tools need nothing. A paid call needs one of three things: an API key, a sign-in from an MCP client, or an x402 payment. The first two draw on the same monthly quota.

## API key

Create a key at [iposignal.xyz/account](https://iposignal.xyz/account). Send it on every paid request, in either header:

```http
Authorization: Bearer ips_live_YOUR_KEY
```

```http
X-API-Key: ips_live_YOUR_KEY
```

| Plan | Calls a month |
| --- | --- |
| Free account | 250 |
| Subscription | 10,000 |

- The quota belongs to the account, not to a key: all of an account's keys draw on one allowance.
- It resets on the 1st of each month, UTC.
- Only a delivered `200` is counted. The `X-API-Quota-Remaining` response header carries what is left.
- When the quota is spent, the call is not refused outright: it answers `402` with x402 terms, and the `error` field says the quota ran out. A client that can pay continues; one that cannot stops there until the reset.
- An unknown or revoked key answers `401`.
- A key is `ips_live_` followed by 43 characters. We store only its SHA-256 hash.

[Plans and prices](https://iposignal.xyz/pricing).

## Sign in from an MCP client (OAuth)

MCP clients such as Claude, ChatGPT, Cursor and VS Code connect to `https://iposignal.xyz/api/oauth/mcp` without a key. The client opens a browser, you sign in to IPOSignal and approve the connection, and from then on its calls to premium tools use your account's quota, exactly as an API key's would.

- You see a consent page naming the app and where your browser goes next. Approve only a connection you started.
- Connected apps are listed on your [account page](https://iposignal.xyz/account), where you can disconnect any of them.
- A connection is for the MCP server only. The HTTP endpoints take an API key.

For client developers: this is OAuth 2.1 with PKCE (S256) and dynamic client registration.

| Document | URL |
| --- | --- |
| Protected resource metadata (RFC 9728) | `https://iposignal.xyz/.well-known/oauth-protected-resource/api/oauth/mcp` |
| Authorization server metadata (RFC 8414) | `https://iposignal.xyz/.well-known/oauth-authorization-server` |

Access tokens last one hour. Refresh tokens are single-use: each refresh returns a new one, and presenting a used one ends the connection.

## x402: pay per call, no account

[x402](https://docs.x402.org) is an open protocol for paying for an HTTP request. It suits an autonomous agent that holds a wallet. Payment is in USDC on Base (network `eip155:8453`).

1. Call a paid endpoint with no key. It answers `402`. The JSON body, repeated base64-encoded in the `PAYMENT-REQUIRED` header, states the price, the asset, the network and the recipient.
2. Your x402 client signs a payment for that amount and retries with it in the `PAYMENT-SIGNATURE` header.
3. We verify the payment, look the data up, and settle only if there is a result to deliver. The response carries the settlement receipt in the `PAYMENT-RESPONSE` header.

A paid request that finds nothing returns `404` and the payment is never settled.

## On the MCP server

- **Sign-in:** point the client at `https://iposignal.xyz/api/oauth/mcp`. It answers `401` until the client has signed you in.
- **API key:** send the same `Authorization: Bearer` header when the client connects, to either MCP URL. Premium tools are then covered by the quota.
- **x402:** on `/api/mcp`, which needs no credential, an unpaid premium tool returns the payment terms as a tool result marked `isError`, with the terms in `structuredContent`. The client retries the call with the signed payment in `_meta["x402/payment"]`, and the paid result carries the receipt in `_meta["x402/payment-response"]`.

Setup for each client is in [MCP server](https://iposignal.xyz/docs/mcp.md).