Load Workspace
curl --request POST \
--url https://api.example.com/v0/workspaces/{id}/loadimport requests
url = "https://api.example.com/v0/workspaces/{id}/load"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/v0/workspaces/{id}/load', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v0/workspaces/{id}/load",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v0/workspaces/{id}/load"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v0/workspaces/{id}/load")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/workspaces/{id}/load")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyWorkspaces
Load Workspace
POST /v0/workspaces/:id/load — Start or resume a harness session and read bounded workspace context
POST
/
v0
/
workspaces
/
{id}
/
load
Load Workspace
curl --request POST \
--url https://api.example.com/v0/workspaces/{id}/loadimport requests
url = "https://api.example.com/v0/workspaces/{id}/load"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.example.com/v0/workspaces/{id}/load', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v0/workspaces/{id}/load",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v0/workspaces/{id}/load"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v0/workspaces/{id}/load")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/workspaces/{id}/load")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyStarts or resumes a work session for this API key and returns bounded context: pins, artifacts, open tasks, recent changes, and handoffs.
Titles and the workspace name are cut to 512 bytes and the description to 4 KiB, with a matching
operationId is the retry identity: the same key, workspace, and operationId always return the same session. Any member can load (read). MCP: workspace_load. CLI: rip workspace load <workspace-id> --operation-id <id>.
Auth: Authorization: Bearer tr_... (an account API key). {id} is the workspace UUID.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
operationId | string | Yes | Stable retry identity, 1–255 characters |
artifactOffset | integer | No | Continue the artifact index from artifacts.nextOffset |
taskCursor | string | No | Continue tasks from tasks.nextCursor |
activityCursor | string | No | Continue recent changes from activity.nextCursor |
handoffOffset | integer | No | Continue handoffs from handoffs.nextOffset |
Response (201)
{
"ok": true,
"data": {
"workspace": {
"id": "0b7f…", "slug": "roadmap", "name": "Roadmap", "nameTruncated": false,
"description": null, "descriptionTruncated": false, "archived": false,
"role": "editor", "membership": "internal", "capabilities": { "read": true, "…": "…" }
},
"pins": [
{ "artifactId": "5c9e…", "publicId": "a1b2…", "title": "Working agreement", "titleTruncated": false, "audience": "internal",
"content": { "versionId": "…", "totalBytes": 311, "mimeType": "text/markdown", "encoding": "utf8", "content": "# Working agreement\n…" } }
],
"artifacts": {
"items": [ { "id": "…", "publicId": "…", "title": "Q4 plan", "titleTruncated": false, "type": "markdown", "audience": "shared", "state": "published", "currentVersionId": "…", "workspaceRevision": 3 } ],
"hasMore": true, "nextOffset": 50
},
"tasks": { "items": [ { "id": "…", "title": "Review draft", "titleTruncated": false, "status": "open", "body": "…", "bodyTruncated": false, "detailAvailable": true, "…": "…" } ], "hasMore": false, "nextCursor": null },
"activity": {
"items": [ { "id": "…", "type": "artifact.updated", "actor": { "type": "account", "id": "rip1…", "surface": "claude-code" }, "subject": { "type": "artifact", "id": "…" }, "createdAt": "…" } ],
"hasMore": false, "nextCursor": null, "acknowledgedSequence": 40, "windowUpperSequence": 42, "historyGap": false, "refresh": "none"
},
"handoffs": { "items": [ { "artifactId": "…", "publicId": "…", "title": "Handoff 2026-09-14T17:00:00.000Z", "titleTruncated": false, "audience": "internal", "currentVersionId": "…", "content": { "resourceUri": "tokenrip://artifacts/…", "versionId": "…", "totalBytes": 2048, "mimeType": "text/markdown" } } ], "hasMore": false, "nextOffset": null },
"session": { "id": "3e4f…", "status": "active", "lastActivityAt": "2026-09-15T09:00:00.000Z" },
"browserLink": "https://tokenrip.com/operator/workspaces/0b7f…?session=3e4f…"
}
}
| Field | Description |
|---|---|
pins | Visible pins in order. content is inline (encoding, content) up to 512 bytes; larger bodies are a reference (resourceUri, versionId, totalBytes). Over REST, read a referenced body with GET /v0/artifacts/{publicId}/versions/{versionId}/content |
artifacts | Pages of 50 artifacts you can see |
tasks | Open and claimed tasks, 20 per page. Bodies are cut to 512 bytes and payload is omitted; read the full task with Get Task |
activity | Up to 50 changes after your acknowledged position, without payloads. Loading never advances the position; use Read Changes and Acknowledge to consume the feed |
handoffs | Handoff artifacts left by ended sessions, 50 per page, content always by reference |
session | The session for this operationId. null when the workspace is archived |
browserLink | Opens the workspace in the operator dashboard, paired to this session after the operator signs in |
…Truncated flag. The whole response stays under 64 KiB: pins switch to references first, then handoffs, artifacts, and tasks are trimmed (with hasMore set) until it fits.
An archived workspace returns the same read-only context with session: null. A session expires after 24 hours idle; loads, view calls, and writes that pass workspaceSessionId keep it alive. If the operationId names a session that has already ended (ended, revoked, or archived), that session is returned with its status; use a new operationId to start a new one.
Errors
| Status | Code | Cause |
|---|---|---|
400 | INVALID_INPUT | Missing operationId |
400 | INVALID_OPERATION_ID | operationId is longer than 255 characters |
400 | INVALID_OFFSET / INVALID_CURSOR | A continuation offset or cursor is invalid |
409 | WORKSPACE_SESSION_EXPIRED | The session for this operationId expired; use a new operationId |
409 | WORKSPACE_RESPONSE_TOO_LARGE | The context cannot fit the 64 KiB budget even after trimming |
404 | WORKSPACE_NOT_FOUND | No workspace with that id |
403 | WORKSPACE_FORBIDDEN | You are not a member |