curl --request GET \
--url https://api.reasonmachines.com/v3/organizations/{orgId}/reasons/{reasonId} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.reasonmachines.com/v3/organizations/{orgId}/reasons/{reasonId}"
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}/reasons/{reasonId}', 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}/reasons/{reasonId}",
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}/reasons/{reasonId}"
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}/reasons/{reasonId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reasonmachines.com/v3/organizations/{orgId}/reasons/{reasonId}")
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{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"user_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"mine": true,
"visibility": "workspace",
"main": true,
"appearance": {
"color": "black",
"eyes": "pills",
"glasses": "none",
"accessory": "none"
},
"instructions": "<string>",
"session_id": "<string>",
"default_model": "<string>",
"default_reasoning_effort": "minimal",
"default_repositories": [
"<string>"
],
"audience": "personal",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}{
"error": "missing_bearer",
"message": "Authorization required"
}{
"error": "missing_scope",
"required_scope": "sessions:read"
}{
"error": "session_not_found"
}{
"error": {
"type": "rate_limited",
"message": "This API key exceeded its request-rate limit"
}
}Get a Reason
Returns one Reason the caller can see: their own, or another member’s Reason shared with the workspace or with them. Any other id, an archived Reason included, returns 404 reason_not_found.
sessions:readcurl --request GET \
--url https://api.reasonmachines.com/v3/organizations/{orgId}/reasons/{reasonId} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.reasonmachines.com/v3/organizations/{orgId}/reasons/{reasonId}"
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}/reasons/{reasonId}', 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}/reasons/{reasonId}",
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}/reasons/{reasonId}"
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}/reasons/{reasonId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reasonmachines.com/v3/organizations/{orgId}/reasons/{reasonId}")
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{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"user_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"mine": true,
"visibility": "workspace",
"main": true,
"appearance": {
"color": "black",
"eyes": "pills",
"glasses": "none",
"accessory": "none"
},
"instructions": "<string>",
"session_id": "<string>",
"default_model": "<string>",
"default_reasoning_effort": "minimal",
"default_repositories": [
"<string>"
],
"audience": "personal",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}{
"error": "missing_bearer",
"message": "Authorization required"
}{
"error": "missing_scope",
"required_scope": "sessions:read"
}{
"error": "session_not_found"
}{
"error": {
"type": "rate_limited",
"message": "This API key exceeded its request-rate limit"
}
}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 Reason id, returned as id by listReasons and createReason.
Response
The Reason.
A Reason is the long-running agent a person keeps: their main Reason, or a named one for an area of work. Each has its own conversation, its own Loops (scheduled and triggered work) and the Sessions it starts, which are filed under it. Messaging the Reason is the primary way to give it work: it decides whether to answer, start Sessions or set up Loops.
Reason id. Pass it as reasonId to the other Reason tools.
Display name. The main Reason is always called Reason.
The owner, the only person who can open, rename or archive it.
True when the caller owns this Reason.
workspace: every member sees it in their list; private: only its owner does.
workspace, private True for the person's main Reason, which is always listed and is never renamed or archived.
How the Reason's bot avatar looks in the app. Purely visual; it changes nothing the agent does.
Show child attributes
Show child attributes
Plain-text guidance for new Sessions started with this Reason. Blank when unset or when the caller does not own the Reason.
Its conversation Session once it has been opened, and only on the caller's own Reasons; null otherwise. sendReasonMessage and listReasonMessages reach the conversation of any Reason you can open without it.
The model a new Session under this Reason starts on when its create names none, by an id listAgentModels returns; null when it uses the workspace's default.
The reasoning effort that Session starts at when its create names none; null for the model's default.
minimal, low, medium, high, xhigh, max, off The owner/name repositories a new Session under this Reason checks out when its create names none, the first being the Session's own; empty when it has none. Null when the caller cannot start Sessions under this Reason.
Who talks to it. personal: only its owner; team: the people it is shared with; customer: a team Reason that people outside the team (customers, in Slack for example) also talk to, whose runs use only what was added to the Reason itself.
personal, team, customer 
