curl --request GET \
--url https://api.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}', 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.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$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.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
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.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"benchmark_profile": null,
"runtime_profile": null,
"experimental_runtime_profile": null,
"experimental_runtime_features": null,
"session_policy": {
"version": 1,
"mode": "standard",
"workspaceOwnership": "managed",
"components": {
"memoryRead": true,
"memoryWrite": true,
"skills": true,
"inheritedInstructions": true,
"integrations": true,
"secretInjection": true
}
},
"session_id": "ses_91af3c",
"project_id": null,
"reason_id": null,
"created_by_session_id": null,
"automation_id": null,
"status": "exit",
"suspended_reason": null,
"url": "http://127.0.0.1:3001/agents/ses_91af3c",
"created_at": null,
"started_at": null,
"finished_at": null,
"updated_at": null,
"title": null,
"prompt": null,
"prompt_truncated": false,
"prompt_bytes": null,
"tags": [],
"agent_id": null,
"agent_name": null,
"origin": "ui",
"origin_agent": null,
"agent_identity_source": null,
"repo": null,
"provider": null,
"model": null,
"reason_version": null,
"reason_commit_sha": null,
"reasoning_effort": null,
"hands_mode": "adaptive",
"branch": null,
"branch_has_commits": null,
"pr_url": null,
"pr_title": null,
"result_summary": "Review finished.",
"outcome": "success",
"result": null,
"blocker": null,
"failure": null,
"error_class": null,
"diagnostic_message": null,
"error_message": null,
"failure_diagnostics": null,
"failure_stage": null,
"reason_code": null,
"root_cause": null,
"trigger_source": null,
"duration_ms": null,
"cost_usd": null,
"usage": {
"input_tokens": null,
"output_tokens": null,
"total_tokens": null
},
"context": {
"tokens": null,
"window": null,
"percent": null
},
"archived_at": null,
"is_archived": false,
"session_type": "session",
"source_session_id": null,
"read_only": false
}Retrieve a session
Returns the stable Session identity with current execution state, a bounded redacted error_message, and best-effort failure_diagnostics. Unknown diagnostic fields are null. A previously returned physical Attempt UUID remains accepted as a compatibility alias, but the response always carries the Session session_id and URL. The opening prompt is repeated on every read, in prompt (up to 16 KiB; prompt_truncated and prompt_bytes say when it was cut) and, for a Session without a title of its own, as the first 200 characters of title. To poll cheaply, pass fields (for example fields=status,outcome,result) and read the complete Session once. A response narrowed by fields carries only session_id and the named properties, so it omits properties the Session schema marks required.
sessions:readcurl --request GET \
--url https://api.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}', 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.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$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.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
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.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"benchmark_profile": null,
"runtime_profile": null,
"experimental_runtime_profile": null,
"experimental_runtime_features": null,
"session_policy": {
"version": 1,
"mode": "standard",
"workspaceOwnership": "managed",
"components": {
"memoryRead": true,
"memoryWrite": true,
"skills": true,
"inheritedInstructions": true,
"integrations": true,
"secretInjection": true
}
},
"session_id": "ses_91af3c",
"project_id": null,
"reason_id": null,
"created_by_session_id": null,
"automation_id": null,
"status": "exit",
"suspended_reason": null,
"url": "http://127.0.0.1:3001/agents/ses_91af3c",
"created_at": null,
"started_at": null,
"finished_at": null,
"updated_at": null,
"title": null,
"prompt": null,
"prompt_truncated": false,
"prompt_bytes": null,
"tags": [],
"agent_id": null,
"agent_name": null,
"origin": "ui",
"origin_agent": null,
"agent_identity_source": null,
"repo": null,
"provider": null,
"model": null,
"reason_version": null,
"reason_commit_sha": null,
"reasoning_effort": null,
"hands_mode": "adaptive",
"branch": null,
"branch_has_commits": null,
"pr_url": null,
"pr_title": null,
"result_summary": "Review finished.",
"outcome": "success",
"result": null,
"blocker": null,
"failure": null,
"error_class": null,
"diagnostic_message": null,
"error_message": null,
"failure_diagnostics": null,
"failure_stage": null,
"reason_code": null,
"root_cause": null,
"trigger_source": null,
"duration_ms": null,
"cost_usd": null,
"usage": {
"input_tokens": null,
"output_tokens": null,
"total_tokens": null
},
"context": {
"tokens": null,
"window": null,
"percent": null
},
"archived_at": null,
"is_archived": false,
"session_type": "session",
"source_session_id": null,
"read_only": false
}Authorizations
Your Reason API key from Settings › API keys. New keys use reason_; legacy ara_ keys remain accepted. Keys are capability-scoped: run, mcp:read, mcp:write, secrets:read, secrets:write, sessions:read, sessions:debug, knowledge:read, memory:read, memory:write, skills:read, skills:write, repos:read, repos:write, reviews:read, reviews:write, deployment:read, analytics:read, org:read, org:write, attachments:read, attachments:write, guardrails:read, guardrails:write, network:read, network:write, automations:read, automations:write, agent_auth:read. network:read and network:write are opt-in, excluded from default keys. network:read reads the saved workspace network policy; network:write replaces custom allowed hosts and requires a current organization owner/admin. Legacy project PATCH requests containing network_allowed_hosts also require network:write plus their existing run scope and project management permission; saved project hosts do not affect current session egress. Only owners/admins can mint or manage keys with network:write; keys cannot grant themselves more authority. See /docs/network-policies for replacement semantics and runtime applicability. mcp:write manages MCP server configuration only; it does not authorize remote MCP-tool execution. sessions:read reads sessions, including the assistant, reasoning and tool activity in their events. sessions:debug is privileged: only for organization owners/admins, it expands session events to the full diagnostic projection (diagnostic event kinds, status text and raw event metadata).
Path Parameters
Organization id or slug. Resolve it with GET /v3/self.
The session id, returned as session_id by createSession and listSessions.
Query Parameters
The Session properties a poll needs, comma-separated, for example status,outcome,result; session_id always comes back. Name top-level properties (usage, not usage.input_tokens); an unknown name is refused with 400 invalid_request listing allowed_fields. The narrowed response leaves out every other property, even ones the Session schema marks required, and one this Session lacks (for example machine). Omit it for the full Session, which repeats prompt (up to 16 KiB) on every read.
"status,outcome,result"
Response
The session.
Server-resolved immutable Session policy. Enabled components remain subject to normal permissions and configuration.
Show child attributes
Show child attributes
The Session's stable id; pass it as sessionId to the other session tools.
Lifecycle state, not task success: running, exit (execution completed), error (execution failed), or suspended (cancelled/quota; suspended_reason says which). An exit can have outcome failure or action_required. The task succeeded if and only if outcome is success; check outcome, result, and diagnostics before treating work as successful.
running, exit, error, suspended Web URL to watch the session.
When the Session was created.
Always null: benchmark_profile is retired.
"coding-benchmark-v1"runtime/reason-sync-yield-v1 on a retired isolated Session that requested it through the retired runtime_profile field. Null otherwise.
"runtime/reason-sync-yield-v1"The runtime profile the Session's latest Attempt runs: the default C2 harness on every Session that runs it, whether or not its request named it (a Session of the retired runtime/reason-capability-shell-v1 continues on it) — reported as runtime/reason-c2-tools-v7; runtime/reason-v7-sync-yield-v1 or runtime/reason-v7-sync-yield-machine-sdk-v1 on a stored Session of that retired harness; runtime/reason-v7-2026-10, runtime/reason-v7-2026-11, runtime/reason-v8-2026-10, runtime/reason-v8.1-2026-10, runtime/reason-v8.2-2026-10, runtime/reason-agent-1.2 or runtime/reason-agent-1.3 on a Session that runs it; a Session of a deleted v7 evaluation profile reports the default C2 harness, which it re-admits to. Null otherwise.
runtime/reason-c2-tools-v7, runtime/reason-v7-sync-yield-v1, runtime/reason-v7-sync-yield-machine-sdk-v1, runtime/reason-v7-2026-10, runtime/reason-v7-2026-11, runtime/reason-v8-2026-10, runtime/reason-v8.1-2026-10, runtime/reason-v8.2-2026-10, runtime/reason-agent-1.2, runtime/reason-agent-1.3 The runtime features the Session's create named (experimental_runtime_features), in canonical order. Null when it named none.
banner, sdk_index, service_tier, output_cap, git_metadata, serial_reads, recovery_defer_idle_hands, fewer_tests_low, fewer_tests_medium, fewer_tests_high, fewer_tests_max, fewer_tests_max_alone, verify_line_alone, addendum_placebo, bash_yield, sync_bash, turn_line_removed, turn_line_questions, output_cap_continue, image_history_append_only, cache_ttl_1h Where the Session was started: ui is the Reason app, external:cli, external:mcp and external:api the CLI, an MCP client and the API.
ui, external:cli, external:mcp, external:api Name of the agent or client that started the Session, when known.
How origin_agent was established: self_reported by the caller, from the credential, or from the Device.
self_reported, credential, device Why status is suspended: cancelled (an explicit cancel stopped the Session) or quota_exhausted (the Workspace ran out of quota). Null for every other status.
cancelled, quota_exhausted When execution started; null before it starts.
When execution finished; null while running.
When the Session's current Attempt last changed (status, result, pull request, usage); sort or diff on it to see which Sessions moved since a previous read.
Display title: the Session's own title, else the issue title, else the start of the opening prompt.
The opening instruction, truncated to 16 KiB. Check prompt_truncated; read the session messages for the full text.
True when prompt was cut to the 16 KiB echo limit.
UTF-8 byte length of the full prompt, before truncation.
The Session's tag labels; empty when it has none.
Deprecated: Projects are retired in favour of Reasons. Project containing the session, or null for an unassigned session.
^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$The Reason (listReasons) this Session is listed under: the one whose conversation started it, directly or through the Sessions it started. A Session filed in a former Project names that Project's id, which its Reason kept. Null when no Reason started it.
The Session whose agent started this one with sessions_create; null when a person, a trigger or a Loop started it.
The automation (Loop) whose trigger started this Session, as listReasonLoops (or listAutomations) names it; null otherwise.
Present on GET: the execution target this Session was created with (cloud, or the Device and root it runs on). A later handoff is not reflected. A Machine target reads back as its placed headless worker; see machine.
- Option 1
- Option 2
- Option 3
Show child attributes
Show child attributes
Present on GET for a Session attempt that targets a Machine: its queue state, live queue position while waiting, and the worker it was placed on.
Show child attributes
Show child attributes
The Session's starting repository as owner/name; null for a repository-neutral Session.
Source-control provider for the session repository.
github, gitlab Concrete model selected for this session, or null when inherited.
The Reason Agent version (X.Y, e.g. 1.4 for Reason Agent 1.4) of the server that executed the Session's latest turn. It names the daily release; reason_commit_sha is the exact build. During a rolling deploy this is the release that actually ran the turn, not the newest one. Null before the turn starts and for turns that ran before versions were recorded.
The commit the server that executed the Session's latest turn was built from. Null when reason_version is null or the build carried no commit.
Reasoning effort override the Session runs with; null when none was set.
Durable physical execution policy. Brain-only sessions never acquire a shell, browser, sandbox, or physical secret environment.
adaptive, brain_only Name of the Session's working branch in its workspace. It is assigned when the machine starts, before any commit, so it exists on the remote only once the Session pushed to it: check pr_url and branch_has_commits.
Whether the working branch reached the remote without a pull request: true when it has pushed commits, false when the Session ended without pushing any (the branch may not exist on the remote). Null while undetermined, and when pr_url is set.
URL of the pull request the Session opened or continued; null when there is none.
Title of that pull request.
Text summary of the latest turn's answer; null before a turn finishes.
The task verdict, and the one field that says whether the work succeeded: the task succeeded if and only if outcome is success. Retrieve a session and List sessions report the same value. With completion_mode: run_outcome it is the verdict the agent recorded (success, failure, or action_required when a person or an unavailable dependency must act); a run that stops without recording one never reports success, normally action_required with its reply in result. Recording a verdict is a tool call, so a prompt that forbids tools gets action_required even when the reply is correct. Without completion_mode no verdict is recorded: an exit reports success because the execution completed (action_required when the turn ended waiting on a person), which does not say the work was checked. Null while running and when status is error or suspended without a verdict.
success, failure, action_required Caller-defined JSON result for a noninteractive completion, or the ordinary final summary for legacy Sessions.
When outcome is failure or action_required: what blocked the Session and the next step a person takes, in one sentence the agent wrote (for example "Connect 1password: the deploy reads its token from the vault"). The agent states it when it records the verdict, or it is the access card the turn waits on. Null when the agent stated none, while running, and when outcome is success. List sessions reports it on each row.
Why the latest turn stopped and how to get it going again, for a caller that does not read the transcript. Null while running and when the turn did not stop on a failure (an agent's own verdict is in outcome and blocker). List sessions reports it on each row.
Show child attributes
Show child attributes
Stable runtime failure class when execution did not produce a task outcome. Runtime codes use the run_ prefix (for example run_error, run_timeout, run_cancelled) and cloud execution codes the cloud_ prefix (for example cloud_device_unavailable); since 2026-10 they replace the earlier runtime-internal and ara_cloud_ spellings, which the API no longer reports.
Present on GET: the pending automatic continuation after a connected model account's usage limit. Null when none is pending, including after Stop or newer input. A pending continuation does not guarantee provider capacity. Poll this field instead of repeatedly sending the same request.
Show child attributes
Show child attributes
Redacted persisted error preview, bounded to 1000 characters; null when unavailable.
Best-effort attribution from persisted failure signatures. Unknown stages and root causes remain null.
Show child attributes
Show child attributes
Execution stage where failure occurred.
Specific machine-readable reason code for the failure. Runtime and cloud execution codes use the run_ and cloud_ prefixes, as in error_class.
Root cause classification of the failure.
The most recent failed Attempt of the current Turn before the current Attempt, so a failure stays readable after a retry replaced it (for example a cloud_device_unavailable start failure followed by a successful retry). The current Attempt's own failure is in error_class and failure_diagnostics; this is null when the current Attempt failed, no earlier Attempt of the Turn did, or the current run is not a Session Attempt (a resource transition or wake). Returned by getSession on a full read, or when fields names it; not on the Session list.
Show child attributes
Show child attributes
Fixed public message selected from an allowlisted persisted error class, never error prose, prompts or tool output. Null when unknown.
160Execution time in milliseconds; null when not recorded.
Total model spend in USD across the session's turns. Null when usage was never reported.
Token usage totals for the session. Fields are null for runs that predate usage persistence.
Show child attributes
Show child attributes
Live context occupancy after the latest turn (not billing throughput).
Show child attributes
Show child attributes
True when the Session is archived (archiveSession); listSessions hides it unless status is archived or all.
Session, sidechat fork, or read-only subagent Session.
session, sidechat, subagent The fork source for a sidechat or spawning Session for a subagent; null for a normal Session.
True only for subagent Sessions.
Every repository currently attached to the session, as owner/name. Present on Retrieve a session only, and only when recorded.
Every change request the session opened, including ones in repositories other than repo. Present on Retrieve a session only, and only when recorded.
Show child attributes
Show child attributes

