Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Conventions

Everything in this section is under /api/v1 on the registry's own origin. The registry describes itself at GET /.well-known/tar-registry, which is the first thing a client should read: it reports the API base, whether reads are public, which authentication methods are configured, the SPARQL endpoint, the llms.txt location and the peers it federates with.

curl https://registry.example.org/.well-known/tar-registry

Authentication

A credential is a bearer token, whatever kind it is:

Authorization: Bearer <token>

Reads are anonymous by default (TAR_PUBLIC_READ). Writes always need a credential. Which credential to use, and how a deployment gets one, is How a tool authenticates.

GET /api/v1/whoami reports what a credential resolved to — the principal, its roles, its scopes and the deployment it acts as, if any. It is the first thing to call when a job gets a 403.

Roles and scopes

Two orthogonal things. Roles come from a person's identity provider token, or from the root token; scopes are carried by registry-minted API tokens and bound the deployment credentials.

RoleMay
readerread
curatorregister and edit software, deployments, releases and vocabulary terms
admineverything, including peers and token administration
ScopePermits
advertise:produceadvertise artifacts a run produced
advertise:consumeadvertise artifacts a run consumed
register:softwareregister and update software
register:instanceregister deployments
read:privateread records that are not publicly readable
admin:*everything

Errors

Every error path returns RFC 9457 application/problem+json:

{
  "type": "https://w3id.org/tar/problem/forbidden",
  "title": "Forbidden",
  "status": 403,
  "detail": "credential lacks the advertise:produce scope (has: advertise:consume)"
}
Statustype suffixWhen
400bad-requestMalformed request.
401unauthorizedNo credential, or one that did not verify. WWW-Authenticate: Bearer is set.
403forbiddenA valid credential lacking the role or scope. Retrying with different arguments will not help.
404not-foundNo such record.
409conflictA uniqueness rule was violated.
410tombstonedThe record was withdrawn. It still resolves and says so.
422shacl-validation-failedThe write is well-formed JSON but not a record the registry accepts.
502upstream-failedA peer or repository the registry had to reach did not answer.

The 422, specifically

A rejected write carries the SHACL engine's own report alongside the problem document:

{
  "type": "https://w3id.org/tar/problem/shacl-validation-failed",
  "title": "Write rejected by SHACL validation",
  "status": 422,
  "detail": "kind: value must be one of service, library, cli, desktop, workflow",
  "report": "@prefix sh: … a sh:ValidationReport ; sh:result [ … ] .",
  "report_media_type": "text/turtle"
}

Each result in the report carries a tar:jsonField naming the JSON field that caused it, so a form can attach the message to the input that produced it without parsing sh:resultPath back into a field name.

The vocabulary rule reports through the same report, deliberately. A caller has one error shape to handle, not two — see Artifact types and topics.

Listing, filtering and pagination

List endpoints return:

{ "items": [ … ], "total": 42, "next_cursor": "https://registry.example.org/software/01a05…", "facets": [ … ] }

Pagination is keyset, not offset. Pass the next_cursor you were given back as ?cursor= to get the following page; a null cursor means the end. The cursor is a record IRI, and the ordering is descending IRI string — which is newest-first within one registry, because ids are UUIDv7 and sort by mint time. ?limit= defaults to 25 and is clamped to 200.

facets accompanies the software listing with the value counts a filter UI needs, so a client does not have to fetch the whole catalogue to know what is worth filtering on. Other listings omit it.

Idempotency

The advertisement endpoints are idempotent on (run, artifact, role), keyed by the run's external_key. A retried CI step does not duplicate lineage. See Advertising runs and artifacts.

Request size

Bodies are capped by TAR_MAX_PAYLOAD_BYTES, default 2 MiB. Software records carry whole READMEs, so this is worth raising if you are importing large ones.

Audit

Every write is recorded. GET /api/v1/audit returns the log, for admins.