# rate-hub API – GET /v1/categories

> rate-hub API – GET /v1/categories is a paid API for AI agents from x402-v1.sky-1.org, paid per call via x402, $0.05/call, status unknown (last checked 2026-10-11).

Returns the list of all asset/token categories (e.g. Layer 1, Stablecoins) with their IDs, display names, and associated asset UIDs

## Facts

- Endpoint: GET https://x402-v1.sky-1.org/v1/categories?utm_source=zero.xyz
- Price: $0.05/call
- Payment: x402
- Status: unknown
- Last checked: 2026-10-11
- Activations on Zero: 0
- Tags: x402
- Canonical page: https://www.zero.xyz/c/rate-hub-api-get-v1-categories-670fd396
- Structured record (JSON): https://api.zero.xyz/v1/capabilities/cap_vyFh1roAHe8eSupTLiFOC

Status and success rate cover calls made through Zero and Zero's own probes. Third-party monitors may report differently.

## How to call it through Zero

Zero handles the 402 payment challenge and records the run. With the Zero CLI installed (`npm i -g @zeroxyz/cli`):

```sh
zero fetch --capability rate-hub-api-get-v1-categories-670fd396
```

Example prompt: Can you pull the full list of crypto asset categories from rate-hub — I need the category IDs and which asset UIDs fall under each one, like Layer 1 or Stablecoins?

## When to prefer this

Use this endpoint when you need to discover or enumerate the full taxonomy of asset categories supported by rate-hub, especially before querying rates or prices filtered by category. Prefer this over hardcoding category IDs, as the list may evolve with new asset groups. It is the canonical source for valid `category_id` values to use in other rate-hub endpoints.

## Known failure modes

- 402 Payment Required – no valid Bearer token or token is spent/expired; must pay USDC on Base to obtain a new credit token
- 404 Not Found – endpoint not found on a non-x402 (classic) deployment
- Token unknown or expired – returns 402 with snake_case error field explaining the reason
- Network/server error – 5xx if the upstream data source is unavailable

## How this service works

**Access.** A deployment runs in one of two modes and the free `GET /v1/x402` tells which: it answers `200` with the offer on an x402 deployment and `404` on a classic one.

- **x402 deployment** (the public one). There is no API key. A payment of USDC on Base buys a credit token for a pack of requests. Call a paid route without credentials: the answer is `402` with the offer in the `PAYMENT-REQUIRED` header (base64 JSON) and in the body. Pay by repeating the request with a `PAYMENT-SIGNATURE` header (base64 JSON x402 v2 `PaymentPayload`, scheme `exact`). The paying response is the normal answer plus `X-Credit-Token` (your token), `X-Credit-Remaining` and `PAYMENT-RESPONSE`. Keep the token and send `Authorization: Bearer <token>` on every later request. A token that is unknown, spent or expired, and any payment that cannot be accepted, answer `402` again: every payment problem is a `402` with a snake_case reason in `error`, never a `400`. On `/mcp` the same problems come back as `200` tool results, see `/mcp`. A `503` with `Retry-After` can mean the same payment is being processed right now: retry shortly. If the payment facilitator does not answer, the answer is `502` and nothing is charged.
- **Classic deployment.** The client sends its key in the `X-API-Key` header. A missing or unknown key answers `401`.

Paid routes: every `/v1` path except `GET /v1/x402`, and MCP `tools/call`. Free: `GET /v1/x402`, `/healthz`, `/readyz`, `/version`, `/openapi.yaml`, `/openapi.json` and `/.well-known/x402` (x402 deployments only), `/docs` (with `/docs/behavior` and `/docs/behavior.md`), `/llms.txt`, and the MCP methods `initialize`, `ping`, `tools/list` and `notifications/*`. On an x402 deployment every served request costs one credit, whatever its status, except `5xx`, which is refunded. Requests that match no route (`404`, `405`) are free.

Client rules, in order. Read these before the paths.

- Ignore unknown JSON fields. The server adds fields without a new major version.
- Map an unknown enum value to an `unknown` case. A Swift `Codable` enum with no fallback crashes the decode and drops the whole response.
- Honor `Retry-After` on `429` and `503`. The header is always an integer number of seconds, never an HTTP-date. `pending` rates carry `retry_after` in seconds for that asset only.
- Fiat live quotes: `source_code` `s10` is a live rate table with no observation time of its own, so `as_of` is the fetch instant (about every 30 minutes by default); `day_change_pct` and `high_volatility` stay a move against the last rate of the previous UTC day, not against the previous poll. A currency that table does not cover keeps its last quote (`source_code` `s3`, `as_of` midnight UTC of that document's date) and turns `stale` after the fiat stale limit. Fiat daily quotes (`/v1/rates/daily`, `source_code` `s3`): `as_of` is midnight UTC of the upstream document date (the rate for that UTC calendar day), not the fetch instant. When present, optional `day` (`YYYY-MM-DD`) repeats that calendar day explicitly. Optional `fetched_at` is when rate-hub last received the live quote from upstream.
- Freshness: live responses (`/v1/rates`, `/v1/top`, `/v1/assets`, `/v1/meta`, errors) carry `Cache-Control: no-cache`, so a client or CDN must ask again before reusing one. A refresh always returns the newest snapshot rate-api holds, so the collector's polling cadence is the floor on freshness. Judge a price by `as_of` (when the price was observed) and `fetched_at` (when rate-hub last refreshed it), not by when you asked.
- `server_time`, quote `as_of`, and quote `fetched_at` use RFC3339 with millisecond precision (fractional seconds trimmed; no sub-millisecond noise).
- Integration tests can observe `pending` by requesting a catalog uid that has no row in the loaded in-memory quote snapshot (for example a cold asset before the first lazy fetch).
- Back off exponentially with jitter. Do not retry in a tight loop.
- Prices and percent changes are decimal strings, never JSON numbers. Parse them with a decimal type. Do not use binary floating point.

Edge cases this schema does not show (dynamic coins and their changing uids, placeholder icons, series limits, data lifetimes) are in the [behaviour notes](/docs/behavior) ([raw Markdown](/docs/behavior.md)).

Conventions: lowercase `snake_case`, full field names, statuses as strings, versioned under `/v1`. Changes inside v1 are additive only.

Prices are rounded to 10 significant digits. This service is an indicative cache, not an oracle. Live `/v1/rates` quotes are not a full history product; additive `/v1/rates/daily` returns one immutable USD (or requested `vs`) rate per catalog uid per UTC calendar day for backfill and prewarm (see those paths for day definitions and archive limits).

## Output

A JSON object containing: a list of category objects each with an `id` (slug), `name` (display label), and `uids` (array of integer asset IDs); plus `as_of` (data timestamp), `server_time` (current server time), and `build` (API version string).

## Request schema (JSON Schema)

```json
{
 "type": "object",
 "$schema": "https://json-schema.org/draft/2020-12/schema",
 "required": [
  "input"
 ],
 "properties": {
  "input": {
   "type": "object",
   "required": [
    "type",
    "method"
   ],
   "properties": {
    "type": {
     "type": "string",
     "const": "http"
    },
    "method": {
     "enum": [
      "GET",
      "HEAD",
      "DELETE"
     ],
     "type": "string"
    },
    "headers": {
     "type": "object",
     "additionalProperties": {
      "type": "string"
     }
    },
    "queryParams": {
     "type": "object",
     "additionalProperties": {
      "type": "string"
     }
    }
   },
   "additionalProperties": false
  },
  "output": {
   "type": "object",
   "required": [
    "type"
   ],
   "properties": {
    "type": {
     "type": "string"
    },
    "example": {
     "type": "object"
    }
   }
  }
 }
}
```

## Response schema (JSON Schema)

```json
{
 "type": "json",
 "example": {
  "as_of": "2026-10-10T03:00:12.000Z",
  "build": "0.18.0-a1b2c3d",
  "categories": [
   {
    "id": "layer-1",
    "name": "Layer 1 (L1)",
    "uids": [
     200000001,
     200000002
    ]
   },
   {
    "id": "stablecoins",
    "name": "Stablecoins",
    "uids": [
     200000007,
     200000043
    ]
   }
  ],
  "server_time": "2026-10-10T12:00:03.500Z"
 }
}
```

## More

- Live health (JSON, refreshed every minute): https://www.zero.xyz/c/rate-hub-api-get-v1-categories-670fd396/health.json
- [Zero catalog index](https://www.zero.xyz/llms.txt)
- [Other services from x402-v1.sky-1.org](https://www.zero.xyz/host/x402-v1.sky-1.org/llms.txt)
