# AGENTS.md — CRYPTOCARDS.GG public API

> This file is **public API documentation for AI agents and developers** who
> want to consume CryptoCards.gg data programmatically. It is served at
> <https://cryptocards.gg/AGENTS.md>. (It is *not* the repository's internal
> contributor rules.)

CryptoCards.gg is an independent, side-by-side index of every crypto debit card
on the market — fees, ATM limits, cashback, custody, and banking rails. All of
the comparison data is available as a free, public, read-only JSON API.

## Base URL

```
https://api.cryptocards.gg
```

No API key, no auth, no sign-up. CORS is open (`Access-Control-Allow-Origin: *`),
so you can call it directly from a browser, a server, or an agent tool.

## Endpoints

| Method & path | Returns |
| --- | --- |
| `GET /` | `{ "cards": [ … ] }` — the full comparison dataset |
| `GET /rss` | RSS 2.0 feed, one `<item>` per card |

Responses are served from a stale-while-revalidate edge cache (~1-minute fresh
window, refreshed in the background) and pretty-printed (2-space indent). Only
`GET` is supported.

## Response shape

`GET /` returns a single object with a `cards` array. Cards are listed in the
canonical column order of the source spreadsheet.

```jsonc
{
  "cards": [
    {
      "name": "COCA",                 // card / product name
      "issuer": "Wirex",              // card issuer
      "banking": "Wirex",             // banking rails (null if unknown; may start with "?" if uncertain)
      "avgFee": -1,                   // avg total fee as a % — number (2-dec rounded), or null
      "url": "https://…",             // website / sign-up URL
      "specs": {                      // every comparison row, keyed by its label
        "KYC": true,                  // booleans for yes/no specs
        "Self-custodial": true,
        "Top-up fee": "0%",           // rich strings kept verbatim
        "ATM daily limit": "€850/day/account",
        "Card daily limit": "$30,000",
        "Cashback": "1.00%"
        // …~30 specs total
      }
    }
    // …one object per card
  ]
}
```

### Field notes

- **`avgFee`** is a **number** representing a percentage, rounded to two decimals
  (e.g. `-1`, `2.1`, `4.22`), or `null` when not computed. Negative means net
  cashback.
- **`specs`** values are adaptively typed:
  - `true` / `false` for yes/no rows,
  - `null` for blank cells,
  - bare numbers for purely numeric cells,
  - otherwise a cleaned string. Rich values like `"0% on stablecoins / 2-5% else"`,
    `"∞"`, or `"€850/day/account"` are preserved exactly — never lossily coerced.
- **Line breaks** inside any string are encoded as `\n` (newline characters),
  not `<br>`. Render or strip them as you see fit.
- **Strings are literal UTF-8** (`€`, `∞`, `—`) — there are no `\uXXXX` escapes.
- **Spec labels and card names can change** over time (they are editor-owned).
  Match on the data you need defensively; don't assume a fixed label set.

## Examples

cURL:

```bash
curl https://api.cryptocards.gg
```

JavaScript (fetch):

```js
const { cards } = await fetch('https://api.cryptocards.gg').then(r => r.json());
const cheapest = cards
  .filter(c => c.avgFee != null)
  .sort((a, b) => a.avgFee - b.avgFee)[0];
console.log(cheapest.name, cheapest.avgFee);
```

Python:

```python
import urllib.request, json
cards = json.load(urllib.request.urlopen("https://api.cryptocards.gg"))["cards"]
for c in cards:
    print(c["name"], c["avgFee"], "| banking:", c["banking"])
```

## Usage & attribution

- The data is provided as-is for informational use; verify card terms with the
  issuer before acting on them. Figures change frequently.
- Please cache responses (the edge TTL is ~1 min — there's no benefit to
  hammering the endpoint) and identify your agent/app via a `User-Agent`.
- Attribution to **CryptoCards.gg** (<https://cryptocards.gg>) is appreciated.

For a human-readable comparison, see <https://cryptocards.gg>. For a feed,
subscribe to <https://api.cryptocards.gg/rss>.
