Skip to content

REST API ​

Everything the web interface manages can also be done over HTTP with JSON: repositories, components, search, blob stores, users and roles, tasks and the settings of the server. The API lives under /service/rest/v1/ on the same address as the web interface and the repositories, and it checks the same users, privileges and audit log. The examples use astrum.example.com; ASTRUM_TOKEN holds an access token of the user ci-deployer.

Where it lives ​

PathWhat it is
/service/rest/v1/...The REST API described on this page
/service/rest/swagger.jsonThe OpenAPI 3 document of the API; it needs no sign-in
/service/rest/repository/browse/<repository>/A plain HTML index of a repository, with download links
/repository/<repository>/...Repository content for build tools, see connect build tools
/service/metrics/prometheusPrometheus metrics, see monitoring
/mcpThe Model Context Protocol endpoint for agents, see agents over MCP

Paths under /service/rest/internal/ belong to the web interface. They are not in the OpenAPI document, and scripts should use the /v1 paths instead.

The API page ​

Settings → System → API, also API in the main menu, renders the OpenAPI document with Swagger UI: the operations grouped by area, a filter, the request and response models, and Try it out to send a request from the browser. Requests sent from this page run as the signed-in user, with the session of the browser. The page needs the privilege astrum:settings:read (as-admin has it).

The document lists most of the /v1 operations. The tables at the end of this page also list routes that are not in it yet: capabilities, cleanup policies, remote and group blob stores, LDAP, SSL certificates and the system information.

Authentication ​

A client signs in on every request; there is no separate login call.

  • Basic authentication with a user name and password: curl -u ci-deployer:<password>. This works for local users and for LDAP users with their directory password.
  • Access tokens: as the password of Basic authentication (curl -u "ci-deployer:$ASTRUM_TOKEN"), or as Authorization: Bearer astrum_.... Users who sign in through OpenID Connect have no password and use a token. A token with the access Read only is allowed only reading and browsing; anything that changes the server needs a Read and write token. See access tokens.

Wrong credentials are answered 401, also when anonymous access is on: a request with credentials never falls back to the anonymous user. The tokens that agents get through OAuth for /mcp are refused everywhere else.

Every endpoint checks the privileges of the user, for example astrum:tasks:read to list tasks and astrum:tasks:start to run one; the role as-admin has all of them. Repositories and their content are checked per repository, so a user sees only the repositories, components and assets they may browse or read.

Requests from the web interface ​

The web interface signs in once and keeps a session in the cookie astrum_session. A request that relies on that cookie and changes something (any method other than GET, HEAD and OPTIONS) must carry the header X-Astrum-CSRF with the value of the cookie astrum_csrf, and is refused with 403 when the browser marks it as coming from another site. Scripts that send their credentials in Authorization need neither.

Anonymous access ​

While Settings → Security → Anonymous Access allows it, requests without credentials run as the anonymous user with the rights of its role (as-anonymous by default): they can list the repositories and search the content that role may read. When anonymous access is off, such requests are answered 401 with the challenge WWW-Authenticate: Basic realm="Astrum Repository". See anonymous access.

The OpenAPI document, /v1/status and /v1/status/writable answer without credentials either way. The upload specifications under /v1/formats need a signed-in user.

Requests and responses ​

  • Request bodies are JSON with Content-Type: application/json; a body without that header is answered 415. Uploads to /v1/components are multipart/form-data.
  • Responses are JSON. Times are in RFC 3339, such as 2026-10-24T09:15:02.118+00:00.
  • Addresses in responses, such as url and downloadUrl, start with the base URL when one is set, and with the address of the request otherwise.

Pagination ​

The lists of components and assets and the search results come in pages:

json
{
  "items": [ ... ],
  "continuationToken": "b2Zmc2V0OjUw"
}

Pass the token back as the query parameter continuationToken to get the next page, with the other parameters unchanged. The last page has "continuationToken": null. A page holds 100 items for /v1/components and /v1/assets and 50 for the search endpoints. The token is opaque; one that the server cannot read is answered 400. /v1/tasks uses the same shape but returns every task at once.

Errors ​

Most errors are answered with JSON:

StatusWhenBody
400The request is not validA list of problems, each with the field in id (* when it concerns the whole request) and a message: [{"id": "PARAMETER remoteUrl", "message": "..."}]
401No valid credentials{"id": "*", "message": "authentication is required"} and a WWW-Authenticate challenge
403The user lacks the privilege{"id": "*", "message": "you do not have the permission this needs"}
404The repository, component or other object does not exist, or the user may not see it{"id": "*", "message": "..."}; a path that is not a route at all answers 404 with an empty body
409The request conflicts with the current state, such as running a task that already runs{"id": "*", "message": "..."}
415A JSON body without Content-Type: application/json{"id": "*", "message": "..."}
500The server failed{"id": "*", "message": "the server failed; the log names it <reference>"}; search the log for the reference

Some errors that come from the content of a repository, such as a few refusals of an upload and the errors of the HTML index, are plain text with the message instead.

Examples ​

List repositories ​

shell
curl -u "ci-deployer:$ASTRUM_TOKEN" https://astrum.example.com/service/rest/v1/repositories
json
[
  {
    "name": "maven-releases",
    "format": "maven2",
    "type": "hosted",
    "url": "https://astrum.example.com/repository/maven-releases",
    "online": true,
    "attributes": {},
    "size": 73400320
  }
]

The list holds the repositories the user may see; proxies carry their remote address in attributes.proxy.remoteUrl, and size is the space their files take, in bytes. The complete settings of one repository are at /v1/repositories/<format>/<type>/<name>, for example /v1/repositories/maven/hosted/maven-releases; see repositories for what they hold. In these paths Maven is called maven, every other format by its name in the format field.

Search components and assets ​

shell
curl -u "ci-deployer:$ASTRUM_TOKEN" \
  "https://astrum.example.com/service/rest/v1/search?repository=maven-releases&maven.groupId=com.example&name=my-library"
json
{
  "items": [
    {
      "id": "bWF2ZW4tcmVsZWFzZXM6MmE",
      "repository": "maven-releases",
      "format": "maven2",
      "group": "com.example",
      "name": "my-library",
      "version": "1.0.0",
      "assets": [
        {
          "downloadUrl": "https://astrum.example.com/repository/maven-releases/com/example/my-library/1.0.0/my-library-1.0.0.jar",
          "path": "/com/example/my-library/1.0.0/my-library-1.0.0.jar",
          "id": "bWF2ZW4tcmVsZWFzZXM6MmI",
          "repository": "maven-releases",
          "format": "maven2",
          "checksum": { "md5": "...", "sha1": "...", "sha256": "...", "sha512": "..." },
          "contentType": "application/java-archive",
          "fileSize": 18342,
          "lastModified": "2026-10-24T09:15:02.118+00:00",
          "lastDownloaded": null
        }
      ]
    }
  ],
  "continuationToken": null
}

The assets carry more fields than shown here, such as the uploader, the blob store and the attributes of their format. /v1/search/assets takes the same parameters and returns the matching assets on their own, in the shape of the assets above.

ParameterMatches
qA keyword: components whose name, group or version, some descriptive attributes of their format, or the path of one of their files contain it, ignoring case. With several words separated by spaces, a component matches when any of them does
repositoryOne repository; a group searches its members
formatThe format, such as maven2, npm or docker
group, name, versionThe group, name or version, ignoring case; * stands for any characters, so version=1.2.* finds every 1.2 version
md5, sha1, sha256, sha512An asset with this checksum
<format>.<attribute>An attribute of the format, such as maven.groupId, maven.extension, npm.scope or docker.imageTag; * works here too, and an empty value matches where the attribute is missing or empty
sort, directionname, version, group or repository, and asc or desc; without sort the results come in the order they were stored
continuationTokenThe next page

The Advanced Search page of the web interface (/search/custom) lists the format attributes that can be searched.

Download the file a search finds ​

/v1/search/assets/download takes the same parameters and redirects (302) to the download address of the asset when exactly one matches, or to the first one when sort is given. Several matches without sort are answered 400, none 404:

shell
curl -L -u "ci-deployer:$ASTRUM_TOKEN" -o my-library.jar \
  "https://astrum.example.com/service/rest/v1/search/assets/download?repository=maven-releases&maven.groupId=com.example&maven.artifactId=my-library&version=1.0.0&maven.extension=jar&maven.classifier="

The empty maven.classifier leaves out the sources and javadoc jars of the same version.

Upload a component ​

POST /v1/components?repository=<name> takes a multipart form and uploads to a hosted repository, the same way as the Upload page. It answers 204 when the component is stored. The fields are named after the format: component fields as <format>.<field>, each file as <format>.asset<N> and the fields of that file as <format>.asset<N>.<field>.

A raw file:

shell
curl -u "ci-deployer:$ASTRUM_TOKEN" \
  -F raw.directory=/tools \
  -F raw.asset1=@build/tool-1.4.0.tar.gz \
  -F raw.asset1.filename=tool-1.4.0.tar.gz \
  "https://astrum.example.com/service/rest/v1/components?repository=raw-hosted"

A Maven jar with a generated POM:

shell
curl -u "ci-deployer:$ASTRUM_TOKEN" \
  -F maven2.groupId=com.example -F maven2.artifactId=my-library -F maven2.version=1.0.0 \
  -F maven2.generate-pom=true \
  -F maven2.asset1=@target/my-library-1.0.0.jar -F maven2.asset1.extension=jar \
  "https://astrum.example.com/service/rest/v1/components?repository=maven-releases"

When a file with the extension pom and no classifier is part of the upload, the coordinates are read from it instead. GET /v1/formats/upload-specs lists the fields of every format that takes uploads, and GET /v1/formats/<format>/upload-specs those of one; the page of each format describes its own.

Delete a component ​

Take the id of the component from a search or from /v1/components?repository=<name>:

shell
curl -u "ci-deployer:$ASTRUM_TOKEN" -X DELETE \
  https://astrum.example.com/service/rest/v1/components/bWF2ZW4tcmVsZWFzZXM6MmE

The answer is 204. Deleting a component deletes all its assets, and needs the right to delete every one of them. DELETE /v1/assets/<id> deletes a single file.

Run a task ​

Look the task up by its type, then start it by its id:

shell
curl -u "ci-deployer:$ASTRUM_TOKEN" \
  "https://astrum.example.com/service/rest/v1/tasks?type=repository.cleanup"

curl -u "ci-deployer:$ASTRUM_TOKEN" -X POST \
  https://astrum.example.com/service/rest/v1/tasks/<id>/run

The run is queued and the answer is 204. A task that already runs or is about to run is answered 409, a disabled one 405. GET /v1/tasks/<id> shows currentState, lastRun and lastRunResult; see tasks for the task types.

Status and health ​

shell
curl -fs https://astrum.example.com/service/rest/v1/status/writable

The status endpoints and what they check are described in monitoring.

Endpoints ​

Paths are relative to /service/rest.

Repositories ​

Method and pathWhat it does
GET /v1/repositoriesThe repositories the user may see, with format, type, address, state and size
GET /v1/repositories/{name}The summary of one repository, without its size
DELETE /v1/repositories/{name}Deletes the repository and everything in it
POST /v1/repositories/{format}/{type}Creates a repository; {type} is hosted, proxy or group
GET /v1/repositories/{format}/{type}/{name}The complete settings of a repository
PUT /v1/repositories/{format}/{type}/{name}Changes the settings of a repository
POST /v1/repositories/{name}/invalidate-cacheProxy and group repositories: marks the cached content so that it is checked against the remote again
POST /v1/repositories/{name}/rebuild-indexAccepted for hosted and proxy repositories; on a proxy it marks the cached content like invalidate-cache
GET /v1/repositorySettingsThe complete settings of every repository the user may read the settings of

Components and assets ​

Method and pathWhat it does
GET /v1/components?repository={name}The components of a repository, 100 a page
POST /v1/components?repository={name}Uploads a component to a hosted repository from a multipart form
GET /v1/components/{id}One component with its assets
DELETE /v1/components/{id}Deletes a component and its assets
GET /v1/assets?repository={name}The assets of a repository, 100 a page
GET /v1/assets/{id}One asset
DELETE /v1/assets/{id}Deletes an asset
GET /v1/formats/upload-specsThe upload fields of every format that takes uploads
GET /v1/formats/{format}/upload-specsThe upload fields of one format

Search and browse ​

Method and pathWhat it does
GET /v1/searchSearches components, 50 a page
GET /v1/search/assetsSearches assets, 50 a page
GET /v1/search/assets/downloadRedirects to the download address of the asset a search finds
GET /repository/browse/{name}/An HTML index of a folder of the repository, with download links

Blob stores ​

Method and pathWhat it does
GET /v1/blobstoresThe blob stores with their type, blob count, size, free space and soft quota
DELETE /v1/blobstores/{name}Deletes a blob store
GET /v1/blobstores/{name}/quota-statusWhether the store is over its soft quota
POST /v1/blobstores/fileCreates a file blob store
GET, PUT /v1/blobstores/file/{name}Reads or changes a file blob store
POST /v1/blobstores/s3Creates an S3 blob store
GET, PUT /v1/blobstores/s3/{name}Reads or changes an S3 blob store
POST /v1/blobstores/test-connectionTries the connection settings of an S3 blob store
POST /v1/blobstores/remoteCreates a remote blob store
GET, PUT /v1/blobstores/remote/{name}Reads or changes a remote blob store
POST /v1/blobstores/groupCreates a group blob store
GET, PUT /v1/blobstores/group/{name}Reads or changes a group: its members and fill policy
POST /v1/blobstores/group/convert/{name}/{newNameForOriginal}Turns a store that repositories use into a group of the same name, with the store under its new name as the only member

See blob stores.

Cleanup policies and routing rules ​

Method and pathWhat it does
GET, POST /v1/cleanup-policiesLists or creates cleanup policies
GET, PUT, DELETE /v1/cleanup-policies/{name}Reads, changes or deletes a cleanup policy
GET, POST /v1/routing-rulesLists or creates routing rules
GET, PUT, DELETE /v1/routing-rules/{name}Reads, changes or deletes a routing rule

See cleanup policies and routing rules.

Users, roles and privileges ​

Method and pathWhat it does
GET /v1/security/usersLists users; source picks the user source and userId filters by ID
POST /v1/security/usersCreates a local user
PUT, DELETE /v1/security/users/{userId}Changes or deletes a user
PUT /v1/security/users/{userId}/change-passwordSets the password of a local user
GET /v1/security/user-sourcesThe user sources
GET, POST /v1/security/rolesLists or creates roles
GET /v1/security/roles/assignableThe roles the user may grant to others
GET, PUT, DELETE /v1/security/roles/{id}Reads, changes or deletes a role
GET /v1/security/privilegesLists privileges
POST /v1/security/privileges/{type}Creates a privilege of the type application, wildcard, repository-view, repository-admin or repository-content-selector
PUT /v1/security/privileges/{type}/{name}Changes a privilege
GET, DELETE /v1/security/privileges/{name}Reads or deletes a privilege
GET, POST /v1/security/content-selectorsLists or creates content selectors
GET, PUT, DELETE /v1/security/content-selectors/{name}Reads, changes or deletes a content selector

See users, roles and privileges.

Sign-in and security settings ​

Method and pathWhat it does
GET /v1/security/realms/availableThe realms the server knows
GET, PUT /v1/security/realms/activeThe active realms, in the order they are tried
GET, PUT /v1/security/anonymousThe anonymous access settings
GET, PUT /v1/security/ssrf-protectionWhich addresses outgoing requests of the server may not reach
GET, POST /v1/security/ldapLists or adds LDAP servers
GET /v1/security/ldap/templatesPresets of user and group settings for common directories
POST /v1/security/ldap/change-orderSets the order the LDAP servers are tried in
DELETE /v1/security/ldap/cacheDrops the cached LDAP users and sign-ins
POST /v1/security/ldap/verify-connectionTries the connection settings of an LDAP server
POST /v1/security/ldap/verify-user-mappingLists the first users and groups the settings find
POST /v1/security/ldap/verify-loginTries the password of a user against the settings
GET, PUT, DELETE /v1/security/ldap/{name}Reads, changes or deletes an LDAP server
GET /v1/security/ssl?host={host}&port={port}Fetches the certificate a server presents
GET, POST /v1/security/ssl/truststoreLists or adds trusted certificates
DELETE /v1/security/ssl/truststore/{id}Removes a trusted certificate

See users, realms and sign-in and SSL certificates.

System ​

Method and pathWhat it does
GET, PUT /v1/httpThe settings of outbound HTTP: user agent, timeout, retries and proxies
GET, PUT, DELETE /v1/emailThe mail server settings; DELETE removes them
POST /v1/email/verifySends a test message
GET, POST /v1/capabilitiesLists or creates capabilities
GET /v1/capabilities/typesThe capability types and their fields
GET, PUT, DELETE /v1/capabilities/{id}Reads, changes or deletes a capability
GET /v1/tasksLists tasks; type filters by task type
POST /v1/tasksCreates a task
GET /v1/tasks/templatesThe task types with their fields and defaults
GET /v1/tasks/templates/{type}One task type
GET, PUT, DELETE /v1/tasks/{id}Reads, changes or deletes a task
POST /v1/tasks/{id}/runStarts a task
POST /v1/tasks/{id}/stopStops a running task

See outbound HTTP, capabilities and tasks.

Status and support ​

Method and pathWhat it does
GET /v1/statusWhether the database answers
GET /v1/status/writableWhether the server accepts writes
GET /v1/status/checkThe named health checks
POST /v1/support/supportzipBuilds a support ZIP and returns it
POST /v1/support/supportzippathBuilds a support ZIP in the data directory and returns its path
GET /atlas/system-informationVersion, node, directories, runtime, operating system, database and blob stores of the server; needs astrum:atlas:read
GET /swagger.jsonThe OpenAPI document

See monitoring and logs.

Released under the MIT License.