Premex Artifacts - Package Registry
Feed this document to an AI assistant to enable it to integrate with the Artifacts package registry. It covers authentication, API usage, and complete publish/consume workflows for npm, Maven, Swift, Raw, and KMP packages.
Overview
Artifacts is a package registry supporting npm, Maven, Swift, Raw, and KMP (Kotlin Multiplatform) packages.
- Base URL:
https://artifacts.premex.se - Web UI:
https://artifacts.premex.se— create accounts, manage repositories, and generate API tokens - Auth: API tokens (
art_prefix) for all CLI and API access - Protocols: Standard npm registry, Maven HTTP repository, Swift Package Registry (SE-0292), Raw file storage, and KMP build pipeline
1. Authentication
1.1 Token Types
Artifacts has three token types:
| Type | Prefix | Scope | Create location |
|---|---|---|---|
| Account | art_ |
Acts as your user identity | Settings > API Tokens |
| Organization | org_ |
All repos in an org | Org Settings > Organization Tokens |
| Repository | rep_ |
A single repo | Repo Settings > Repository Tokens |
For quick CLI access, create an account token at Settings > API Tokens.
For CI/CD, use an org token (org_). For customer distribution, use a repo token (rep_).
Tokens look like: art_a1b2c3d4e5f6789012345678901234567890abcdef
The token is shown only once when created. Store it securely.
1.2 Auth Methods
All API routes accept these auth methods:
| Method | Format | Used by |
|---|---|---|
| API token (Bearer) | Authorization: Bearer art_|org_|rep_... |
npm CLI, Swift PM, curl |
| Basic auth | Authorization: Basic base64(token:art_|org_|rep_...) |
Maven/Gradle |
For Basic auth, the username can be anything (conventionally token), and the password is the API token.
1.3 Token Scopes
All three token types use the same hierarchical scopes:
| Scope | Level | Grants |
|---|---|---|
read |
0 | Download/list packages |
write |
1 | Publish packages (includes read) |
admin |
2 | Manage repos, tokens, members (includes write and read) |
Scope enforcement: a token can only perform actions up to its highest scope level.
- Account tokens (
art_): scopes are checked on top of user membership roles - Org tokens (
org_): scopes grant direct access to all repos in the org (no membership check) - Repo tokens (
rep_): scopes grant direct access to the specific repo (no membership check)
1.4 Token Management API
Three endpoints manage the three token types:
Account tokens — GET|POST|DELETE /api/auth/token
- Auth: Firebase ID token only (web session)
Org tokens — GET|POST|DELETE /api/orgs/{orgSlug}/tokens
- Create: Firebase auth only (org admin+)
- List/Delete: Firebase auth (org admin+) or
org_admin token
Repo tokens — GET|POST|DELETE /api/repos/{repoId}/tokens
- All operations: Firebase auth (repo admin+) or
org_admin token for the repo's org
# Create an org token (requires Firebase auth + org admin role)
curl -X POST "https://artifacts.premex.se/api/orgs/ORGSLUG/tokens" \
-H "Authorization: Bearer $FIREBASE_ID_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "CI Pipeline", "scopes": ["read", "write"]}'
# Create a repo token (org_ admin token can do this programmatically)
curl -X POST "https://artifacts.premex.se/api/repos/REPO_ID/tokens" \
-H "Authorization: Bearer org_your_admin_token" \
-H "Content-Type: application/json" \
-d '{"name": "customer-readonly", "scopes": ["read"]}'
# List repo tokens
curl "https://artifacts.premex.se/api/repos/REPO_ID/tokens" \
-H "Authorization: Bearer org_your_admin_token"
# Delete a token
curl -X DELETE "https://artifacts.premex.se/api/repos/REPO_ID/tokens?tokenId=TOKEN_ID" \
-H "Authorization: Bearer org_your_admin_token"
Create token fields:
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Human-readable label |
scopes |
string[] | No | Default varies by endpoint |
expiresInDays |
number | No | Days until expiration (omit for no expiry) |
Response:
{
"token": {
"id": "token-id",
"tokenType": "repo",
"name": "customer-readonly",
"tokenPrefix": "rep_a1b2c3d4",
"scopes": ["read"],
"expiresAt": "2027-02-26T00:00:00.000Z",
"createdAt": "2026-02-26T12:00:00.000Z"
},
"rawToken": "rep_a1b2c3d4e5f6..."
}
rawToken is only returned at creation time. Subsequent GET calls return token metadata without the secret.
2. Repository Management
2.1 Creating a Repository
Repositories are polyglot — each repo supports one or more package types simultaneously. A single repo can serve npm, Maven, Swift, Raw, and/or KMP packages at the same time, with each protocol's proxy working independently. The packageTypes field is an array (e.g., ["npm", "maven"]).
Repositories can be created via the web UI or the API.
curl -s "https://artifacts.premex.se/api/repos" \
-X POST \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"name": "my-npm-repo",
"packageTypes": ["npm"],
"visibility": "private",
"description": "Internal npm packages"
}'
| Field | Type | Required | Values |
|---|---|---|---|
name |
string | Yes | 2-64 chars, lowercase, numbers, hyphens only |
packageTypes |
string[] | Yes | Non-empty array of: npm, maven, swift, raw, kmp |
visibility |
string | No | private (default) or public |
description |
string | No | Free text |
kmpConfig |
object | Only when packageTypes includes kmp |
See KMP Packages |
Response (HTTP 201):
{
"repo": {
"id": "my-npm-repo",
"name": "my-npm-repo",
"packageTypes": ["npm"],
"visibility": "private",
"description": "Internal npm packages",
"ownerId": "user123",
"members": { "user123": "owner" },
"memberUids": ["user123"],
"packageCount": 0,
"downloadCount": 0,
"createdAt": "2026-02-16T10:30:00.000Z",
"updatedAt": "2026-02-16T10:30:00.000Z"
}
}
The id field is the repo ID used in all subsequent API calls and CLI URLs.
2.2 Listing Repositories
curl -s "https://artifacts.premex.se/api/repos" \
-H "Authorization: Bearer $TOKEN"
Returns { "repos": [...] } — all repos the authenticated user is a member of.
2.3 Public Repository Discovery
List all public repositories (no authentication required):
curl -s "https://artifacts.premex.se/api/repos/public"
Returns repos with their packages embedded:
{
"repos": [{
"id": "my-public-repo",
"name": "my-public-repo",
"description": "Public packages",
"packageTypes": ["npm"],
"packageCount": 3,
"downloadCount": 42,
"createdAt": "2026-02-16T10:30:00.000Z",
"updatedAt": "2026-02-16T14:30:00.000Z",
"packages": [{
"id": "pkg-id",
"name": "@scope/package-name",
"packageType": "npm",
"latestVersion": "1.0.0",
"description": "A package",
"scope": "scope",
"groupId": null,
"artifactId": null,
"downloadCount": 10,
"versionCount": 3
}]
}]
}
2.4 Repository Details, Update, Delete
# Get details
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID" \
-H "Authorization: Bearer $TOKEN"
# Update (requires admin role)
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID" \
-X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"description": "Updated description", "visibility": "public"}'
# Delete (requires owner role)
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID" \
-X DELETE \
-H "Authorization: Bearer $TOKEN"
2.5 Managing Members
# List members
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/members" \
-H "Authorization: Bearer $TOKEN"
# Add member (requires admin role)
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/members" \
-X POST \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"userId": "other-user-uid", "role": "write"}'
# Remove member (requires admin role)
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/members?userId=other-user-uid" \
-X DELETE \
-H "Authorization: Bearer $TOKEN"
List members response:
{
"members": [
{
"uid": "user123",
"role": "admin",
"displayName": "Jane Smith",
"email": "jane@example.com",
"avatarUrl": "https://..."
}
]
}
Role hierarchy: read < write < admin < owner
2.6 Listing Packages in a Repository
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/packages" \
-H "Authorization: Bearer $TOKEN"
Returns { "packages": [...] }.
3. npm Packages
3.1 Registry URL Pattern
https://artifacts.premex.se/api/npm/$REPO_ID/
Example: https://artifacts.premex.se/api/npm/my-npm-repo/
3.2 Publishing npm Packages
Option A: Using npm CLI
Configure .npmrc in your project directory:
# For scoped packages (@yourscope/*)
@yourscope:registry=https://artifacts.premex.se/api/npm/REPO_ID/
//artifacts.premex.se/api/npm/REPO_ID/:_authToken=art_your_token_here
# For unscoped packages
registry=https://artifacts.premex.se/api/npm/REPO_ID/
//artifacts.premex.se/api/npm/REPO_ID/:_authToken=art_your_token_here
Then publish:
npm publish --registry https://artifacts.premex.se/api/npm/REPO_ID/
Option B: Using the Upload API
curl -s "https://artifacts.premex.se/api/packages/upload" \
-X POST \
-H "Authorization: Bearer $TOKEN" \
-F "repoId=REPO_ID" \
-F "packageName=@scope/package-name" \
-F "version=1.0.0" \
-F "packageType=npm" \
-F "description=My package" \
-F "file=@./my-package-1.0.0.tgz"
3.3 Installing npm Packages
Configure .npmrc:
@yourscope:registry=https://artifacts.premex.se/api/npm/REPO_ID/
//artifacts.premex.se/api/npm/REPO_ID/:_authToken=art_your_token_here
Then install normally:
npm install @yourscope/package-name
3.4 npm Search
npm search --registry https://artifacts.premex.se/api/npm/REPO_ID/ searchterm
Or via API:
curl -s "https://artifacts.premex.se/api/npm/REPO_ID/-/v1/search?text=hello" \
-H "Authorization: Bearer $TOKEN"
3.5 npm API Endpoints Reference
| Operation | Method | URL Pattern |
|---|---|---|
| Get packument | GET | /api/npm/{repoId}/{packageName} |
| Get packument (scoped) | GET | /api/npm/{repoId}/@{scope}/{name} |
| Download tarball | GET | /api/npm/{repoId}/-/tarball/{encodedPackageName}/{version} |
| Publish | PUT | /api/npm/{repoId}/{packageName} |
| Search | GET | /api/npm/{repoId}/-/v1/search?text={query} |
3.6 Packument Response Format
{
"_id": "@scope/package-name",
"_rev": "1-0",
"name": "@scope/package-name",
"description": "Package description",
"dist-tags": { "latest": "1.0.0" },
"versions": {
"1.0.0": {
"name": "@scope/package-name",
"version": "1.0.0",
"description": "Package description",
"dist": {
"tarball": "https://artifacts.premex.se/api/npm/REPO_ID/-/tarball/%40scope%2Fpackage-name/1.0.0",
"shasum": "hex-sha1-checksum",
"integrity": "sha256-base64-checksum"
},
"_id": "@scope/package-name@1.0.0"
}
},
"time": {
"created": "2026-02-16T10:30:00.000Z",
"modified": "2026-02-16T14:30:00.000Z",
"1.0.0": "2026-02-16T14:30:00.000Z"
}
}
4. Maven Packages
4.1 Repository URL Pattern
https://artifacts.premex.se/api/maven/$REPO_ID/
Example: https://artifacts.premex.se/api/maven/my-maven-repo/
4.2 Publishing Maven Packages with Gradle
build.gradle.kts:
plugins {
`java-library`
`maven-publish`
}
group = "com.example"
version = "1.0.0"
publishing {
publications {
create<MavenPublication>("maven") {
from(components["java"])
}
}
repositories {
maven {
name = "artifacts"
url = uri(System.getenv("ARTIFACTS_URL") ?: "https://artifacts.premex.se/api/maven/REPO_ID/")
credentials {
username = "token"
password = System.getenv("ARTIFACTS_TOKEN") ?: ""
}
}
}
}
Publish:
export ARTIFACTS_URL="https://artifacts.premex.se/api/maven/REPO_ID/"
export ARTIFACTS_TOKEN="art_your_token_here"
./gradlew publishMavenPublicationToArtifactsRepository
4.3 Publishing Maven Packages with Maven CLI
~/.m2/settings.xml:
<settings>
<servers>
<server>
<id>artifacts</id>
<username>token</username>
<password>art_your_token_here</password>
</server>
</servers>
</settings>
pom.xml:
<distributionManagement>
<repository>
<id>artifacts</id>
<url>https://artifacts.premex.se/api/maven/REPO_ID/</url>
</repository>
</distributionManagement>
mvn deploy
4.4 Consuming Maven Packages with Gradle
build.gradle.kts:
repositories {
maven {
url = uri(System.getenv("ARTIFACTS_URL") ?: "https://artifacts.premex.se/api/maven/REPO_ID/")
credentials {
username = "token"
password = System.getenv("ARTIFACTS_TOKEN") ?: ""
}
}
}
dependencies {
implementation("com.example:hello-lib:1.0.0")
}
4.5 Consuming Maven Packages with Maven CLI
~/.m2/settings.xml (same as publishing config above)
pom.xml:
<repositories>
<repository>
<id>artifacts</id>
<url>https://artifacts.premex.se/api/maven/REPO_ID/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>hello-lib</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
4.6 Maven API Endpoints Reference
| Operation | Method | URL Pattern |
|---|---|---|
| Download file | GET | /api/maven/{repoId}/{groupPath}/{artifactId}/{version}/{filename} |
| Get metadata | GET | /api/maven/{repoId}/{groupPath}/{artifactId}/maven-metadata.xml |
| Get checksum | GET | /api/maven/{repoId}/{groupPath}/{artifactId}/maven-metadata.xml.sha1 |
| Check existence | HEAD | /api/maven/{repoId}/{groupPath}/{artifactId}/{version}/{filename} |
| Upload file | PUT | /api/maven/{repoId}/{groupPath}/{artifactId}/{version}/{filename} |
Auth: Basic auth with username token and password art_....
4.7 Maven Metadata Response Format
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>com.example</groupId>
<artifactId>hello-lib</artifactId>
<versioning>
<latest>1.0.0</latest>
<release>1.0.0</release>
<versions>
<version>1.0.0</version>
</versions>
<lastUpdated>20260216143000</lastUpdated>
</versioning>
</metadata>
4.8 Maven Path Conventions
Group ID maps to a directory path: com.example becomes com/example/.
Full artifact path: {groupPath}/{artifactId}/{version}/{filename}
Example: com/example/hello-lib/1.0.0/hello-lib-1.0.0.jar
5. Swift Packages
5.1 Registry URL Pattern
https://artifacts.premex.se/api/swift/$REPO_ID/
Example: https://artifacts.premex.se/api/swift/my-swift-repo/
5.2 Package Naming
Swift packages in Artifacts use a scope.name convention:
- Scope: organization or namespace (e.g.,
myorg) - Name: package name (e.g.,
hello-lib) - Combined identifier:
myorg.hello-lib
5.3 Publishing Swift Packages via API
Create a source archive (zip of the entire Swift package):
# In your Swift package directory
zip -r source-archive.zip Package.swift Sources/ Tests/ -x "*.DS_Store" ".build/*"
Publish the archive:
curl -s -X PUT \
"https://artifacts.premex.se/api/swift/REPO_ID/SCOPE/PACKAGE_NAME/VERSION" \
-H "Authorization: Bearer art_your_token_here" \
-H "Content-Type: application/zip" \
--data-binary "@source-archive.zip"
Example:
curl -s -X PUT \
"https://artifacts.premex.se/api/swift/my-swift-repo/myorg/hello-lib/1.0.0" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/zip" \
--data-binary "@source-archive.zip"
Response: HTTP 201 on success.
Optionally, also upload the Package.swift manifest separately (for serving via the manifest endpoint):
curl -s -X POST "https://artifacts.premex.se/api/packages/upload" \
-H "Authorization: Bearer $API_TOKEN" \
-F "repoId=REPO_ID" \
-F "packageName=hello-lib" \
-F "version=1.0.0" \
-F "packageType=swift" \
-F "scope=myorg" \
-F "description=My Swift library" \
-F "file=@Package.swift;type=text/x-swift"
5.4 Consuming Swift Packages
Configure Swift Package Manager to use the registry:
swift package-registry set https://artifacts.premex.se/api/swift/REPO_ID/
swift package-registry login https://artifacts.premex.se/api/swift/REPO_ID/ --token art_your_token_here
In your Package.swift:
dependencies: [
.package(id: "myorg.hello-lib", from: "1.0.0"),
]
5.5 Swift Registry API Endpoints Reference
All responses include the Content-Version: 1 header.
| Operation | Method | URL Pattern |
|---|---|---|
| List releases | GET | /api/swift/{repoId}/{scope}/{name} |
| Get release metadata | GET | /api/swift/{repoId}/{scope}/{name}/{version} |
| Download source archive | GET | /api/swift/{repoId}/{scope}/{name}/{version}.zip |
| Download Package.swift | GET | /api/swift/{repoId}/{scope}/{name}/{version}/Package.swift |
| Publish | PUT | /api/swift/{repoId}/{scope}/{name}/{version} |
5.6 Swift Releases List Response
{
"releases": {
"1.0.0": {
"url": "https://artifacts.premex.se/api/swift/REPO_ID/myorg/hello-lib/1.0.0"
},
"1.0.1": {
"url": "https://artifacts.premex.se/api/swift/REPO_ID/myorg/hello-lib/1.0.1"
}
}
}
5.7 Swift Release Metadata Response
{
"id": "myorg.hello-lib",
"version": "1.0.0",
"resources": [
{
"name": "source-archive",
"type": "application/zip",
"checksum": "sha256-hex-string"
}
],
"metadata": {
"description": "Package description"
}
}
5.8 Source Archive Download Headers
Content-Type: application/zip
Content-Disposition: attachment; filename="source-archive.zip"
Content-Version: 1
Digest: sha-256=hex-checksum
6. Raw Packages
Raw packages provide simple file storage with versioning. Any file type can be uploaded and downloaded using a straightforward path-based API.
6.1 URL Pattern
https://artifacts.premex.se/api/raw/$REPO_ID/{packageName}/{version}/{filename}
Example: https://artifacts.premex.se/api/raw/my-raw-repo/my-tool/1.0.0/my-tool-linux-amd64
6.2 Uploading Raw Files
Upload a file by PUTting the binary content directly:
curl -s -X PUT \
"https://artifacts.premex.se/api/raw/REPO_ID/PACKAGE_NAME/VERSION/FILENAME" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/octet-stream" \
--data-binary "@/path/to/file"
Example — upload a zip archive:
curl -s -X PUT \
"https://artifacts.premex.se/api/raw/my-raw-repo/my-tool/1.0.0/my-tool.zip" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/zip" \
--data-binary "@my-tool.zip"
Requires write role. Response: HTTP 201 { "ok": true }.
The upload automatically creates the package metadata if it doesn't exist. Multiple files can be uploaded under the same package name and version (e.g., platform-specific binaries).
6.3 Downloading Raw Files
curl -s -O \
"https://artifacts.premex.se/api/raw/REPO_ID/PACKAGE_NAME/VERSION/FILENAME" \
-H "Authorization: Bearer $TOKEN"
Requires read role. Public repos allow unauthenticated downloads.
The response includes a Content-Disposition: attachment header and a content type guessed from the file extension.
6.4 Listing Package Versions
curl -s "https://artifacts.premex.se/api/raw/REPO_ID/PACKAGE_NAME" \
-H "Authorization: Bearer $TOKEN"
Response:
{
"name": "my-tool",
"latestVersion": "1.0.0",
"versions": [
{
"version": "1.0.0",
"publishedAt": "2026-02-16T14:30:00.000Z",
"size": 12345
}
]
}
6.5 Deleting Raw Files
curl -s -X DELETE \
"https://artifacts.premex.se/api/raw/REPO_ID/PACKAGE_NAME/VERSION/FILENAME" \
-H "Authorization: Bearer $TOKEN"
Requires admin role. Response: { "ok": true }.
6.6 Raw API Endpoints Reference
| Operation | Method | URL Pattern | Role |
|---|---|---|---|
| List versions | GET | /api/raw/{repoId}/{packageName} |
read |
| Download file | GET | /api/raw/{repoId}/{packageName}/{version}/{filename} |
read |
| Upload file | PUT | /api/raw/{repoId}/{packageName}/{version}/{filename} |
write |
| Delete file | DELETE | /api/raw/{repoId}/{packageName}/{version}/{filename} |
admin |
6.7 Using the Upload API for Raw Files
Raw files can also be uploaded via the generic upload endpoint:
curl -s "https://artifacts.premex.se/api/packages/upload" \
-X POST \
-H "Authorization: Bearer $TOKEN" \
-F "repoId=REPO_ID" \
-F "packageName=my-tool" \
-F "version=1.0.0" \
-F "packageType=raw" \
-F "description=My tool binary" \
-F "file=@./my-tool.zip"
7. Upload API
For all package types, there is a generic upload endpoint:
curl -s "https://artifacts.premex.se/api/packages/upload" \
-X POST \
-H "Authorization: Bearer $TOKEN" \
-F "repoId=REPO_ID" \
-F "packageName=package-name" \
-F "version=1.0.0" \
-F "packageType=npm|maven|swift|raw" \
-F "description=Optional description" \
-F "file=@/path/to/file"
Additional fields by type:
| Package Type | Extra Fields | File Type |
|---|---|---|
| npm | — | .tgz |
| maven | groupId, artifactId |
.jar, .pom |
| swift | scope |
.zip, Package.swift |
| raw | — | Any file |
8. Error Responses
All errors return JSON:
{
"error": "Human-readable error message",
"code": "ERROR_CODE"
}
| HTTP Status | Code | When |
|---|---|---|
| 400 | BAD_REQUEST |
Missing/invalid parameters |
| 401 | UNAUTHORIZED |
Missing, invalid, or expired auth |
| 403 | FORBIDDEN |
Insufficient role for the operation |
| 404 | NOT_FOUND |
Resource does not exist |
| 409 | CONFLICT |
Duplicate repository name |
| 500 | (none) | Internal server error |
9. KMP Packages (Kotlin Multiplatform)
KMP repos are a special type that don't receive direct uploads. Instead, they watch a Maven source for Kotlin Multiplatform libraries and automatically build JS (npm) and XCFramework (Swift) outputs via GitHub Actions.
9.1 Creating a KMP Repository
A KMP repo requires a kmpConfig field specifying the Maven source:
# Source from another Artifacts Maven repo
curl -s "https://artifacts.premex.se/api/repos" \
-X POST \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"name": "my-kmp-repo",
"packageTypes": ["kmp"],
"kmpConfig": {
"sourceType": "artifacts",
"sourceRepoId": "my-maven-repo"
}
}'
# Source from an external Maven repository
curl -s "https://artifacts.premex.se/api/repos" \
-X POST \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"name": "my-kmp-repo",
"packageTypes": ["kmp"],
"kmpConfig": {
"sourceType": "external",
"sourceUrl": "https://repo1.maven.org/maven2"
}
}'
kmpConfig Field |
Type | Required | Description |
|---|---|---|---|
sourceType |
string | Yes | "artifacts" or "external" |
sourceRepoId |
string | If artifacts |
ID of the Artifacts Maven repo to watch |
sourceUrl |
string | If external |
URL of the external Maven repository |
9.2 Watched Packages
Watched packages define which Maven coordinates to monitor for new versions.
# List watched packages
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/kmp/watched" \
-H "Authorization: Bearer $TOKEN"
# Add a watched package
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/kmp/watched" \
-X POST \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"groupId": "com.example",
"artifactId": "my-library",
"npmPackageName": "@my-kmp-repo/my-library",
"swiftScope": "my-kmp-repo",
"swiftName": "my-library",
"enableNpm": true,
"enableSwift": true,
"appleTargets": ["iosArm64", "macosArm64"]
}'
# Get a watched package
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/kmp/watched/$WATCHED_ID" \
-H "Authorization: Bearer $TOKEN"
# Update a watched package
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/kmp/watched/$WATCHED_ID" \
-X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"enableSwift": false, "appleTargets": ["iosArm64"]}'
# Delete a watched package (requires admin)
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/kmp/watched/$WATCHED_ID" \
-X DELETE \
-H "Authorization: Bearer $TOKEN"
Add watched package fields:
| Field | Type | Required | Default |
|---|---|---|---|
groupId |
string | Yes | — |
artifactId |
string | Yes | — |
enableNpm |
boolean | No | true |
enableSwift |
boolean | No | true |
npmPackageName |
string | If enableNpm |
— |
swiftScope |
string | If enableSwift |
— |
swiftName |
string | If enableSwift |
— |
appleTargets |
string[] | No | [] |
Updatable fields: enableNpm, enableSwift, appleTargets, npmPackageName, swiftScope, swiftName.
9.3 Polling for New Versions
Trigger a poll to check the Maven source for new versions of all watched packages:
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/kmp/poll" \
-X POST \
-H "Authorization: Bearer $TOKEN"
Requires write role. Response:
{
"results": [
{
"watchedPackageId": "wp-id",
"groupId": "com.example",
"artifactId": "my-library",
"newVersions": ["1.1.0"],
"discoveredVersions": ["1.0.1", "1.0.0-beta1"],
"buildsTriggered": 1,
"errors": []
}
]
}
Poll behavior: Only the latest stable version automatically triggers a build (status pending). Other new versions (older stable versions, pre-release versions) are recorded with status discovered and can be triggered manually.
Pre-release patterns detected: alpha, beta, rc, dev, snapshot, eap, experimental, m1/m2/etc.
9.4 Builds
Builds represent individual version build jobs.
# List builds
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/kmp/builds" \
-H "Authorization: Bearer $TOKEN"
# List builds with filters
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/kmp/builds?status=pending,building&stableOnly=true&limit=50&counts=true" \
-H "Authorization: Bearer $TOKEN"
# Get a single build
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/kmp/builds/$BUILD_ID" \
-H "Authorization: Bearer $TOKEN"
# Manually trigger a build for a specific version
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/kmp/builds" \
-X POST \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"watchedPackageId": "wp-id", "version": "1.0.0"}'
# Retry a failed or discovered build
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/kmp/builds/$BUILD_ID" \
-X POST \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"action": "retry"}'
# Delete a single build (requires admin)
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/kmp/builds/$BUILD_ID" \
-X DELETE \
-H "Authorization: Bearer $TOKEN"
# Delete all builds in repo (requires admin)
curl -s "https://artifacts.premex.se/api/repos/$REPO_ID/kmp/builds" \
-X DELETE \
-H "Authorization: Bearer $TOKEN"
Build list query parameters:
| Parameter | Type | Description |
|---|---|---|
status |
string | Comma-separated filter: discovered, pending, queued, building, success, failed |
stableOnly |
boolean | Only return stable (non-pre-release) versions |
limit |
number | Max results (default 200, max 500) |
counts |
boolean | Include statusCounts map in response |
Build list response:
{
"builds": [
{
"id": "build-id",
"repoId": "my-kmp-repo",
"watchedPackageId": "wp-id",
"groupId": "com.example",
"artifactId": "my-library",
"version": "1.1.0",
"isStable": true,
"status": "success",
"githubRunId": 12345,
"githubRunUrl": "https://github.com/owner/repo/actions/runs/12345",
"npmPublished": true,
"swiftPublished": true,
"error": null,
"startedAt": "2026-02-16T14:30:00.000Z",
"completedAt": "2026-02-16T14:45:00.000Z",
"createdAt": "2026-02-16T14:30:00.000Z",
"updatedAt": "2026-02-16T14:45:00.000Z"
}
],
"statusCounts": {
"discovered": 5,
"pending": 0,
"queued": 0,
"building": 1,
"success": 10,
"failed": 2
}
}
Build statuses:
| Status | Meaning |
|---|---|
discovered |
Version found but not auto-built (older or pre-release). Trigger manually with retry. |
pending |
Build created, waiting for GitHub Actions dispatch |
queued |
GitHub Actions workflow dispatched |
building |
Build in progress |
success |
Build completed successfully, packages published |
failed |
Build failed (check error field) |
Retry: Can only retry builds with status failed or discovered. Returns { "success": true, "status": "pending" } or HTTP 502 if GitHub dispatch fails.
9.5 KMP API Endpoints Reference
| Operation | Method | URL Pattern | Role |
|---|---|---|---|
| List watched packages | GET | /api/repos/{repoId}/kmp/watched |
read |
| Add watched package | POST | /api/repos/{repoId}/kmp/watched |
write |
| Get watched package | GET | /api/repos/{repoId}/kmp/watched/{watchedId} |
read |
| Update watched package | PATCH | /api/repos/{repoId}/kmp/watched/{watchedId} |
write |
| Delete watched package | DELETE | /api/repos/{repoId}/kmp/watched/{watchedId} |
admin |
| Poll for new versions | POST | /api/repos/{repoId}/kmp/poll |
write |
| List builds | GET | /api/repos/{repoId}/kmp/builds |
read |
| Trigger build | POST | /api/repos/{repoId}/kmp/builds |
write |
| Delete all builds | DELETE | /api/repos/{repoId}/kmp/builds |
admin |
| Get build | GET | /api/repos/{repoId}/kmp/builds/{buildId} |
read |
| Retry build | POST | /api/repos/{repoId}/kmp/builds/{buildId} |
write |
| Delete build | DELETE | /api/repos/{repoId}/kmp/builds/{buildId} |
admin |
10. Role-Based Access Control
Each repository has a members map where each user has a role:
| Role | Level | Can Do |
|---|---|---|
read |
0 | List packages, download artifacts |
write |
1 | All of read + publish packages |
admin |
2 | All of write + manage members, update repo settings, delete files/builds |
owner |
3 | All of admin + delete repository |
Public repositories allow read access without any authentication. All other operations require auth.
API token scoping: Tokens can be restricted to specific scopes and repositories. A token can only perform actions within its scope and repo restrictions, up to the user's own role in each repo.