GitHub - qualtyco/api-doctor: AI compiles hallucinated code that pass. This fixes it before accepting it. 100% Deterministic

GitHub

3 min read Original article ↗

node version npm downloads

api-doctor scans AI-generated code for bad API integrations.

Deterministic AST rules. Not a prompt. Same input, same output, every time.

Website

output.mp4

Quick Start

# Scan your project
npx @api-doctor/cli .

# Or install as an agent skill (Claude Code, Cursor, Windsurf)
npx @api-doctor/cli install

Install In Your Codebase (recommended)

Run it in CI on every PR

📦 Supported Providers

Provider Rules
Resend 13 rules
Supabase 12 rules
Auth0 4 rules
Firebase 19 rules
Browserbase 11 rules
OpenAI 7 rules
Tiptap 10 rules
ElevenLabs 10 rules
Twilio 9 rules
OpenAI Realtime 9 rules
S2 17 rules
AgentMail 14 rules

Full rule catalogs live in the GitHub repo under src/providers/<name>/README.md.


What it catches

Rules cover three categories: security (CWE/OWASP mapped), correctness (wrong endpoints), and reliability (production failure modes)

Category What it means Examples
Security Are your integrations secure? Mapped to CWE and OWASP audits. Hardcoded API keys, secrets in the client bundle, webhooks read before signature verification
Correctness Are you using the right endpoint or API for the job? Marketing email via batch send, missing unsubscribe links, test domain in production
Reliability Is your integration production ready or following suggested best practices? Missing idempotency keys, batch limits not enforced, error codes not mapped

Why deterministic matters

You can't test AI code with AI. api-doctor breaks that loop. Same rules, same output, every time. Not a model call. Not a prompt.


Telemetry

api-doctor sends anonymous usage data to PostHog so we can see whether the tool is helping developers catch real bugs.

What we collect:

  • CLI version, Node.js version, platform
  • Run context: local, CI, or agent
  • Which API SDKs were detected (e.g. resend, supabase) — provider names only
  • Which rules fired — rule names only, no code
  • Which documented SDK methods the scanned code calls (sdk_used, e.g. emails.send), plus a count of unrecognized calls on those clients (unknown_sdk_calls) — method names come from a fixed per-provider list shipped with the tool, never from your code
  • Which AI model (or agent) most likely wrote the scanned code (ai_model), plus which signal determined it (ai_model_source). This is inferred locally from agent config files (e.g. CLAUDE.md, .cursor/), AI co-author trailers in git history (e.g. Co-Authored-By: Claude Opus 4.8), model ids in local agent session state for this project (Claude Code's ~/.claude/projects/, aider's .aider.chat.history.md, Codex's ~/.codex/sessions/), and the --agent-model flag (or API_DOCTOR_AGENT_MODEL) that the installed agent skill asks coding agents to pass. Only the single resolved name is sent — never session content, commit data, or the underlying evidence
  • Score and finding counts
  • Score delta between runs on the same project (stored locally in that project's .api-doctor/run-history.json)
  • A hashed project identifier (project_hash) — SHA-256 of the scanned directory path, not the path itself
  • Sanitized error messages and stack traces on unexpected crashes (paths redacted)

What we never collect:

  • Your code or file contents
  • Raw file paths or project names
  • Email, name, or any personally identifying information
  • Git commit messages, human author names, or human author emails
  • Agent session transcripts — prompts, responses, and code in session files never leave your machine

A random anonymous ID is stored at ~/.api-doctor/install-id. Per-project run history is stored at <project>/.api-doctor/run-history.json. Both stay on your machine — only the event data above is sent to PostHog.

Opt out:

npx @api-doctor/cli . --no-telemetry
npx @api-doctor/cli install --no-telemetry

Or set API_DOCTOR_TELEMETRY=0 or DO_NOT_TRACK=1 in your environment.


Troubleshooting

Seeing an old version? npx sometimes caches an older resolution. Force a fresh pull with

npx @api-doctor/cli@latest .

Help

MIT © Qualty