# Set up Stillroach token checks (Roach Agent API)

You are an AI agent adding Solana token holder reads to your own tools. This guide is the full contract in plain markdown. Human docs: https://app.stillroach.com/docs

## Base URL

- API: `https://api.stillroach.com`
- All API paths below are on this host only.
- Machine-readable contract: `https://api.stillroach.com/openapi.json` (OpenAPI 3.1)
- x402 discovery: `https://api.stillroach.com/.well-known/x402`

Server-side clients should send no `Origin` header. Browser origins other than stillroach.com get `403 origin_not_allowed`.

## Pick a way to pay

1. **x402 pay-per-call** (no account, no key): USDC on Solana, settled per request. Best for agents with an x402 wallet.
2. **API key with credits**: sign in with a Solana wallet at https://app.stillroach.com/watch#keys, get a key `rk_live_...`, send it as `Authorization: Bearer <key>`.
3. **MCP**: the same reads as tools over HTTP at `/mcp`, with the API key.

## Pricing

| call | x402 (USDC) | API key |
|---|---|---|
| `lite` read (fresh or cached) | 0.02 | 3 fresh a day free, then 1 credit; cached 0 |
| `full` read, fresh | 0.08 | 1 credit |
| `full` read, cached | 0.02 | 0 |
| AI read on a `full` call (`include_ai: true`) | +0.04 | +1 credit |
| `basic` read (cached summary, API key or MCP only) | n/a | free |

x402 payment settles only after a successful scan. A failed scan settles nothing.

Free daily checks: 3 fresh lite reads a day with a key, and the `basic` read is free. Wallet-signed keys get up to 10 free credits a month.

Refills every 30 days from your start date. Your start date is your Bag Watch plan start, the day your $STILL tier was first granted, or your first key. Full pool from day one, unused monthly credits do not roll over, pack credits are separate. `GET /v1/quota` returns `pool_resets_at`.

Credit packs: 100 credits for 0.05 SOL, 5 USDC, or $STILL at 20% off (`GET /v1/packs`). Bag Watch includes 400 credits a month (Watch+ 1,000).

## Depths

- `lite` (~1-2 s): top-10 holder share, dev stake, launch buy and dev sold, tracked callers (KOL wallets), basic flags.
- `full` (~20-45 s): everything in lite plus linked-wallet groups, snipers, bundles, dump impact, wallet memory, verdict codes.

## Request body

Both `POST /x402/v1/token-analysis` and `POST /v1/token-analysis` take JSON:

```json
{"mint": "<Solana token mint, base58>", "depth": "lite", "include_ai": false, "max_data_age_seconds": 600}
```

- `mint` (required): base58, 32-44 chars.
- `depth`: `lite` or `full` (default `full`); the keyed endpoint also accepts `basic`.
- `include_ai`: `full` only.
- `max_data_age_seconds` (full reference): 0-3600, default 600. A cached scan up to this age is served and priced as cached.

Unknown fields are rejected with `400 bad_input`.

## x402 flow

```bash
# 1. Ask. The first reply is 402 with a PAYMENT-REQUIRED header (base64 JSON, x402 v2, scheme "exact", Solana).
curl -s -i -X POST https://api.stillroach.com/x402/v1/token-analysis \
  -H 'content-type: application/json' \
  -d '{"mint":"<token mint>","depth":"lite"}'

# 2. Your x402 client signs the payment in PAYMENT-REQUIRED and you retry the same body
#    with the PAYMENT-SIGNATURE header, within 120 s.
curl -s -i -X POST https://api.stillroach.com/x402/v1/token-analysis \
  -H 'content-type: application/json' \
  -H "PAYMENT-SIGNATURE: $PAYMENT_SIGNATURE" \
  -d '{"mint":"<token mint>","depth":"lite"}'

# 3. 200: body schema roach.analysis.v1, plus a PAYMENT-RESPONSE header once settled.
```

A payment signature is valid for one request only. Reusing it for a different body gives `409 payment_for_another_request`.

## API key flow

```bash
# Get a key at https://app.stillroach.com/watch#keys (wallet sign-in; the key is shown once).
# Store it in a secret store, never in a prompt or a repo.

curl -s -X POST https://api.stillroach.com/v1/token-analysis \
  -H "Authorization: Bearer $ROACH_API_KEY" \
  -H 'content-type: application/json' \
  -d '{"mint":"<token mint>","depth":"lite"}'

curl -s https://api.stillroach.com/v1/quota -H "Authorization: Bearer $ROACH_API_KEY"
```

Agents without a browser can create a key programmatically: `POST /v1/keys/nonce` returns a Sign-In-With-Solana message; sign it and `POST /v1/keys`. Creating a key replaces the previous one. `DELETE /v1/keys/current` revokes it.

## MCP

Streamable HTTP, stateless JSON-RPC: POST only, no SSE, no session. Endpoint `https://api.stillroach.com/mcp`, header `Authorization: Bearer <key>`. Without a key only `check_solana_token_basic` works.

Tools: `check_solana_token_basic`, `check_solana_token_lite`, `analyze_solana_token`, `watch_report`, `alerts_since`, `get_quota`, `get_credit_packs`.

```bash
claude mcp add --transport http roach https://api.stillroach.com/mcp --header "Authorization: Bearer $ROACH_API_KEY"

curl -s https://api.stillroach.com/mcp -H "Authorization: Bearer $ROACH_API_KEY" -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_quota","arguments":{}}}'
```

Out of credits: tool results carry `isError` with `pack_url` and `x402_url`. More client setups: https://api.stillroach.com/docs/mcp-setup.md

## Other endpoints

| method | path | what |
|---|---|---|
| GET | `/v1/health` | liveness |
| GET | `/v1/packs` | credit pack prices |
| POST | `/v1/packs/quote`, `/v1/packs/verify` | buy a 100-credit pack on-chain |
| GET | `/v1/watch/report/{mint}` | Bag Watch report (Watch plan) |
| GET | `/v1/alerts` | Bag Watch alerts since a cursor (Watch plan) |
| GET/POST/DELETE | `/v1/webhooks` | alert webhooks, max 3 (Watch plan) |

## Limits

- 60 calls/min and 600/hour per wallet, shared between REST and MCP.
- Every 429 has a `Retry-After` header. Wait that many seconds.

## Errors

Errors are JSON: `{"error": "<code>", "message": "..."}`.

| status | code | meaning / what to do |
|---|---|---|
| 400 | `bad_input`, `bad_json` | fix the body (mint format, depth, unknown fields) |
| 401 | `key_required`, `bad_key` | send a valid `Authorization: Bearer` key |
| 401 | `bad_nonce`, `bad_signature` | key creation: get a fresh nonce and sign again |
| 402 | (x402 challenge) | pay per the PAYMENT-REQUIRED header and retry |
| 402 | `payment_not_verified`, `settle_failed` | payment rejected; nothing was charged for the scan, get a new challenge |
| 402 | `watch_required` | endpoint needs a Bag Watch plan |
| 403 | `origin_not_allowed` | browser origin refused; call from a server with no Origin |
| 404 | `not_found`, `not_watched` | unknown path, or the coin is not on your watch list |
| 405 | `method_not_allowed` | wrong HTTP method (for example GET on `/mcp`) |
| 409 | `in_progress` | the same scan is running; retry shortly |
| 409 | `challenge_used`, `payment_for_another_request` | a payment is single-use and bound to one request |
| 409 | `ai_unavailable` | AI read not available for this call |
| 413 | `too_large` | body too large |
| 422 | `idempotency_mismatch` | same Idempotency-Key with a different body |
| 429 | `rate_limited`, `quota_exhausted`, `free_lite_used`, `key_daily_cap` | slow down per Retry-After, buy a pack, or pay with x402 |
| 502 | `scan_failed` | upstream scan failed; x402 settles nothing; retry later |
| 503 | `busy`, `capacity`, `rpc_unavailable`, `facilitator_unavailable`, `ai_unavailable` | temporary; retry after Retry-After |
