Check if an npm or PyPI package — or a specific function in it — exists
Last updated:
This API answers one question an AI coding agent can't answer on its own: does this npm or PyPI package exist, and does the function or method it's about to call actually exist in the exact version pinned in your lockfile? It reads the published package itself — TypeScript .d.ts declarations, DefinitelyTyped, Python wheel source and .pyi stubs — without running any of its code, and answers over MCP or REST.
Why this exists
A USENIX Security 2025 study (Spracklen et al.) had 16 models write 576,000 code samples. Of the 2.23 million package recommendations in them, 440,445 (19.7%) named packages that do not exist, 205,474 unique names. In a separate test, the authors re-ran 500 prompts that had produced a hallucination 10 times each, and 43% of those hallucinated names came back in all 10 runs (paper). Predictable names are what make "slopsquatting" (registering the invented name with malware) practical.
The quieter failure is calling a real API that isn't in your version — useActionState exists in React 19 but not React 18; numpy.asfarray was removed in NumPy 2.0. The code looks right, passes review, and breaks at runtime.
What it checks
| Endpoint | Question it answers | Price |
|---|---|---|
check_symbols / POST /v1/symbols | Does symbol exist in package@version? Returns exists, kind, signature, deprecation notes and did-you-mean suggestions | $0.002 per symbol |
check_packages / POST /v1/packages | Does the package exist? Was the pinned version published? Is it a look-alike of a popular package, brand new, or an npm security placeholder? | $0.0005 per package |
check_diff / POST /v1/diff | For a diff: every added import, and whether each imported name exists in the pinned version | $0.01 per diff |
exists: null means "cannot be known statically" (a dynamic Python __getattr__, a compiled extension, or an untyped npm package) — it is never reported as a guess.
Example (real output)
curl -s https://dropin-apis--exactground-api.apify.actor/v1/symbols \
-H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" \
-d '{"ecosystem":"pypi","package":"numpy","version":"2.1.0","symbols":["numpy.linalg.norm","numpy.asfarray"]}'{
"ecosystem": "pypi", "package": "numpy", "version": "2.1.0", "packageExists": true,
"results": [
{ "symbol": "numpy.linalg.norm", "exists": true, "kind": "function" },
{ "symbol": "numpy.asfarray", "exists": false, "missingAt": "numpy.asfarray",
"suggestions": ["array", "asarray", "NDArray", "ndarray", "recarray"] }
]
}A package check on a typo'd name:
{ "ecosystem": "pypi", "name": "reqeusts", "verdict": "block", "registry": "missing",
"reasons": ["\"reqeusts\" does not exist on PyPI", "did you mean \"requests\"? (it is 1 edit away)"] }How it compares
| Tool | Answers | What it's for |
|---|---|---|
| This Actor | Yes/no, from the published artifact itself | Does this exact name/version/symbol exist |
| Context7 | Documentation text for a prompt | What does this library's docs say |
| Socket | Security score for packages that exist | Is this existing package malicious or risky |
Context7 and Socket solve different, adjacent problems — this tool is the one that catches a name or API that was never real in the first place.
Connect an agent (MCP)
claude mcp add --transport http exactground https://dropin-apis--exactground-api.apify.actor/mcp \
--header "Authorization: Bearer $APIFY_TOKEN"Also works with Cursor, VS Code, Codex and any MCP-compatible client (mcp.json or ~/.codex/config.toml), and can be found by agents on the Apify MCP server via search-actors.
Pricing
Pay per event, no subscription. A typical agent session (5 package checks, 20 symbol checks, 2 diffs) costs about $0.06. Requests that fail (invalid input, registry unreachable) are not charged; setting a maximum total charge stops the API with HTTP 402 once reached.
Open ExactGround on Apify · Free local install guard
FAQ
How do I stop Claude Code or Cursor from installing hallucinated packages?
Install the free ExactGround hook — it blocks npm/pnpm/yarn/bun/npx and pip/uv/poetry/pdm/pipx installs of names that don't exist, before they run. This API adds version-exact function/method checks on top.
What is slopsquatting?
Attackers publish malware under package names AI models tend to invent. When an agent runs an install command on the invented name, it installs the attacker's code instead.
How is this different from Context7?
Context7 puts documentation text into the prompt. This API answers a yes/no question from the published artifact itself — does a given symbol exist in a given version — and returns a verdict (ok, warn or block). It does not intercept installs itself; the free local ExactGround hook is what refuses an install in your agent.
Which languages are supported?
npm (JavaScript and TypeScript) and PyPI (Python).
Is my code sent anywhere?
Only what you send in a request — package names and symbol paths, or a diff for check_diff. Nothing is stored after the response.
Is this affiliated with npm, PyPI, Anthropic, OpenAI or Cursor?
No. It is an independent tool.