API v1

Onboarding / Getting Started

The first 15 minutes with Tokens API v1.

Welcome aboard. You now have access to the Tokens Assets API (v1): a JSON HTTP API for working with canonical assets, their Solana mint variants, and related market, charting, and risk data.

This page is meant to be the “first 15 minutes” guide: how auth works, how to make your first calls, and which endpoints to start with.

Base URL + authentication

  • Base URL: https://api.tokens.xyz/v1
  • Auth header: x-api-key: <YOUR_API_KEY>
  • Content type: for POST requests send Content-Type: application/json

Set these locally for the examples below:

export API_BASE_URL="https://api.tokens.xyz"
export API_KEY="..."

Most integrations should call Tokens servers directly. You do not deploy your own Tokens API.

Keep your API key server-side

Treat your API key like a password:

  • Don’t ship it in frontend code or public repos
  • Prefer calling the API from your server (or an edge function) and proxying responses to the browser

Key concepts

Canonical assetId vs Solana mint

  • assetId: a canonical identifier (for example: solana, btc, apple) representing a real-world asset grouping.
  • mint: a Solana token address (base58).

Many endpoints are asset-scoped but accept an optional mint= query param to target a specific token variant. If you provide mint, it must be a variant of that asset (otherwise you’ll get a BadRequestError).

Singleton assets (solana-<mint>)

If an on-chain token doesn’t map to a known canonical asset, the API represents it as a deterministic “singleton” canonical asset:

  • Singleton assetId format: solana-<mint>

This makes it safe to link to and cache “unknown” tokens without ever using the raw mint as a canonical assetId.

Quick start (copy/paste)

# Health check (no auth)
curl -sS "$API_BASE_URL/v1/health"

# Search assets
curl -sS "$API_BASE_URL/v1/assets/search?q=bitcoin&limit=5" \
  -H "x-api-key: $API_KEY"

# Resolve user input -> canonical assetId (or singleton solana-<mint>)
curl -sS "$API_BASE_URL/v1/assets/resolve?ref=btc" \
  -H "x-api-key: $API_KEY"

# Fetch the canonical asset (optionally request include blocks)
curl -sS "$API_BASE_URL/v1/assets/btc?include=profile,risk,ohlcv,markets" \
  -H "x-api-key: $API_KEY"

Scopes (permissions)

Most endpoints require assets:read.

The asset detail endpoint also supports fine-grained scopes for its include blocks:

  • assets:profile:read
  • assets:risk:read
  • assets:ohlcv:read
  • assets:markets:read

assets:read is an umbrella scope that covers the entire assets surface.

GET /v1/assets/search

  • Query params
    • q (required): search text
    • limit (optional, default 20, max 50)
    • category (optional): filters by asset category (invalid values return a 400 with allowed categories)

Use this to power autocomplete and broad discovery.

2) Resolve

GET /v1/assets/resolve

  • Provide either
    • ref=<string> (canonical id / alias / identifier)
    • mint=<solanaMint> (Solana address)

Returns a normalized assetId plus the best “primary” variant when available.

3) Asset detail (+ includes)

GET /v1/assets/:assetId

  • Query params
    • include=profile,risk,ohlcv,markets (optional; comma-separated)

Returns:

  • asset: canonical identity + variants/groups + primary variant
  • includes (optional): best-effort include blocks with { ok: true, data } or { ok: false, reason, message }

4) Variants

GET /v1/assets/:assetId/variants

  • Query params
    • kind (optional): native|wrapped|bridged|etf|yield|leveraged|basket|lst|stablecoin|tokenized_equity
    • liquidityTier (optional): tier1|tier2|tier3
    • trustTier (optional, deprecated alias): tier1|tier2|tier3

experimental is still accepted as a legacy alias for tier3.

Returns variants sorted by market liquidity, then derived liquidity tier, then 24h volume.

5) Markets (order book venues / pools; paginated)

GET /v1/assets/:assetId/markets

  • Query params
    • mint (optional): choose a specific variant mint
    • offset (optional, default 0)
    • limit (optional, default 10, max 50)

6) OHLCV candles (mint-scoped)

GET /v1/assets/:assetId/ohlcv

  • Query params
    • mint (optional): choose a specific variant mint
    • interval (optional, default 1H): 1m|5m|15m|1H|4H|1D|1W
    • from (optional, unix seconds; default is ~7d ago)
    • to (optional, unix seconds; default is now)

7) Price chart (canonical-first, with mint fallback)

GET /v1/assets/:assetId/price-chart

Same query params as OHLCV (interval, from, to, optional mint).

If a canonical source exists for the asset, this endpoint prefers it; otherwise it falls back to mint candles.

8) Risk

  • Asset-scoped

    • GET /v1/assets/:assetId/risk-summary
    • GET /v1/assets/:assetId/risk-details
    • Optional mint to target a specific variant
  • Mint-scoped quick score

    • GET /v1/assets/risk-summary?mint=<solanaMint>
    • Requires either assets:read or assets:risk:read

Curated lists + batch endpoints

Curated lists

GET /v1/assets/curated

  • Query params
    • list: all|majors|lsts|currencies|rwas|etfs|metals|stocks
    • groupBy: asset (default) or mint

Batch market snapshots (POST)

POST /v1/assets/market-snapshots

Body:

{ "mints": ["<solanaMint1>", "<solanaMint2>"] }

Supports mints or addresses and dedupes automatically (max 250).

Batch variant market snapshots (GET)

GET /v1/assets/variant-markets?mints=<comma,separated>

Supports mints or addresses (max 50).

Error handling + debugging

Standard error envelope

Non-2xx responses return JSON:

{ "error": { "_tag": "BadRequestError", "message": "…", "details": "…" } }

Common status codes

  • 400 BadRequestError (invalid params / invalid mint / invalid include)
  • 401 UnauthorizedError (missing or invalid x-api-key)
  • 403 ForbiddenError (insufficient scope)
  • 404 NotFoundError
  • 429 RateLimitedError

Request IDs

Every response includes an x-request-id header. If you need help debugging an issue, send us:

  • the request URL
  • the response body (redact your API key)
  • the x-request-id
  • the timestamp (UTC if possible)

Rate limits, quotas, and freshness

  • Rate limits and monthly quotas are enforced per API key.
  • Some endpoints are cached; if data is stale or missing, your request may trigger background refresh and you may need to retry shortly after.
  • If you see 429, implement exponential backoff and retry.

Support

If you hit anything unexpected (auth, scopes, shape mismatches, data freshness), reply to the access email with the x-request-id and we’ll dig in quickly.

Next steps

On this page