@api-doctor/cli
v0.0.19
Published
Deterministic verification rules for AI-generated API integrations
Maintainers
Readme
api-doctor
api-doctor scans AI-generated code for bad API integrations.
Deterministic AST rules. Not a prompt. Same input, same output, every time.
Website →
https://github.com/user-attachments/assets/53dab24f-528b-4f1b-87a9-8870002053d8
Quick Start
npx @api-doctor/cli .After running it installs api-doctor as a skill
at .agents/skills/api-doctor/SKILL.md type "\api-doctor fix it" to get a quick fix or integrate our CI for larger and continous fixes
Install In Your Codebase (recommended)
📦 Upgrading API Providers
# Plan a major-version upgrade — copy the target from the "Upgrade plan" column
npx @api-doctor/cli . --migrate supabase@2| Provider | Rules | SDK verified | Upgrade plan |
| --- | --- | --- | --- |
| Resend | 13 rules | [email protected] | — |
| Supabase | 10 rules | @supabase/[email protected] | --migrate supabase@2 |
| Auth0 | 4 rules | [email protected] | — |
| Firebase | 19 rules | — | — |
| Browserbase | 12 rules | @browserbasehq/[email protected] | --migrate browserbase@2 |
| OpenAI | 6 rules | — | — |
| Tiptap | 10 rules | @tiptap/[email protected] | --migrate tiptap@3 |
| ElevenLabs | 10 rules | @elevenlabs/[email protected] | — |
| Twilio | 7 rules | — | — |
| OpenAI Realtime | 9 rules | — | — |
| S2 | 18 rules | @s2-dev/[email protected] | --migrate [email protected] |
| AgentMail | 15 rules | [email protected] | --migrate [email protected] |
SDK verified is the release a human last read the SDK source against — not the latest published version, and never a version api-doctor tells you to be on.
Upgrade plan is available for providers with hand-verified records of what a
major version changed. --migrate <provider>@<version> maps every call site that
changes on the way, grouped by how much judgement each one needs.
See Planning an SDK upgrade. It only runs when you ask for it by name; a plain scan never mentions an upgrade.
Full rule catalogs live in the GitHub repo under src/providers/<name>/README.md.
What it catches
| 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 | | Compatabiltiy | Is your SDK version updated to latest release? | Upgrade your codebase with the latest SDK version with best practices for that version |
Planning an SDK upgrade
A scan tells you what is wrong against the SDK version you have installed.
--migrate never upgrades anything, never fails a build, and never runs on its
own
npx @api-doctor/cli@latest . --migrate supabase@2Migration plan @supabase/supabase-js 1.35.7 → 2.x
12 call sites across 9 changes
● Drop-in replacements — 2 sites
verified identical on the wire — safe to apply in bulk
auth.update → auth.updateUser (1)
auth.verifyOTP → auth.verifyOtp (1)
● Replacements with a behaviour change — 3 sites
maps one-to-one, but the behaviour differs
getSubscriptions → getChannels (1)
removeAllSubscriptions → removeAllChannels (1)
removeSubscription → removeChannel (1)
● Splits — the arguments decide — 2 sites
successor depends on the arguments at each site
auth.signIn → auth.signInWithPassword | auth.signInWithOtp | ... (2)
● Contract changes — surrounding code moves — 4 sites
call shape changes — surrounding code moves with it
auth.session → auth.getSession (1)
auth.user → auth.getUser (3)
● Removed with no successor — 1 site
no successor; a person has to decide
auth.setAuth → no successor (1)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) - Which AI model (or agent) most likely wrote the scanned code (
ai_model), plus which signal determined it (ai_model_source). - For fix runs: which agent was chosen (
claude,cursor, orcodex) - 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
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-telemetryTroubleshooting
Seeing an old version? npx sometimes caches an older resolution. Force a fresh pull with
npx @api-doctor/cli@latest .Help
- New provider? Open an issue
MIT © Qualty
