GraphQL API
The GraphQL API provides flexible queries for complex data needs. Available on Pro, Cloud, and Enterprise editions.
Endpoint
POST /graphql
Playground
In development, access the GraphQL Playground at:
GET /graphql/playground
Enable with GRAPHQL_PLAYGROUND=true and GRAPHQL_INTROSPECTION=true.
Authentication
Use the Authorization header with either the root admin token or a CMA token generated in the admin UI:
# Using the root admin token
curl -X POST https://packages.example.com/graphql \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query": "{ customers { id name } }"}'
# Using a CMA token
curl -X POST https://packages.example.com/graphql \
-H "Authorization: Bearer cma_xY9kL2mN4pQ7rS1tU5vW8xZ3aB6cD9e" \
-H "Content-Type: application/json" \
-d '{"query": "{ customers { id name } }"}'
CMA tokens respect their assigned level: owner and admin can execute both queries and mutations, while viewer tokens can only execute queries (mutations will return a FORBIDDEN error).
Schema
Queries
type Query {
# Customers
customer(id: ID!): Customer
customerByExternalId(externalId: String!): Customer
customers(
filter: CustomerFilter
pagination: Pagination
): CustomerConnection!
# Packages
package(name: String!): Package
packages(
filter: PackageFilter
pagination: Pagination
): PackageConnection!
# Collections
collection(slug: String!): Collection
collections: [Collection!]!
# Analytics
downloadStats(packageName: String, period: Period): DownloadStats!
# Vulnerabilities (Pro+)
vulnerabilities(packageName: String): [Vulnerability!]!
# Proxy (Pro+)
proxyStatus: ProxyStatus!
# Audit Logs (Pro+)
auditLogs(filter: AuditLogFilter, pagination: Pagination): AuditLogConnection!
# Statistics
stats: RegistryStats!
# GitHub App
githubAppStatus: GitHubAppStatus!
githubAppInstallations: [GitHubAppInstallation!]!
# OAuth Connections
oauthConnections: [OAuthConnection!]!
}
Mutations
type Mutation {
# Customers
createCustomer(input: CreateCustomerInput!): Customer!
updateCustomer(id: ID!, input: UpdateCustomerInput!): Customer!
deleteCustomer(id: ID!): Boolean!
suspendCustomer(id: ID!, reason: String): Customer!
reactivateCustomer(id: ID!): Customer!
freezeCustomer(id: ID!, versions: [VersionFreeze!]): Customer!
# Tokens (Scoped)
createToken(customerId: ID!, input: CreateTokenInput!): ScopedTokenCreatedResponse!
revokeToken(customerId: ID!, tokenId: ID!): Boolean!
rotateToken(customerId: ID!, tokenId: ID!): ScopedTokenCreatedResponse!
# Legacy Token Operations
regenerateToken(customerId: ID!): TokenResponse!
revokeAllTokens(customerId: ID!): Boolean!
# Package Access
grantPackageAccess(
customerId: ID!
packages: [PackageAccessInput!]!
): Customer!
revokePackageAccess(customerId: ID!, packageName: String!): Customer!
# Packages
addPackage(input: AddPackageInput!): Package!
syncPackage(name: String!): Package!
deletePackage(name: String!): Boolean!
# Collections
createCollection(input: CreateCollectionInput!): Collection!
updateCollection(slug: String!, input: UpdateCollectionInput!): Collection!
deleteCollection(slug: String!): Boolean!
# GitHub App
removeGitHubAppInstallation(id: ID!): Boolean!
}
Subscriptions
type Subscription {
packageSynced(name: String): PackageSyncEvent!
customerActivity(customerId: ID): CustomerActivityEvent!
}
Complexity Limiting
Query complexity is limited per edition to prevent abuse:
| Edition | Max Complexity |
|---|---|
| Pro | 500 |
| Cloud | 1000 |
| Enterprise | Unlimited |
Deeply nested queries that exceed the limit will be rejected with a QUERY_TOO_COMPLEX error.
Example Queries
Get Customer with Packages
query GetCustomer($id: ID!) {
customer(id: $id) {
id
name
email
status
packages {
name
constraint
grantedAt
}
}
}
List Packages with Versions
query ListPackages($filter: PackageFilter) {
packages(filter: $filter) {
edges {
node {
name
description
versions {
version
releasedAt
downloads
}
latestVersion
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
Download Statistics
query Stats {
downloadStats(period: LAST_30_DAYS) {
totalDownloads
byPackage {
name
downloads
}
byDay {
date
downloads
}
}
}
Vulnerability Scan Results
query Vulnerabilities($packageName: String!) {
vulnerabilities(packageName: $packageName) {
id
advisory
severity
affectedVersions
patchedVersions
description
}
}
Collections
query {
collections {
slug
name
packages {
name
latestVersion
}
}
}
GitHub App Status
query {
githubAppStatus {
configured
appId
appSlug
}
githubAppInstallations {
id
accountLogin
accountType
repositorySelection
status
}
}
Types
Customer
type Customer {
id: ID!
name: String!
email: String!
externalId: String
status: CustomerStatus!
packages: [PackageAccess!]!
createdAt: DateTime!
updatedAt: DateTime!
}
enum CustomerStatus {
ACTIVE
SUSPENDED
FROZEN
EXPIRED
}
Package
type Package {
name: String!
description: String
repositoryUrl: String!
type: GitProviderType!
versions: [Version!]!
latestVersion: String
syncedAt: DateTime
createdAt: DateTime!
}
Collection
type Collection {
slug: String!
name: String!
packages: [Package!]!
createdAt: DateTime!
updatedAt: DateTime!
}