-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference
This page summarizes every REST endpoint exposed by OsWL. For interactive documentation with request/response schemas, use Swagger UI in the local profile (http://localhost:8080/swagger-ui.html). Swagger is disabled in prod.
Browser-based requests use Spring Security cookie sessions. Login via POST /login.
CLI endpoints require:
Authorization: Bearer oswl_<api_key>
POST /api/scan additionally requires submitterEmail and submitterPassword in the JSON body to authenticate the submitter. Successful ingests are recorded in the audit log (SCAN.INGEST) with the submitter email — not in a dedicated scan-result column.
| Method | Path | Description |
|---|---|---|
GET |
/login |
Login page |
POST |
/login |
Submit credentials |
GET |
/login/otp-verify |
OTP verification page |
POST |
/login/otp-verify |
Submit OTP code |
POST |
/login/otp-resend |
Re-send OTP email |
GET |
/setup |
Setup wizard page (first boot only) |
POST |
/setup |
Submit setup wizard form |
| Method | Path | Permission | Description |
|---|---|---|---|
GET |
/projects |
PROJECT_VIEW |
Projects dashboard |
GET |
/projects/list |
PROJECT_VIEW |
Projects list (JSON) |
DELETE |
/projects/{id} |
PROJECT_DELETE |
Soft-delete project |
POST |
/projects/{id}/restore |
PROJECT_RESTORE |
Restore from trash |
DELETE |
/projects/{id}/permanent |
PROJECT_PERMANENT_DELETE |
Permanently delete |
DELETE |
/projects/trash/all |
PROJECT_PERMANENT_DELETE |
Empty trash |
DELETE |
/projects/trash/selected |
PROJECT_PERMANENT_DELETE |
Delete selected trash |
POST |
/projects/trash/restore-selected |
PROJECT_RESTORE |
Bulk restore |
GET |
/projects/cards |
PROJECT_VIEW |
Project card HTML fragment (dashboard) |
GET |
/projects/scan-status/stream?ids= |
PROJECT_VIEW |
SSE — scan-update when listed projects finish scanning |
POST |
/projects |
PROJECT_CREATE |
Create project (JSON) |
PATCH |
/api/projects/{id}/deployment-profile |
PROJECT_UPDATE |
Set AI deployment profile for CVE triage ({ "deploymentProfile" }) |
Requires PROJECT_CREATE (or System Admin). Session auth.
| Method | Path | Description |
|---|---|---|
GET |
/projects/quick-import |
Quick Import page |
GET |
/api/quick-import/connections |
List VCS connections for the current user |
GET |
/api/quick-import/repos?provider= |
List repositories from a provider (GITHUB, GITLAB, BITBUCKET) |
POST |
/api/quick-import/start |
Enqueue a new import job ({ "repoUrl", "branch" } → { "jobId" }) |
POST |
/api/quick-import/job/{jobId}/cancel |
Cancel a queued or running job (404 when unknown or already finished) |
GET |
/api/quick-import/jobs |
List all jobs for the current user (queued, running, recent) |
GET |
/api/quick-import/job/{jobId} |
Poll one job (QuickImportJobStatus) |
GET |
/api/quick-import/job/{jobId}/stream |
SSE — event job-update with JSON status (fallback: poll) |
Job phases: QUEUED → CLONING → PARSING → SCANNING → ENRICHING → DONE | FAILED.
Up to three imports run concurrently (oswl.quick-import.max-concurrent); additional jobs wait in a FIFO queue (queuePosition).
During ENRICHING, responses include percent, subPhase (CVE, LICENSE, INSIGHTS), detailLines, and aiPreviews, plus the deps.dev cache decision stats (cacheTotal, cacheHit, cacheToFetch).
The separate aiStatus field tracks background AI enrichment (NOT_APPLICABLE, PENDING, RUNNING, COMPLETED, FAILED) — a job can reach DONE while aiStatus is still PENDING/RUNNING.
| Method | Path | Description |
|---|---|---|
POST |
/api/github/connect |
Connect a GitHub PAT |
DELETE |
/api/github/disconnect |
Remove GitHub connection |
GET |
/api/github/status |
Connection status |
GET |
/api/github/accounts |
List authenticated accounts |
GET |
/api/github/repos |
List accessible repositories |
GET |
/api/github/branches |
List branches for a repo |
GET |
/api/github/branches/by-project |
List branches for a project's linked repo (?projectId= — used by the Apply Patch modal) |
GET |
/api/github/branch-updated-at |
Last commit date for a branch |
DELETE |
/api/github/accounts/{login} |
Remove a specific account |
| Method | Path | Auth | Description |
|---|---|---|---|
POST |
/api/auth |
API key | Validate API key (legacy) |
GET |
/api/scan/ping |
API key | Connectivity and key validity check |
GET |
/api/scan/manifest-rules |
API key | Manifest file collection rules (same as /scripts/manifest-rules.json) |
POST |
/api/scan/parse |
API key | Parse a manifest zip archive (CLI step 1) |
POST |
/api/scan |
API key + credentials | Submit a dependency scan (CLI step 2) |
GET |
/api/scan/{scanId}/status |
Session | Poll scan status — returns status, componentCount, the separate AI enrichment state aiStatus (the scan completes independently of AI), and securityPostureInsight
|
POST |
/api/scan/gate |
API key |
v1.0.4 — PR / CI security gate; verdict with exitCode
|
| Method | Path | Permission | Description |
|---|---|---|---|
GET |
/projects/{id}/security-center |
SECURITY_CENTER_VIEW |
Security Center page |
PATCH |
/projects/{id}/security-center/bulk-status |
SECURITY_CENTER_UPDATE_STATUS |
Bulk CVE status update |
GET |
/projects/{id}/security-center/export |
SECURITY_CENTER_EXPORT |
Download the CVE list as CSV (?scanId=, ?format=csv) |
POST |
/projects/{id}/security-center/batch-pr |
SECURITY_CENTER_UPDATE_STATUS |
v1.0.4 — Open one upgrade PR for all selected components |
GET |
/security-center/compliance-report |
SECURITY_CENTER_EXPORT |
v1.0.4 — Print-ready compliance report |
| Method | Path | Permission | Description |
|---|---|---|---|
GET |
/api/projects/{projectId}/sbom |
SECURITY_CENTER_EXPORT |
CycloneDX 1.6 SBOM (application/vnd.cyclonedx+json) |
GET |
/api/projects/{projectId}/vex |
SECURITY_CENTER_EXPORT |
CycloneDX VEX built from triage decisions |
GET |
/api/projects/{projectId}/sarif |
SECURITY_CENTER_EXPORT |
SARIF 2.1.0 (application/sarif+json) |
POST |
/api/sbom/import |
PROJECT_CREATE |
Import a third-party CycloneDX file (multipart) |
| Method | Path | Permission | Description |
|---|---|---|---|
GET |
/projects/{id}/components/{compId} |
COMPONENT_DETAIL_VIEW |
Component detail (full page or HTMX fragment) |
POST |
/projects/{id}/components/{compId}/cves/{cveDbId}/ai-summarize |
SECURITY_CENTER_UPDATE_STATUS |
Regenerate AI triage for one CVE |
POST |
/projects/{id}/components/{compId}/defer |
SECURITY_CENTER_UPDATE_STATUS |
Record remediation deferral |
POST |
/projects/{id}/components/{compId}/create-pr |
SECURITY_CENTER_UPDATE_STATUS |
Open a VCS pull request with a dependency fix |
POST |
/projects/{id}/components/{compId}/jira-ticket |
SECURITY_CENTER_UPDATE_STATUS |
v1.0.4 — Create a Jira issue for this finding |
| Method | Path | Permission | Description |
|---|---|---|---|
GET |
/projects/{id}/license |
LICENSE_VIEW |
License Analysis page |
POST |
/projects/{id}/license/refresh-insights?scanId= |
LICENSE_VIEW |
Regenerate AI insights for one scan |
| Method | Path | Permission | Description |
|---|---|---|---|
GET |
/projects/{id}/risk-trend |
RISK_TREND_VIEW |
Risk Trend page |
| Method | Path | Permission | Description |
|---|---|---|---|
GET |
/projects/{id}/version-diff |
VERSION_DIFF_VIEW |
Version Diff page |
| Method | Path | Permission | Description |
|---|---|---|---|
GET |
/projects/{id}/scan-history |
SCAN_HISTORY_VIEW |
Scan History page |
DELETE |
/projects/{id}/scan-history/{scanId} |
PROJECT_DELETE |
Delete a scan record |
| Method | Path | Permission | Description |
|---|---|---|---|
GET |
/api/projects/{id}/keys |
SETTINGS_CLI_KEY_MANAGE + project membership |
List project keys |
POST |
/api/projects/{id}/keys |
SETTINGS_CLI_KEY_MANAGE + project membership |
Create a key |
DELETE |
/api/projects/{id}/keys/{keyId} |
SETTINGS_CLI_KEY_MANAGE + project membership |
Revoke a key |
| Method | Path | Description |
|---|---|---|
GET |
/api/admin/users |
List all users |
POST |
/api/admin/users |
Create / invite a user |
PUT |
/api/admin/users/{id}/roles |
Update user roles |
PUT |
/api/admin/users/{id}/display-name |
Change display name |
PUT |
/api/admin/users/{id}/activate |
Activate account |
PUT |
/api/admin/users/{id}/deactivate |
Deactivate account |
DELETE |
/api/admin/users/{id} |
Delete user |
| Method | Path | Description |
|---|---|---|
GET |
/api/admin/role-templates |
List templates |
POST |
/api/admin/role-templates |
Create template |
GET |
/api/admin/role-templates/permissions |
List all available permissions |
PUT |
/api/admin/role-templates/{id} |
Update template |
DELETE |
/api/admin/role-templates/{id} |
Delete template |
| Method | Path | Description |
|---|---|---|
GET |
/api/admin/audit-logs |
Paginated audit log |
GET |
/api/admin/audit-logs/export.csv |
Export as CSV |
GET |
/api/admin/audit-logs/export?format=jsonl|cef |
v1.0.4 — SIEM export (AUDIT_LOG_EXPORT) |
| Method | Path | Permission | Description |
|---|---|---|---|
GET |
/org-dashboard |
ORG_DASHBOARD_VIEW |
Portfolio-wide posture, ranking, KEV and licence rollups |
All endpoints require the SYSTEM_ADMIN role (or the SETTINGS_SNAPSHOT_MANAGE permission).
| Method | Path | Description |
|---|---|---|
GET |
/api/admin/snapshot |
Store status — air-gapped flag plus, per source (osv, depsdev-version, depsdev-advisory, epss, kev): record count, importedAt, and v2 provenance (bundleId, builtAt, sourceAsOf, origin; null for sources imported from v1/meta-less bundles). Also oldestSourceAsOf (oldest sourceAsOf across sources) and the configured staleness thresholds (stalenessWarnDays, stalenessCriticalDays) used by the definition-freshness badge |
POST |
/api/admin/snapshot/import |
Import a snapshot bundle (multipart zip of JSONL files + meta.json). ?mode=replace|merge overrides the bundle's own meta.json mode: replace (default) clears each source before writing; merge upserts by key and honors "_deleted":true tombstones. v2 checksums are verified before any store mutation — a mismatch rejects the whole bundle |
POST |
/api/admin/snapshot/import-from-path |
Import a bundle already on the server's disk ({ "path", "mode" }) — for large bundles where a browser upload is impractical. Disabled (400) unless oswl.airgapped.import-dir is set; path must resolve under that directory |
GET |
/api/admin/snapshot/wanted-list |
Stream this instance's wanted-list as NDJSON (application/x-ndjson) — one {"ecosystem","name","version"} line per distinct scanned component, for oswl-vdb build --wanted on an online machine. No project names or repository URLs leave the instance |
GET |
/api/admin/snapshot/export |
Export a v2 snapshot bundle (application/zip) built from this instance's already-fetched data; meta.json origin is derived-from-scan. Run on an online instance, then import the bundle on the air-gapped one |
| Method | Path | Description |
|---|---|---|
GET |
/actuator/health |
Health check (admin-gated) |
GET |
/actuator/info |
Build / version info |
GET |
/actuator/prometheus |
Micrometer metrics for Prometheus |
POST |
/projects/{projectId}/cve-alerts/acknowledge |
Acknowledge new-CVE alerts (SECURITY_CENTER_VIEW) |
| Method | Path | Description |
|---|---|---|
GET |
/api/admin/cli-keys |
List global CLI keys |
POST |
/api/admin/cli-keys |
Create global key |
PATCH |
/api/admin/cli-keys/{keyId}/toggle |
Enable / disable key |
| Method | Path | Permission | Description |
|---|---|---|---|
GET |
/api/settings/security |
SETTINGS_SECURITY_MANAGE |
Get security settings |
PUT |
/api/settings/security |
SETTINGS_SECURITY_MANAGE |
Update settings |
POST |
/api/settings/security/mail/test |
SETTINGS_SECURITY_MANAGE |
Send test email |
| Method | Path | Permission | Description |
|---|---|---|---|
GET |
/api/settings/ai |
SETTINGS_AI_MANAGE |
Active provider + enrichment preferences (temperature, limits, deployment default, …) |
PUT |
/api/settings/ai |
SETTINGS_AI_MANAGE |
Upsert provider credentials and/or preferences |
PUT |
/api/settings/ai/deactivate |
SETTINGS_AI_MANAGE |
Deactivate active provider (optional preference body) |
PUT |
/api/settings/ai/activate/{provider} |
SETTINGS_AI_MANAGE |
Switch active provider |
POST |
/api/settings/ai/test-connection |
SETTINGS_AI_MANAGE |
Test provider connectivity (no persist). Lists available models rather than sending a completion, so it costs no tokens and does not count against the daily call cap; response includes a warning hint if the configured model ID isn't in the returned catalogue |
GET |
/api/settings/ai/prompts |
SETTINGS_AI_MANAGE |
Editable prompt templates + overrides |
POST |
/api/settings/ai/golden-test |
SETTINGS_AI_MANAGE |
Run built-in prompt regression fixtures |
GET |
/api/settings/ai/usage |
SETTINGS_AI_MANAGE |
AI usage stats — today's calls/tokens/estimated cost, daily cap, and the last 7 days, read from the daily aggregate table |
GET |
/api/settings/ai/usage/events |
SETTINGS_AI_MANAGE |
Recent AI call events, newest first (?page=, ?size=, default size 10). Only the last 100 events are retained (FIFO), so at most 10 pages exist |
GET |
/api/settings/ai/embedded |
SETTINGS_AI_MANAGE |
Embedded AI status (running, external, binaryFound, activeModel, fallbackUsed, lastError, availableModels, modelsDir, baseUrl, and while a default-model download is in flight: downloading, downloadedBytes, downloadTotalBytes) |
POST |
/api/settings/ai/embedded/start?model= |
SETTINGS_AI_MANAGE |
Start the llama.cpp sidecar (optional model file name; auto-fallback across candidates, 400 with reason on failure). On a fresh install with no .gguf present, downloads the Apache-2.0 Qwen3-1.7B model in the background instead and returns immediately (downloading: true) — poll GET .../embedded for progress |
POST |
/api/settings/ai/embedded/stop |
SETTINGS_AI_MANAGE |
Stop the sidecar and deactivate the LOCAL provider |
PUT |
/api/settings/ai/embedded/config |
SETTINGS_AI_MANAGE |
Save folder/model overrides { "dir", "model" } (null keeps current, blank clears; 400 if dir missing) |
Providers: OPENAI, ANTHROPIC, GEMINI, LOCAL. The embedded endpoints manage the built-in llama.cpp LOCAL provider — see Embedded AI.
| Method | Path | Permission | Description |
|---|---|---|---|
GET |
/api/settings/license-policy |
LICENSE_POLICY_MANAGE |
List SPDX policy entries |
PUT |
/api/settings/license-policy/{spdxId} |
LICENSE_POLICY_MANAGE |
Update status for one license |
| Method | Path | Permission | Description |
|---|---|---|---|
GET |
/api/settings/vcs |
SETTINGS_VCS_MANAGE |
List connections |
POST |
/api/settings/vcs |
SETTINGS_VCS_MANAGE |
Add connection |
DELETE |
/api/settings/vcs/{id} |
SETTINGS_VCS_MANAGE |
Remove connection |
Controls how long library CVE/license data from deps.dev and OSV is reused between scans.
| Method | Path | Permission | Description |
|---|---|---|---|
GET |
/api/settings/cache |
SETTINGS_CACHE_MANAGE |
List cache keys (DEPS_DEV, OSV_VULN) with TTL and last-cleared metadata |
PUT |
/api/settings/cache |
SETTINGS_CACHE_MANAGE |
Update TTL for one key (cacheKey, ttlSeconds) |
POST |
/api/settings/cache/clear?cacheKey=… |
SETTINGS_CACHE_MANAGE |
Mark cache cleared — libraries fetched before that time are re-fetched on the next enrichment |
TTL semantics (Settings → Cache UI maps to DEPS_DEV TTL used by enrichment):
| UI mode | ttlSeconds |
Behaviour |
|---|---|---|
| Always Refresh | 1 |
Re-fetch every library on every scan |
| Custom TTL |
N (seconds) |
Re-fetch when libraries.fetched_at is older than N |
| Permanent Cache | very large (e.g. 50 years) | Fetch each library only once |
Note: The former
/api/settings/externalendpoints andexternal_api_settingstable were removed. Cache is managed solely via/api/settings/cache.
| Method | Path | Description |
|---|---|---|
GET |
/data/test |
Reset DB and seed rich test data |
GET |
/data/test-api-key |
Get a usable test API key |