# Stack Facts with curl: a free try, then a 402 decoded

Every paid route of Stack Facts first answers `402 Payment Required` with the price in a `PAYMENT-REQUIRED`
header (x402 v2). You need `curl`, `base64` and `python3` (for pretty JSON). No account or API key.
Dates and the `payTo` address in the sample answers will differ from yours.

Set the base URL once:

```sh
BASE=https://g5joilnmeep4ntz3nwezxt5dmu.srv.us
```

## 1. Free: a signed sample answer

`/v1/try/eol` is free and has the same shape as the paid `/v1/eol/{product}` (it always answers for nodejs).

```sh
curl -s "$BASE/v1/try/eol"
```

```text
{"data":{"product":"nodejs","label":"Node.js","cycles":[{"cycle":"26","eol":"2029-04-30","latest":"26.11.1", …
```

Every answer is `{data, meta}`; `meta` names the snapshot, its sha256 and an Ed25519 signature you can check against
`/v1/keys`.

## 2. Paid: the 402 offer

The same call on the paid route, with `-i` to see the status line and headers. Errors and 402s are never charged.

```sh
curl -si "$BASE/v1/eol/nodejs" | grep -iE '^(HTTP/|payment-required:|cache-control:)' | cut -c1-80
```

```text
HTTP/1.1 402 Payment Required
cache-control: no-store
payment-required: eyJ4NDAyVmVyc2lvbiI6MiwiZXJyb3IiOiJQQVlNRU5ULVNJR05BVFVSRSBoZW
```

## 3. Decode the offer

`PAYMENT-REQUIRED` is standard base64 of UTF-8 JSON (the 402 body holds the same JSON, so
`curl -s "$BASE/v1/eol/nodejs"` shows it too).

```sh
curl -s -o /dev/null -D - "$BASE/v1/eol/nodejs" | grep -i '^payment-required:' | cut -d' ' -f2 | tr -d '\r' | base64 --decode | python3 -m json.tool --no-ensure-ascii
```

The output, with `extensions` cut (it holds `bazaar`, the route's input and output schema with an example answer,
and `payment-identifier`, for safe retries):

```json
{
  "x402Version": 2,
  "error": "PAYMENT-SIGNATURE header is required",
  "resource": {
    "url": "https://g5joilnmeep4ntz3nwezxt5dmu.srv.us/v1/eol/nodejs",
    "description": "List every release cycle of a product (Node.js, Python, Ubuntu…) and if it is still supported: EOL (end-of-life) date, support status, LTS, latest version.",
    "mimeType": "application/json"
  },
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:8453",
      "amount": "3000",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "payTo": "<PAYTO_ADDRESS>",
      "maxTimeoutSeconds": 60,
      "extra": {
        "name": "USD Coin",
        "version": "2"
      }
    }
  ]
}
```

Read it as: pay `amount` = 3000 atomic units of USDC (6 decimals, so $0.003) at `asset` (USDC on the chain named in
`network`) to `payTo`, using the `exact` scheme (an EIP-3009 transferWithAuthorization signed with the
EIP-712 domain `extra.name` / `extra.version`), within `maxTimeoutSeconds`.

## 4. Pay

Paying means signing that authorization with a wallet, so it is not a curl one-liner. Build the PaymentPayload
(`x402Version`, `resource`, `accepted` = the accepts entry, `payload` = `{signature, authorization}`), base64 its
JSON and call again:

```text
curl -s -H "PAYMENT-SIGNATURE: <base64 PaymentPayload>" "$BASE/v1/eol/nodejs"
```

The answer is a 200 with the data and a `PAYMENT-RESPONSE` header (base64 JSON with the settlement `transaction`).
Two complete clients do this step: `fetch-x402.mjs` (Node, no dependencies) and `python_x402.py` (Python standard
library), next to this file. Add your signer to pay. The stock
x402 client for JavaScript is `@x402/fetch`.
