# Developers

> pay server and pay catalog — gate an API with stablecoin payments, then make it discoverable.

The Developers group covers the publisher side: run a payment gateway in front of your service, then publish a provider entry so agents can discover it.

For the narrative ("how do I gate my API and ship it?") see [Building with pay → Getting started](/docs/building-with-pay/getting-started). This page is the syntax reference.

## `pay server`

Gate your API with stablecoin payments.

```sh
pay server <subcommand>
```

| Subcommand                                   | Purpose                                           |
| -------------------------------------------- | ------------------------------------------------- |
| [`demo`](#pay-server-demo)                   | Local demo with a dashboard for tracing payments. |
| [`start`](#pay-server-start)                 | Run the gateway against a provider YAML spec.     |
| [`scaffold`](#pay-server-scaffold)           | Generate a starter `provider.yml`.                |
| [`plans publish`](#pay-server-plans-publish) | Derive on-chain Plan PDAs from a spec.            |

### `pay server demo`

Start a local demo with a dashboard for tracing payments. Uses bundled endpoints — no spec required.

```sh
pay --sandbox server demo
pay --sandbox server demo --local
```

| Flag             | Type        | Default        | Description                                                                 |
| ---------------- | ----------- | -------------- | --------------------------------------------------------------------------- |
| `--bind`         | string      | `0.0.0.0:1402` | Address to bind to.                                                         |
| `--recipient`    | string      | —              | Recipient wallet address for payments.                                      |
| `--currency`     | string      | `USDC`         | Payment currency (`USDC`, `USDT`, `SOL`, …).                                |
| `--local`        | bool        | `false`        | Use local Surfpool (`http://localhost:8899`) instead of the hosted sandbox. |
| `--otlp-sidecar` | `HOST:PORT` | —              | Export traces and metrics to an OTLP HTTP sidecar.                          |

### `pay server start`

Start a proxy that gates your API with stablecoin payments. Reads endpoint pricing and payment requirements from a YAML spec.

```sh
pay --sandbox server start provider.yml
pay server start provider.yml --bind 0.0.0.0:8080
pay server start provider.yml --openapi openapi.json --public-url https://gateway.example.com
```

| Flag             | Type        | Default        | Description                                                                                                                                             |
| ---------------- | ----------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<SPEC>`         | positional  | —              | Path to the provider YAML spec file. Required.                                                                                                          |
| `--bind`         | string      | `0.0.0.0:1402` | Address to bind to.                                                                                                                                     |
| `--recipient`    | string      | —              | Recipient wallet address for payments. Overrides `operator.recipient` in the spec.                                                                      |
| `--currency`     | string      | `USDC`         | Default payment currency for endpoints that don't specify one.                                                                                          |
| `--rpc-url`      | string      | —              | RPC URL for payment verification.                                                                                                                       |
| `--debugger`     | bool        | `false`        | Launch the Payment Debugger UI alongside the gateway. Automatic under `--sandbox`.                                                                      |
| `--otlp-sidecar` | `HOST:PORT` | —              | Export traces and metrics to an OTLP HTTP sidecar.                                                                                                      |
| `--openapi`      | path        | —              | OpenAPI 3 or Google Discovery JSON describing the upstream API. The gateway re-serves it at `GET /openapi.json` with URLs rewritten to point at itself. |
| `--public-url`   | URL         | —              | Override the public base URL used when rewriting `servers[].url` / `rootUrl`. Derived from the request `Host` header when omitted.                      |

See [YAML Specification](/docs/building-with-pay/yaml-specification) for the spec format and [Defining pricing](/docs/building-with-pay/pricing) for how to price each endpoint.

### `pay server scaffold`

Generate a starter `provider.yml`.

```sh
pay server scaffold provider.yml
```

| Argument   | Type       | Default        | Description       |
| ---------- | ---------- | -------------- | ----------------- |
| `[OUTPUT]` | positional | `provider.yml` | Output file path. |

### `pay server plans publish`

Derive on-chain Plan PDAs for `subscription:` endpoints in a spec. The default is a dry run that prints the derived PDAs without modifying the YAML.

```sh
pay server plans publish
pay server plans publish --spec pay-demo.yaml --dry-run
pay server plans publish --spec pay-demo.yaml --write
```

| Flag        | Type   | Default         | Description                                                                                                                                                 |
| ----------- | ------ | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--spec`    | path   | `pay-demo.yaml` | YAML spec containing `subscription:` endpoints.                                                                                                             |
| `--owner`   | base58 | —               | Plan owner pubkey. Falls back to `operator.recipient` in the spec.                                                                                          |
| `--dry-run` | bool   | `true`          | Print the derived Plan PDAs without modifying the YAML.                                                                                                     |
| `--write`   | bool   | `false`         | Write the derived Plan PDAs back into the YAML. Use after publishing the Plan accounts on-chain through another tool — `pay` does not broadcast them in v0. |

## `pay catalog`

Make your API discoverable in pay's public catalog.

```sh
pay catalog <subcommand>
```

| Subcommand                          | Purpose                                                                                    |
| ----------------------------------- | ------------------------------------------------------------------------------------------ |
| [`scaffold`](#pay-catalog-scaffold) | Scaffold a starter `PAY.md` from an OpenAPI document.                                      |
| [`check`](#pay-catalog-check)       | Read-only validation — parse, frontmatter check, probe, Solana verdict.                    |
| [`build`](#pay-catalog-build)       | Full registry build: validate, then emit `dist/skills.json` and per-provider detail files. |

### `pay catalog scaffold`

Scaffold a new provider `PAY.md` from an OpenAPI document URL. The leaf segment of the FQN becomes the `name:` field; the full FQN is used as a comment hint.

```sh
pay catalog scaffold quicknode/rpc https://example.com/openapi.json
pay catalog scaffold quicknode/rpc https://example.com/openapi.json --output-dir ./providers
```

| Flag            | Type       | Default | Description                                                    |
| --------------- | ---------- | ------- | -------------------------------------------------------------- |
| `<FQN>`         | positional | —       | Fully-qualified provider name, e.g. `quicknode/rpc`. Required. |
| `<OPENAPI_URL>` | positional | —       | URL to the OpenAPI document (JSON or YAML). Required.          |
| `--output-dir`  | path       | `.`     | Output directory. Written as `<dir>/<fqn>/PAY.md`.             |
| `--force`       | bool       | `false` | Overwrite the output file if it already exists.                |

### `pay catalog check`

Read-only validation: parse, frontmatter check, live probe, Solana verdict. Used by PR CI and local development. Never writes to disk.

```sh
pay catalog check
pay catalog check ./providers/quicknode/rpc/PAY.md
pay catalog check --changed-from main
pay catalog check --files providers/google/translate/PAY.md providers/google/maps/PAY.md
```

| Flag                  | Type       | Default     | Description                                                                                                                          |
| --------------------- | ---------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `[PATH]`              | positional | `.`         | Registry root, or a single `PAY.md`. When pointed at a file, the FQN is derived from parent directories.                             |
| `--no-probe`          | bool       | `false`     | Skip live probing (frontmatter-only check).                                                                                          |
| `--probe-timeout`     | seconds    | `10`        | Per-endpoint probe timeout.                                                                                                          |
| `--probe-concurrency` | int        | `5`         | Max concurrent provider probes.                                                                                                      |
| `--currencies`        | csv        | `USDC,USDT` | Accepted stablecoin symbols. Non-listed currencies are flagged as `wrong_currency`.                                                  |
| `--strict`            | bool       | `false`     | Treat every non-Solana endpoint as a blocking error (default: warn).                                                                 |
| `--format`            | enum       | `table`     | Verdict output format. `table`, `json`, or `github` (emits Actions `::warning::`/`::error::` annotations).                           |
| `--verbose` (`-v`)    | bool       | `false`     | Print per-provider, per-endpoint probe + verdict breakdown.                                                                          |
| `--summary-out`       | path       | —           | Also write a GitHub-flavored markdown summary to this path, regardless of `--format`.                                                |
| `--files`             | paths      | —           | Specific PAY.md files to check (relative to the registry root when `PATH` is a directory). Mutually exclusive with `--changed-from`. |
| `--changed-from`      | git-ref    | —           | Check providers whose `PAY.md` or sidecar files changed between `<REF>` and `HEAD`. Requires `git` on `$PATH`.                       |

### `pay catalog build`

Full registry build: run the same checks as `check`, then write `dist/skills.json` and per-provider detail files.

```sh
pay catalog build
pay catalog build --base-url https://catalog.pay.sh/v1
pay catalog build --only quicknode/rpc,helius/das --previous-dist ./dist-prev
```

| Flag                  | Type       | Default                     | Description                                                                                                                  |
| --------------------- | ---------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `[PATH]`              | positional | `.`                         | Registry root containing `providers/`, `affiliates/`, `aggregators/`.                                                        |
| `--base-url`          | URL        | `https://catalog.pay.sh/v1` | CDN base URL for detail-file references in the index.                                                                        |
| `--output` (`-o`)     | path       | `<path>/dist`               | Output directory.                                                                                                            |
| `--no-probe`          | bool       | `false`                     | Skip live probing. Output omits probe-derived pricing/protocol/`supported_usd` metadata.                                     |
| `--probe-timeout`     | seconds    | `10`                        | Per-endpoint probe timeout.                                                                                                  |
| `--probe-concurrency` | int        | `5`                         | Max concurrent provider probes.                                                                                              |
| `--only`              | csv FQNs   | —                           | (Re)build these providers from source; copy every other provider from `--previous-dist`. Fast partial rebuild at merge time. |
| `--previous-dist`     | path       | —                           | Path to a previously-built `dist/` directory. Required when `--only` is set.                                                 |
