Using the API
Query conda-forge packages through the OSV-compatible audit API.
The audit API returns advisories matched to a conda-forge package version. The query endpoints follow the OSV API conventions.
- Base URL:
https://api.basilisk.prefix.dev - Authentication: none
- Format: JSON
Query one package
Send a conda package URL in the CEP 63 form to POST /v1/query. The channel is the PURL namespace:
curl -X POST "https://api.basilisk.prefix.dev/v1/query" \
-H "Content-Type: application/json" \
-d '{"package": {"purl": "pkg:conda/conda-forge/pillow@10.2.0"}}'The response contains optional vulns with matching advisory documents and no response-level extensions. When there are no matches, the response is {}: vulns is omitted, not an empty array. Without a version or artifact qualifier, Basilisk returns advisories matched to any known version of the package.
You can also send {"package": {"name": "pillow", "ecosystem": "conda-forge"}, "version": "10.2.0"}. Name/ecosystem queries look up the package name directly, without PURL alias lookup.
An optional top-level version supplies an exact version when the PURL omits it. Conflicting versions, malformed PURLs or qualifiers, duplicate qualifier keys, empty qualifier values, and combining package.purl with package.name or package.ecosystem return HTTP 400.
Use POST /v1/querybatch to query several packages at once. Its response contains only results, in request order. Each result contains optional vulns entries with id and modified fields, or is {} when there are no matches. Use GET /v1/vulns/{id} to fetch one advisory by ID.
Look up indexed package inventory
Use the public, credentialless GET /v1/resolve?purl=<URL-encoded PURL> endpoint to look up a package identity in Basilisk's indexed inventory. The only lookup input is the required purl query string; embed any version in the PURL. It does not accept a name/ecosystem lookup or a separate version. Missing or malformed PURLs return HTTP 400.
The lookup shares PURL parsing, alias lookup, and artifact selection with OSV queries. Conda PURLs retain their qualifiers. platform selects the literal repodata subdir; build selects the complete, case-sensitive build string, not a build number or pattern. Canonical PURLs sort lowercase qualifier keys and percent-encode values without changing their case.
For example, looking up a known package and version with a missing build:
curl --get "https://api.basilisk.prefix.dev/v1/resolve" \
--data-urlencode "purl=pkg:conda/conda-forge/pinject@0.14.1?build=missing_build_0&platform=noarch"returns the resolution directly, with no wrapper:
{"status": "unknown", "reason": "artifact"}The lookup reports indexed repodata identity, not audit coverage or a vulnerability verdict:
resolvedincludespackage_id,package_name, and the requestedversion,platform, andbuild. Qualified requests includeartifact_count; a singleton includesartifactwith its ID, filename, build number, and available hashes.unknownidentifies a missingpackage,version, orartifactinreason. A complete version + platform + build selector matching multiple physical archives returnsambiguous_artifact, rather than choosing an archive arbitrarily.not_coveredreportsunsupported_channel,unsupported_qualifier, orunsupported_purl_typeinreason. Supported lookups use conda PURLs inconda-forge. Only theplatformandbuildqualifiers are supported. Other qualifiers, includingrepository_url, are retained by the parser but explicitly unsupported by resolution.
Without platform or build, an exact known version resolves even if artifact metadata is unavailable; artifact_count and artifact are then null. A partial selector resolves its matching artifact set. platform=linux-64 does not implicitly include noarch: the platform is an artifact subdir, not a host installation target.
An identity absent from the index is not necessarily absent upstream. This endpoint only reads indexed inventory: it does not look up advisories, evaluate live advisory ranges, or report source coverage, freshness, or platform-specific vulnerability applicability. A resolved result does not mean an artifact is clean. Inventory lookup is optional, not a required preflight for an audit.
Artifact selectors in OSV queries
OSV queries use the same selectors without returning inventory resolution. They intersect version-wide matches with the selected artifact set and include matching platform-qualified evidence. Missing or ambiguous artifacts produce {} (or a {} batch entry); they never fall back to a broader version query or live range evaluation. Unsupported channels, ecosystems, PURL types, and qualifiers also produce empty responses.
Unqualified OSV version queries retain live range evaluation for versions absent from repodata. A separate inventory lookup can therefore return unknown with reason version while an OSV query finds matching advisories for that version.
Omitted vulns is not evidence that an artifact is clean. Use the structured audit endpoint below to distinguish a missing selection, incomplete evaluation, and platform-qualified applicability.
Audit a platform or build
POST /v1/audit accepts the same package query as /v1/query, but returns
typed scope and applicability rather than OSV documents:
curl -X POST "https://api.basilisk.prefix.dev/v1/audit" \
-H "Content-Type: application/json" \
-d '{"package": {"purl": "pkg:conda/conda-forge/pillow@10.2.0?platform=linux-aarch64"}}'The response includes inventory resolution, independent evaluation
complete, and canonical advisories with a qualification assessment.
advisory_total and advisories_truncated describe the bounded output.
An empty list with complete: false does not establish a negative result.
Each qualification retains the literal version/platform/build selection and distinguishes:
verdict | Meaning |
|---|---|
globally_affected | Unqualified source evidence matches the requested version scope; this is a machine range result, not an exploitability decision |
platform_dependent | Qualified evidence matches, but no platform/build scope was selected; it is not a package-wide positive |
affected | Qualified evidence matches the selected artifact scope |
unaffected_on_selected_platform | Current, complete evidence excludes the selected scope for this advisory; it is not a claim of safety from other advisories |
indeterminate | Selection or evaluation is missing, stale, unsupported, or otherwise unresolved |
Read complete and reasons alongside verdict: positive evidence does not
prove every source was evaluated. available_artifacts lists current inventory
with complete build strings, filenames, checksums, and repodata operations.
Each artifact has its own verdict, evaluated independently of the requested
platform/build selection. The inventory can therefore show an ARM match beside
an excluded x86 artifact without applying the aggregate verdict to both.
affected_platforms reports qualified membership, not every subdirectory that
publishes the version. These lists and sources carry totals and explicit
truncation flags.
Source evidence retains parsed hardware/software qualifiers, their subject, mapping fingerprint, matcher version, and the referenced artifact snapshot and generation provenance. Matching uses that captured snapshot rather than silently substituting newly ingested artifacts.
build_patch_status is unknown. Selecting a build narrows the machine
range result; it does not prove that a backport exists or that a larger build
number fixes the vulnerability.
The lazy REST applicability endpoint
GET /v1/advisories/{id}/packages/{package}/applicability also includes
qualification and accepts optional version, platform, and build query
parameters. Its existing unqualified release-axis projection remains a
separate fact; consumers must not use that broad rail as the selected
artifact's verdict.
OSV response envelopes stay unchanged. Per-document
database_specific.basilisk.qualification carries the conda-specific assessment
where applicable. Conditional evidence does not become a standard broad
conda affected-version claim. Batch results remain ID/modified pairs; use
/v1/audit when scope or unknown-state detail is required.
For GCC / CVE-2023-4039, the AArch64 condition describes generated code, not the compiler's host subdirectory. The assessment retains that condition and stays indeterminate without target and usage evidence, including for a compiler hosted on x86.
Endpoint reference
The generated reference comes from the same OpenAPI document served by the API at /openapi.json. Each endpoint page includes a request form and examples for cURL, Python, JavaScript, Rust, Go, Java, and C#.
Reading the response
Matches come from advisory ranges and package identity mappings. Their metadata includes the source advisory, the identity used for matching, and the matcher version.
A conda-forge entry carries that metadata, plus package-specific remediation metadata, under database_specific.basilisk:
{
"package": {
"ecosystem": "conda-forge",
"name": "libexpat"
},
"database_specific": {
"basilisk": {
"applicability": "evaluated",
"comparator": "conda",
"matcher_version": "v8",
"matched_identity": {
"kind": "cpe",
"value": "cpe:2.3:a:libexpat_project:libexpat:*:*:*:*:*:*:*:*"
},
"fix_version": "2.8.2",
"conda_publication": "not_published",
"reported_fixes": [
{
"source_kind": "nvd",
"source_advisory_id": "CVE-2026-50219",
"reported_fix": "2.8.2",
"conda_publication": "not_published"
}
]
}
}
}matched_identity is the identity that joined the advisory to the conda-forge package: kind is purl or cpe, and value is the PURL or CPE itself. Use it to tell whether another ecosystem's entry in the same document refers to the same project. A conda-forge pnpm entry matched through pkg:npm/pnpm shares its fixes with the npm entry, while a conda-forge libpq entry matched through a CPE is unrelated to an npm package that happens to be called libpq. When several matches with different metadata join the same package, the entry carries a matches array instead, and each element has its own matched_identity.
fix_version is Basilisk's latest compatibility upgrade target under conda version ordering. It is present only when the matcher can select a boundary that covers the known affected versions, and it does not by itself mean that the release exists on conda-forge. conda_publication describes that exact spelling as published, not_published, or unknown. reported_fixes preserves the contributing source boundaries without collapsing sources. Canonical source pages are included in references with type ADVISORY; additional source references use the controlled OSV reference vocabulary.
See Terminology for the applicability and confidence fields, or Traceability for the provenance model.
Permanent Activity history
GET /v1/activity reads captured dataset refreshes, not operational job logs. History begins when capture is deployed: existing datasets are not reconstructed into a baseline. Before the first captured run, the response has availability: "unavailable". A filtered empty result still has availability: "available". Captured history is retained indefinitely, independently of queue pruning.
Use GET /v1/activity/{id} for public run metadata, attempts, processing and operation attribution. Fetch semantic changes separately with GET /v1/activity/{id}/changes. Each change preserves its source, before/after public facts, identity additions/removals and captured severity. Public responses do not expose job inputs, raw failure messages, actor slugs or private source evidence.
Feed and change windows accept offset (default 0) and limit (default 50, maximum 100). Reuse the first response's opaque snapshot token for later windows and both detail endpoints. Nonzero offsets without a snapshot are rejected. The snapshot fixes ordering, totals, relative date boundaries and published content; transactions still in progress at that snapshot do not appear later in the same scrolling session. Start again without a token to see new work.
Filters compose:
range:24h,7d(default),30d, orall.query: a literal, case-insensitive substring over retained public history. A nonempty query bypasses onlyrange.outcome:all,running,completed,partial,failed, orcompleted-after-retry.run_kind:all,scheduled,manual, orbaseline. No baseline is fabricated.severity:all,critical,high,medium,low, orunknown.
Search and severity must match the same nested advisory change unless the run metadata itself matches the search. Use the same filters for feed and change windows. A running, failed, skipped or incompletely evaluated run is never presented as a successful no-change evaluation. Earlier committed changes remain visible when a later stage fails.
Expanded metadata includes at most 100 attempts and 100 operation references, with totals and explicit completeness flags. Change facts, identity lists and large captured payloads are also bounded; details_complete: false means details are incomplete, not that no change occurred. Each fact's before_known and after_known distinguish known absence from unavailable historical details. An empty change window only means there are no further changes matching that window's filters.
