Free VS Code Extension

Know every API
your code exposes.

Your OpenAPI file, gateway config, and traffic logs describe the API second-hand. The source code defines it. APIScout reads the source — locally, in VS Code — and turns it into an endpoint inventory you can review and export.

No code leaves your machineNo running service requiredOpenAPI 3.x YAML and JSON

Need a specification from an existing backend? Follow the generate OpenAPI from code workflow.

payments.ts - payments-api•••
TSpayments.ts×
src › routes › payments.ts
1  import { Router } from "express";
2  import { requireAuth } from "../middleware/auth";
3
4  const router = Router();
5
6  router.get("/payments", requireAuth,
7    async (req, res) => {
8      const payments = await db.payment.findMany({
9        where: { accountId: req.user.accountId }
10     });
11
12     return res.json({ data: payments });
13   }
14 );
AGET /paymentsExplain endpointView in Explorer
APIScout: 24 endpointsLn 12, Col 44 UTF-8 TypeScript

The problem

Your API surface is
emergent, not declared.

No file in your repository lists the endpoints your service exposes. That list is assembled at startup, from route registrations spread across modules and combined with prefixes applied wherever routers are mounted.

Everything that describes the result is secondary, and each decays differently:

  • An OpenAPI file describes the API as it was understood when someone last edited it.
  • A gateway config describes the routes that gateway manages — not the ones the service implements behind it.
  • A traffic log describes the routes something called while you were watching.

All three are useful. None is authoritative. When they disagree with the code, the code wins — because the code is what is running. The gap between them has its own OWASP entry: improper inventory management.

Why this happens

Four changes that pass review.

None is a bug in the ordinary sense. Each changes what the service exposes in a way a line-oriented diff does not surface.

diffComposition
- app.use("/internal", adminRouter);
+ app.use("/v1/admin", adminRouter);
01

A one-line change with no diff in any handler

Prefixes are applied where routers are mounted, files away from the handlers. No handler changed here — but every route in adminRouter moved from a prefix an ingress rule blocked to one it forwards. The reviewer sees one changed line.

pythonOpacity
app.mount("/legacy", legacy_wsgi_app)
02

The routes a schema generator cannot see

springdoc and FastAPI's built-in schema read the framework's own routing table, so they cover routes declared the expected way and miss the rest. A mounted sub-application is opaque to that mechanism: reachable in production, absent from /openapi.json.

typescriptAuthorization
router.patch("/:id", requireAuth, updateProject);
router.delete("/:id", requireAuth, deleteProject);
03

A destructive method added for symmetry

An agent asked to let users edit projects adds delete too, because the pattern looks incomplete without it. requireAuth proves the caller is authenticated — not that they own this project. That is the whole substance of a broken object-level authorization (BOLA) finding, in two lines.

typescriptDrift
app.use("/v1", legacyRouter); // "temporary"
app.use("/v2", currentRouter);
04

The version that outlived its documentation

Traffic-based discovery only sees routes something called during capture, and nobody calls v1 much. Two years on the portal documents v2 only, security scopes tests from the portal, and v1 is still mounted — still running the authorization logic it shipped with.

How APIScout solves it

Read the definition,
not a description of it.

APIScout analyses backend source in your workspace and reconstructs the surface the way the framework does: it follows route registration through the modules that declare it, resolves mount-time prefixes, and reports a full path, method, and source location for every endpoint.

01

It runs where the code is

Discovery is local, on the workspace already open in VS Code. No environment to stand up, no service running, no traffic window, no upload. You can scan a branch that has never been deployed.

02

It keeps the link to the implementation

Every endpoint resolves to a file and line. When a row raises a question — who calls this, is it still needed — the answer is one jump away.

03

It produces a standard artifact

The export is OpenAPI 3.x. Deliberately unremarkable: it feeds documentation portals, client generators, contract tests, and security scanners with no proprietary format in between.

On the optional AI

APIScout can use local models to summarize endpoints and draft descriptions. Opt-in, on your machine. Discovery itself is deterministic analysis — the models add editorial convenience, not the inventory.

Supported frameworks

Will it read your backend?

APIScout ships a parser per framework, so it resolves routes the way that framework registers them rather than guessing from string matches.

FastAPI

Python

Recognized by fastapi in requirements.txt or pyproject.toml

Read endpoint discovery guide

Django

Python

Recognized by manage.py in project root

Read endpoint discovery guide

Flask

Python

Recognized by flask in requirements.txt or pyproject.toml

Express

Node.js

Recognized by express in package.json dependencies

Read endpoint discovery guide

NestJS

TypeScript

Recognized by @nestjs/core in package.json dependencies

Also an input

An existing OpenAPI file in the workspace is parsed alongside the source, so you can compare what a checked-in spec claims against what the code registers.

Not yet covered

Spring, Rails, Laravel, and Go have no parser today. A scan of those projects returns whatever the OpenAPI parser finds, not a source-derived route inventory.

Technical workflow

From checkout to exported spec.

Step 01

Install and open

Install from the VS Code Marketplace and open the backend repository. No configuration, no annotations, no dependency added to the application.

Step 02

Scan the source tree

APIScout walks the workspace and resolves route registrations into full paths with their methods, grouped by module.

Step 03

Review and trace

Filter by method or path. Open an endpoint to see its source location, then jump into the file to check middleware and handler logic.

Step 04

Export and hand off

Export OpenAPI YAML or JSON. Commit it as a baseline, feed a documentation portal, or import it into ApyGuard as test scope.

Source treeEndpoint inventoryOpenAPI 3.xDocs, clients, tests

Inside the extension

See the API you
actually expose.

Search by path or method, inspect source-backed details, and jump from the inventory to the implementation. This sample is interactive — try filtering it.

API Explorer
PAYMENTS3
CUSTOMERS2
Scan complete24 endpoints
GET/payments

Lists account-scoped payment records and maps the route back to the source file instantly.

Source
Authentication✓Bearer token
Response200200 application/json
Review cues2 findings
!

Parameter and auth context stay attached to the route

APIScout keeps route details grounded in implementation context so OpenAPI cleanup starts from real code.

A

Move from code discovery to schema export

The extension helps teams turn route inventory into an OpenAPI baseline instead of manually reconstructing paths from scattered files.

Three ways to build an inventory

Source, traffic, or specification.

These are competing evidence types more than competing products. Knowing which question each one answers is most of the skill.

QuestionSource analysisTraffic captureSpec-first
Finds a route nobody has calledYes — registration is in the codeNo — coverage equals observed trafficOnly if someone documented it
Reflects code merged five minutes agoYes — scans the working treeAfter deploy, then after trafficOnly after a manual edit
Requires a running serviceNoYes — needs a deployed environmentNo
Proves authorization actually holdsNo — structure, not behaviorPartially — observed responsesNo — describes intent

Source analysis shows what is implemented, while browser traffic shows what is exercised. Compare those perspectives by exploring the Chrome extension workflow with live API traffic.

What changes for each role

Visibility pays before it becomes a requirement.

For developers

You stop reconstructing routing graphs by hand. Onboarding starts with a list of what a service exposes. Before opening a pull request, you can check what your branch made reachable — including routes an agent added while you reviewed something else.

For teams and architects

The API surface becomes a reviewable artifact instead of tribal knowledge. Migrations start from a route baseline rather than assumptions, and committed exports turn contract change into something you can diff between releases.

For security and DevSecOps

Test scope stops depending on whichever spec development could find. Undocumented, internal, and legacy routes enter the inventory on equal footing. Because discovery runs pre-deploy, a new privileged endpoint can be assessed before it becomes production behavior.

Export and test

Turn visibility into
a usable spec.

Once you know the real API surface, export OpenAPI YAML or JSON from the implementation. Use it for documentation, contract work, or API security testing in ApyGuard.

  • 1. Discover what is exposed

    Scan backend source locally to find routes that traffic capture and stale specs can miss.

  • 2. Trace every route to code

    Filter by method and path, then jump to the file that defines the endpoint and its context.

  • 3. Export a usable OpenAPI baseline

    Generate YAML or JSON from the implementation for documentation, testing, and security workflows.

openapi: 3.1.0
info:
  title: payments-api
  version: 1.0.0
paths:
  /payments:
    get:
      summary: List payments
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Payment list
    post:
      summary: Create payment
      responses:
        "201":
          description: Payment created
  /payments/{id}:
    get:
      summary: Get payment by id
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
Export readyOpenAPI 3.x compatible

In practice

Make API visibility a normal step.

Check the API surface on pull requests that touch route registration.

Not on every pull request, and not from the diff alone.

Commit reviewed exports as release artifacts.

The diff between two releases is the shortest description of contract change.

Scope security tests from the export, with disposable identities.

Not from the developer portal — that describes the product, not the service.

Give every intentionally undocumented route an owner.

Undocumented is a legitimate choice; unowned is not.

Run discovery on first checkout of an unfamiliar service.

A route list explains it faster than a README written for an older version.

Treat a traffic inventory as complete for its capture window only.

And a green CI run as evidence that features work, not that exposure is intended.

FAQ

Questions engineers ask before installing.

How is this different from swagger-autogen, springdoc, or FastAPI's built-in schema?

Those run inside your application and read the framework's routing table, so they only see routes registered the expected way. APIScout analyses source without executing anything. If you already publish a generated spec, this is a good way to check what it missed.

Why not just use traffic-based API discovery?

Traffic tells you what was called; source tells you what can be called. Most teams need both — which is why ApyGuard offers traffic discovery alongside APIScout, not instead of it.

Does my source code leave my machine?

No. Scanning is local to the workspace open in VS Code, and the optional AI runs against local models. Discovery and export need no account and no network call.

Is the generated OpenAPI file production-ready documentation?

It is a source-backed baseline. Paths and methods come from the implementation and are reliable; descriptions and examples are not something code can supply. Generate the structure, then add the meaning.

What does it cost?

Free, from the Visual Studio Code Marketplace, and it works without an ApyGuard account.

Can it detect vulnerabilities?

No. APIScout reports structure. The most serious API flaws — broken object- and function-level authorization — are runtime properties of a specific identity, and proving them means sending requests as one user and seeing what another user's data does in the response.

How often should the inventory be regenerated?

When routing changes, not on a calendar. Adding a router, moving a mount point, or changing an authentication boundary warrants a new one.

When APIScout is not enough

Discovery is the first step,
not the whole job.

Static discovery reports structure. It does not execute your application, and there are questions it cannot answer.

It cannot confirm that a deployment mounts the routes a branch declares, or that an ingress or service mesh has not added paths of its own. And it cannot tell you whether authorization holds — whether GET /invoices/:id returns another tenant's invoice for a valid token belonging to someone else.

That last category is where the most damaging API flaws live — broken object-level authorization and broken function-level authorization. Proving them requires real requests under controlled identities. No amount of source analysis substitutes for it.

How ApyGuard extends the workflow

Test the surface you discovered.

ApyGuard takes the OpenAPI file APIScout generated and uses it as test scope, exercising each endpoint under controlled identities to check for OWASP API Top 10 conditions — authorization failures, mass assignment, injection, misconfiguration — against development, staging, production, or private-network APIs.

The split is clean: APIScout answers what is exposed, ApyGuard answers whether that exposure is safe.

Source code → APIScout → OpenAPI → ApyGuard → Automated security testing

Test this API in ApyGuard

APIScout for VS Code

Find out what your
service actually exposes.

Free and local-first. Install it, open a backend repository, and read the endpoint inventory before your next release decides it for you.