Static-analysis CLI that detects mismatches between frontend API calls and backend endpoints.
Project description
๐ป API Ghost Hunter
A static-analysis CLI tool that scans full-stack codebases, detects API calls made by the frontend, detects API endpoints exposed by the backend, compares them, and identifies broken paths, potentially unused endpoints, and method mismatches. Supports both local directories and remote GitHub repositories.
The Problem
In modern full-stack web applications, frontends and backends evolve at different speeds. Over time, APIs get renamed, endpoints are deleted, and query/path parameter requirements shift. This leaves:
- Ghost Calls: Frontend code calling endpoints that no longer exist, causing
404 Not Founderrors in production. - Ghost Endpoints: Backend controllers exposing dead code that is no longer consumed by the frontend, adding maintenance overhead.
API Ghost Hunter solves this problem by statically analyzing your repository without requiring a running server, dynamic agents, or complicated integration test suites.
Key Features
- Static Analysis: Scans source code directly. Safe, fast, and does not require running your application or database.
- Remote Repository Scanning: Directly scan remote GitHub, GitLab, or Bitbucket repositories by passing the Git URL.
- Frontend Support: Automatically detects JS/TS
fetch()calls, direct and config-styleaxiosrequests,axios.create()instances with custombaseURLresolutions, Angular HttpClient, and jQuery AJAX shorthand/config calls. - Backend Support: Full detection of Spring Boot, Express.js, Flask, FastAPI, Django & DRF, NestJS, Go (Gin, Echo, Chi, net/http), Ruby on Rails, and OpenAPI/Swagger specs.
- Dynamic Route Matching: Correctly handles and matches path parameters such as
/api/users/123with backend mappings like/api/users/{id}. - Method Mismatch Detection: Reports when paths match but HTTP methods differ (e.g., frontend requests GET but backend expects POST).
- Intelligent Recommendations: Suggests similar matching endpoints using deterministic similarity algorithms (difflib, segment edit distance) with a confidence score.
- Environment Variable Resolution: Reads
.env,.env.local, and.env.developmentfiles to resolve runtime URL strings used in frontends. - CI/CD Integration: Supports custom exit codes (
--fail-on-broken), ignore files, JSON/SARIF reporting formats, and summary-only output.
Installation
You can install API Ghost Hunter from source or via pip (once published):
# Clone the repository
git clone https://github.com/api-ghost-hunter/api-ghost-hunter.git
cd api-ghost-hunter
# Install in editable mode
pip install -e .
Quick-Start Example
Scan your local workspace from the command line:
api-ghost-hunter scan .
Scan a remote GitHub repository directly:
api-ghost-hunter scan https://github.com/owner/fullstack-app
Scan separate remote frontend and backend repositories:
api-ghost-hunter scan . --frontend https://github.com/owner/frontend --backend https://github.com/owner/backend
Generate a SARIF report file for GitHub Code Scanning integration:
api-ghost-hunter scan . --format sarif -o results.sarif
Fail the CI build if there are broken calls with minimal output:
api-ghost-hunter scan . --quiet --fail-on-broken
Create a template configuration file:
api-ghost-hunter init
Display the complete interactive guide and tech reference:
api-ghost-hunter guide
Example Terminal Output
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ โ
โ โ
โ โโโโ โโโโ โโโ โโโโ โ โ โโโโ โโโโ โโโโโ โ โ โ โ โโโโ โโโโโ โโโ โโโโ โ
โ โโโโ โโโโ โ โ โโ โโโโ โ โ โโโโ โ โโโโ โ โ โ โ โ โโโ โโโโ โ
โ โ โ โ โโโ โโโโ โ โ โ โ โโโโ โ โ โ โโโโ โ โ โ โโโ โ โโ โ
โ โ
โ ยป Static API Contract & Drift Analyzer ยซ v0.1.0 โ
โ โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
โญโ ๐ Scan Metrics โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ Frontend API Calls Scanned 13 โ
โ Backend Endpoints Scanned 64 โ
โ API Contract Matches 10 โ
โ Broken Calls (Ghost APIs) 2 โ
โ HTTP Method Mismatches 0 โ
โ Potentially Unused Endpoints 55 โ
โ Unresolved Dynamic Calls 1 โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
๐ด GHOST APIS DETECTED (BROKEN CONTRACTS)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ CRITICAL: Frontend tries to call non-existent endpoint: โ
โ POST /api/posts โ
โ โ
โ Location: frontend/src/api.js:17 (axios framework) โ
โ ยป POST /api/users (63%) โ
โ ยป POST /api/users (63%) โ
โ ยป POST /api/users (63%) โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ CRITICAL: Frontend tries to call non-existent endpoint: โ
โ GET /api/orders โ
โ โ
โ Location: frontend/src/api.js:40 (axios framework) โ
โ ยป GET /api/users (66%) โ
โ ยป GET /api/users (66%) โ
โ ยป GET /api/users (66%) โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
Detailed Technical Architecture & Logic
1. Static Parsing Engine
A. Frontend API Call Detection
The frontend parser scans JS/TS/TSX files for API calls. Rather than using simplistic global regexes, it uses a multi-stage parser:
- Comment Stripping: The parser strips block (
/* ... */) and line (// ...) comments while replacing characters with whitespace/newlines. This preserves the exact code positions and line numbers for warnings and errors. - Fetch Extraction: Resolves calls to the standard
fetch()API. If a method option is not explicitly found, it defaults toGET. - Axios Extraction: Resolves direct axios methods (
axios.get,axios.post, etc.), standard axios configuration parameters (axios({ method: "...", url: "..." })), and custom client instances initialized viaaxios.create({ baseURL: "/api" }). The parser tracks multiple instances and automatically prepends their configuredbaseURLvalues to relative target endpoints. - Angular HttpClient: Extracts constructor-injected
HttpClientcalls (e.g.this.http.get<Item[]>('/api/items')orthis.http.request('POST', ...)) in TypeScript components. - jQuery AJAX: Resolves shorthand jQuery calls (
$.get,$.post,$.getJSON) and config objects ($.ajax({ url: '/api', method: 'PUT' })). - Template Literals: Translates template string placeholders (e.g.
`/api/users/${userId}`) into generic tokens (e.g./api/users/{param}) for route matching. - Environment Variables: Resolves
process.env.*andimport.meta.env.*references by matching them with keys found in local.env,.env.local, and.env.developmentfiles. - Unresolved Variable Detection: If the endpoint URL is composed of an unresolvable variable or custom function call (e.g.,
fetch(apiUrl)), it logs the expression asUNRESOLVEDto prevent false positive broken alerts.
B. Backend Endpoint Detection
The backend parser extracts exposed controller mappings:
- Spring Boot (Java/Kotlin): Scans
@RequestMapping("/prefix")annotations declared at the controller class level. - Express.js (Node.js): Resolves router instances,
app.get/post, chaining, and mount paths using.use(). - Flask (Python): Parses
@app.route(),methods=arrays, Blueprint routing, and<converter>variables. - FastAPI (Python): Extracts path parameters, async/sync routes, and
APIRoutersub-routers. - Django (Python): Resolves urlpatterns (
path(),re_path()), DRF Routers (DefaultRouter,SimpleRouter), ViewSets, and@api_viewdecorated functions. - NestJS (TypeScript): Detects controller decorators, HTTP method mappings, and router prefix structures.
- Go (Go): Resolves Gin (
r.GET), Echo (e.POST), Chi (r.Get), net/http (http.HandleFunc), and route groups. - Ruby on Rails (Ruby): Parses
routes.rbfor standard verbs, resource macros (resources :users), scopes, namespaces, and root paths. - OpenAPI / Swagger Specs: Parses API schemas (
openapi.yaml/json,swagger.yaml/json), extracting URLs, basePath configuration, servers block, and HTTP methods.
C. Smart Parser Selection
To ensure fast execution in large codebases, the scanner does not run all backend parsers on every file. It matches file extensions to select relevant parsers (e.g. .py files only invoke Django/Flask/FastAPI parsers, .go only invokes Go parser, etc.), significantly reducing processing time.
2. Route Normalization
Before matching, paths are normalized to guarantee comparison consistency:
- Query Stripping: Removes query parameters (e.g.
/api/users?page=1becomes/api/users). - Hash/Fragment Stripping: Removes hash segments (e.g.
/api/users#profilebecomes/api/users). - Slash Consolidation: Collapses consecutive slashes (e.g.
/api//users/becomes/api/users). - Trailing Slash Removal: Strips trailing slashes (e.g.
/api/users/becomes/api/users). - Spring Parameter Regex Normalization: Cleans up path parameter validation regexes (e.g.,
/api/users/{id:\d+}becomes/api/users/{id}). - Case Insensitivity: Converts paths to lowercase.
3. Matching & Similarity Engine
The engine resolves matching in five sequential passes to prevent false reports:
| Pass | Match Category | Details |
|---|---|---|
| 1 | Exact Match | Matches exact normalized path and HTTP method (e.g. frontend GET /api/users vs backend GET /api/users). |
| 2 | Dynamic Route Match | Matches path parameters and dynamic variables (e.g. frontend /api/users/123 or /api/users/{param} vs backend /api/users/{id}). |
| 3 | Method Mismatch | Matches the endpoint path, but the HTTP method differs (e.g., frontend sends GET /api/orders but backend accepts POST /api/orders). |
| 4 | Similar suggestions | If there is no match, computes similarity scores between the broken path and exposed backend endpoints using token segment comparison combined with edit-distance ratios. |
| 5 | Potentially Unused | Any backend endpoints that remain unmatched by any frontend call are flagged as "Potentially Unused". |
Supported Technologies
| Layer | Library / Framework | Support Features |
|---|---|---|
| Frontend | JS/TS fetch() |
Direct URLs, Multi-line options objects, Method extraction, Template literals |
| Frontend | Axios (axios) |
Direct calls, Config-style calls, axios.create() instances, baseURL resolutions |
| Frontend | Angular HttpClient |
http.get<T>(), http.post(), etc., http.request(), constructor injection resolution |
| Frontend | jQuery AJAX | $.get(), $.post(), $.getJSON(), $.ajax() configuration parameters |
| Backend | Spring Boot | @RequestMapping, @GetMapping, @PostMapping, etc., class-level + method-level path combination, array paths |
| Backend | Express.js (Node.js) | app.get(), app.post(), app.put(), app.patch(), app.delete(), app.all(), app.route(), express.Router(), app.use() mounting, :param path params |
| Backend | Flask (Python) | @app.route(), @app.get(), @app.post(), methods array, converters, Blueprints |
| Backend | FastAPI (Python) | @app.get(), @app.post(), @app.api_route(), APIRouter, {param}, {param:type}, async routes |
| Backend | Django (Python) | path(), re_path(), default and simple DRF routers, DRF ViewSets, @api_view decorators |
| Backend | NestJS (TypeScript) | @Controller() with prefix, @Get(), @Post(), @Put(), @Patch(), @Delete(), @All(), :param path params |
| Backend | Go Router | Gin (r.GET), Echo (e.POST), Chi (r.Get), net/http (http.HandleFunc), group prefix resolution |
| Backend | Ruby on Rails | get/post/put/delete, resources macro with only/except filters, namespace, scope blocks |
| Specs | OpenAPI / Swagger | YAML & JSON format support, servers configuration blocks, basePath definitions |
Configuration
You can configure options in a project-root configuration file called ghosthunter.yaml:
frontend:
paths:
- frontend/src
backend:
paths:
- backend/src
ignore:
- "/actuator/**"
- "/api/internal/**"
exclude:
- "**/*.test.ts"
- "**/generated/**"
Configuration Fields
- frontend.paths: A list of paths to look for frontend files in. Defaults to root scan directory if omitted.
- backend.paths: A list of paths to look for backend files in. Defaults to root scan directory if omitted.
- ignore: API URL path patterns (glob-style) to ignore from matching. If an API call or endpoint starts with or matches a prefix, it is skipped.
- exclude: File exclusion patterns (glob-style) to skip scanning (e.g. test files, mock databases).
CLI arguments take precedence over any settings specified in ghosthunter.yaml.
CLI Reference
api-ghost-hunter scan
api-ghost-hunter scan [DIRECTORY] [OPTIONS]
Arguments
DIRECTORY: The root workspace directory or remote Git repository URL to scan. Defaults to..
Options
--frontend: Override frontend folder paths or remote Git URL.--backend: Override backend folder paths or remote Git URL.--format: Output format:terminal(polished panels),json, orsarif.--output,-o: File path to write the JSON/SARIF report to.--quiet,-q: Print only a one-line summary. Ideal for CI/CD usage.--fail-on-broken: If set, returns exit code1when any broken frontend call is detected.--ignore: Add API patterns to ignore during scan.--verbose: Show detailed debug logs and warnings.
api-ghost-hunter init
api-ghost-hunter init [DIRECTORY] [OPTIONS]
Generates a starter ghosthunter.yaml configuration file.
api-ghost-hunter guide
api-ghost-hunter guide
Displays complete user manual and framework documentation directly in the terminal.
Exit Codes
0: Scan completed cleanly with no broken calls.1: Broken frontend calls (or method mismatches) were detected (only triggers if--fail-on-brokenis enabled).2: Configuration, parsing, or command execution error.
CI/CD Usage
GitHub Actions (SARIF Integration)
Add this step to your GitHub Actions workflow file to run checks and upload results:
- name: Run API Ghost Hunter Scan
run: |
pip install api-ghost-hunter
api-ghost-hunter scan . --format sarif --output results.sarif
- name: Upload SARIF report
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
Contributing
Please read CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file api_ghost_hunter-0.1.0.tar.gz.
File metadata
- Download URL: api_ghost_hunter-0.1.0.tar.gz
- Upload date:
- Size: 61.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6d8d7c971b9117a00576f6292d8dfa6137dfea56791d30ef854db092d59284e
|
|
| MD5 |
757b6c35632ba185bc220e3810f647ca
|
|
| BLAKE2b-256 |
91a3d6e87a98138bdf486375f1f70f8d892035eb237953b10c9e58fc630c304d
|
File details
Details for the file api_ghost_hunter-0.1.0-py3-none-any.whl.
File metadata
- Download URL: api_ghost_hunter-0.1.0-py3-none-any.whl
- Upload date:
- Size: 70.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
adacb515bf5d3532936b98d97a69d5ecf44cf682249f31e9a217c3a8c1a12c5b
|
|
| MD5 |
69aa9404a60ad3bc69a29977e90f5fa8
|
|
| BLAKE2b-256 |
d917d1cc088c7460517745852606eba3de2faea55a6a5da918e2a4df6da14bec
|