Workbenches is an open standard. Read why
Docs Workbenches and registry

API reference

Workbenches and registry

Every organization Workbench is internal until a reviewed publish makes it public. An internal Workbench resolves, downloads, and lists only for a key of its organization holding catalog:read, or a signed-in member. Everyone else gets 404, the same as for a Workbench that does not exist.

The Workbench object#

GET /v1/workbenches/:id, POST /v1/resolutions, and POST /v1/searches return Workbench objects:

Field Type Meaning
id UUID Use with GET /v1/workbenches/:id.
workbench_id UUID
slug string The registry name.
name string
summary string or null
runner string
model string The model ID.
spec 0 or 1 The manifest spec of the latest version.
runtimes list of strings Declared runtimes, in declaration order.
runtime string The first of runtimes, kept for older clients.
requirements object os, arch, cpu, memory_gb, disk_gb, and gpu (default false).
sandboxed boolean True when runtimes includes docker or e2b with an image, or daytona. Only sandboxed Workbenches run in the cloud.
status active, unlisted, deprecated, or rejected
visibility public or private private is internal.
source github or registry Where the package came from.
source_path, source_reference, source_url strings Provenance.
publisher object id, slug, aliases, name, accent, logo_url, verified.
repository object or null id, owner, name, url.
latest_version object See below.
metrics object saves, runs.
character_roll integer Which character the registry draws for it.
first_published_at, updated_at date-time

latest_version has id, version, spec, source_commit, digest (SHA-256 of the package), artifact_url, manifest (the parsed manifest, with model as { id, routes? }), artifact_size, validation (valid, validator), published_at, and provenance: human_reviewed, trusted_publisher, internal (stored by the organization, not reviewed), or legacy.

List Workbenches#

GET /v1/workbenches

Open. Public Workbenches, plus your own organization's internal ones when the caller can see them. Response 200 { "workbenches": [ ... ] }.

Get a Workbench#

GET /v1/workbenches/:id

Open. One Workbench with its latest version.

POST /v1/searches

Open. With organization_id, a key with catalog:read or a signed-in member also gets that organization's internal Workbenches.

Field Type Meaning
query string, up to 120 characters Free text.
publisher_slug string Only this publisher.
slug string Only this name.
organization_id UUID Include this organization's internal Workbenches.
runnable any or cloud any, the default, returns every visible Workbench. cloud returns only sandboxed ones.

Response 200 { "workbenches": [ ... ] }.

Resolve a name#

POST /v1/resolutions

Open. Resolves publisher and workbench names to one Workbench.

{ "publisher": "acme", "workbench": "code-review" }

Response 200: the Workbench. 404 when it does not exist or you cannot see it.

Package files#

GET /v1/artifacts/:id

Open, for a version the caller can see. :id is a version ID. Returns the package:

{
    "format": 1,
    "files": [
        { "path": "workbench.yml", "content": "<base64>", "executable": false }
    ]
}

A package holds at most 256 files. Each path is up to 512 characters and each content is base64.

Push a version#

POST /v1/versions

Key packages:write, or session: manager. Body limit 16 MB.

Field Type Meaning
organization_id UUID Required.
slug string The registry name. Defaults to the manifest's name.
package package Required. { "format": 1, "files": [ ... ] }, as above.

Stores the package as a new immutable internal version. It never makes a Workbench public. The Workbench is created as internal when it does not exist.

Response 201:

{
    "workbench": {
        "id": "uuid",
        "slug": "code-review",
        "organization_slug": "acme",
        "visibility": "private"
    },
    "version": { "id": "uuid", "version": "1.2.0", "digest": "..." }
}
Status When
400 The manifest is invalid. A mix of spec 0 and spec 1 fields names the fields; another spec value is Manifest spec N is not supported.
402 plan_limit A new Workbench would pass the plan's private Workbench cap.
409 The manifest version is not greater than every stored version, or the Workbench is public. A public Workbench takes new versions only through a submission.

Pushing the same version with identical bytes again changes nothing. wb push and the MCP push tool call this route.

Submissions#

A submission asks for public review. Approval makes the Workbench public. There is no other path to public.

Submit for review#

POST /v1/submissions

Body limit 16 MB. The body is one of three forms:

Form Body Auth
A stored version { "version_id": "uuid", "files_become_public": false } Key packages:write with manager creator, or session: manager.
A package { "organization_id": "uuid", "slug": "code-review", "package": { ... } } Key packages:write, or session: member.
A GitHub source { "repository_id": "uuid", "source_commit": "<40 to 64 characters>", "source_paths": [".workbenches/core/workbench.yml"], "files_become_public": false } Key packages:write, or session: member.

Only the latest stored version can be submitted. files_become_public acknowledges that files from a private repository become publicly downloadable after approval. Response 201 { "submissions": [ ... ], "next_cursor": null }.

The submission object#

Field Meaning
id
organization_id, publisher_slug, publisher_name The publisher.
submitted_by The user.
slug, name, version, digest What was submitted.
status pending, changes_requested, approved, rejected, withdrawn, or superseded.
kind new or update.
source registry or github, with repository_id, source_commit, source_path, repository_url.
manifest, artifact_size The package.
visibility, files_become_public
feedback The reviewer's feedback, or null.
superseded_by, version_id, latest_approved_version
dashboard_url Where to follow it.
created_at, updated_at, decided_at

Reviewers approve an exact digest, request changes with feedback, or reject with feedback. Changed bytes for the same unapproved version supersede the earlier submission. If a newer version is pushed while a review is open, approval fails and the newer version must be submitted.

List submissions#

GET /v1/submissions

Key packages:write (its own organization only), or a session (your own submissions).

Query Type Meaning
organization_id UUID
status submission status
cursor UUID next_cursor from the previous page.
limit integer, 1 to 200 Default 100.

Response 200 { "submissions": [ ... ], "next_cursor": "uuid or null" }.

Get, withdraw, and read a submission#

Method Path Auth Result
GET /v1/submissions/:id Key packages:write, or session: member { "submission", "history", "previous" }. history is the audit trail: id, actor_id, action, subject_id, reason, created_at.
DELETE /v1/submissions/:id Key packages:write, or session: member Withdraw an open submission. Same response.
GET /v1/submissions/:id/package Key packages:write, or session: member The submitted package files.

Unpublish#

DELETE /v1/publications/:id

Key packages:write with manager creator, or session: manager. :id is the Workbench ID. Returns a public Workbench to internal at once and withdraws its open submissions. Copies already downloaded stay with their clients.

Response 200:

{
    "unpublished": true,
    "workbench": {
        "id": "uuid",
        "slug": "code-review",
        "organization_slug": "acme",
        "visibility": "private"
    }
}

POST /v1/publications, the legacy direct publish, returns 409 while review is required. Use POST /v1/submissions.

Change the character#

PATCH /v1/workbenches/:id with { "character_roll": 0 } (0 to 1,000,000)

Key packages:write with manager creator, or session: manager. Changes which character the registry draws for the Workbench. Returns the Workbench.

CLI counts#

POST /v1/events

Open. The CLI records an anonymous save or run of a registry version here. Replies 202 { "accepted": true }.

Field Type
idempotency_key UUID
version_id UUID
kind save or run
cli_version string, 1 to 40 characters
occurred_at date-time