---
title: Software lists and imports
description: How to tell a website monitor what software the site and its server run, for vulnerability alerts: the plain-text list format, supported files, names and prefixes.
---

# Software lists and imports

On the Pro plan, website and API monitors can alert when a vulnerability is published for the software the website runs. A weekly scan finds what the website shows publicly: its CMS and plugins, framework, web server and some libraries. What it cannot see, such as the server's operating system, runtimes and the exact versions of your dependencies, you tell it with a file or a list.

Add software in any of these places:

- **The monitor form:** with "Newly discovered vulnerabilities" checked, choose files and type anything else under **Software the website runs**. Each is imported when you save.
- **The monitor's page:** **Vulnerabilities → Import software** takes files and a list together; **Add software** adds one item.
- **The API:** `POST /api/v1/monitors/{id}/software/import` with `{"content": "…", "filename": "…", "name": "…"}`, once per file, or `POST /api/v1/monitors/{id}/software` with `{"name": "…", "version": "…"}`. See the [API reference](/docs/api#vulnerabilities).
- **MCP:** the `import_software` and `add_software` tools. See [MCP server](/docs/mcp).

## Code repositories

A **Code repository** monitor watches a GitHub or GitLab repository instead of a website, on every plan. Every day (every hour on Pro and on paid monitors) it reads the repository's dependency manifests (the same files as below: package.json and lockfiles, Dockerfiles and compose files, composer, Python, Ruby, Go, Rust, Elixir, Java and .NET) and alerts on known and newly published vulnerabilities in them, like a website's software.

- **URL:** `https://github.com/owner/repository` or `https://gitlab.com/group/project`. To read one branch or folder of a monorepo, use its URL: `…/tree/main/frontend` (GitLab: `…/-/tree/main/frontend`).
- **What is read:** the default branch (or the one in the URL). Folders of installed dependencies, tests and examples are skipped (`node_modules`, `vendor`, `test`, `examples`…), and a folder's package.json or composer.json is skipped when its lockfile is next to it, since the lockfile has the exact versions. At most 50 files, 5 MB each.
- **Private repositories** need the Pro plan, or a paid monitor bought through the API, and an access token: on GitHub a fine-grained token with read-only access to the repository's Contents, on GitLab a token with `read_api`. It is stored encrypted and sent only to GitHub's or GitLab's API.
- **Alerts** go to the monitor's contacts for vulnerabilities at the severity you choose, and when the repository cannot be read (a moved repository, an expired token); the next read that works resolves that.
- **Fixing:** update the dependency in the repository; the next read, or **Check now** on the monitor's page, picks it up. An hourly read that finds changed dependencies checks them at once; newly published vulnerabilities are checked for daily on every plan. Entries you add by hand stay, and **Ignore** stops checking an entry.

Through the API or MCP, create a monitor with `"kind": "repository"`, the URL in `url` and, for a private repository, `"check_options": {"token": "…"}`.

## Plain-text list

One piece of software per line: its name, then its version. Anything an AI assistant or a person writes in that shape works.

```text
# Server
Debian 12
nginx 1.24.0
PHP 8.2.12
OpenSSL 3.0.11
MariaDB 10.11.6

# Application
WordPress 6.6.2
wp-plugin:woocommerce 9.3.3
wp-plugin:contact-form-7 5.9.8
npm:lodash 4.17.21
```

The rules:

- **One item per line**, the name first. The version is optional; without one, only advisories from the last 90 days that have no fixed release yet, or that attackers exploit, are listed for that item, marked "version unknown".
- **Separators:** a space, `:`, `=`, `==`, `@` or `/`, or the version in parentheses. These all read as nginx 1.24.0: `nginx 1.24.0`, `nginx: 1.24.0`, `nginx==1.24.0`, `nginx@1.24.0`, `nginx/1.24.0`, `nginx (1.24.0)`, `nginx v1.24.0`.
- **Operating systems** take their release number or codename: `Debian 12` or `Debian bookworm`, `Ubuntu 22.04` or `Ubuntu jammy`. A trailing `LTS` is ignored.
- **Ignored:** empty lines, comments starting with `#`, headings and lines that end with `:` (`Server:`), list bullets (`-`, `*`, `1.`), Markdown emphasis and code marks, and Markdown table borders. A table row such as `| nginx | 1.24.0 |` reads as one item.
- **Names** are either a name from the list below (case does not matter: `next.js`, `Next.js` and `nextjs` all work) or a prefixed package (next section).
- **Use the installed version**, not a range: `1.24.0`, not `^1.24`. With several versions of one item, the lowest is kept.
- **Lines that name nothing we know** are not imported; the import reports them back so you can fix them. The rest is imported.

### Prefixes for packages and anything else

| Prefix | For | Example |
|---|---|---|
| `npm:` | npm packages | `npm:lodash 4.17.21`, `npm:@angular/core 17.0.8` |
| `composer:` | PHP (Packagist) packages | `composer:guzzlehttp/guzzle 7.8.1` |
| `pypi:` | Python packages | `pypi:requests 2.31.0` |
| `gem:` | Ruby gems | `gem:nokogiri 1.15.4` |
| `go:` | Go modules | `go:github.com/gin-gonic/gin 1.9.1` |
| `maven:` | Java packages, as group:artifact | `maven:org.apache.logging.log4j:log4j-core 2.14.1` |
| `nuget:` | .NET packages | `nuget:Newtonsoft.Json 13.0.1` |
| `cargo:` | Rust crates | `cargo:tokio 1.32.0` |
| `wp-plugin:` | Any WordPress plugin, by its wordpress.org slug | `wp-plugin:polylang 3.6.4` |
| `wp-theme:` | Any WordPress theme, by its slug | `wp-theme:astra 4.6.0` |
| `cpe:` | Any product NVD knows, as vendor:product | `cpe:zabbix:zabbix 6.0.21` |

A plugin's slug is the folder name in its wordpress.org address: `wordpress.org/plugins/contact-form-7` is `wp-plugin:contact-form-7`.

### Names

**Operating systems** (checked for end of support): AlmaLinux, Alpine Linux, Amazon Linux, CentOS, Debian, FreeBSD, Red Hat Enterprise Linux, Rocky Linux, Ubuntu, Windows Server.

**Software:** .NET, Angular, AngularJS, Apache HTTP Server, Apache Tomcat, Astro, Bootstrap, Bun, Caddy, Concrete CMS, Confluence, Coolify, Craft CMS, curl, Discourse, Django, Docker Engine, Docusaurus, Drupal, Elasticsearch, Elixir, Erlang/OTP, Express, Flask, Gatsby, Ghost, Gitea, GitLab, Go, Grafana, Grav, Gunicorn, HAProxy, Hugo, Jekyll, Jenkins, Joomla!, jQuery, jQuery UI, Keycloak, Kubernetes, Laravel, LiteSpeed Web Server, Magento / Adobe Commerce, MariaDB, Matomo, MediaWiki, Microsoft IIS, MongoDB, Moodle, MySQL, Next.js, Nextcloud, nginx, Node.js, Nuxt, OpenLiteSpeed, OpenResty, OpenSSH, OpenSSL, PHP, phpMyAdmin, PostgreSQL, PrestaShop, Python, React, Redis, Roundcube, Ruby, Ruby on Rails, Shopware, Spring Boot, Spring Framework, Strapi, Svelte, SvelteKit, Symfony, Traefik, TYPO3, Vue.js, WordPress.

**WordPress plugins** known by name (any other plugin works as `wp-plugin:<slug>`): Advanced Custom Fields, All in One SEO, Contact Form 7, Elementor, Jetpack, LiteSpeed Cache, Slider Revolution, UpdraftPlus, WooCommerce, Wordfence Security, WPForms, WPForms Lite, Yoast SEO.

### Ask an AI assistant to write it

Give this to an assistant that can see your server or project, then paste its answer as the list. The same prompt is behind **Prompt for an AI assistant** in the dashboard.

```text
List the software this website and its server run: the operating system, web server, runtimes, frameworks, databases, hosting tools and the CMS with its plugins. Write one item per line as "name version", such as "Debian 12" or "nginx 1.24.0". Prefix packages with their manager: npm:lodash 4.17.21, composer:vendor/package 1.2.3, pypi:django 4.2.7, wp-plugin:slug 1.0. Use exact installed versions, leave out a version you are unsure of, and write nothing else.
```

On a server, `cat /etc/os-release`, `nginx -v`, `apache2 -v`, `php -v`, `node -v`, `python3 --version`, `openssl version` and `mysql --version` give the exact versions.

## Files

Choose one or more files, or send each with its `filename`, which tells the format; a file without a name is recognized by its contents. Alongside them, type anything the files do not cover, such as the server's operating system or Coolify, as a list.

A website with a frontend and a backend often has two files with the same name. Give each a label, such as `frontend/package.json` and `backend/package.json` (in the API, the `name` field): each label keeps its own list, and importing it again replaces only that list.

| File | What is read |
|---|---|
| `package-lock.json`, `npm-shrinkwrap.json` | Every installed package with its exact version, except dev dependencies |
| `yarn.lock`, `pnpm-lock.yaml`, `bun.lock` | Every package with its exact version (for bun.lock, except the root's dev dependencies) |
| `package.json` | `dependencies` (not dev dependencies) and the Node.js version in `engines`. Ranges such as `^14.1.0` are kept without a version: import the lockfile for exact versions |
| `composer.lock` | Every package except `packages-dev`, with exact versions |
| `composer.json` | `require`, without versions unless pinned |
| `requirements.txt` | Packages; versions pinned with `==` |
| `Pipfile.lock`, `poetry.lock` | Packages with exact versions, except dev ones |
| `Gemfile.lock` | Every gem with its exact version |
| `go.mod` | The Go version and every required module |
| `Cargo.lock` | Every crate from crates.io |
| `mix.lock` | Every Hex package with its exact version |
| `pom.xml` | Dependencies with literal versions (not test scope), and the Spring Boot version of `spring-boot-starter-parent` |
| `*.csproj`, `packages.config` | NuGet packages and the .NET version (`TargetFramework`) |
| `Dockerfile` | The image the final stage runs, through any stages it starts from: `php:8.2-fpm-bookworm` is PHP 8.2 on Debian 12, `nginx:1.25-alpine3.18` is nginx 1.25 on Alpine 3.18. `ARG` defaults are applied |
| `docker-compose.yml`, `compose.yaml` | Every service's image, the same way |
| `.nvmrc`, `.node-version`, `.python-version`, `.ruby-version` | That runtime's version |
| `.tool-versions` | Node.js, Python, Ruby, PHP, Go and .NET versions |

## What happens to imports

- Each import is listed under its label (by default the file name) on the monitor's page. **Importing under the same label again replaces what it imported before**, so re-import a lockfile after an upgrade. Typed lists are labelled "software list", so a new list replaces the last one.
- Software you add by hand wins over imports, and both win over what the scan detects. Removing a detected item ignores it, so the next scan does not add it back.
- The monitor is checked again right after an import, and alerts follow the usual rules: new vulnerabilities from the last 30 days at the monitor's severity, actively exploited ones, and releases reaching end of support. Older vulnerabilities found in an import are listed without an alert.

## Marking a vulnerability fixed

Each finding on the monitor's page, and in the alert email, has two actions:

- **Mark fixed:** records that the software now runs the first version that fixes it, on the release line it was on (14.1.0 with a fix in 14.2.25 becomes 14.2.25). For a release that lost support, the newest supported release.
- **Mark fixed with version…:** records the exact version you installed.

Either one sets that software's version and checks the monitor again: findings that no longer apply disappear, and one that still applies stays, marked with the version. In the email they open a confirmation page; nothing changes until you press its button, so mail scanners that open links do not mark anything fixed. They work for 10 days, without signing in, until the contact is turned off.

Marking something fixed only records the version. If the website's next scan still shows the old version, or a re-imported lockfile has it, that wins and the finding comes back.

## Limits

Files up to 5 MB; a plain list up to 1,000 lines; up to 2,000 items per import and 3,000 per monitor.
