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
    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

    Django

    Python

    Recognized by manage.py in project root

    Flask

    Python

    Recognized by flask in requirements.txt or pyproject.toml

    Express

    Node.js

    Recognized by express in package.json dependencies

    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
    AuthenticationBearer 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 gives the best coverage of what exists, traffic the best evidence of what is used, a specification the clearest statement of intent. Mature API programs keep all three and reconcile the differences deliberately.

    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.