Biosimulant CLI
There is one headless biosimulant CLI. The same package, command parser, JSON schema and exit codes run in Studio, local terminals, CI, servers and containers.
The CLI drives the Biosimulant runtime on your own machine. It can’t create account workspaces, managed Runs or Evidence Passports. Those come from Studio, the Developer API or an agent. Its registry token and an agent’s authorization are separate credentials for separate services, so see Which surface do I want? if you’re not sure which you need.
pipx install biosimulant
biosimulant doctorCommon commands
biosimulant auth login # only needed for private labs and publishing
biosimulant labs pull acme/cell-study@1.0.0
biosimulant labs validate ./cell-study
biosimulant labs run ./cell-study --json
biosimulant labs publish ./cell-studybiosimulant validate and biosimulant run are aliases for the labs commands. To build and publish a package, see Package and publish.
Install and upgrade
The biosimulant package on PyPI is the CLI. pipx keeps it isolated and puts the command on your PATH:
pipx install biosimulant
pipx upgrade biosimulant
pipx install "biosimulant==0.0.28" # an exact releaseuv works the same way:
uv tool install biosimulant
uv tool upgrade biosimulant
uv tool install "biosimulant==0.0.28"In a virtual environment or CI job, pin the version:
python -m pip install "biosimulant==0.0.28"
python -m biosimulant --versionStudio workspaces already include the CLI, so don’t reinstall it there.
Shell completion
For bash:
register-python-argcomplete biosimulant >> ~/.bash_completionFor zsh:
autoload -U bashcompinit
bashcompinit
eval "$(register-python-argcomplete biosimulant)"Registries and authentication
The Hub is the default registry, so a plain reference resolves there. For another registry, put its host in front:
acme/cell-study@1.0.0
registry.example.com/acme/cell-study@1.0.0Versions are immutable. labs pull without a version gets the registry’s current default, so pin the version for reproducible work. Publishing needs an explicit package name and version.
Sign in
Most work needs no sign-in. Local runs (biosimulant labs run) and pulls of
public labs are anonymous. You need credentials only to pull a private lab or to
publish.
On a machine with a browser, sign in there:
biosimulant auth login --webThis opens a Biosimulant page, asks you to approve a key for this machine, and
hands it back to the CLI over a listener on 127.0.0.1. The key never travels
through a URL and you never paste anything. It appears in the
developer console named after your
hostname, and you can revoke it there. Add the global --no-open flag to print
the approval URL instead of launching a browser.
If you belong to a team, the page asks which account the key is for. A team key publishes under the team’s namespace and reads only the team’s private labs, never your personal ones. To publish under a team with a personal key, name the team’s namespace in the reference instead. See Team namespaces.
Without a browser, paste a key instead:
biosimulant auth loginThe CLI’s registry token is a developer API key. Create one at the
developer console. It needs the
packages:read scope to pull private labs and packages:write to publish.
Either way the CLI resolves the key to an account before storing it, so a bad key fails at sign-in rather than at your next publish. Check an existing credential the same way:
biosimulant auth status --verifyOne sign-in covers both surfaces: biosimulant runs reuses the stored
developer key when BIOSIMULANT_API_KEY is unset, so you do not have to set an
environment variable as well. Only a developer key is reused, and only against
the default API host.
Signing in to the Hub is not how you connect Claude or Codex. Agents use the MCP server, which has its own browser sign-in and needs no token and no CLI — see Codex and Claude and Which surface do I want?.
Another registry
The Hub is the default, but any Registry API v1 service works. Pass its host and put the token on stdin so it never appears in process arguments or shell history:
printf '%s\n' "$TOKEN" | \
biosimulant auth login registry.example.com --token-stdin
biosimulant auth status registry.example.com
biosimulant auth logout registry.example.comIn CI, put the key on stdin or in BIOSIMULANT_TOKEN; --web needs a browser
and a person, so it is not for automation.
A registry that doesn’t implement the identity endpoint can’t verify the token
at sign-in; the CLI says so and stores it anyway. Use --no-verify to skip the
check deliberately.
Where credentials come from
For each operation, the CLI checks these in order:
BIOSIMULANT_TOKEN- Workspace-scoped token exchange
- A configured credential helper
- The OS keychain
- An owner-only credentials file at
~/.config/biosimulant/credentials.json(mode0600on Unix)
Keep credentials out of references, command history, lab files and logs.
Inside a Studio workspace, Studio injects a workspace-bound identity token. The CLI exchanges it for a short-lived operation token only when a private pull or publish starts, so long-lived user credentials never enter the workspace. Automation that uses a developer key needs packages:read, packages:write, or both.
Machine output
--json prints one schema-v1 result:
{
"ok": true,
"data": {},
"error": null,
"meta": {
"schemaVersion": "1",
"command": "labs.validate",
"cliVersion": "0.0.28"
}
}Failures use the same envelope with ok: false, data: null and a structured error.
--json-stream prints ordered JSONL events and then exactly one final result. Each event has a type, an increasing seq, a timestamp, the command, a stage, a message and an optional percentage.
Global flags can go before or after the subcommand:
biosimulant --json labs validate ./lab
biosimulant labs validate ./lab --jsonUse --legacy-json only while you move off an older machine contract.
Exit codes
| Code | Meaning |
|---|---|
0 | Success |
1 | Operation or internal failure |
2 | Invalid command usage |
3 | Authentication or permission failure |
4 | Resource not found |
5 | Invalid content or validation failure |
6 | Conflict, including immutable-version conflicts |
7 | Capability unavailable in this environment |
130 | Cancelled |
Every command exists wherever the CLI runs. If the current environment can’t provide what a command needs, it exits with 7.
Commands
Generated from biosimulant 0.0.37. Global options can go before or after the subcommand:
--data-dir--json--json-stream--legacy-json--no-open--profile
Utilities
biosimulant doctor
Check the headless CLI and local runtime installation
usage: biosimulant doctor [-h]
options:
-h, --help show this help message and exitbiosimulant commands list
List the canonical machine-readable command catalog
usage: biosimulant commands list [-h]
options:
-h, --help show this help message and exitAuthentication
biosimulant auth login
Verify and store a registry token for one registry
usage: biosimulant auth login [-h] [--token-stdin] [--web] [--no-verify]
[registry]
positional arguments:
registry
options:
-h, --help show this help message and exit
--token-stdin
--web Sign in through the browser instead of pasting a token
--no-verify Store the token without checking it against the registrybiosimulant auth status
Inspect, and optionally verify, credentials for one registry
usage: biosimulant auth status [-h] [--verify] [registry]
positional arguments:
registry
options:
-h, --help show this help message and exit
--verify Resolve the stored credential to an accountbiosimulant auth logout
Remove credentials for one registry
usage: biosimulant auth logout [-h] [registry]
positional arguments:
registry
options:
-h, --help show this help message and exitLabs and registry
biosimulant labs init
Create a local runnable lab
usage: biosimulant labs init [-h] --name NAME [--description DESCRIPTION]
[--force] [--empty] [--json]
[path]
positional arguments:
path
options:
-h, --help show this help message and exit
--name NAME
--description DESCRIPTION
--force
--empty Create only lab.yaml without a starter model
--jsonbiosimulant labs create
Create a managed local lab
usage: biosimulant labs create [-h] --name NAME [--description DESCRIPTION]
[--force] [--empty] [--json]
[path]
positional arguments:
path
options:
-h, --help show this help message and exit
--name NAME
--description DESCRIPTION
--force
--empty
--jsonbiosimulant labs list
List local labs
usage: biosimulant labs list [-h] [--json] [root]
positional arguments:
root
options:
-h, --help show this help message and exit
--jsonbiosimulant labs get
Inspect a local lab
usage: biosimulant labs get [-h] [--root ROOT] [--json] [lab]
positional arguments:
lab
options:
-h, --help show this help message and exit
--root ROOT
--jsonbiosimulant labs save
Save a local lab
usage: biosimulant labs save [-h] [--root ROOT]
[--manifest-file MANIFEST_FILE]
[--wiring-layout-file WIRING_LAYOUT_FILE]
[--clear-wiring-layout] [--json]
[lab]
positional arguments:
lab
options:
-h, --help show this help message and exit
--root ROOT
--manifest-file MANIFEST_FILE
--wiring-layout-file WIRING_LAYOUT_FILE
--clear-wiring-layout
--jsonbiosimulant labs rename
Rename a local lab
usage: biosimulant labs rename [-h] [--root ROOT] [--json]
target_or_name [name]
positional arguments:
target_or_name
name
options:
-h, --help show this help message and exit
--root ROOT
--jsonbiosimulant labs delete
Delete a local lab
usage: biosimulant labs delete [-h] [--root ROOT] [--yes] [--json] [lab]
positional arguments:
lab
options:
-h, --help show this help message and exit
--root ROOT
--yes
--jsonbiosimulant labs add-model
Add a model to a lab
usage: biosimulant labs add-model [-h] [--lab LAB] [--root ROOT]
[--alias ALIAS] [--json]
model
positional arguments:
model
options:
-h, --help show this help message and exit
--lab LAB
--root ROOT
--alias ALIAS
--jsonbiosimulant labs change-model
Change a lab model
usage: biosimulant labs change-model [-h] [--lab LAB] [--root ROOT] [--json]
alias model
positional arguments:
alias
model
options:
-h, --help show this help message and exit
--lab LAB
--root ROOT
--jsonbiosimulant labs vendor-model
Vendor a model into a lab
usage: biosimulant labs vendor-model [-h] [--lab LAB] [--root ROOT]
[--alias ALIAS] [--replace] [--json]
model
positional arguments:
model
options:
-h, --help show this help message and exit
--lab LAB
--root ROOT
--alias ALIAS
--replace
--jsonbiosimulant labs inspect-owned
Inspect lab-owned model sources
usage: biosimulant labs inspect-owned [-h] [--root ROOT] [--json] [lab]
positional arguments:
lab
options:
-h, --help show this help message and exit
--root ROOT
--jsonbiosimulant labs validate
Validate a lab
usage: biosimulant labs validate [-h] [--json] [lab]
positional arguments:
lab
options:
-h, --help show this help message and exit
--jsonbiosimulant labs capabilities
Check local CPU, memory, and GPU support
usage: biosimulant labs capabilities [-h] [--target TARGET] [--force]
[--registry-url REGISTRY_URL] [--json]
[lab]
positional arguments:
lab
options:
-h, --help show this help message and exit
--target TARGET Destination for auto-pulled registry refs
--force
--registry-url REGISTRY_URL
--jsonbiosimulant labs run
Run a lab
usage: biosimulant labs run [-h] [--target TARGET] [--force]
[--registry-url REGISTRY_URL] [--no-install-deps]
[--dependency-root DEPENDENCY_ROOT]
[--require-local-capability]
[--results-file RESULTS_FILE]
[--report-file REPORT_FILE]
[--run-input-file RUN_INPUT_FILE] [--json]
[lab]
positional arguments:
lab
options:
-h, --help show this help message and exit
--target TARGET Destination for auto-pulled registry refs
--force Replace an existing auto-pull target
--registry-url REGISTRY_URL
--no-install-deps
--dependency-root DEPENDENCY_ROOT
Writable Lab-local dependency state directory for a
.bsilab archive
--require-local-capability
Fail before execution unless declared CPU, memory, and
GPU needs fit this host
--results-file RESULTS_FILE
--report-file REPORT_FILE
Write a standalone HTML run report
--run-input-file RUN_INPUT_FILE
JSON object containing parameters and
simulation_config overlays
--jsonbiosimulant labs serve
Serve a lab locally
usage: biosimulant labs serve [-h] [--target TARGET] [--force]
[--registry-url REGISTRY_URL] [--host HOST]
[--port PORT] [--open] [--no-open]
[--no-install-deps] [--no-agent]
[--agent-read-only] [--json]
[lab]
positional arguments:
lab
options:
-h, --help show this help message and exit
--target TARGET Destination for auto-pulled registry refs
--force Replace an existing auto-pull target
--registry-url REGISTRY_URL
--host HOST
--port PORT
--open Open browser automatically (default)
--no-open Do not open a browser automatically
--no-install-deps
--no-agent Do not expose this lab to a local agent over MCP
--agent-read-only Let a connected agent read the lab but not change or
run it
--jsonbiosimulant labs package
Build a lab package
usage: biosimulant labs package [-h] [--out OUT] [--package PACKAGE_NAME]
[--version VERSION]
[--visibility {private,public}]
[--vendor-dependencies]
[--registry-url REGISTRY_URL] [--json]
[lab]
positional arguments:
lab
options:
-h, --help show this help message and exit
--out OUT
--package PACKAGE_NAME
--version VERSION
--visibility {private,public}
--vendor-dependencies
--registry-url REGISTRY_URL
--jsonbiosimulant labs search
Search a Biosimulant registry
usage: biosimulant labs search [-h] [--page PAGE] [--page-size PAGE_SIZE]
[--tags TAGS] [--registry-url REGISTRY_URL]
[--json]
[query]
positional arguments:
query
options:
-h, --help show this help message and exit
--page PAGE
--page-size PAGE_SIZE
--tags TAGS
--registry-url REGISTRY_URL
--jsonbiosimulant labs info
Inspect registry lab metadata
usage: biosimulant labs info [-h] [--registry-url REGISTRY_URL] [--json]
reference
positional arguments:
reference
options:
-h, --help show this help message and exit
--registry-url REGISTRY_URL
--jsonbiosimulant labs versions
List immutable registry versions
usage: biosimulant labs versions [-h] [--page PAGE] [--page-size PAGE_SIZE]
[--registry-url REGISTRY_URL] [--json]
reference
positional arguments:
reference
options:
-h, --help show this help message and exit
--page PAGE
--page-size PAGE_SIZE
--registry-url REGISTRY_URL
--jsonbiosimulant labs pull
Pull a registry lab
usage: biosimulant labs pull [-h] [--target TARGET] [--force] [--no-deps]
[--registry-url REGISTRY_URL] [--json]
reference
positional arguments:
reference
options:
-h, --help show this help message and exit
--target TARGET
--force
--no-deps
--registry-url REGISTRY_URL
--jsonbiosimulant labs publish
Publish an immutable lab version
usage: biosimulant labs publish [-h] [--visibility {private,public}]
[--registry-url REGISTRY_URL]
lab [reference]
positional arguments:
lab
reference
options:
-h, --help show this help message and exit
--visibility {private,public}
--registry-url REGISTRY_URLbiosimulant labs sync-status
Compare a local lab with its registry version
usage: biosimulant labs sync-status [-h] [--registry-url REGISTRY_URL] [lab]
positional arguments:
lab
options:
-h, --help show this help message and exit
--registry-url REGISTRY_URLbiosimulant labs release validate
Validate a release manifest
usage: biosimulant labs release validate [-h] [--json] manifest
positional arguments:
manifest
options:
-h, --help show this help message and exit
--jsonbiosimulant labs release build
Build a release manifest
usage: biosimulant labs release build [-h] [--out OUT] [--json] manifest
positional arguments:
manifest
options:
-h, --help show this help message and exit
--out OUT
--jsonbiosimulant labs release publish
Build and publish a release manifest
usage: biosimulant labs release publish [-h] [--out OUT]
[--registry-url REGISTRY_URL]
[--dry-run]
manifest
positional arguments:
manifest
options:
-h, --help show this help message and exit
--out OUT
--registry-url REGISTRY_URL
--dry-runbiosimulant labs release ci
Validate, build, and publish a release manifest
usage: biosimulant labs release ci [-h] [--out OUT]
[--registry-url REGISTRY_URL] [--dry-run]
manifest
positional arguments:
manifest
options:
-h, --help show this help message and exit
--out OUT
--registry-url REGISTRY_URL
--dry-runCompatibility
biosimulant compatibility standard
Show the installed compatibility standard release
usage: biosimulant compatibility standard [-h]
options:
-h, --help show this help message and exitbiosimulant compatibility profiles
List installed compatibility profiles
usage: biosimulant compatibility profiles [-h]
options:
-h, --help show this help message and exitbiosimulant compatibility show
Show one exact compatibility profile
usage: biosimulant compatibility show [-h] profile
positional arguments:
profile
options:
-h, --help show this help message and exitbiosimulant compatibility validate
Validate compatibility declarations in model.yaml
usage: biosimulant compatibility validate [-h] manifest
positional arguments:
manifest
options:
-h, --help show this help message and exitbiosimulant compatibility compare
Compare one output port with one input port
usage: biosimulant compatibility compare [-h] [--sample-json SAMPLE_JSON]
source target
positional arguments:
source model.yaml#outputs.port_name
target model.yaml#inputs.port_name
options:
-h, --help show this help message and exit
--sample-json SAMPLE_JSON
Optional JSON value to checkRuntime
biosimulant runtime status
Inspect the managed runtime
usage: biosimulant runtime status [-h]
options:
-h, --help show this help message and exitbiosimulant runtime detect-python
Report the current Python runtime
usage: biosimulant runtime detect-python [-h]
options:
-h, --help show this help message and exitbiosimulant runtime prepare
Prepare an isolated execution runtime
usage: biosimulant runtime prepare [-h] [--python PYTHON]
options:
-h, --help show this help message and exit
--python PYTHONRuns
biosimulant runs list
List managed runs
usage: biosimulant runs list [-h] [--limit LIMIT] [--cursor CURSOR]
options:
-h, --help show this help message and exit
--limit LIMIT
--cursor CURSORbiosimulant runs get
Inspect a managed run
usage: biosimulant runs get [-h] run_id
positional arguments:
run_id
options:
-h, --help show this help message and exitbiosimulant runs create
Create a managed run
usage: biosimulant runs create [-h] [--inputs INPUTS]
[--compute-profile COMPUTE_PROFILE]
[--idempotency-key IDEMPOTENCY_KEY]
ref
positional arguments:
ref
options:
-h, --help show this help message and exit
--inputs INPUTS
--compute-profile COMPUTE_PROFILE
--idempotency-key IDEMPOTENCY_KEYbiosimulant runs cancel
Cancel a managed run
usage: biosimulant runs cancel [-h] run_id
positional arguments:
run_id
options:
-h, --help show this help message and exitbiosimulant runs results
Get managed run results
usage: biosimulant runs results [-h] run_id
positional arguments:
run_id
options:
-h, --help show this help message and exitbiosimulant runs logs
Get managed run events or logs
usage: biosimulant runs logs [-h] [--after AFTER] [--limit LIMIT] run_id
positional arguments:
run_id
options:
-h, --help show this help message and exit
--after AFTER
--limit LIMITbiosimulant runs remote catalog
List remote compute profiles
usage: biosimulant runs remote catalog [-h]
options:
-h, --help show this help message and exitbiosimulant runs remote create
Create a remote managed run
usage: biosimulant runs remote create [-h] [--inputs INPUTS]
[--compute-profile COMPUTE_PROFILE]
ref
positional arguments:
ref
options:
-h, --help show this help message and exit
--inputs INPUTS
--compute-profile COMPUTE_PROFILEbiosimulant runs remote get
Inspect a remote managed run
usage: biosimulant runs remote get [-h] run_id
positional arguments:
run_id
options:
-h, --help show this help message and exitbiosimulant runs remote results
Get remote run results
usage: biosimulant runs remote results [-h] run_id
positional arguments:
run_id
options:
-h, --help show this help message and exitStable aliases
biosimulant validate
Alias for labs validate
usage: biosimulant labs validate [-h] [--json] [lab]
positional arguments:
lab
options:
-h, --help show this help message and exit
--jsonbiosimulant run
Alias for labs run
usage: biosimulant labs run [-h] [--target TARGET] [--force]
[--registry-url REGISTRY_URL] [--no-install-deps]
[--dependency-root DEPENDENCY_ROOT]
[--require-local-capability]
[--results-file RESULTS_FILE]
[--report-file REPORT_FILE]
[--run-input-file RUN_INPUT_FILE] [--json]
[lab]
positional arguments:
lab
options:
-h, --help show this help message and exit
--target TARGET Destination for auto-pulled registry refs
--force Replace an existing auto-pull target
--registry-url REGISTRY_URL
--no-install-deps
--dependency-root DEPENDENCY_ROOT
Writable Lab-local dependency state directory for a
.bsilab archive
--require-local-capability
Fail before execution unless declared CPU, memory, and
GPU needs fit this host
--results-file RESULTS_FILE
--report-file REPORT_FILE
Write a standalone HTML run report
--run-input-file RUN_INPUT_FILE
JSON object containing parameters and
simulation_config overlays
--jsonListed but not available
These appear in biosimulant commands list with "available": false. Calling one fails with exit code 7 and the error code capability_unavailable.
| Command | Why |
|---|---|
biosimulant runs start | A managed run starts when it is created; use biosimulant runs create. |
biosimulant runs upload | Uploading run artifacts is not available in this CLI. |
biosimulant jobs list | Background jobs are not exposed by the public API; use biosimulant runs list for managed runs. |
biosimulant jobs get | Background jobs are not exposed by the public API; use biosimulant runs get for a managed run. |
Removed commands
These older commands are no longer part of the public CLI. They fail with exit code 7 and the error code deprecated_desktop_command: raw, settings, which, install-cli, uninstall-cli, self, config, agent, agents, chat, labs open, labs import and runs open. Use pipx upgrade biosimulant instead of self update.
Registry API v1
This section is for anyone running their own registry. Registry API v1 is the protocol the CLI uses to talk to the Hub and compatible registries. The examples use https://hub.biosimulant.com as the origin. Clients must discover the API base instead of assuming its path.
Discovery
Request the well-known document without authentication:
GET /.well-known/biosimulant-registry HTTP/1.1
Host: hub.biosimulant.comThe response gives the protocol version, API base, authentication endpoints and capabilities:
{
"protocolVersion": "1",
"apiBase": "/api/registry/v1",
"auth": {
"type": "bearer",
"tokenEndpoint": "/api/registry/v1/auth/exchange",
"workspaceExchangeTokenEndpoint": "/api/registry/v1/auth/workspace-exchange-tokens"
},
"capabilities": [
"search",
"metadata",
"versions",
"pull",
"publish",
"private-packages",
"workspace-token-exchange",
"immutable-versions",
"checksum-idempotency"
]
}Resolve relative URLs against the registry origin. Reject an unsupported protocolVersion, or a registry that doesn’t advertise a capability the operation needs.
Package endpoints
Paths are relative to the discovered apiBase.
| Method | Path | Purpose | Required access |
|---|---|---|---|
GET | /packages?q=&type=&page=&pageSize= | Search visible packages | Anonymous for public packages; packages:read for private ones |
GET | /packages/{namespace}/{name} | Package metadata and its default version | Same as search |
GET | /packages/{namespace}/{name}/versions | List immutable versions | Same as search |
GET | /packages/{namespace}/{name}/{version} | One exact version and its checksum | Same as search |
GET | /packages/{namespace}/{name}/{version}/download | Download the exact artifact | Same as search |
POST | /packages | Publish an artifact | packages:write |
Search takes type=model or type=lab, uses one-based pages and caps pageSize at 100. Package and version responses include the canonical reference, SHA-256 digest, byte size, visibility, status and download URL.
Private packages return 404 when the caller can’t access them, so an outsider can’t tell whether they exist.
Token exchange
Send an operation token as a bearer credential:
Authorization: Bearer <operation-token>Public reads can be anonymous. Private reads need packages:read, and publishing needs packages:write.
Long-lived user credentials must not be copied into Studio workspaces. Instead, an authenticated application issues a workspace-bound exchange token:
POST /auth/workspace-exchange-tokens
Content-Type: application/json
{
"workspaceSessionId": "16a74428-370d-4557-a92f-92dce233505f",
"scopes": ["packages:read", "packages:write"]
}The workspace exchanges it when an operation starts:
POST /auth/exchange
Authorization: Bearer <workspace-exchange-token>
Content-Type: application/json
{
"registry": "https://hub.biosimulant.com",
"scopes": ["packages:read"]
}The result is a short-lived registry_operation bearer token with its scopes, audience and expiry. Requested scopes can’t exceed what the workspace token was granted, and the workspace session must still be active.
Publishing
Send the package archive as the request body:
POST /packages
Authorization: Bearer <operation-token>
Content-Type: application/gzip
X-Biosimulant-Filename: cell-study-1.0.0.tar.gz
X-Biosimulant-Sha256: 68b0…
X-Biosimulant-Package: acme/cell-study
X-Biosimulant-Version: 1.0.0
X-Biosimulant-Visibility: private
<artifact bytes>X-Biosimulant-Filename and the full lowercase hex X-Biosimulant-Sha256 are required. The package, version and visibility headers state what you intend, and the server checks them against the artifact manifest.
A new version returns 201:
{
"artifact": {
"reference": "acme/cell-study@1.0.0",
"version": "1.0.0",
"sha256": "68b0…"
},
"idempotent": false
}Publishing the same version with the same checksum again returns 200 with idempotent: true. The same version with different content returns 409 immutable_version_conflict.
Errors and verification
Registry errors use the HTTP status plus a JSON detail, which is either a message or an object with a stable code and supporting fields.
| Status | Meaning |
|---|---|
401 | Missing, expired or invalid credential |
403 | The caller lacks the required scope |
404 | Package, version or active workspace session not found or not visible |
409 | The immutable version already exists with a different checksum |
422 | Invalid manifest, checksum, scope, reference, version or request header |
Clients must compute the downloaded artifact’s SHA-256 and compare it with the resolved version before extracting it. A mismatch is a hard failure and must never be cached as a successful pull.
Compatibility requirements
A compatible Registry API v1 implementation must:
- Serve the well-known discovery document.
- Return immutable, checksum-addressed versions.
- Allow anonymous public reads.
- Enforce
packages:readandpackages:writewhere authentication is required. - Treat identical publishes as idempotent.
- Reject a same-version, different-content publish with
409. - Keep credentials out of references, redirect URLs and logs.