GraphQL APIs

JFrog Catalog exposes a GraphQL API for querying packages, vulnerabilities, licenses, operational risk data, and managing custom labels. This page provides examples for each domain.

Note

  • This API is in beta phase and subject to changes.
  • The request is a POST HTTP request to path /catalog/api/v1/custom/graphql with standard GraphQL over POST format for the body.
  • All list queries support Relay-style pagination using first, after, before, and last parameters.

Packages

Get a package

{
  package(type: "npm", name: "lodash") {
    id
    name
    type
    vendor
    homepage
    vcsUrl
    description
    published
    modified
    latestVersion {
      version
      published
      isLatest
    }
  }
}

Search packages

{
  packages(
    first: 10
    where: { nameContainsFold: "log4j", type: "maven" }
    orderBy: { field: NAME, direction: ASC }
  ) {
    edges {
      node {
        name
        type
        description
        latestVersion {
          version
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

Package Filter Options (PackageWhereInput)

FieldTypeDescription
searchPackagesStringFull-text search across packages
type / typeInString / [String]Exact match or list of package types
typeContainsFoldStringCase-insensitive type substring
name / nameInString / [String]Exact match or list of names
nameContainsFoldStringCase-insensitive name substring
nameHasPrefixFoldStringCase-insensitive name prefix
and / or[PackageWhereInput]Combine filters

Get a package version

{
  packageVersion(type: "npm", name: "lodash", version: "4.17.21") {
    id
    version
    published
    modified
    isLatest
    summary
    package {
      name
      type
    }
  }
}

Search package versions

{
  packageVersions(
    first: 10
    where: {
      hasPackageWith: [{ name: "lodash", type: "npm" }]
      isLatest: true
    }
    orderBy: { field: VERSION, direction: DESC }
  ) {
    edges {
      node {
        version
        published
        isLatest
        package {
          name
          type
        }
      }
    }
  }
}

Package Version Filter Options (PackageVersionWhereInput)

FieldTypeDescription
version / versionInString / [String]Exact match or list
versionContainsFoldStringCase-insensitive version substring
isLatestBooleanOnly latest versions
vulnerabilitiesCountGTE / LTEIntFilter by vulnerability count
publishedGTE / publishedLTEDateFilter by publish date range
hasPackageWith[PackageWhereInput]Filter by parent package
hasVulnerabilitiesWith[VulnerabilityWhereInput]Filter versions that have matching vulnerabilities
hasLicenseInfoWith[LicenseInfoWhereInput]Filter by license
includeNonListedVersionsBooleanInclude unlisted versions

Get package version statistics

{
  packageVersionStats(
    statType: SEVERITY
    where: { hasPackageWith: [{ type: "npm" }] }
  ) {
    name
    count
  }
}

Get package type statistics

{
  packageTypeStats {
    name
    count
    type
  }
}

Get dependencies of a package version

{
  packageVersion(type: "npm", name: "express", version: "4.18.2") {
    version
    dependencies(first: 20, where: { dependency: { isDirect: true } }) {
      edges {
        node {
          version {
            version
            package {
              name
              type
            }
          }
          isDirect
          path
        }
      }
      aggregatedCounters {
        direct
        indirect
        severities {
          name
          count
        }
        licenses {
          name
          count
        }
      }
    }
  }
}

Get a package binary by SHA256

{
  packageBinary(sha256: "abc123def456...") {
    id
    sha256
    sha1
    architectures
    operatingSystems
    packageArtifacts {
      version {
        version
        package {
          name
          type
        }
      }
    }
  }
}

Get package source information

{
  packageSource(type: "git", url: "https://github.com/lodash/lodash") {
    id
    name
    url
    type
  }
}

Security / Vulnerabilities

Get a vulnerability

{
  vulnerability(name: "CVE-2021-44228", ecosystem: "maven") {
    id
    name
    ecosystem
    severity
    description
    withdrawn
    publishedAt
    modifiedAt
    cwe
    references
    aliases
    cvss {
      preferredBaseScore
      v3 {
        baseScore
        attackVector
        attackComplexity
        privilegesRequired
        userInteraction
        scope
        confidentialityImpact
        integrityImpact
        availabilityImpact
      }
    }
    knownExploit {
      dateAdded
      dueDate
    }
    advisories {
      ... on Nvd {
        name
        url
        severity
        shortDescription
      }
      ... on Ghsa {
        name
        url
        severity
        summary
      }
      ... on JfrogAdvisory {
        name
        url
        severity
        shortDescription
        fullDescription
        impact
        resolution
        vulnerabilityType
        impactReasons {
          name
          description
          isPositive
        }
      }
    }
  }
}

Search vulnerabilities

{
  vulnerabilities(
    first: 10
    where: {
      nameHasPrefix: "CVE-2024"
      severityFilter: [{ severity: CRITICAL }]
      hasKnownExploit: true
    }
    orderBy: { field: PUBLISHED_AT, direction: DESC }
  ) {
    edges {
      node {
        name
        ecosystem
        severity
        cvss {
          preferredBaseScore
        }
        knownExploit {
          dateAdded
        }
        publishedAt
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

Vulnerability Filter Options (VulnerabilityWhereInput)

FieldTypeDescription
name / nameInString / [String]CVE ID exact match or list
nameHasPrefixStringCVE ID prefix (e.g., CVE-2024)
nameContainsFoldStringCase-insensitive name substring
ecosystem / ecosystemInString / [String]Package ecosystem filter
severityFilter[SeverityFilterInput]Filter by severity level and/or CVSS score range
hasKnownExploitBooleanOnly vulnerabilities with known active exploits
includeWithdrawnBooleanInclude withdrawn/retracted vulnerabilities
onlyTransitiveBooleanOnly vulnerabilities from transitive dependencies
includeTransitiveBooleanInclude transitive dependency vulnerabilities
cweContainsFoldStringFilter by CWE identifier
hasAdvisoriesWithVulnerabilityAdvisoryWhereInputFilter by advisory source (NVD, GHSA, JFrog, etc.)

Severity Filter with CVSS Score

{
  vulnerabilities(
    first: 10
    where: {
      severityFilter: [{
        severity: CRITICAL
        hasCvssWith: [{ preferredBaseScoreGTE: 9.0 }]
      }]
    }
  ) {
    edges {
      node {
        name
        severity
        cvss { preferredBaseScore }
      }
    }
  }
}

Advisory Sources

Advisory TypeDescription
NvdNational Vulnerability Database
GhsaGitHub Security Advisory
JfrogAdvisoryJFrog Security Research advisory (includes impact analysis and remediation)
DebianSecurityTrackerDebian security tracker
RedhatOvalRed Hat OVAL data

Get vulnerabilities for a package version

{
  packageVersion(type: "npm", name: "lodash", version: "4.17.20") {
    version
    vulnerabilities(first: 10, orderBy: { field: SEVERITY, direction: DESC }) {
      edges {
        node {
          name
          severity
          cvss { preferredBaseScore }
          knownExploit { dateAdded }
        }
      }
    }
    severities {
      severityLevel
      count
    }
  }
}

Get security info for a package

{
  package(type: "npm", name: "event-stream") {
    name
    securityInfo {
      maliciousInfo {
        knownToBeMalicious
        summary
        shortDescription
        remediation
        classification {
          type
          description
        }
        infectionMethod
      }
    }
  }
}

Get vulnerable packages for a vulnerability

{
  vulnerability(name: "CVE-2021-44228", ecosystem: "maven") {
    name
    vulnerablePackages(first: 10) {
      edges {
        node {
          packageVersion {
            version
            package { name type }
          }
          fixVersions { version }
          isTransitive
        }
      }
    }
    cwes(first: 5) {
      edges {
        node {
          identifier
          name
          description
        }
      }
    }
  }
}

Legal / Licenses

Get a license

{
  license(name: "MIT") {
    name
    description
    isSpdx
    licenseCategory
    copyrightRiskScore
    copyleftRiskScore
    royaltyRiskScore
    patentRiskScore
    permissions {
      value
    }
    conditions {
      value
    }
    limitations {
      value
    }
    licenseText
  }
}

Search licenses

{
  licenses(
    first: 10
    where: { nameContainsFold: "apache" }
    orderBy: { field: NAME, direction: ASC }
  ) {
    edges {
      node {
        name
        isSpdx
        licenseCategory
        copyleftRiskScore
      }
    }
  }
}

Get license information for a package version

{
  packageVersion(type: "npm", name: "lodash", version: "4.17.21") {
    version
    licenseInfo {
      expression
      licenses {
        name
        isSpdx
        licenseCategory
        copyrightRiskScore
        copyleftRiskScore
        permissions { value }
        conditions { value }
        limitations { value }
      }
    }
  }
}

Operational Risk

Get OpenSSF Scorecard for a package

{
  package(type: "npm", name: "express") {
    name
    operationalInfo {
      openSsf {
        aggregatedScore
        scorecardVersion
        calculationDate
        checks {
          score
          reason
          definition {
            name
            description
            risk
            remediation
          }
        }
      }
    }
  }
}

Get JFrog Popularity metrics

{
  package(type: "npm", name: "lodash") {
    name
    operationalInfo {
      jfrogPopularityInfo {
        bySubscription(first: 5) {
          edges {
            node {
              type
              percentile
            }
          }
        }
        bySegment(first: 5) {
          edges {
            node {
              name
              percentile
            }
          }
        }
      }
    }
  }
}

Get operational info for a specific version

{
  packageVersion(type: "npm", name: "express", version: "4.18.2") {
    version
    operationalInfo {
      openSsf {
        aggregatedScore
        checks {
          score
          definition { name }
        }
      }
      jfrogPopularityVersionInfo {
        bySubscription(first: 5) {
          edges {
            node { type percentile }
          }
        }
      }
    }
  }
}

Labels

Get a label with its assigned packages and package versions

{
  customCatalogLabel {
    getLabel(name: "my_label") {
      name
      description
      publicPackagesConnection(first: 5) {
        edges {
          node {
            name
            type
          }
        }
      }
      publicPackageVersionsConnection(first: 5) {
        edges {
          node {
            publicPackage {
              name
              type
            }
            version
          }
        }
      }
    }
  }
}

Search labels

{
  customCatalogLabel {
    searchLabels(
      first: 10
      where: { nameContainsFold: "approved" }
      orderBy: { field: NAME, direction: ASC }
    ) {
      edges {
        node {
          name
          description
          publicPackagesConnection(first: 4) {
            edges {
              node { name type }
            }
          }
          publicPackageVersionsConnection(first: 4) {
            edges {
              node {
                publicPackage { name type }
                version
              }
            }
          }
        }
      }
    }
  }
}

Get a package with its labels

{
  publicPackage {
    getPackage(name: "my_package", type: "npm") {
      name
      type
      customCatalogLabelsConnection(first: 4) {
        edges {
          node { name }
        }
      }
    }
  }
}

Get a package version with its labels

{
  publicPackageVersion {
    getVersion(name: "my_package", type: "npm", version: "1.0.0") {
      publicPackage {
        name
        type
        customCatalogLabelsConnection(first: 4) {
          edges {
            node { name }
          }
        }
      }
      version
      customCatalogLabelsConnection(first: 4) {
        edges {
          node { name }
        }
      }
    }
  }
}

Create a label

mutation {
  customCatalogLabel {
    createCustomCatalogLabel(
      label: { name: "my_label", description: "some description" }
    ) {
      name
      description
    }
  }
}

Create multiple labels

mutation {
  customCatalogLabel {
    createCustomCatalogLabels(
      labels: [
        { name: "my_label1", description: "description1" },
        { name: "my_label2", description: "description2" }
      ]
    ) {
      name
      description
    }
  }
}

Assign a label to a package

mutation {
  customCatalogLabel {
    assignCustomCatalogLabelsToPublicPackage(
      publicPackageLabels: {
        publicPackage: { name: "my_package", type: "npm" }
        labelNames: ["my_label"]
      }
    )
  }
}

Assign a label to a package version

mutation {
  customCatalogLabel {
    assignCustomCatalogLabelsToPublicPackageVersion(
      publicPackageVersionLabels: {
        publicPackageVersion: {
          publicPackage: { name: "my_package", type: "npm" }
          version: "1.0.0"
        }
        labelNames: ["my_label1"]
      }
    )
  }
}

Assign a label to multiple package versions

mutation {
  customCatalogLabel {
    assignCustomCatalogLabelToPublicPackageVersions(
      publicPackageVersionsLabel: {
        publicPackageVersions: [
          { publicPackage: { name: "my_package", type: "npm" }, version: "1.0.0" },
          { publicPackage: { name: "my_package", type: "npm" }, version: "1.0.1" }
        ]
        labelName: "my_label1"
      }
    )
  }
}

Remove labels from a package

mutation {
  customCatalogLabel {
    removeCustomCatalogLabelsFromPublicPackage(
      publicPackageLabels: {
        labelNames: ["my_label", "my_label2"]
        publicPackage: { name: "my_package", type: "npm" }
      }
    )
  }
}

Remove labels from a package version

mutation {
  customCatalogLabel {
    removeCustomCatalogLabelsFromPublicPackageVersion(
      publicPackageVersionLabels: {
        labelNames: ["my_label1", "my_label2"]
        publicPackageVersion: {
          publicPackage: { name: "my_package", type: "npm" }
          version: "1.0.0"
        }
      }
    )
  }
}

Remove a label from multiple package versions

mutation {
  customCatalogLabel {
    removeCustomCatalogLabelFromPublicPackageVersions(
      publicPackageVersionsLabel: {
        labelName: "my_label1"
        publicPackageVersions: [
          { publicPackage: { name: "my_package", type: "npm" }, version: "1.0.0" },
          { publicPackage: { name: "my_package", type: "npm" }, version: "1.0.1" }
        ]
      }
    )
  }
}

Update a label

mutation {
  customCatalogLabel {
    updateCustomCatalogLabel(
      label: {
        name: "my_label"
        updatedName: "my_label_new"
        updatedDescription: "updated description"
      }
    ) {
      name
      description
    }
  }
}

Delete a label

mutation {
  customCatalogLabel {
    deleteCustomCatalogLabel(label: { name: "my_label" })
  }
}

Delete multiple labels

mutation {
  customCatalogLabel {
    deleteCustomCatalogLabels(labels: [{ name: "x1" }, { name: "x2" }])
  }
}

Combining Domains

You can query across domains in a single request. For example, get a package version with its vulnerabilities, license info, operational risk, and labels:

{
  packageVersion(type: "npm", name: "express", version: "4.18.2") {
    version
    published
    isLatest

    # Security
    vulnerabilities(first: 5, orderBy: { field: SEVERITY, direction: DESC }) {
      edges {
        node {
          name
          severity
          cvss { preferredBaseScore }
        }
      }
    }
    severities {
      severityLevel
      count
    }
    securityInfo {
      maliciousInfo {
        knownToBeMalicious
      }
    }

    # Legal
    licenseInfo {
      expression
      licenses {
        name
        licenseCategory
        copyleftRiskScore
      }
    }

    # Operational
    operationalInfo {
      openSsf {
        aggregatedScore
      }
    }

    # Dependencies
    dependencies(first: 5) {
      aggregatedCounters {
        direct
        indirect
      }
    }
  }
}

GraphQL API Error Messages

Error MessageDescription
Creating more than 500 labels is not supportedReturned from CreateCustomCatalogLabels if given too many labels
Assigning more than 1 label is not supportedReturned from label assignment mutations if given too many labels
Some of the labels already existReturned from create mutations if labels already exist
Deleting more than 500 labels is not supportedReturned from DeleteCustomCatalogLabels if given too many labels
Removing more than 500 labels assignments in a single operation is not supportedReturned from remove mutations if given too many items
Assigning a label to more than 500 package versions in a single operation is not supportedReturned from bulk assign mutation
A label name cannot be emptyReturned from create/update if name is empty
Labels must be specified for the assignmentReturned from assign mutations if label list is empty
A requested package version already has a label assigned. More than one label per package version is not supported yetReturned if a version already has a label
A requested package already has a label assigned. More than one label per package is not supported yetReturned if a package already has a label
Label name is too long, must have fewer than 1000 charactersReturned from create/update
Label description is too long, must have fewer than 10000 charactersReturned from create/update
Label does not existReturned from update if the target label doesn't exist
Label with name already existsReturned from update if the new name conflicts
The following labels were not found. All labels must exist when assignedReturned from assign mutations if referenced labels don't exist