> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coinpaprika.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Coverage checker - Check if an asset exists in CoinPaprika's dataset

> Use this tool to quickly verify whether an asset exists in CoinPaprika's dataset. Enter a contract address, token name, or ticker symbol; we’ll search our coverage and show the closest matches.

export function CoverageResults({externalData}) {
  const [results, setResults] = useState(null);
  const [lastQuery, setLastQuery] = useState("");
  const fmtNum = n => n === null || n === undefined || Number.isNaN(n) ? "—" : Number(n).toLocaleString(undefined, {
    maximumFractionDigits: 6
  });
  useEffect(() => {
    try {
      const raw = sessionStorage.getItem(STORE_LAST);
      if (raw) {
        const {query, results} = JSON.parse(raw);
        if (results && typeof results === "object") {
          setResults({
            currencies: Array.isArray(results.currencies) ? results.currencies : [],
            exchanges: Array.isArray(results.exchanges) ? results.exchanges : [],
            icos: Array.isArray(results.icos) ? results.icos : [],
            people: Array.isArray(results.people) ? results.people : [],
            tags: Array.isArray(results.tags) ? results.tags : []
          });
          setLastQuery(query || "");
        }
      }
    } catch {}
  }, []);
  useEffect(() => {
    if (externalData && externalData.results && typeof externalData.results === "object") {
      const r = externalData.results;
      setResults({
        currencies: Array.isArray(r.currencies) ? r.currencies : [],
        exchanges: Array.isArray(r.exchanges) ? r.exchanges : [],
        icos: Array.isArray(r.icos) ? r.icos : [],
        people: Array.isArray(r.people) ? r.people : [],
        tags: Array.isArray(r.tags) ? r.tags : []
      });
      setLastQuery(externalData.query || "");
    }
  }, [externalData]);
  if (results === null) return null;
  const totalCount = (results.currencies?.length || 0) + (results.exchanges?.length || 0) + (results.icos?.length || 0) + (results.people?.length || 0) + (results.tags?.length || 0);
  return <div className="space-y-2">
      {lastQuery && <div className="text-sm opacity-70">
          Results for: <span className="font-medium">{lastQuery}</span>
        </div>}

      {totalCount === 0 ? <div>No results.</div> : <div className="space-y-6">
          {results.currencies?.length > 0 && <div style={{
    overflowX: "auto"
  }}>
              <div className="font-medium mb-2">Currencies ({results.currencies.length})</div>
              <table className="w-full table-auto text-sm">
                <thead>
                  <tr>
                    <th className="text-left py-2 pr-4">ID</th>
                    <th className="text-left py-2 pr-4">Symbol</th>
                    <th className="text-left py-2 pr-4">Name</th>
                    <th className="text-left py-2 pr-4">Rank</th>
                    <th className="text-left py-2 pr-4">Type</th>
                    <th className="text-left py-2 pr-4">Active</th>
                  </tr>
                </thead>
                <tbody>
                  {results.currencies.map((c, i) => <tr key={`${c.id}:${i}`}>
                      <td className="py-2 pr-4"><span className="font-mono text-xs">{c.id || "—"}</span></td>
                      <td className="py-2 pr-4">{c.symbol || "—"}</td>
                      <td className="py-2 pr-4">{c.name || "—"}</td>
                      <td className="py-2 pr-4">{fmtNum(c.rank)}</td>
                      <td className="py-2 pr-4">{c.type || "—"}</td>
                      <td className="py-2 pr-4">{c.is_active === true ? "Yes" : c.is_active === false ? "No" : "—"}</td>
                    </tr>)}
                </tbody>
              </table>
            </div>}

          {results.exchanges?.length > 0 && <div style={{
    overflowX: "auto"
  }}>
              <div className="font-medium mb-2">Exchanges ({results.exchanges.length})</div>
              <table className="w-full table-auto text-sm">
                <thead>
                  <tr>
                    <th className="text-left py-2 pr-4">ID</th>
                    <th className="text-left py-2 pr-4">Name</th>
                    <th className="text-left py-2 pr-4">Rank</th>
                  </tr>
                </thead>
                <tbody>
                  {results.exchanges.map((ex, i) => <tr key={`${ex.id}:${i}`}>
                      <td className="py-2 pr-4"><span className="font-mono text-xs">{ex.id || "—"}</span></td>
                      <td className="py-2 pr-4">{ex.name || "—"}</td>
                      <td className="py-2 pr-4">{fmtNum(ex.rank)}</td>
                    </tr>)}
                </tbody>
              </table>
            </div>}

          {results.icos?.length > 0 && <div style={{
    overflowX: "auto"
  }}>
              <div className="font-medium mb-2">ICOs ({results.icos.length})</div>
              <table className="w-full table-auto text-sm">
                <thead>
                  <tr>
                    <th className="text-left py-2 pr-4">ID</th>
                    <th className="text-left py-2 pr-4">Symbol</th>
                    <th className="text-left py-2 pr-4">Name</th>
                    <th className="text-left py-2 pr-4">New</th>
                  </tr>
                </thead>
                <tbody>
                  {results.icos.map((ico, i) => <tr key={`${ico.id}:${i}`}>
                      <td className="py-2 pr-4"><span className="font-mono text-xs">{ico.id || "—"}</span></td>
                      <td className="py-2 pr-4">{ico.symbol || "—"}</td>
                      <td className="py-2 pr-4">{ico.name || "—"}</td>
                      <td className="py-2 pr-4">{ico.is_new === true ? "Yes" : ico.is_new === false ? "No" : "—"}</td>
                    </tr>)}
                </tbody>
              </table>
            </div>}

          {results.people?.length > 0 && <div style={{
    overflowX: "auto"
  }}>
              <div className="font-medium mb-2">People ({results.people.length})</div>
              <table className="w-full table-auto text-sm">
                <thead>
                  <tr>
                    <th className="text-left py-2 pr-4">ID</th>
                    <th className="text-left py-2 pr-4">Name</th>
                    <th className="text-left py-2 pr-4">Teams</th>
                  </tr>
                </thead>
                <tbody>
                  {results.people.map((p, i) => <tr key={`${p.id}:${i}`}>
                      <td className="py-2 pr-4"><span className="font-mono text-xs">{p.id || "—"}</span></td>
                      <td className="py-2 pr-4">{p.name || "—"}</td>
                      <td className="py-2 pr-4">{fmtNum(p.teams_count)}</td>
                    </tr>)}
                </tbody>
              </table>
            </div>}

          {results.tags?.length > 0 && <div style={{
    overflowX: "auto"
  }}>
              <div className="font-medium mb-2">Tags ({results.tags.length})</div>
              <table className="w-full table-auto text-sm">
                <thead>
                  <tr>
                    <th className="text-left py-2 pr-4">ID</th>
                    <th className="text-left py-2 pr-4">Name</th>
                  </tr>
                </thead>
                <tbody>
                  {results.tags.map((t, i) => <tr key={`${t.id || t.name || i}:${i}`}>
                      <td className="py-2 pr-4"><span className="font-mono text-xs">{t.id || "—"}</span></td>
                      <td className="py-2 pr-4">{t.name || "—"}</td>
                    </tr>)}
                </tbody>
              </table>
            </div>}
        </div>}
    </div>;
}

export const CoverageChecker = ({onUpdate}) => {
  const SEARCH_API = "https://api.coinpaprika.com/v1/search/";
  const STORE_LAST = "dp:coverage:last";
  const CACHE_PREFIX = "dp:coverage:query:";
  const CACHE_TTL_MS = 5 * 60 * 1000;
  const PRIMARY = "#CA312C";
  const SEARCH_LIMIT = 25;
  function cacheKey(q) {
    return `${CACHE_PREFIX}${q.toLowerCase().trim()}`;
  }
  function loadCache(q) {
    try {
      const raw = sessionStorage.getItem(cacheKey(q));
      if (!raw) return null;
      const {ts, data} = JSON.parse(raw);
      return Date.now() - ts > CACHE_TTL_MS ? null : data;
    } catch {
      return null;
    }
  }
  function saveCache(q, data) {
    try {
      sessionStorage.setItem(cacheKey(q), JSON.stringify({
        ts: Date.now(),
        data
      }));
    } catch {}
  }
  function saveLast(query, results) {
    try {
      sessionStorage.setItem(STORE_LAST, JSON.stringify({
        ts: Date.now(),
        query,
        results
      }));
    } catch {}
  }
  const [query, setQuery] = useState("");
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");
  function publish(query, results) {
    saveLast(query, results);
    try {
      if (typeof onUpdate === "function") onUpdate({
        query,
        results
      });
    } catch {}
  }
  async function doSearch(q) {
    setLoading(true);
    setError("");
    try {
      const cached = loadCache(q);
      if (cached) {
        publish(q, cached);
        return;
      }
      const url = `${SEARCH_API}?q=${encodeURIComponent(q)}&limit=${SEARCH_LIMIT}`;
      const res = await fetch(url, {
        mode: "cors"
      });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const payload = await res.json();
      const results = {
        currencies: Array.isArray(payload.currencies) ? payload.currencies : [],
        exchanges: Array.isArray(payload.exchanges) ? payload.exchanges : [],
        icos: Array.isArray(payload.icos) ? payload.icos : [],
        people: Array.isArray(payload.people) ? payload.people : [],
        tags: Array.isArray(payload.tags) ? payload.tags : []
      };
      saveCache(q, results);
      publish(q, results);
    } catch (e) {
      setError(e.message || "Couldn’t load results. Please try again.");
    } finally {
      setLoading(false);
    }
  }
  const onSubmit = e => {
    e.preventDefault();
    const q = query.trim();
    if (q.length < 3) {
      setError("Please type at least 3 characters.");
      return;
    }
    doSearch(q);
  };
  return <div className="space-y-2">
      <form onSubmit={onSubmit} className="flex gap-3 items-center">
        <div className="relative flex-1">
          <span className="absolute left-3 top-1/2 -translate-y-1/2 opacity-60" aria-hidden>
            🔍
          </span>
          <input className="w-full pl-9 pr-3 py-2 rounded-lg border border-neutral-300 bg-white dark:bg-transparent shadow-sm focus:outline-none" placeholder="Enter ticker, name, or contract (min 3 chars)…" value={query} onChange={e => {
    setQuery(e.target.value);
    if (error) setError("");
  }} aria-label="Search term" />
        </div>
        <button className="px-4 py-2 rounded-lg text-white disabled:opacity-60 disabled:cursor-not-allowed" style={{
    backgroundColor: PRIMARY
  }} type="submit" disabled={loading || query.trim().length < 3} title={query.trim().length < 3 ? "Type at least 3 characters" : ""}>
          {loading ? "Searching…" : "Search"}
        </button>
      </form>
      {error && <div role="alert" className="text-red-600 text-sm">{error}</div>}
    </div>;
};

export default function CoverageCheckerPage() {
  const [data, setData] = useState(null);
  return <>
      <CoverageChecker onUpdate={setData} />
      <CoverageResults externalData={data} />

      <h3>FAQs</h3>
      <AccordionGroup>
        <Accordion title="How do I find a coin ID (e.g., btc-bitcoin)?">
          Search by token name, ticker, or contract address. Results include canonical CoinPaprika IDs.
        </Accordion>
        <Accordion title="Can I search by contract address?">
          Yes. Paste the EVM/Solana/etc. contract address to resolve the asset and its CoinPaprika ID.
        </Accordion>
        <Accordion title="What if my asset isn’t found?">
          Try an alternative ticker/name or paste a contract. If still missing, contact support with details.
        </Accordion>
        <Accordion title="How do I use the ID in the API?">
          Use it in REST endpoints like <code>/v1/tickers/&#123;coin_id&#125;</code> or in Streaming API subscriptions.
        </Accordion>
        <Accordion title="Is the checker data live?">
          It queries our current dataset; availability reflects the latest index.
        </Accordion>
      </AccordionGroup>
    </>;
}
