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.
Search#
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 |