Skip to content

Projects API ​

30 endpoints. Request and response schemas are described on the schemas page; the other tags are listed in the API index.

Endpoints ​

GET /api/v1/admin/projects/settings ​

Get project settings

Global admins only. self_create is the effective projects.self_create value: the stored setting, else the OPENARTIFACT_PROJECTS_SELF_CREATE / projects.selfCreate default.

Responses

StatusDescriptionBody
200Project settingsapplication/json: ProjectSettings
403Admin access required-

PUT /api/v1/admin/projects/settings ​

Update project settings

Global admins only. Turning self_create on lets any human user create projects (and become their owner).

Request body (required)

application/json: ProjectSettings

Responses

StatusDescriptionBody
200Settings savedapplication/json: ProjectSettings
400Invalid requestapplication/json: Error
403Admin access required-

GET /api/v1/projects ​

List projects

List the projects the caller holds a role in, each with my_role, repository_count, member_count (direct members), usage and quota (computed for the whole list with grouped queries); with all=true, every project (global administrators only, others get 403). can_create tells whether the caller may create a project (global admin, or any human user while the projects.self_create setting is on).

Parameters

NameInTypeRequiredDescription
allquerybooleannoList every project instead of only the caller's own. Global administrators only. Default: false.
qquerystringnoCase-insensitive substring of the project name, slug or display name.

Responses

StatusDescriptionBody
200List of projectsapplication/json: object
400Invalid request, including a NUL byte in the URL or the bodyapplication/json: Error
403Forbiddenapplication/json: Error

Fields of the 200 response (application/json):

FieldTypeRequiredDescription
can_createbooleanno-
projectsarray of ProjectListItemno-

POST /api/v1/projects ​

Create project

Create a project. Global admins always may and can set the owner and the policy fields; any other human user may only while projects.self_create is on, becomes the owner, and gets the default policy (policy fields or owner in the body give 403). Tokens with scopes and deploy tokens cannot create projects.

Request body (required)

application/json: ProjectCreateRequest

Responses

StatusDescriptionBody
201Project createdapplication/json: Project
400Invalid name, slug or policy field-
403Self-service project creation is off, the caller is not a human user, or a non-admin sent policy fields or an owner-
404Owner user not found-
409Project name or slug already taken-

GET /api/v1/projects/{project} ​

Get project

Get details of a specific project. Requires a role in the project (viewer or above) or global admin; a non-member gets 404.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-

Responses

StatusDescriptionBody
200Project detailsapplication/json: Project
400Invalid request, including a NUL byte in the URL or the bodyapplication/json: Error
403Forbiddenapplication/json: Error
404Project not found or the caller is not a member-

PATCH /api/v1/projects/{project} ​

Update project

Partially update a project: only the fields present in the body change. display_name and description need the owner role or global admin; the policy fields need global admin (403 otherwise).

Parameters

NameInTypeRequiredDescription
projectpathstringyes-

Request body (required)

application/json: ProjectUpdateRequest

Responses

StatusDescriptionBody
200Project updatedapplication/json: Project
400Invalid policy field-
403Not an owner, or a policy field sent by a non-admin-
404Project not found or the caller is not a member-

DELETE /api/v1/projects/{project} ​

Delete project

Delete a project. Requires the owner role or global admin.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-

Responses

StatusDescriptionBody
204Project deleted-
400Invalid request, including a NUL byte in the URL or the bodyapplication/json: Error
403Not an owner-
404Project not found or the caller is not a member-
409Project still owns repositories, or it is the system project-

GET /api/v1/projects/{project}/activity ​

Project activity

Audit events of the project and of the repositories it owns (member, group, token, quota, policy and repository changes, plus events recorded against its repositories), newest first. Keyset paging only: follow next_cursor while has_more is true; no row is counted. Client addresses are not returned. Any member; a non-member gets 404.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-
per_pagequeryintegernoDefault: 25. Minimum: 1. Maximum: 100.
cursorquerystringnoOpaque next_cursor of the previous page; omit for the newest entries.
actorquerystringnoCase-insensitive substring of the actor name or actor id.
actionquerystringnoCase-insensitive substring of the action name.

Responses

StatusDescriptionBody
200One page of activityapplication/json: ActivityPage
400Malformed cursor-
403Forbiddenapplication/json: Error
404Project not found or the caller is not a member-

GET /api/v1/projects/{project}/activity/export ​

Export project activity

Export the project's activity (same scope and visibility as GET /api/v1/projects/{project}/activity: project.token_* events only for maintainers and above, no client addresses) as JSONL or CSV, for any member. Streams the log as a download without counting rows: entries are read in keyset pages (newest first) and flushed after every page, so memory stays bounded however long the log is. The body is chunked (no Content-Length); if the server fails after the response started the connection is aborted rather than ended normally, so a truncated file is detectable. In CSV, cells starting with =, +, -, @, tab or CR are prefixed with ' to defuse spreadsheet formula injection. Fields: id, timestamp (RFC 3339, UTC), action, actor, actor_type, message, resource_type, resource_id, repository_id.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-
formatquerystringnojsonl (default): one JSON object per line. csv: header row plus one record per entry. One of: jsonl, csv. Default: jsonl.
sincequerystringnoOnly entries at or after this instant: RFC 3339 timestamp or YYYY-MM-DD (00:00 UTC).
untilquerystringnoOnly entries strictly before this instant (same forms as since); must be after since.
actorquerystringnoCase-insensitive substring of the actor name or actor id.
actionquerystringnoCase-insensitive substring of the action name.

Responses

StatusDescriptionBody
200Activity export stream Headers: Content-Disposition.application/x-ndjson: string; text/csv: string
400Unknown format, malformed since/until, or since not before until-
403Access denied-
404Project not found or the caller is not a member-

GET /api/v1/projects/{project}/cleanup-policies ​

List project cleanup policies

Default cleanup policies of the project. A project policy applies to every live hosted repository of the project that has no enabled policy of its own (a repository policy overrides the default). Any member.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-

Responses

StatusDescriptionBody
200Policiesapplication/json: object
400Invalid request, including a NUL byte in the URL or the bodyapplication/json: Error
403Forbiddenapplication/json: Error
404Project not found or the caller is not a member-

Fields of the 200 response (application/json):

FieldTypeRequiredDescription
policiesarray of CleanupPolicyno-

POST /api/v1/projects/{project}/cleanup-policies ​

Create project cleanup policy

Owners and global admins. Same fields and validation as a repository cleanup policy.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-

Request body (required)

application/json: object

FieldTypeRequiredDescription
enabledbooleanno-
keep_last_nintegerno-
keep_since_daysintegerno-
namestringno-
name_patternstringno-
schedule_cronstringno-

Responses

StatusDescriptionBody
201Createdapplication/json: CleanupPolicy
400Invalid policy-
403Not an owner-
404Project not found or the caller is not a member-

PUT /api/v1/projects/{project}/cleanup-policies/{id} ​

Update project cleanup policy

Owners and global admins. Partial update.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-
idpathstring (uuid)yes-

Request body (required)

application/json: object

FieldTypeRequiredDescription
enabledbooleanno-
keep_last_nintegerno-
keep_since_daysintegerno-
namestringno-
name_patternstringno-
schedule_cronstringno-

Responses

StatusDescriptionBody
200Updatedapplication/json: CleanupPolicy
400Invalid policy-
403Not an owner-
404Project or policy not found-

DELETE /api/v1/projects/{project}/cleanup-policies/{id} ​

Delete project cleanup policy

Owners and global admins.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-
idpathstring (uuid)yes-

Responses

StatusDescriptionBody
204Deleted-
400Invalid request, including a NUL byte in the URL or the bodyapplication/json: Error
403Not an owner-
404Project or policy not found-

POST /api/v1/projects/{project}/cleanup-policies/{id}/dry-run ​

Preview what a project default cleanup policy would remove

Owners and global admins. Expands the policy over the repositories a run would cover and lists, per repository, the rows a run would remove (capped at 500 each). Nothing is changed.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-
idpathstring (uuid)yes-

Responses

StatusDescriptionBody
200What a run would removeapplication/json: ProjectCleanupPreview
defaultErrorapplication/json: Error

GET /api/v1/projects/{project}/groups ​

List project groups

List groups attached to a project, with the role each group's members get. Requires a role in the project (viewer or above) or global admin; a non-member gets 404.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-

Responses

StatusDescriptionBody
200List of project groupsapplication/json: object
400Invalid request, including a NUL byte in the URL or the bodyapplication/json: Error
403Forbiddenapplication/json: Error
404Project not found-

Fields of the 200 response (application/json):

FieldTypeRequiredDescription
groupsarray of ProjectGroupno-

PUT /api/v1/projects/{project}/groups/{group} ​

Attach or update project group

Attach a group with a role, or change the role of an attached group. Requires the owner or maintainer role or global admin (maintainers may only touch roles below maintainer); a viewer or developer gets 403, a non-member 404. Granting or changing the maintainer role needs the owner role.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-
grouppathstringyesGroup ID or exact group name

Request body (required)

application/json: ProjectGroupUpdateRequest

Responses

StatusDescriptionBody
200Group attached or updatedapplication/json: ProjectGroup
400Invalid role-
403Not allowed to grant or change this role-
404Project or group not found-

DELETE /api/v1/projects/{project}/groups/{group} ​

Detach project group

Detach a group. Requires the owner or maintainer role or global admin (maintainers may only touch roles below maintainer); a viewer or developer gets 403, a non-member 404.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-
grouppathstringyesGroup ID or exact group name

Responses

StatusDescriptionBody
204Group detached-
400Invalid request, including a NUL byte in the URL or the bodyapplication/json: Error
403Not allowed to grant or change this role-
404Group not attached-

GET /api/v1/projects/{project}/members ​

List project members

List members of a project. Requires a role in the project (viewer or above) or global admin; a non-member gets 404.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-

Responses

StatusDescriptionBody
200List of project membersapplication/json: object
400Invalid request, including a NUL byte in the URL or the bodyapplication/json: Error
403Forbiddenapplication/json: Error
404Project not found or the caller is not a member-

Fields of the 200 response (application/json):

FieldTypeRequiredDescription
membersarray of ProjectMemberno-

POST /api/v1/projects/{project}/members ​

Add project member

Add a user (by user_id or username, exactly one) to a project; the role defaults to viewer. Requires the owner or maintainer role or global admin (maintainers may only touch roles below maintainer); a viewer or developer gets 403, a non-member 404.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-

Request body (required)

application/json: ProjectMemberCreateRequest

Responses

StatusDescriptionBody
201Member addedapplication/json: ProjectMember
400Invalid role-
403Not allowed to grant this role-
404Project or user not found-
409User is already a member-

PATCH /api/v1/projects/{project}/members/{user_id} ​

Update project member

Change a member's role. Requires the owner or maintainer role or global admin (maintainers may only touch roles below maintainer); a viewer or developer gets 403, a non-member 404. The recorded project owner cannot be demoted and the last owner cannot be demoted or removed (409).

Parameters

NameInTypeRequiredDescription
projectpathstringyes-
user_idpathstring (uuid)yes-

Request body (required)

application/json: ProjectMemberUpdateRequest

Responses

StatusDescriptionBody
200Member updatedapplication/json: ProjectMember
400Invalid role-
403Not allowed to change this role-
404Project or member not found-
409Would remove or demote the recorded or last owner-

DELETE /api/v1/projects/{project}/members/{user_id} ​

Remove project member

Remove a member. Requires the owner or maintainer role or global admin (maintainers may only touch roles below maintainer); a viewer or developer gets 403, a non-member 404. The recorded project owner and the last owner cannot be removed (409).

Parameters

NameInTypeRequiredDescription
projectpathstringyes-
user_idpathstring (uuid)yes-

Responses

StatusDescriptionBody
204Member removed-
400Invalid request, including a NUL byte in the URL or the bodyapplication/json: Error
403Not allowed to change this role-
404Member not found-
409Would remove or demote the recorded or last owner-

GET /api/v1/projects/{project}/quota ​

Get project quota

The project's storage ceiling (0 = unlimited) and its live usage. Any member.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-

Responses

StatusDescriptionBody
200Project quotaapplication/json: ProjectQuota
400Invalid request, including a NUL byte in the URL or the bodyapplication/json: Error
403Forbiddenapplication/json: Error
404Project not found or the caller is not a member-

PUT /api/v1/projects/{project}/quota ​

Set project quota

Global admins only: sets the ceiling over the sum of the project's repositories (0 = unlimited). An upload must fit both its repository's limit and the project's. Enabling a limit initialises the project counters from the repositories' usage. Omitted fields keep their value. Repository limits above the project limit are refused when set.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-

Request body (required)

application/json: object

FieldTypeRequiredDescription
max_artifact_countinteger (int64)noMinimum: 0.
max_size_bytesinteger (int64)noMinimum: 0.
warn_threshold_percentintegernoMinimum: 0. Maximum: 100.

Responses

StatusDescriptionBody
200Project quotaapplication/json: ProjectQuota
400Invalid limits-
403Not a global admin-
404Project not found or the caller is not a member-

GET /api/v1/projects/{project}/repositories ​

List project repositories

List the live (not trashed) repositories of a project, newest first. Requires a role in the project (viewer or above) or global admin; a non-member gets 404.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-
pagequeryintegernoDefault: 1. Minimum: 1.
limitqueryintegernoDefault: 25. Minimum: 1. Maximum: 100.

Responses

StatusDescriptionBody
200A page of repositoriesapplication/json: object
400Invalid request, including a NUL byte in the URL or the bodyapplication/json: Error
403Forbiddenapplication/json: Error
404Project not found or the caller is not a member-

Fields of the 200 response (application/json):

FieldTypeRequiredDescription
limitintegerno-
pageintegerno-
repositoriesarray of Repositoryno-
totalintegerno-

POST /api/v1/projects/{project}/repositories ​

Create a repository in a project

Create a repository owned by the project. Requires the maintainer or owner role in the project, or global admin; a non-member gets 404. The body is the one of POST /api/v1/repositories without project (the URL names it). For a caller who is not a global admin the project policy applies: format in allowed_formats (when set), repo_type in allowed_repo_types, name starting with repo_name_prefix (400 validation_failed), public only when allow_public_repos (403), member_repos readable by the caller (403) and the project below max_repositories (409 project_repository_limit).

Parameters

NameInTypeRequiredDescription
projectpathstringyes-

Request body (required)

application/json: object

FieldTypeRequiredDescription
cache_ttl_secondsintegerno-
descriptionstringno-
federatedbooleannoEnable federation at creation. Only valid for hosted repositories of the formats raw, maven, npm, docker, helm, pypi, cargo, go and nuget (400 otherwise when true).
formatstringyes-
immutable_releasesbooleanno-
max_stale_secondsintegerno-
member_reposarray of stringno-
merge_proxy_versionsbooleannoGroup repositories only, administrators only (403 otherwise). Default false: hosted members win a package name and proxy versions of the same name are hidden. true merges proxy versions into the group.
namestringyes-
negative_cache_ttl_secondsintegerno-
presign_downloadsbooleannoNullable.
publicbooleanno-
repo_typestringnoOne of: hosted, proxy, group.
sign_packagesbooleannoHosted rpm repositories only (400 otherwise when true). When true, uploaded RPMs are signed with the active GPG key; existing packages are not re-signed.
trash_retention_daysintegernoNullable.
upstream_passwordstringno-
upstream_urlstringno-
upstream_usernamestringno-

Responses

StatusDescriptionBody
201Repository createdapplication/json: Repository
400Invalid request or a project policy violation (format, type, name prefix)-
403Role below maintainer, public repository not allowed, or a member repository the caller cannot read-
404Project not found or the caller is not a member-
409Name already taken, or the project reached max_repositories (project_repository_limit)-

POST /api/v1/projects/{project}/repositories/{name}/transfer ​

Transfer a repository to another project

Move a repository of {project} to the project named in the body. Requires the owner role in both projects (global admin holds both); a caller with no role in one of them gets 404 for it, a lower role 403. For a caller who is not a global admin the target project's policy applies as at creation (format, type, name prefix, public) and its max_repositories (409). Access of both projects' members changes immediately.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-
namepathstringyes-

Request body (required)

application/json: object

FieldTypeRequiredDescription
to_projectstringyes-

Responses

StatusDescriptionBody
200Repository transferredapplication/json: Repository
400Missing to_project, same project, or a target policy violation-
403Not an owner of the source or the target project, or the target forbids public repositories-
404Project or repository not found, or the caller has no role in a project-
409The target project reached max_repositories-

GET /api/v1/projects/{project}/tokens ​

List project tokens

List the active tokens of a project. Maintainers, owners and global admins see all tokens; other members only the ones they minted. A non-member gets 404.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-

Responses

StatusDescriptionBody
200Project tokensapplication/json: object
400Invalid request, including a NUL byte in the URL or the bodyapplication/json: Error
403Forbiddenapplication/json: Error
404Project not found or the caller is not a member-

Fields of the 200 response (application/json):

FieldTypeRequiredDescription
tokensarray of ProjectTokenno-

POST /api/v1/projects/{project}/tokens ​

Create project token

Mint a deploy token for CI. It belongs to a service account of the project: it can only use the repositories of this project (viewer: read, developer: read and write), never /api/v1/**, and is revoked when its creator leaves the project, is disabled or deleted. Requires a session (API tokens cannot mint). The role may not exceed the caller's own role. expires_at is required when the project limits token lifetime (token_max_ttl_days) and may not exceed it. At most 100 active tokens per project; names are unique among them. The secret is returned once.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-

Request body (required)

application/json: ProjectTokenCreateRequest

Responses

StatusDescriptionBody
201Token createdapplication/json: ProjectTokenCreateResponse
400Invalid name, role or expiry-
403Not a session, or the role exceeds the caller's own role-
404Project not found or the caller is not a member-
409Name already in use, or the project has 100 active tokens-

DELETE /api/v1/projects/{project}/tokens/{token_id} ​

Revoke project token

Revoke a project token; it stops working immediately. Maintainers, owners and global admins may revoke any token of the project, other members only their own (403 otherwise).

Parameters

NameInTypeRequiredDescription
projectpathstringyes-
token_idpathstring (uuid)yes-

Responses

StatusDescriptionBody
204Token revoked-
400Invalid request, including a NUL byte in the URL or the bodyapplication/json: Error
403Not allowed to revoke this token-
404Project or token not found-

GET /api/v1/projects/{project}/usage ​

Project usage

Storage usage of a project: the sum of its repositories' counters, the project quota and one line per live repository, largest first. Every repository of a hosted type is metered (quota_enforced); proxy and group repositories hold no uploaded packages. Any member; a non-member gets 404. project.token_created and project.token_revoked events are returned to maintainers and above only.

Parameters

NameInTypeRequiredDescription
projectpathstringyes-

Responses

StatusDescriptionBody
200Usageapplication/json: ProjectUsage
400Invalid request, including a NUL byte in the URL or the bodyapplication/json: Error
403Forbiddenapplication/json: Error
404Project not found or the caller is not a member-

Free software under the AGPL-3.0-or-later.