Skip to contentSkip to content

Use the API ​

Everything you can do to a repository on its pages, you can do over HTTPS: create it, set its upstreams and content rules, add a domain, share it.

The API base URL is https://artifex.soh.gg/api/v1/. The OpenAPI document at https://artifex.soh.gg/api/v1/openapi.json describes every endpoint, including its fields and responses.

Authenticate ​

Every request carries a personal access token:

Authorization: Bearer TOKEN

The token access level decides what the request can do:

AccessWhat the token can do through the API
ReadRead the repositories it covers.
WriteRead, and publish with Maven or Gradle.
ManageEverything: settings, upstreams, content rules, domains, and sharing. With Every repository you can access, also create repositories.

Maven and Gradle use the same token as the repository password, so a tool that configures a repository can also verify a build against it.

Two ways to get a token:

  • Create one on the Tokens page and give it to the tool.
  • Let the tool request one with the OAuth 2.0 device flow, described in the next section. Nothing has to be created or copied ahead of time.

Authorize a browserless tool with the device flow ​

A tool that can't open a browser requests a device code and a user code from Artifex:

curl -s -X POST https://artifex.soh.gg/api/v1/device \
  -H 'content-type: application/json' \
  -d '{"name":"Claude Code on ruby-laptop"}'
json
{
  "deviceCode": "dc_8f3k...",
  "userCode": "WDJB-MJHT",
  "verificationUrl": "https://artifex.soh.gg/device?code=WDJB-MJHT",
  "expiresIn": 900,
  "interval": 5
}

The tool stores the deviceCode value for polling and shows you the verificationUrl. The userCode value is part of that URL, so you don't enter it. On the page, sign in, read the tool's name, choose the token access level and repositories as you do on the Tokens page, and click Approve. The token appears on your Tokens page under the tool's name, and you can revoke it there at any time.

Meanwhile the tool polls the token endpoint, at most once every interval seconds:

curl -s -X POST https://artifex.soh.gg/api/v1/device/token \
  -H 'content-type: application/json' \
  -d '{"deviceCode":"dc_8f3k..."}'
json
{ "status": "pending", "interval": 5 }
json
{ "status": "approved", "token": "cs_pat_...", "tokenId": "..." }

The token is returned once. A denied status means you clicked Deny; expired means the device code is older than 15 minutes or the token was already retrieved.

Example API workflow ​

The following commands create a private repository, list the presets, give the repository Maven Central and a remote upstream with a content rule, and read the result. A preset upstream is named by its preset identifier and has no settings of its own. Replace RUBY with your username.

The API retains slug as the wire field for a repository name and scope as the wire field for a content rule's resolution context.

export ARTIFEX_TOKEN=cs_pat_...
A="authorization: Bearer $ARTIFEX_TOKEN"
J="content-type: application/json"
API=https://artifex.soh.gg/api/v1

curl -s -H "$A" $API/me
curl -s -H "$A" $API/presets
curl -s -H "$A" -H "$J" -X POST $API/repositories \
  -d '{"slug":"libs","displayName":"Libraries","visibility":"private"}'
curl -s -H "$A" -H "$J" -X POST $API/repositories/RUBY/libs/upstreams \
  -d '{"kind":"preset","preset":"maven-central"}'
curl -s -H "$A" -H "$J" -X POST $API/repositories/RUBY/libs/upstreams \
  -d '{"kind":"remote","displayName":"Fabric","url":"https://maven.fabricmc.net/","exclusive":true}'
curl -s -H "$A" -H "$J" -X POST $API/repositories/RUBY/libs/upstreams/UPSTREAM_ID/rules \
  -d '{"effect":"include","scope":"group","groupPattern":"net.fabricmc"}'
curl -s -H "$A" $API/repositories/RUBY/libs/upstreams

Upstreams are requested in the order they are listed. To change the order, send every upstream ID in the new order:

curl -s -H "$A" -H "$J" -X PUT $API/repositories/RUBY/libs/upstreams/order \
  -d '{"ids":["UPSTREAM_ID","OTHER_ID"]}'

Errors ​

An error is a JSON object with a machine-readable error code and a human-readable message:

json
{
  "error": {
    "code": "validation",
    "message": "Some fields need attention.",
    "details": { "fields": { "url": "Enter an https address." } }
  }
}
StatusCodeMeaning
401unauthorizedNo token, or an expired or revoked one.
403forbiddenThe token access level doesn't allow this.
404not_foundThe resource doesn't exist, or the token doesn't have access to it.
409slug_takenThe account already has a repository with that repository name.
422validationA field is missing or invalid. details.fields names each one.
429slow_downThe device flow was polled faster than interval.