---
title: "Index API"
description: "Public JSON API and MCP server for an index of services advertising stablecoin payments over x402 and MPP, with HTTP endpoints probed for payment-challenge signals. No key; the read endpoints are CORS open."
canonical: "https://www.superstables.com/docs/index-api"
last-updated: 2026-10-05
---

# Index API

Everything on the [Discover](https://www.superstables.com/discover) page is served by a public JSON API.
The index read endpoints are CORS open. Field names are a stable contract.
Machine-readable spec: [openapi.json](https://www.superstables.com/openapi.json).

## Endpoints

- `GET /api/v1/services` - list services. Filters: rail (x402|mpp|acp), chain, asset, live=true, q (free text), limit (1-500), cursor.
- `GET /api/v1/services/:id` - one service plus its last 20 liveness probes.
- `POST /api/v1/services/batch` - bulk lookup: `{"ids": [...]}` (1-100) returns `{ found: [...], missing: [...] }`. Also `GET ...?ids=a,b,c`.
- `GET /api/v1/stats` - census counts: total, live, probed, dual-rail, rails.
- `POST /api/v1/submit` - submit a service: `{"endpoint","name","contact"}`. New submissions are reviewed before listing.
- `GET /ask?query=...` - natural-language questions. See [Ask in natural language](#ask-in-natural-language).

## Buy a service over HTTP (preview)

An agent can buy the testnet services Superstables operates with plain HTTP calls. The
[quickstart](https://www.superstables.com/docs/purchase.md) covers the whole flow.

- `GET /api/v1/purchase/services` - services an agent can buy, with closed-set inputs and the seller's payment terms: protocol, chain, token, atomic amount and recipient. The catalogue uses test USDC on Base Sepolia, Arc Testnet and Solana devnet, or test pathUSD on Tempo Moderato. Simulated services are marked.
- `POST /api/v1/purchases` - create a purchase, without a key. Returns a bearer token for it, and an approval link and match code for the owner. Nothing is signed or paid until the owner approves.
- `GET /api/v1/purchases/{id}?wait=20` - the purchase, read with its bearer token: payment, delivery and receipt as separate facts. Unknown outcomes are checked against the chain; do not buy again while `final` is `false`.
- `GET /api/v1/purchase` - the purchase journey: who does each step, and where.

## Budgets over HTTP (preview)

An agent with its own key can ask its owner, through superstables.com, for a USDC allowance it then
spends without asking again. [Budgets on superstables.com](https://www.superstables.com/docs/budgets.md) is the whole contract.

- `POST /api/v1/budget/links` - create an add-agent request (`kind: "link"`) to add the agent to its owner's account. Signed by the agent's key.
- `POST /api/v1/budget/approvals` - ask the owner to send one transaction: a grant, a revoke or a gas top-up.
- `GET /api/v1/budget/requests/{id}?wait=20` - read the request with its bearer token, until `final` is `true`.
- `GET /api/v1/budget/services` - testnet services a budget can pay.

To pay from the owner's machine instead, with the CLI or the agent skill, see the
[Superstables client](https://www.superstables.com/docs/client.md).

## Example

```bash
curl "https://www.superstables.com/api/v1/services?rail=x402&live=true&q=compute&limit=20"
```

Returns `{ generated_at, counts: { total, live, dual_rail }, page: { limit, offset, next_offset, next_cursor }, services: [...] }`
where each service has id, name, description, category, rails, chains, assets, price `{display, usd}`,
payment_terms, endpoint, facilitator, live, last_seen_live, first_indexed, sources. The JSON below is an abridged, illustrative response.

```json
{
  "generated_at": "2026-09-04T12:00:00.000Z",
  "counts": { "total": 1913, "live": 390, "dual_rail": 10 },
  "page": { "limit": 20, "offset": 0, "next_offset": 20, "next_cursor": "…" },
  "services": [
    {
      "id": "api.nosana.io",
      "name": "Nosana GPU compute",
      "description": "GPU jobs paid per second over x402.",
      "rails": ["x402"],
      "chains": ["solana"],
      "assets": ["USDC"],
      "price": { "display": "$0.001 / call", "usd": 0.001 },
      "endpoint": "https://api.nosana.io/v1/jobs",
      "live": true,
      "last_seen_live": "2026-09-04T11:40:12.000Z",
      "sources": ["x402-bazaar"]
    }
  ]
}
```

## Batch lookup

```bash
curl -X POST https://www.superstables.com/api/v1/services/batch \
  -H "Content-Type: application/json" -d '{"ids":["10x402.com","example.invalid"]}'
```

Read-only. Up to 100 ids per request; ids are case-insensitive and duplicates are ignored.
The response lists the records found (same shape as the list endpoint, without probe history)
and the ids that are not in the index, so a list of endpoints reconciles in one round trip.

## Whole index as a feed

```bash
curl https://www.superstables.com/feeds/services.jsonl
```

Newline-delimited JSON, one schema.org Service object per line for every indexed service
(payment rails, chains, assets, liveness and price in additionalProperty). Listed in the
schema map at [/schemamap.xml](https://www.superstables.com/schemamap.xml), referenced from robots.txt.

## Pagination

Cursor-based. Pass `limit` (1-500, default 100). Every list response includes `page.next_cursor`:
pass it as `cursor` for the next page, and stop when it is null. A cursor marks the last service
read, not a position, so services moving ahead of it do not shift the next page. Offset paging
still works: `offset` (default 0) and `page.next_offset`.

## Errors

Handled index errors are JSON: `{ "error": { "code": "...", "message": "..." } }`. Handle a non-JSON
answer too, from an unsupported method or an unhandled failure.
Codes are stable: not_found, invalid_endpoint, invalid_json, invalid_ids, invalid_cursor, missing_query, method_not_allowed,
internal_error. New codes may be added, so treat an unknown one as information. Unknown API paths
return 404 with the list of paths that do exist. The purchase and budget APIs have their own codes,
on their pages.

## Rate limits

Index list, detail, batch and stats responses advertise a soft limit of 300 requests per minute
(`RateLimit-Limit: 300`, `RateLimit-Policy: 300;w=60`). They send
`Cache-Control: s-maxage=300, stale-while-revalidate=3600`: shared caches may reuse an answer for five
minutes, and serve it stale for up to an hour while they fetch a new one. The purchase API has its own enforced limits: purchases are
not cached, and the list of services to buy is cached for 60 seconds. See
[Limits and errors](https://www.superstables.com/docs/purchase.md#limits-and-errors).

## Testing safely

The catalogue list, detail, batch lookup, stats, JSONL feed, /ask endpoint and MCP tools only read
the index. They do not make payments or probe the listed endpoints.

`POST /api/v1/submit` writes to the moderation queue and immediately probes the submitted URL.
Nothing is published automatically; repeated submissions of the same endpoint within 24 hours
are deduplicated. Do not use submission, early-access forms or administrative crawl jobs as
read-only checks. Use a disposable private environment to test write operations.

`POST /api/v1/purchases` is not a read-only check either: it creates a purchase and a payment
request for an owner. Create one only when the user asked for the service. The same goes for
`POST /api/v1/budget/links` and `POST /api/v1/budget/approvals`, which ask an owner to act.

## Versioning and deprecation

The version is the path prefix (/api/v1). Within a version, fields of the index API are only
added, never renamed or removed. Nothing is deprecated today.

Before an index endpoint or API version is retired, its responses carry a `Deprecation` header
([RFC 9745](https://www.rfc-editor.org/rfc/rfc9745)) with the deprecation date and a `Sunset` header
([RFC 8594](https://www.rfc-editor.org/rfc/rfc8594)) with the retirement date, at least 90 days before
that date. The [changelog](https://github.com/superstables/superstables/blob/main/CHANGELOG.md)
announces it when the headers first appear. The purchase and budget previews may still change before
they handle real money; released changes are in the changelog.

## Ask in natural language

```bash
curl "https://www.superstables.com/ask?query=live%20gpu%20compute%20on%20solana"
```

NLWeb-style: returns `{ query, interpreted, summary, results[] }` with schema.org
objects. Add `streaming=true` for server-sent events.

## MCP server

Streamable HTTP, no auth: `https://www.superstables.com/api/mcp`.
Claude, Codex and other MCP clients can use the index as native tools: `find_services`, `get_service` and `get_stats`. Add it with:

```json
{
  "mcpServers": {
    "superstables-index": {
      "url": "https://www.superstables.com/api/mcp"
    }
  }
}
```

For POST requests, use `Accept: application/json, text/event-stream` and handle either response
format. An absent Accept header or `*/*` permits both formats. JSON-only clients are not supported;
unsupported Accept headers receive HTTP 406.
Server card: [/.well-known/mcp/server-card.json](https://www.superstables.com/.well-known/mcp/server-card.json)

## What "live" means

We GET every listed HTTP endpoint on a rolling schedule. `live: true` means the endpoint returned HTTP 402 or a detected
payment-challenge signal (a detected payment-challenge header or challenge body) at its last unpaid probe.
It does not establish payment compatibility, settlement, delivery or output quality.
Non-HTTP entries are listed but never probed; their `live` is null. Probe history is kept, and the
last 20 probes are exposed per service.

## Authentication

The index API and the MCP server need none. The purchase preview gives each purchase its own
bearer token, and only the owner's wallet can approve a payment. The budget preview checks a
signature by the agent's own key on each request that asks the owner for something, and gives each
request its own bearer token. See [/auth.md](https://www.superstables.com/auth.md).

Contact: [x.com/superstables](https://x.com/superstables)
