curl --request GET \
--url https://api.reasonmachines.com/v3/organizations/{orgId}/sessions \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.reasonmachines.com/v3/organizations/{orgId}/sessions"
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', 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",
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"
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")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reasonmachines.com/v3/organizations/{orgId}/sessions")
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{
"items": [
{
"session_policy": {
"version": 1,
"mode": "standard",
"components": {
"memoryRead": true,
"memoryWrite": true,
"skills": true,
"inheritedInstructions": true,
"integrations": true,
"secretInjection": true
},
"workspaceOwnership": "managed",
"personalContext": false,
"pullRequestPolicy": "draft_only"
},
"session_id": "<string>",
"status": "running",
"url": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"benchmark_profile": "coding-benchmark-v1",
"runtime_profile": "runtime/reason-sync-yield-v1",
"experimental_runtime_profile": "runtime/reason-c2-tools-v7",
"experimental_runtime_features": [
"banner"
],
"origin": "ui",
"origin_agent": "<string>",
"agent_identity_source": "self_reported",
"suspended_reason": "cancelled",
"started_at": "2023-11-07T05:31:56Z",
"finished_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"title": "<string>",
"prompt": "<string>",
"prompt_truncated": true,
"prompt_bytes": 123,
"tags": [
"<string>"
],
"project_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"reason_id": "<string>",
"created_by_session_id": "<string>",
"automation_id": "<string>",
"target": {
"kind": "cloud"
},
"machine": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"state": "waiting",
"queue_position": 123,
"device_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"enqueued_at": "<string>",
"placed_at": "<string>"
},
"repo": "<string>",
"provider": "github",
"model": "<string>",
"reason_version": "<string>",
"reason_commit_sha": "<string>",
"reasoning_effort": "<string>",
"hands_mode": "adaptive",
"branch": "<string>",
"branch_has_commits": true,
"pr_url": "<string>",
"pr_title": "<string>",
"result_summary": "<string>",
"outcome": "success",
"result": "<unknown>",
"blocker": "<string>",
"failure": {
"category": "<string>",
"title": "<string>",
"message": "<string>",
"resolution": "retry",
"actions": [
{
"label": "<string>",
"url": "<string>"
}
]
},
"error_class": "<string>",
"usage_limit_resume": {
"resumes_at": "2023-11-07T05:31:56Z"
},
"error_message": "<string>",
"failure_diagnostics": {
"failure_stage": "<string>",
"reason_code": "<string>",
"root_cause": "<string>"
},
"failure_stage": "<string>",
"reason_code": "<string>",
"root_cause": "<string>",
"previous_attempt_failure": {
"attempt_id": "<string>",
"status": "<string>",
"error_class": "<string>",
"failure_stage": "<string>",
"reason_code": "<string>",
"root_cause": "<string>",
"finished_at": "<string>"
},
"diagnostic_message": "<string>",
"duration_ms": 123,
"cost_usd": 123,
"usage": {
"input_tokens": 123,
"output_tokens": 123,
"total_tokens": 123
},
"context": {
"tokens": 123,
"window": 123,
"percent": 123
},
"is_archived": true,
"session_type": "session",
"source_session_id": "<string>",
"read_only": true,
"repos": [
"<string>"
],
"change_requests": [
{
"url": "<string>",
"status": "active"
}
]
}
],
"end_cursor": "<string>",
"has_next_page": true
}{
"error": "prompt_required"
}{
"error": "missing_bearer",
"message": "Authorization required"
}{
"error": "missing_scope",
"required_scope": "sessions:read"
}List sessions
Returns Sessions newest first, cursor-paginated. By default, status=active hides archived Sessions; status accepts active, archived, or all. origin accepts ui, external, external:cli|mcp|api, or comma-separated values. Follow-up execution Attempts update their Session and never appear as additional list items. A list item reports the same status and outcome as Retrieve a session; its result is the text summary, and Retrieve a session returns a structured result. Responses carry a weak ETag; send it as If-None-Match to receive 304 Not Modified while the page is unchanged. A 304 may repeat usage counters (usage, context, cost_usd, duration_ms) and model up to 10 seconds old; a page narrowed by fields to none of those may be up to 5 minutes old.
sessions:readcurl --request GET \
--url https://api.reasonmachines.com/v3/organizations/{orgId}/sessions \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.reasonmachines.com/v3/organizations/{orgId}/sessions"
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', 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",
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"
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")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reasonmachines.com/v3/organizations/{orgId}/sessions")
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{
"items": [
{
"session_policy": {
"version": 1,
"mode": "standard",
"components": {
"memoryRead": true,
"memoryWrite": true,
"skills": true,
"inheritedInstructions": true,
"integrations": true,
"secretInjection": true
},
"workspaceOwnership": "managed",
"personalContext": false,
"pullRequestPolicy": "draft_only"
},
"session_id": "<string>",
"status": "running",
"url": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"benchmark_profile": "coding-benchmark-v1",
"runtime_profile": "runtime/reason-sync-yield-v1",
"experimental_runtime_profile": "runtime/reason-c2-tools-v7",
"experimental_runtime_features": [
"banner"
],
"origin": "ui",
"origin_agent": "<string>",
"agent_identity_source": "self_reported",
"suspended_reason": "cancelled",
"started_at": "2023-11-07T05:31:56Z",
"finished_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"title": "<string>",
"prompt": "<string>",
"prompt_truncated": true,
"prompt_bytes": 123,
"tags": [
"<string>"
],
"project_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"reason_id": "<string>",
"created_by_session_id": "<string>",
"automation_id": "<string>",
"target": {
"kind": "cloud"
},
"machine": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"state": "waiting",
"queue_position": 123,
"device_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"enqueued_at": "<string>",
"placed_at": "<string>"
},
"repo": "<string>",
"provider": "github",
"model": "<string>",
"reason_version": "<string>",
"reason_commit_sha": "<string>",
"reasoning_effort": "<string>",
"hands_mode": "adaptive",
"branch": "<string>",
"branch_has_commits": true,
"pr_url": "<string>",
"pr_title": "<string>",
"result_summary": "<string>",
"outcome": "success",
"result": "<unknown>",
"blocker": "<string>",
"failure": {
"category": "<string>",
"title": "<string>",
"message": "<string>",
"resolution": "retry",
"actions": [
{
"label": "<string>",
"url": "<string>"
}
]
},
"error_class": "<string>",
"usage_limit_resume": {
"resumes_at": "2023-11-07T05:31:56Z"
},
"error_message": "<string>",
"failure_diagnostics": {
"failure_stage": "<string>",
"reason_code": "<string>",
"root_cause": "<string>"
},
"failure_stage": "<string>",
"reason_code": "<string>",
"root_cause": "<string>",
"previous_attempt_failure": {
"attempt_id": "<string>",
"status": "<string>",
"error_class": "<string>",
"failure_stage": "<string>",
"reason_code": "<string>",
"root_cause": "<string>",
"finished_at": "<string>"
},
"diagnostic_message": "<string>",
"duration_ms": 123,
"cost_usd": 123,
"usage": {
"input_tokens": 123,
"output_tokens": 123,
"total_tokens": 123
},
"context": {
"tokens": 123,
"window": 123,
"percent": 123
},
"is_archived": true,
"session_type": "session",
"source_session_id": "<string>",
"read_only": true,
"repos": [
"<string>"
],
"change_requests": [
{
"url": "<string>",
"status": "active"
}
]
}
],
"end_cursor": "<string>",
"has_next_page": true
}{
"error": "prompt_required"
}{
"error": "missing_bearer",
"message": "Authorization required"
}{
"error": "missing_scope",
"required_scope": "sessions:read"
}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.
Query Parameters
Which Sessions to list by archive state, not by run status: active for the working list, archived for archived Sessions only, all for both.
active, archived, all Where the Sessions were started, one source or several joined by commas: ui is the Reason app, external covers CLI, MCP and API starts together, and external:cli, external:mcp or external:api picks one. Omitted, every source is listed.
100^(?:ui|external|external:(?:cli|mcp|api))(?:,(?:ui|external|external:(?:cli|mcp|api)))*$Older spelling of status, read only when status is omitted: exclude leaves archived Sessions out, only lists just them, include lists both. With neither filter, archived Sessions are left out.
exclude, only, include Words to look for in Session titles, ignoring case and taken literally; transcripts are not searched. A search returns smaller pages, so follow end_cursor for more matches.
3 - 500Deprecated: Projects are retired in favour of Reasons. Filters by an accessible Project ID in this Workspace, as returned in a Session's project_id.
^([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)$Lists only the Sessions filed under this Reason (listReasons), one you can see or one of your archived ones. The same id as project_id: send either, or both with the same value.
^([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)$How many Sessions one page holds, up to 200 (a larger value is capped); a page of search matches holds at most 24.
Same as first, for clients that send limit; first wins when both are set.
Cursor from the previous page's end_cursor.
The Session properties each item needs, comma-separated; session_id always comes back. For a lean page, status,repo,model,updated_at returns each item as session_id plus those four, a small fraction of a full item. Names are those of Retrieve a session except previous_attempt_failure, which only Retrieve a session returns; an unknown name is refused with 400 invalid_request listing allowed_fields. Each item leaves out every other property, even ones the Session schema marks required. Without usage, context, cost_usd, duration_ms and model, the ETag changes when a Session's listed property or who can see it changes, and at least every 5 minutes, so a poll sending If-None-Match gets 304 Not Modified in between; a 304 page is never more than 5 minutes old.
"status,repo,model,updated_at"
Lists only Sessions whose outcome is one of these, comma-separated: success, failure or action_required. outcome=action_required is the digest of blocked Sessions: each one's blocker says what stopped it and the next step (add fields=title,blocker,url for a compact digest). The filter applies to each page as read, so a page may hold fewer items than first, even none; follow end_cursor while has_next_page is true.
60^(?:success|failure|action_required)(?:,(?:success|failure|action_required))*$
