curl --request PATCH \
--url https://api.getmembrane.com/agent-sessions/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"lastActivityAt": "<string>",
"title": "<string>",
"summary": "<string>",
"labels": [
"<string>"
],
"metadata": {},
"startedAt": "<string>",
"endedAt": "<string>",
"opencodeSessionUuid": "<string>",
"output": {},
"outputAttachments": [
{
"title": "<string>",
"data": {}
}
]
}
'import requests
url = "https://api.getmembrane.com/agent-sessions/{id}"
payload = {
"lastActivityAt": "<string>",
"title": "<string>",
"summary": "<string>",
"labels": ["<string>"],
"metadata": {},
"startedAt": "<string>",
"endedAt": "<string>",
"opencodeSessionUuid": "<string>",
"output": {},
"outputAttachments": [
{
"title": "<string>",
"data": {}
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
lastActivityAt: '<string>',
title: '<string>',
summary: '<string>',
labels: ['<string>'],
metadata: {},
startedAt: '<string>',
endedAt: '<string>',
opencodeSessionUuid: '<string>',
output: {},
outputAttachments: [{title: '<string>', data: {}}]
})
};
fetch('https://api.getmembrane.com/agent-sessions/{id}', 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.getmembrane.com/agent-sessions/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'lastActivityAt' => '<string>',
'title' => '<string>',
'summary' => '<string>',
'labels' => [
'<string>'
],
'metadata' => [
],
'startedAt' => '<string>',
'endedAt' => '<string>',
'opencodeSessionUuid' => '<string>',
'output' => [
],
'outputAttachments' => [
[
'title' => '<string>',
'data' => [
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.getmembrane.com/agent-sessions/{id}"
payload := strings.NewReader("{\n \"lastActivityAt\": \"<string>\",\n \"title\": \"<string>\",\n \"summary\": \"<string>\",\n \"labels\": [\n \"<string>\"\n ],\n \"metadata\": {},\n \"startedAt\": \"<string>\",\n \"endedAt\": \"<string>\",\n \"opencodeSessionUuid\": \"<string>\",\n \"output\": {},\n \"outputAttachments\": [\n {\n \"title\": \"<string>\",\n \"data\": {}\n }\n ]\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://api.getmembrane.com/agent-sessions/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"lastActivityAt\": \"<string>\",\n \"title\": \"<string>\",\n \"summary\": \"<string>\",\n \"labels\": [\n \"<string>\"\n ],\n \"metadata\": {},\n \"startedAt\": \"<string>\",\n \"endedAt\": \"<string>\",\n \"opencodeSessionUuid\": \"<string>\",\n \"output\": {},\n \"outputAttachments\": [\n {\n \"title\": \"<string>\",\n \"data\": {}\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.getmembrane.com/agent-sessions/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"lastActivityAt\": \"<string>\",\n \"title\": \"<string>\",\n \"summary\": \"<string>\",\n \"labels\": [\n \"<string>\"\n ],\n \"metadata\": {},\n \"startedAt\": \"<string>\",\n \"endedAt\": \"<string>\",\n \"opencodeSessionUuid\": \"<string>\",\n \"output\": {},\n \"outputAttachments\": [\n {\n \"title\": \"<string>\",\n \"data\": {}\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"workspaceId": "<string>",
"type": "<string>",
"status": "queued",
"prompt": "<string>",
"lastActivityAt": "2023-11-07T05:31:56Z",
"hasWorker": true,
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"tenantId": "<string>",
"ownerName": "<string>",
"orgWorkspaceId": "<string>",
"ownerPlatformUserId": "<string>",
"workspaceElementType": "tenant",
"workspaceElementId": "<string>",
"error": {
"message": "<string>",
"type": "bad_request",
"key": "<string>",
"data": {},
"stack": {},
"causedByError": "<unknown>",
"logs": [
{}
]
},
"archivedAt": "2023-11-07T05:31:56Z",
"title": "<string>",
"summary": "<string>",
"labels": [
"<string>"
],
"metadata": {},
"cost": 123,
"estimatedCost": 123,
"extraSpendAllowance": 123,
"state": "busy",
"promptPending": true,
"promptSynthetic": true,
"inputs": [
{
"id": "<string>",
"sessionId": "<string>",
"sequence": 4503599627370495,
"kind": "prompt",
"state": "queued",
"activationId": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"input": "<string>",
"attachments": [
{
"title": "<string>",
"data": {}
}
],
"synthetic": true,
"producerIdempotencyKey": "<string>",
"deliveredAttemptId": "<string>"
}
],
"stopping": true,
"isExternal": true,
"startedAt": "2023-11-07T05:31:56Z",
"endedAt": "2023-11-07T05:31:56Z",
"externalSessionId": "<string>",
"preset": "general",
"adminCatalog": true,
"launchContext": {
"surface": "console-chat",
"route": "<string>",
"element": {
"type": "tenant",
"id": "<string>"
}
},
"agentHarnessId": "<string>",
"agentHarnessSnapshotId": "<string>",
"modelId": "<string>",
"reasoningEffort": "none",
"output": {},
"outputAttachments": [
{
"title": "<string>",
"data": {}
}
],
"promptAttachments": [
{
"title": "<string>",
"data": {}
}
],
"parentSessionId": "<string>"
}Update an agent session
curl --request PATCH \
--url https://api.getmembrane.com/agent-sessions/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"lastActivityAt": "<string>",
"title": "<string>",
"summary": "<string>",
"labels": [
"<string>"
],
"metadata": {},
"startedAt": "<string>",
"endedAt": "<string>",
"opencodeSessionUuid": "<string>",
"output": {},
"outputAttachments": [
{
"title": "<string>",
"data": {}
}
]
}
'import requests
url = "https://api.getmembrane.com/agent-sessions/{id}"
payload = {
"lastActivityAt": "<string>",
"title": "<string>",
"summary": "<string>",
"labels": ["<string>"],
"metadata": {},
"startedAt": "<string>",
"endedAt": "<string>",
"opencodeSessionUuid": "<string>",
"output": {},
"outputAttachments": [
{
"title": "<string>",
"data": {}
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
lastActivityAt: '<string>',
title: '<string>',
summary: '<string>',
labels: ['<string>'],
metadata: {},
startedAt: '<string>',
endedAt: '<string>',
opencodeSessionUuid: '<string>',
output: {},
outputAttachments: [{title: '<string>', data: {}}]
})
};
fetch('https://api.getmembrane.com/agent-sessions/{id}', 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.getmembrane.com/agent-sessions/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'lastActivityAt' => '<string>',
'title' => '<string>',
'summary' => '<string>',
'labels' => [
'<string>'
],
'metadata' => [
],
'startedAt' => '<string>',
'endedAt' => '<string>',
'opencodeSessionUuid' => '<string>',
'output' => [
],
'outputAttachments' => [
[
'title' => '<string>',
'data' => [
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.getmembrane.com/agent-sessions/{id}"
payload := strings.NewReader("{\n \"lastActivityAt\": \"<string>\",\n \"title\": \"<string>\",\n \"summary\": \"<string>\",\n \"labels\": [\n \"<string>\"\n ],\n \"metadata\": {},\n \"startedAt\": \"<string>\",\n \"endedAt\": \"<string>\",\n \"opencodeSessionUuid\": \"<string>\",\n \"output\": {},\n \"outputAttachments\": [\n {\n \"title\": \"<string>\",\n \"data\": {}\n }\n ]\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://api.getmembrane.com/agent-sessions/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"lastActivityAt\": \"<string>\",\n \"title\": \"<string>\",\n \"summary\": \"<string>\",\n \"labels\": [\n \"<string>\"\n ],\n \"metadata\": {},\n \"startedAt\": \"<string>\",\n \"endedAt\": \"<string>\",\n \"opencodeSessionUuid\": \"<string>\",\n \"output\": {},\n \"outputAttachments\": [\n {\n \"title\": \"<string>\",\n \"data\": {}\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.getmembrane.com/agent-sessions/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"lastActivityAt\": \"<string>\",\n \"title\": \"<string>\",\n \"summary\": \"<string>\",\n \"labels\": [\n \"<string>\"\n ],\n \"metadata\": {},\n \"startedAt\": \"<string>\",\n \"endedAt\": \"<string>\",\n \"opencodeSessionUuid\": \"<string>\",\n \"output\": {},\n \"outputAttachments\": [\n {\n \"title\": \"<string>\",\n \"data\": {}\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"workspaceId": "<string>",
"type": "<string>",
"status": "queued",
"prompt": "<string>",
"lastActivityAt": "2023-11-07T05:31:56Z",
"hasWorker": true,
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"tenantId": "<string>",
"ownerName": "<string>",
"orgWorkspaceId": "<string>",
"ownerPlatformUserId": "<string>",
"workspaceElementType": "tenant",
"workspaceElementId": "<string>",
"error": {
"message": "<string>",
"type": "bad_request",
"key": "<string>",
"data": {},
"stack": {},
"causedByError": "<unknown>",
"logs": [
{}
]
},
"archivedAt": "2023-11-07T05:31:56Z",
"title": "<string>",
"summary": "<string>",
"labels": [
"<string>"
],
"metadata": {},
"cost": 123,
"estimatedCost": 123,
"extraSpendAllowance": 123,
"state": "busy",
"promptPending": true,
"promptSynthetic": true,
"inputs": [
{
"id": "<string>",
"sessionId": "<string>",
"sequence": 4503599627370495,
"kind": "prompt",
"state": "queued",
"activationId": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"input": "<string>",
"attachments": [
{
"title": "<string>",
"data": {}
}
],
"synthetic": true,
"producerIdempotencyKey": "<string>",
"deliveredAttemptId": "<string>"
}
],
"stopping": true,
"isExternal": true,
"startedAt": "2023-11-07T05:31:56Z",
"endedAt": "2023-11-07T05:31:56Z",
"externalSessionId": "<string>",
"preset": "general",
"adminCatalog": true,
"launchContext": {
"surface": "console-chat",
"route": "<string>",
"element": {
"type": "tenant",
"id": "<string>"
}
},
"agentHarnessId": "<string>",
"agentHarnessSnapshotId": "<string>",
"modelId": "<string>",
"reasoningEffort": "none",
"output": {},
"outputAttachments": [
{
"title": "<string>",
"data": {}
}
],
"promptAttachments": [
{
"title": "<string>",
"data": {}
}
],
"parentSessionId": "<string>"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Body
busy, idle Last meaningful session progress timestamp used for inactivity timeout checks.
Human-readable session name shown in the chat list. Rejects an empty title; length is not capped here so a PATCH that echoes an existing (possibly long) title while changing other fields is not rejected. System-generated titles are capped at 80 chars.
1Replaces the whole label set. Send the labels the session should end up with, not the ones to add.
201 - 64Replaces the whole metadata object. Send the metadata the session should end up with, not the keys to merge.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
When the mirrored run actually began. External sessions only — a hosted session starts when it is created, so supplying it there is rejected.
When the mirrored run actually finished. External sessions only — a hosted session ends when its worker says so, so supplying it there is rejected.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
queued, starting, running, completed, failed, cancelled Response
queued, starting, running, completed, failed, cancelled Last meaningful session progress timestamp used for inactivity timeout checks.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$tenant, app, connector, oauth-client, action, connection, browser-session, agent-session, data-table, data-table-record, external-event-log-record, external-event-pull, event-source, event-listener, action-run-log-record, external-api-log-record, incoming-webhook-log-record, external-reference, job, deliverable, receipt, job-contract, job-operator-assignment, crew-member, routine, routine-run, task, intake, command-execution, canvas, screen, file, knowledge-article, source-tree, source-tree-version, source-module Show child attributes
Show child attributes
When set, the session is archived (soft-deleted) and hidden from lists.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$Client-supplied labels on the session — a flat, unordered set used to group sessions across workspaces and elements (benchmark runs, an experiment arm, a customer tier). Trimmed and de-duplicated on write; filterable with the label query on the session list.
201 - 64Freeform client-owned JSON stored on the session and returned unchanged. The platform never reads it; use labels for anything you need to filter on.
Show child attributes
Show child attributes
API-list-price equivalent for subsidized provider usage; not deducted from AI credits.
Money granted to this session beyond the configured lifetime spend ceiling, by an operator continuing a run the ceiling stopped. The session may spend that ceiling plus this. Non-zero means someone decided this run was worth more than the default, which is what makes an unusually expensive run visible rather than silently unlimited.
busy, idle A user turn is queued but not yet picked up. An IDLE session with one is still working, so anything deciding whether a run has settled must read this alongside state (see taskStatusForSettledAgentSession).
The buffered prompt is a hidden system kickoff: the model receives it, but the chat UI must not draw it as a user bubble while the transcript loads.
Unconsumed and withdrawn items in the session input timeline, ordered by sequence.
Show child attributes
Show child attributes
A durable stop targets the open activation and will cancel it at its next fenced wake.
Whether an external harness (e.g. Claude Code) produces the session. An external session is never dispatched to a Membrane worker, whatever its preset says: its producer pushes the transcript up and downloads the composed context package down. One session row carries both directions.
When the mirrored run actually began, as reported by the producer of an external session. A hosted session is created the moment it starts, so createdAt is its start; an external session is created when its producer first uploads, which can be long after the work began. Timeline spans read this in preference to createdAt.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$When the mirrored run actually finished, as reported by the producer of an external session. Read only once the session has settled — a session still working keeps an open span whatever this says.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$The producer's own id for the session this external session mirrors — e.g. a local Claude Code session id. External sessions only; lets a producer recover its local-to-platform mapping from the API.
Which situation the one membrane agent runs in — selects the skills + context it loads.
general, canvas, screen, data, events, knowledge, connection, action, work, client, task, learning Whether the session runs with the platform command catalog (platform-admin sessions).
Where the session was launched from — the resolved surface / route / element envelope shared by the console UI and the agent.
Show child attributes
Show child attributes
AI Gateway model preset used by this session.
Reasoning effort used for every model call in this session. When omitted, the selected model/provider default is preserved; none explicitly disables reasoning.
none, minimal, low, medium, high, xhigh, max Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes