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.
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.
GraphQL
{
package(type: "npm", name: "lodash") {
id
name
type
vendor
homepage
vcsUrl
description
published
modified
latestVersion {
version
published
isLatest
}
}
}
GraphQL
{
packages(
first: 10
where: { nameContainsFold: "log4j", type: "maven" }
orderBy: { field: NAME, direction: ASC }
) {
edges {
node {
name
type
description
latestVersion {
version
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
Field Type Description searchPackagesString Full-text search across packages type / typeInString / [String] Exact match or list of package types typeContainsFoldString Case-insensitive type substring name / nameInString / [String] Exact match or list of names nameContainsFoldString Case-insensitive name substring nameHasPrefixFoldString Case-insensitive name prefix and / or[PackageWhereInput] Combine filters
GraphQL
{
packageVersion(type: "npm", name: "lodash", version: "4.17.21") {
id
version
published
modified
isLatest
summary
package {
name
type
}
}
}
GraphQL
{
packageVersions(
first: 10
where: {
hasPackageWith: [{ name: "lodash", type: "npm" }]
isLatest: true
}
orderBy: { field: VERSION, direction: DESC }
) {
edges {
node {
version
published
isLatest
package {
name
type
}
}
}
}
}
Field Type Description version / versionInString / [String] Exact match or list versionContainsFoldString Case-insensitive version substring isLatestBoolean Only latest versions vulnerabilitiesCountGTE / LTEInt Filter by vulnerability count publishedGTE / publishedLTEDate Filter by publish date range hasPackageWith[PackageWhereInput] Filter by parent package hasVulnerabilitiesWith[VulnerabilityWhereInput] Filter versions that have matching vulnerabilities hasLicenseInfoWith[LicenseInfoWhereInput] Filter by license includeNonListedVersionsBoolean Include unlisted versions
GraphQL
{
packageVersionStats(
statType: SEVERITY
where: { hasPackageWith: [{ type: "npm" }] }
) {
name
count
}
}
GraphQL
{
packageTypeStats {
name
count
type
}
}
GraphQL
{
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
}
}
}
}
}
GraphQL
{
packageBinary(sha256: "abc123def456...") {
id
sha256
sha1
architectures
operatingSystems
packageArtifacts {
version {
version
package {
name
type
}
}
}
}
}
GraphQL
{
packageSource(type: "git", url: "https://github.com/lodash/lodash") {
id
name
url
type
}
}
GraphQL
{
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
}
}
}
}
}
GraphQL
{
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
}
}
}
Field Type Description name / nameInString / [String] CVE ID exact match or list nameHasPrefixString CVE ID prefix (e.g., CVE-2024) nameContainsFoldString Case-insensitive name substring ecosystem / ecosystemInString / [String] Package ecosystem filter severityFilter[SeverityFilterInput] Filter by severity level and/or CVSS score range hasKnownExploitBoolean Only vulnerabilities with known active exploits includeWithdrawnBoolean Include withdrawn/retracted vulnerabilities onlyTransitiveBoolean Only vulnerabilities from transitive dependencies includeTransitiveBoolean Include transitive dependency vulnerabilities cweContainsFoldString Filter by CWE identifier hasAdvisoriesWithVulnerabilityAdvisoryWhereInput Filter by advisory source (NVD, GHSA, JFrog, etc.)
GraphQL
{
vulnerabilities(
first: 10
where: {
severityFilter: [{
severity: CRITICAL
hasCvssWith: [{ preferredBaseScoreGTE: 9.0 }]
}]
}
) {
edges {
node {
name
severity
cvss { preferredBaseScore }
}
}
}
}
Advisory Type Description NvdNational Vulnerability Database GhsaGitHub Security Advisory JfrogAdvisoryJFrog Security Research advisory (includes impact analysis and remediation) DebianSecurityTrackerDebian security tracker RedhatOvalRed Hat OVAL data
GraphQL
{
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
}
}
}
GraphQL
{
package(type: "npm", name: "event-stream") {
name
securityInfo {
maliciousInfo {
knownToBeMalicious
summary
shortDescription
remediation
classification {
type
description
}
infectionMethod
}
}
}
}
GraphQL
{
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
}
}
}
}
}
GraphQL
{
license(name: "MIT") {
name
description
isSpdx
licenseCategory
copyrightRiskScore
copyleftRiskScore
royaltyRiskScore
patentRiskScore
permissions {
value
}
conditions {
value
}
limitations {
value
}
licenseText
}
}
GraphQL
{
licenses(
first: 10
where: { nameContainsFold: "apache" }
orderBy: { field: NAME, direction: ASC }
) {
edges {
node {
name
isSpdx
licenseCategory
copyleftRiskScore
}
}
}
}
GraphQL
{
packageVersion(type: "npm", name: "lodash", version: "4.17.21") {
version
licenseInfo {
expression
licenses {
name
isSpdx
licenseCategory
copyrightRiskScore
copyleftRiskScore
permissions { value }
conditions { value }
limitations { value }
}
}
}
}
GraphQL
{
package(type: "npm", name: "express") {
name
operationalInfo {
openSsf {
aggregatedScore
scorecardVersion
calculationDate
checks {
score
reason
definition {
name
description
risk
remediation
}
}
}
}
}
}
GraphQL
{
package(type: "npm", name: "lodash") {
name
operationalInfo {
jfrogPopularityInfo {
bySubscription(first: 5) {
edges {
node {
type
percentile
}
}
}
bySegment(first: 5) {
edges {
node {
name
percentile
}
}
}
}
}
}
}
GraphQL
{
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 }
}
}
}
}
}
}
GraphQL
{
customCatalogLabel {
getLabel(name: "my_label") {
name
description
publicPackagesConnection(first: 5) {
edges {
node {
name
type
}
}
}
publicPackageVersionsConnection(first: 5) {
edges {
node {
publicPackage {
name
type
}
version
}
}
}
}
}
}
GraphQL
{
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
}
}
}
}
}
}
}
}
GraphQL
{
publicPackage {
getPackage(name: "my_package", type: "npm") {
name
type
customCatalogLabelsConnection(first: 4) {
edges {
node { name }
}
}
}
}
}
GraphQL
{
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 }
}
}
}
}
}
GraphQL
mutation {
customCatalogLabel {
createCustomCatalogLabel(
label: { name: "my_label", description: "some description" }
) {
name
description
}
}
}
GraphQL
mutation {
customCatalogLabel {
createCustomCatalogLabels(
labels: [
{ name: "my_label1", description: "description1" },
{ name: "my_label2", description: "description2" }
]
) {
name
description
}
}
}
GraphQL
mutation {
customCatalogLabel {
assignCustomCatalogLabelsToPublicPackage(
publicPackageLabels: {
publicPackage: { name: "my_package", type: "npm" }
labelNames: ["my_label"]
}
)
}
}
GraphQL
mutation {
customCatalogLabel {
assignCustomCatalogLabelsToPublicPackageVersion(
publicPackageVersionLabels: {
publicPackageVersion: {
publicPackage: { name: "my_package", type: "npm" }
version: "1.0.0"
}
labelNames: ["my_label1"]
}
)
}
}
GraphQL
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"
}
)
}
}
GraphQL
mutation {
customCatalogLabel {
removeCustomCatalogLabelsFromPublicPackage(
publicPackageLabels: {
labelNames: ["my_label", "my_label2"]
publicPackage: { name: "my_package", type: "npm" }
}
)
}
}
GraphQL
mutation {
customCatalogLabel {
removeCustomCatalogLabelsFromPublicPackageVersion(
publicPackageVersionLabels: {
labelNames: ["my_label1", "my_label2"]
publicPackageVersion: {
publicPackage: { name: "my_package", type: "npm" }
version: "1.0.0"
}
}
)
}
}
GraphQL
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" }
]
}
)
}
}
GraphQL
mutation {
customCatalogLabel {
updateCustomCatalogLabel(
label: {
name: "my_label"
updatedName: "my_label_new"
updatedDescription: "updated description"
}
) {
name
description
}
}
}
GraphQL
mutation {
customCatalogLabel {
deleteCustomCatalogLabel(label: { name: "my_label" })
}
}
GraphQL
mutation {
customCatalogLabel {
deleteCustomCatalogLabels(labels: [{ name: "x1" }, { name: "x2" }])
}
}
You can query across domains in a single request. For example, get a package version with its vulnerabilities, license info, operational risk, and labels:
GraphQL
{
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
}
}
}
}
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