API

Errors & limits

Every error is the same shape. Limits clamp instead of rejecting, and the response says what was clamped.

The error body #

JSON
{
  "error": {
    "code": "token_not_found",
    "message": "No tracked token matches \"not-a-coin\". Try GET /v1/tokens?q=…"
  }
}

MCP tools return the same body as a tool error. A call that fails is never charged.

When a token is one CoinGraph knows but cannot check, such as a stablecoin or a coin outside the top 100, token_not_found also says why, what is available for it, and what to do next:

JSON
{
  "error": {
    "code": "token_not_found",
    "message": "Tether (USDT) is a stablecoin, so it is outside the check: there is no state, evaluation or agent run for it…",
    "reason": "stablecoin_not_covered",
    "token": {
      "id": "tether",
      "symbol": "USDT",
      "name": "Tether"
    },
    "coverage": {
      "level": "stablecoin",
      "search": true,
      "state": false,
      "evaluate": false,
      "token_page": "light"
    },
    "coverage_policy": "The top 1,000 tokens are supported: the top 100 get the full check every hour, the rest a light check, and more on request. Stablecoins are priced and valued in wallets but are outside the check.",
    "next_steps": [
      {
        "action": "See stablecoin flows",
        "call": "GET /v1/market?sections=flows"
      }
    ]
  }
}

Status codes #

StatusWhenCodes
400The request is invalidinvalid_input, invalid_json, token_required, invalid_chain, invalid_address, question_or_claim
401The key is wrong or revoked, or a monitor secret is missinginvalid_key, secret_required
402Payment required: pay with x402 and retry, send a key, or top uppayment_required, out_of_credits, settlement_failed
403The plan does not include this (webhook monitors need Pro or above)plan_required
404Nothing matchestoken_not_found, agent_not_found, no_brief, not_found
410A retired endpoint of the old API, or a retired agent idendpoint_retired, retired
413The body is over 16 KBbody_too_large
429Too many requests, or the investigation queue is fullrate_limited, investigations_busy, busy
5xxSomething failed on our sideinternal_error, investigation_failed

402: payment required #

A paid call without a key or payment answers 402. The PAYMENT-REQUIRED header carries the x402 terms (base64 JSON; decoded on Keys & pricing) and the body repeats them in plain words:

402 body (no key, no payment)
{
  "error": {
    "code": "payment_required",
    "message": "This call costs 5 tADA on cardano:preprod (x402). Decode the PAYMENT-REQUIRED header, pay, and retry with PAYMENT-SIGNATURE; or send a design-partner key as Authorization: Bearer cg_…. Docs: https://coingraph.ai/docs/pricing"
  },
  "pricing": {
    "tier": "premium",
    "testnet_tada": 5,
    "mainnet_usd": 0.05,
    "asset": "lovelace",
    "network": "cardano:preprod",
    "pay_to": "addr_test1…"
  }
}

With a key whose account has run out, the body is out_of_credits with how many credits the call needs and how many are left; top up at Account → Billing. Every paid response carries x-credits-charged and x-credits-remaining.

410: retired endpoints #

Every path of the old API answers 410 Gone with the replacement, a ready-made URL when the old request had enough to build one, and a Sunset header. A call that still sends a key also gets key_note. The mapping is on Migrate. A retired agent id answers 410 with the code retired and the call that replaces it.

GET /api/v1/search?q=link → 410 (built by the same code that answers it)
{
  "error": {
    "code": "endpoint_retired",
    "message": "GET /api/v1/search was retired on 19 Oct 2026 with the previous CoinGraph API. Search is now part of the token list: pass q for a name, symbol or contract address.",
    "retired": "GET /api/v1/search",
    "retired_on": "2026-10-19",
    "replacement": {
      "method": "GET",
      "endpoint": "https://coingraph.ai/api/v1/tokens?q={query}",
      "docs": "https://coingraph.ai/docs/api/tokens",
      "example": "https://coingraph.ai/api/v1/tokens?q=link"
    },
    "migration_guide": "https://coingraph.ai/docs/migrate",
    "key_note": "API keys were reissued on 19 Oct 2026: keys from the previous site no longer work. Create a new key (with credits) at https://coingraph.ai/account/keys."
  }
}

Rate limits and sizes #

LimitValue
Requests60 per minute per caller. A 429 carries a Retry-After header.
Request body16 KB.
MonitorsUp to 50 tokens per monitor; public HTTPS webhook URLs only.
Fresh investigations and questions20 to 90 seconds each; the queue answers 429 when it is full. Agent runs take 2 to 20 seconds.
InspectRecent transfers: the last 90 days, 20 rows.
Search25 results.

Time floors and point caps #

Windows are clamped, never rejected, and the answer says so in notes[].

The since floors #

Endpointsince reaches backReported as
History90 dayswindow.since_clamped_to
Track record30 days (default 7)since_clamped_to

The 2,000-point cap #

A history series never carries more than 2,000 points per venue, and its first point can sit up to one bucket before since, because a bucket is labelled by its start. The bucket is widened from 15 minutes to 1 hour to 6 hours until the window fits, and the answer reports the bucket it used in resolution next to the one you asked for in resolution_requested. raw (every stored row) is served for windows up to 48 hours; beyond that the automatic bucket is used and noted. The track record applies the same idea to its calibration: the bucket that groups checks widens from 1 hour to 6 hours, 1 day and 7 days until 2,000 checks remain, and calibration.check_bucket says which.

Detail and retention #

Price, market cap and volume are stored every 10 minutes for 90 days and hourly after that; 1-minute candles for 14 days and hourly after that. History serves candles at 1 minute up to 24 hours and hourly beyond. Exchange net flow is 15-minute, reserves hourly. See What we collect.

Unassessed #

An absent measurement is the string "unassessed", never zero and never a guess. A token with no perpetual market has an unassessed derivatives section; a native coin has an unassessed contract dimension; a policy rule that cannot be measured is unknown. Treat all three as “stop and look”, not as a pass. The full explanation is under Concepts.

✓

Tip

Responses to the same question are cached briefly, so polling every few seconds is cheap but rarely useful. Monitors push a signed message when something changes.