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/graphqlwith standard GraphQL over POST format for the body. - All list queries support Relay-style pagination using
first,after,before, andlastparameters.
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)
PackageWhereInput)| Field | Type | Description |
|---|---|---|
searchPackages | String | Full-text search across packages |
type / typeIn | String / [String] | Exact match or list of package types |
typeContainsFold | String | Case-insensitive type substring |
name / nameIn | String / [String] | Exact match or list of names |
nameContainsFold | String | Case-insensitive name substring |
nameHasPrefixFold | String | Case-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
}
}
}Get a Maven Chainguard package version
Chainguard Libraries for Java packages use type: "maven" with ecosystem: "chainguard". Include the ecosystem parameter when querying package or version details:
{
packageVersion(type: "maven", name: "ai.eto:rikai_2.12", version: "0.1.11", ecosystem: "chainguard") {
version
published
package {
name
type
ecosystem
}
}
}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)
PackageVersionWhereInput)| Field | Type | Description |
|---|---|---|
version / versionIn | String / [String] | Exact match or list |
versionContainsFold | String | Case-insensitive version substring |
isLatest | Boolean | Only latest versions |
vulnerabilitiesCountGTE / LTE | Int | Filter by vulnerability count |
publishedGTE / publishedLTE | Date | Filter by publish date range |
hasPackageWith | [PackageWhereInput] | Filter by parent package |
hasVulnerabilitiesWith | [VulnerabilityWhereInput] | Filter versions that have matching vulnerabilities |
hasLicenseInfoWith | [LicenseInfoWhereInput] | Filter by license |
includeNonListedVersions | Boolean | Include 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)
VulnerabilityWhereInput)| Field | Type | Description |
|---|---|---|
name / nameIn | String / [String] | CVE ID exact match or list |
nameHasPrefix | String | CVE ID prefix (e.g., CVE-2024) |
nameContainsFold | String | Case-insensitive name substring |
ecosystem / ecosystemIn | String / [String] | Package ecosystem filter |
severityFilter | [SeverityFilterInput] | Filter by severity level and/or CVSS score range |
hasKnownExploit | Boolean | Only vulnerabilities with known active exploits |
includeWithdrawn | Boolean | Include withdrawn/retracted vulnerabilities |
onlyTransitive | Boolean | Only vulnerabilities from transitive dependencies |
includeTransitive | Boolean | Include transitive dependency vulnerabilities |
cweContainsFold | String | Filter by CWE identifier |
hasAdvisoriesWith | VulnerabilityAdvisoryWhereInput | Filter 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 Type | Description |
|---|---|
Nvd | National Vulnerability Database |
Ghsa | GitHub Security Advisory |
JfrogAdvisory | JFrog Security Research advisory (includes impact analysis and remediation) |
DebianSecurityTracker | Debian security tracker |
RedhatOval | Red 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" }])
}
}Custom Assigned Licenses
Search Custom Assigned Licenses
{
customLegalInfo {
searchCustomAssignedLicenses(
first: 10
where: { nameContainsFold: "internal" }
orderBy: { field: NAME, direction: ASC }
) {
edges {
node {
name
expiresAt
}
}
pageInfo {
hasNextPage
endCursor
}
totalCount
}
}
}Get Custom Assigned Licenses for a Package
{
publicPackage {
getPackage(name: "my_package", type: "npm") {
name
type
customLegalInfo {
customAssignedLicensesConnection(first: 10) {
edges {
node {
name
expiresAt
}
}
}
}
}
}
}Get Custom Assigned Licenses for a Package Version
{
publicPackageVersion {
getVersion(name: "my_package", type: "npm", version: "1.0.0") {
version
customLegalInfo {
customAssignedLicensesConnection(first: 10) {
edges {
node {
name
expiresAt
}
}
}
}
}
}
}Custom Assigned License Filter Options (CustomAssignedLicenseWhereInput)
CustomAssignedLicenseWhereInput)| Field | Type | Description |
|---|---|---|
nameContainsFold | String | Case-insensitive name substring match |
nameEqualFold | String | Case-insensitive exact name match |
hasExpired | Boolean | Filter by expiration status |
Create a Custom License
mutation {
userDefinedLicense {
createUserDefinedLicense(
input: {
name: "My-Internal-License"
licenseText: "Full license agreement text..."
category: "Proprietary"
}
) {
name
licenseText
category
}
}
}Assign a Custom License to a Package Version
mutation {
userDefinedLicense {
assignUserDefinedLicenseToPackageVersion(
input: {
licenseName: "My-Internal-License"
packageVersion: {
publicPackage: { name: "my_package", type: "npm" }
version: "1.0.0"
}
}
)
}
}Remove a Custom License from a Package Version
mutation {
userDefinedLicense {
removeUserDefinedLicenseFromPackageVersion(
input: {
licenseName: "My-Internal-License"
packageVersion: {
publicPackage: { name: "my_package", type: "npm" }
version: "1.0.0"
}
}
)
}
}Delete a Custom License
mutation {
userDefinedLicense {
deleteUserDefinedLicense(input: { name: "My-Internal-License" })
}
}For more information on creating and managing custom licenses, see Create and Assign Custom Licenses.
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 Message | Description |
|---|---|
| Creating more than 500 labels is not supported | Returned from CreateCustomCatalogLabels if given too many labels |
| Assigning more than 1 label is not supported | Returned from label assignment mutations if given too many labels |
| Some of the labels already exist | Returned from create mutations if labels already exist |
| Deleting more than 500 labels is not supported | Returned from DeleteCustomCatalogLabels if given too many labels |
| Removing more than 500 labels assignments in a single operation is not supported | Returned from remove mutations if given too many items |
| Assigning a label to more than 500 package versions in a single operation is not supported | Returned from bulk assign mutation |
| A label name cannot be empty | Returned from create/update if name is empty |
| Labels must be specified for the assignment | Returned 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 yet | Returned if a version already has a label |
| A requested package already has a label assigned. More than one label per package is not supported yet | Returned if a package already has a label |
| Label name is too long, must have fewer than 1000 characters | Returned from create/update |
| Label description is too long, must have fewer than 10000 characters | Returned from create/update |
| Label does not exist | Returned from update if the target label doesn't exist |
| Label with name already exists | Returned from update if the new name conflicts |
| The following labels were not found. All labels must exist when assigned | Returned from assign mutations if referenced labels don't exist |
Updated 12 days ago
Did this page help you?
