Public API v1

Two endpoints. One reads a completed review, the other asks for a token to be reviewed. Responses are JSON and carry "api_version": "v1".

Before you integrate

A token that has never been reviewed returns 404 with an error body, not an empty result. Do not treat a missing scan, an empty response or a failed request as a favourable answer. Every response carries "unknown_is_safe": false for the same reason.

When part of the supported check set could not be completed, the score is withheld: score is null, score_withheld is true and the band reads Insufficient data. The API never publishes a number the token page would hold back.

Keys and limits

A key is optional. Anonymous requests are served on the tighter public rate limit; sending a valid key in an X-API-Key header moves you to the higher one. Reads do not consume credits. Keys are stored as hashes only and cannot be shown again after they are issued — keep yours somewhere safe.

GET /api/v1/scan/{chain}/{address}

Returns the completed review. chain is one of ethereum, bsc, polygon, arbitrum, base, solana.

curl -s https://vetmytoken.com/api/v1/scan/ethereum/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \
     -H "X-API-Key: your-key-here"

A response looks like this. Values are illustrative.

{
  "api_version": "v1",
  "scanned": true,
  "chain": "ethereum",
  "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  "token": { "name": "Example Token", "symbol": "EXM" },
  "scan_id": "…",
  "scan_status": "ok",
  "verdict": {
    "band": "Guarded",
    "score": 21,
    "score_withheld": false,
    "plain_summary": "This token is centrally administered - someone can change how it behaves - but it is established and widely held."
  },
  "findings": [
    {
      "title": "An administrator can replace the token's code",
      "detail": "An administrator address still controls the upgradeable proxy and can point it at entirely different code without asking holders.",
      "severity": "high"
    },
    {
      "title": "Transfers can be switched off",
      "detail": "An administrator can pause the token, which stops everyone from moving it until the pause is lifted.",
      "severity": "medium"
    },
    {
      "title": "This covers contract controls only",
      "detail": "Team identity, promises made off chain, market behaviour and the intentions of whoever holds these powers are not part of this result.",
      "severity": "info"
    }
  ],
  "checks": {
    "erc1967_administrator": { "state": "verified", "value": "0x…" },
    "solana_permanent_delegate": { "state": "not_found", "value": null },
    "holder_concentration": { "state": "could_not_check", "value": null }
  },
  "checks_completed": 24,
  "checks_unavailable": 3,
  "deployer": {
    "address": "0x…",
    "source": "external_feed",
    "activity_seen": null,
    "activity_count_is_a_minimum": false
  },
  "evidence": {
    "block": 20431122,
    "block_hash": "0x…",
    "observed_at": 1754812800,
    "completeness": 1.0,
    "rules_version": 3
  },
  "limitations": [
    "holder_concentration: not part of the verified control assessment on this chain"
  ],
  "unknown_is_safe": false,
  "web_url": "https://vetmytoken.com/token/example-token"
}

Reading the fields

Errors

{
  "api_version": "v1",
  "scanned": false,
  "error": { "code": "scan_not_found", "message": "This token has not been scanned. No result exists for it, which is not the same as a clean result." },
  "chain": "ethereum",
  "address": "0x…",
  "verdict": null,
  "findings": null,
  "checks": null,
  "deployer": null,
  "evidence": null,
  "limitations": null,
  "unknown_is_safe": false
}

Codes: invalid_address (400), scan_not_found (404). Rate limiting returns 429.

POST /api/v1/scan

Asks for a token to be reviewed. The review runs in the background; this call returns immediately and never contains a result.

curl -s -X POST https://vetmytoken.com/api/v1/scan \
     -H "Content-Type: application/json" \
     -H "X-API-Key: your-key-here" \
     -d '{"chain":"ethereum","address":"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"}'
{
  "api_version": "v1",
  "status": "queued",
  "scan_url": "https://vetmytoken.com/api/v1/scan/ethereum/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  "web_url": null,
  "poll_after_seconds": 30,
  "unknown_is_safe": false
}

status is queued when a new review was started, or exists when one is already on record — in which case poll_after_seconds is 0 and you can read scan_url straight away. Wait poll_after_seconds before the first read; a review that is still running has no row yet, and that read will correctly return scan_not_found rather than an empty result.

What this is not

These endpoints report supported contract controls at a pinned block. They do not detect fraud, guarantee that a token can be sold, establish who is behind a project, or predict what an administrator will do with the powers listed. Read About for the scope and Data disclosures for where the data comes from.