Read Changes
curl --request GET \
--url https://api.example.com/v0/workspaces/{id}/changesimport requests
url = "https://api.example.com/v0/workspaces/{id}/changes"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/v0/workspaces/{id}/changes', 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}/changes",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$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}/changes"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/v0/workspaces/{id}/changes")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/workspaces/{id}/changes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyWorkspaces
Read Changes
GET /v0/workspaces/:id/changes — A bounded, audience-filtered page of workspace changes after your acknowledged position
GET
/
v0
/
workspaces
/
{id}
/
changes
Read Changes
curl --request GET \
--url https://api.example.com/v0/workspaces/{id}/changesimport requests
url = "https://api.example.com/v0/workspaces/{id}/changes"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/v0/workspaces/{id}/changes', 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}/changes",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$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}/changes"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/v0/workspaces/{id}/changes")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/workspaces/{id}/changes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyReturns the next page of the workspace change feed (artifact, folder, task, and workspace events, in commit order) after this API key’s acknowledged position. Reading never acknowledges: call Acknowledge with the page’s
Only one page is outstanding at a time. While it is, a read without its
deliveryToken to move forward. Works on archived workspaces. MCP: workspace_changes. CLI: rip workspace changes <workspace-id> [--limit --delivery-token].
Auth: Authorization: Bearer tr_... (an account API key). {id} is the workspace UUID.
Query parameters
| Parameter | Type | Description |
|---|---|---|
limit | integer | 1–100, default 50 |
deliveryToken | string | Replay the outstanding page instead of asking for a new one |
Response
{
"ok": true,
"data": {
"items": [
{ "id": "…", "type": "artifact.updated",
"actor": { "type": "account", "id": "rip1…", "surface": "claude-code" },
"subject": { "type": "artifact", "id": "…" },
"payload": { "workspaceSessionId": "3e4f…" },
"createdAt": "2026-09-15T09:00:00.000Z" }
],
"deliveryToken": "q8Hc…", "hasMore": false, "historyGap": false, "refresh": "none"
}
}
| Field | Description |
|---|---|
items | Changes you may see: the event’s audience must be one of yours and its subject must still be visible to you, so an external member never sees internal work. Payloads never carry folder paths or counts |
deliveryToken | Acknowledge or replay this page with it. Valid for 10 minutes. null when items is empty |
hasMore | More changes wait after this page |
historyGap | Retention pruned changes past your position; rebuild state from Load |
refresh | required when your access changed since your last read; refetch authorized state before continuing |
deliveryToken is refused; a read with it returns the same page. Once the token expires, the next read issues a fresh page from your acknowledged position.
Errors
| Status | Code | Cause |
|---|---|---|
409 | WORKSPACE_PAGE_UNACKNOWLEDGED | A delivered page is outstanding; replay it with its deliveryToken or acknowledge it |
400 | INVALID_WORKSPACE_DELIVERY | The token is wrong, expired, or belongs to another reader |
400 | INVALID_INPUT / INVALID_LIMIT | limit is not an integer / not between 1 and 100 |
404 | WORKSPACE_NOT_FOUND | No workspace with that id |
403 | WORKSPACE_FORBIDDEN | You are not a member |