Source Code API Discovery
Levo's Source Code API Discovery catalogs every REST endpoint defined in a repository — handlers, paths, methods, path and query parameters, request and response types — and imports the result into Levo.ai. It runs entirely against a source checkout: the application is not executed, no traffic is captured, and no staging environment is required.
This is the fastest path to a complete API inventory for repositories you already govern in source control. Two modes are supported and can be combined on the same repository:
- Source-code scan — statically analyzes application code and generates a new OpenAPI 3.0.1 specification.
- Specification import — locates existing OpenAPI or Swagger specification files (
openapi.yaml,openapi.yml,swagger.json, etc.) in the repository and imports them as-is, preserving the original OpenAPI or Swagger version.
How it works
- The Levo scanner runs locally as a container — on a developer workstation, a CI runner, or any host with Docker — against a repository checkout you control.
- Depending on the mode, the scanner prepares an API specification for upload in one of two ways:
- Source-code scan: static analysis extracts route definitions, handler bindings, annotations, and parameter schemas directly from the source tree and generates an OpenAPI 3.0.1 specification. The application is never compiled-and-run or otherwise executed against live traffic.
- Specification import: the scanner locates existing
.yaml,.yml, or.jsonfiles identified as OpenAPI or Swagger specifications in the repository and uses them as-is. No static analysis is performed, and the specification's original format (OpenAPI 3.x or Swagger 2.0) is preserved.
- The specification is transmitted over TLS to your Levo tenant at https://api.levo.ai.
- Levo validates the specification server-side and imports it into the application and environment you specify. The application record is created automatically on first run.
- Endpoints become available in the Levo dashboard for API inventory, risk scoring, and security testing.
Source code never leaves the host executing the scanner. Only the generated or discovered API specification itself is uploaded to https://api.levo.ai.
Supported languages and frameworks
| Language | File Markers | Notes |
|---|---|---|
| Java | .java, pom.xml, build.gradle | Requires compilation |
| JAR | .jar files | Pre-compiled Java archives |
| JavaScript | .js, package.json | — |
| TypeScript | .ts, tsconfig.json | — |
| Python | .py, requirements.txt, setup.py, pyproject.toml | Supports 3.x through 3.13 |
| C / C++ | .c, .cpp, .h | Includes .h headers and pre-processed .i files |
| PHP | .php, composer.json | Runtime PHP ≥ 7.4 required. Source compatibility: PHP 7.0 – 8.4 |
| Ruby | .rb, Gemfile | Runtime Ruby 4.0.x required. Source compatibility: Ruby 1.8 – 4.0.x |
| C# | .cs, .csproj | Supports C# code targeting .NET Framework 4.x through .NET 9. Pass --language csharp. Uses a Roslyn-based static analyzer bundled in the container image — no application build, runtime, or environment configuration required. VB.NET and F# are not supported. |
| Android APK | .apk files | Requires the Android SDK. Set the ANDROID_HOME environment variable, or use the container image. |
| Scala | .scala, build.sbt | Work in progress |
Prerequisites
- Docker is installed on the host and you can launch containers with outbound network connectivity.
- https://api.levo.ai is reachable from the host that will run the scan.
- Your CLI Authorization Key — get it from app.levo.ai/settings/keys.
- Your Organization ID — get it from app.levo.ai/settings/organization.
Get your CLI authorization key from app.india-1.levo.ai/settings/keys and your organization ID from app.india-1.levo.ai/settings/organization instead.
Approach-specific prerequisites are listed under each approach below.
Integration approaches
Source Code API Discovery can be consumed in one of the following ways today. All approaches run the same underlying scanner (published as the levoai/code-scanner container image) and upload the specification to the same Levo tenant — a generated OpenAPI 3.0.1 spec for source-code scans, or the existing OpenAPI/Swagger spec as-is for specification imports. Additional integrations are on the roadmap.
| Approach | Best suited for |
|---|---|
| Docker | Interactive scans from a developer workstation, scheduled scans in any CI system (Jenkins, GitLab CI, Bitbucket Pipelines, CircleCI, Azure Pipelines, etc.), and ad-hoc runs inside a container. |
| GitHub Action | Declarative, automated scans triggered on every push or pull request for repositories hosted on GitHub. |
Choose based on where your repositories live and how you want scans triggered. You can adopt multiple approaches in the same organization — for example, Docker for ad-hoc backfills and the GitHub Action for continuous coverage.
Approach 1: Docker
Run the scanner locally or in any CI system as a Docker container. No Levo CLI installation is required; everything the scanner needs ships inside the image.
Mode A: Scan source code and discover REST endpoints
Use this mode to reverse-engineer an OpenAPI specification from application source.
First, pull the latest image:
docker pull levoai/code-scanner:latest
Then navigate to the project directory you want to scan. Set --language to match your project's programming language (e.g., java, python, javascript, typescript, c, cpp, php, ruby, csharp, dotnet):
cd /path/to/your/project
docker run --rm \
-e LEVO_BASE_URL=https://api.levo.ai \
-v "$(pwd)":/workspace:rw \
levoai/code-scanner:latest \
--app-name "my-api" \
--env-name "staging" \
--language <your-project-language> \
--key <your-authorization-key>
Example: If your Java project is at /home/john/payment-service:
cd /home/john/payment-service
docker run --rm \
-e LEVO_BASE_URL=https://api.levo.ai \
-v "$(pwd)":/workspace:rw \
levoai/code-scanner:latest \
--app-name "payment-service" \
--env-name "staging" \
--language java \
--key <your-authorization-key>
On success, you'll see: "Application 'payment-service' has been created successfully!" — check your Levo dashboard.
Set -e LEVO_BASE_URL=https://api.india-1.levo.ai instead.
If you belong to multiple organizations, add the -o flag:
docker run --rm \
-e LEVO_BASE_URL=https://api.levo.ai \
-v "$(pwd)":/workspace:rw \
levoai/code-scanner:latest \
--app-name "my-api" \
--env-name "staging" \
--language <your-project-language> \
--key <your-authorization-key> \
-o <your-organization-id>
Flags Reference
| Flag / Env Var | Required | Description |
|---|---|---|
-e LEVO_BASE_URL | No | Levo SaaS API URL. Default: https://api.levo.ai. India: https://api.india-1.levo.ai. |
-v "$(pwd)":/workspace:rw | Yes | Mounts your source code into the container. |
--app-name | Yes | Application name on the Levo dashboard. Created automatically on first scan. |
--env-name | Yes | Environment label (e.g., staging, production). |
--language | Yes | Source language: java, python, javascript, typescript, c, cpp, php, ruby, csharp. |
--key | Yes | Your CLI authorization key. |
-o | No | Organization ID. Required only if you belong to multiple organizations. |
Mode B: Import existing OpenAPI / Swagger specifications
Use this mode when your repositories already contain hand-authored or generated OpenAPI specifications (.yaml, .yml, or .json) and you want to import them directly, without running static analysis.
cd /path/to/your/project
docker run --rm \
-e LEVO_BASE_URL=https://api.levo.ai \
-v "$(pwd)":/workspace:rw \
levoai/code-scanner:latest \
schema \
--dir . \
--env-name "staging" \
--key <your-authorization-key>
Notes:
- The scanner recursively searches the mounted directory for OpenAPI/Swagger spec files; non-spec files are skipped.
- The application name for each imported specification is taken from the
info.titlefield of that specification. - Use
--dir <relative-path>to scan only a sub-directory of the project.
Approach 2: GitHub Action
Automate code scanning in your CI/CD pipeline. Every push to the configured branches triggers a scan, and discovered API endpoints are uploaded to the Levo dashboard automatically. The Action supports the same languages as the Docker approach (see Supported languages and frameworks).
Prerequisites
- A Levo.ai account.
- A GitHub repository with source code in a supported language.
- Your CLI Authorization Key and Organization ID stored as GitHub Secrets.
Setup
Step 1: Add secrets to your repository on GitHub.
Go to your repo → Settings → Secrets and variables → Actions → New repository secret and add the following:
| Secret Name | Where to Get It |
|---|---|
LEVO_AUTH_KEY | app.levo.ai/settings/keys |
LEVO_ORG_ID | app.levo.ai/settings/organization |
Step 2: Create a workflow file in your repository at .github/workflows/levo-code-scan.yml:
name: Levo Code Scan
on:
push:
branches: [main]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Levo Code Scanner
uses: levoai/actions/scan@main
with:
authorization-key: ${{ secrets.LEVO_AUTH_KEY }}
organization-id: ${{ secrets.LEVO_ORG_ID }}
app-name: "my-api"
language: "java"
env-name: "staging"
Replace my-api with your application name and java with your repository's programming language.
Action inputs
| Input | Required | Description |
|---|---|---|
authorization-key | Yes | CLI authorization key. Get it from app.levo.ai/settings/keys. |
organization-id | Yes | Your Levo organization ID. |
app-name | Yes | Application name on the Levo dashboard. |
language | Yes | Source language: java, python, javascript, typescript, c, cpp, php, ruby, csharp. |
dir | No | Relative path within the repository to scan. Default: . (the repository root). Use a subdirectory path (for example, services/payments) to scan only part of a monorepo. |
env-name | No | Environment label. Default: staging. |
saas-url | No | Levo SaaS API URL. Default: https://api.levo.ai. India: https://api.india-1.levo.ai. |
scanner-docker-image | No | Docker image override. Default: levoai/code-scanner:latest. |
Action environment variable
The Action sets the following environment variable for use by downstream steps in the same job:
| Variable | Description |
|---|---|
scan-success | true if the scan succeeded, false otherwise. |