curl --request GET \
--url https://api.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}/trajectory \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}/trajectory"
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}/trajectory', 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}/trajectory",
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}/trajectory"
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}/trajectory")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}/trajectory")
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{
"schema_version": "ATIF-v1.7",
"agent": {
"name": "<string>",
"version": "<string>",
"model_name": "<string>",
"extra": {}
},
"steps": [
{
"step_id": 123,
"source": "system",
"message": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"model_name": "<string>",
"reasoning_effort": "<string>",
"reasoning_content": "<string>",
"tool_calls": [
{
"tool_call_id": "<string>",
"function_name": "<string>",
"arguments": {},
"extra": {}
}
],
"observation": {
"results": [
{
"source_call_id": "<string>",
"content": "<string>",
"extra": {}
}
]
},
"metrics": {
"prompt_tokens": 123,
"completion_tokens": 123,
"cached_tokens": 123,
"cost_usd": 123,
"extra": {}
},
"extra": {}
}
],
"session_id": "<string>",
"trajectory_id": "<string>",
"final_metrics": {
"total_prompt_tokens": 123,
"total_completion_tokens": 123,
"total_cached_tokens": 123,
"total_cost_usd": 123,
"total_steps": 123,
"extra": {}
},
"notes": "<string>",
"extra": {}
}{
"error": "prompt_required"
}{
"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"
}
}Export session trajectory
Export the session trajectory in the Agent Trajectory Interchange Format (ATIF v1.7, RFC 0001): steps, user messages, agent reasoning, tool calls and their results, and token and cost metrics. Reason tool calls made inside codemode appear as tool calls linked to their parent call by extra.parent_tool_call_id. A standard session masks the run’s secret values, known credential shapes and any unbroken run of 40 or more letters, digits, - or _, which includes hashes. An ephemeral session masks only the run’s secret values, as [redacted-secret], and credentials Reason issues. A tool call’s arguments and output are exported whole; extra.fidelity counts the redaction markers and the tool events exported from a 4,000-character preview. agent.version is the Reason release that ran the latest turn. Each subagent Session the session started is embedded in subagent_trajectories, and final_metrics totals include them; final_metrics.extra.session_totals holds the session’s own.
Scope:sessions:readcurl --request GET \
--url https://api.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}/trajectory \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}/trajectory"
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}/trajectory', 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}/trajectory",
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}/trajectory"
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}/trajectory")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reasonmachines.com/v3/organizations/{orgId}/sessions/{sessionId}/trajectory")
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{
"schema_version": "ATIF-v1.7",
"agent": {
"name": "<string>",
"version": "<string>",
"model_name": "<string>",
"extra": {}
},
"steps": [
{
"step_id": 123,
"source": "system",
"message": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"model_name": "<string>",
"reasoning_effort": "<string>",
"reasoning_content": "<string>",
"tool_calls": [
{
"tool_call_id": "<string>",
"function_name": "<string>",
"arguments": {},
"extra": {}
}
],
"observation": {
"results": [
{
"source_call_id": "<string>",
"content": "<string>",
"extra": {}
}
]
},
"metrics": {
"prompt_tokens": 123,
"completion_tokens": 123,
"cached_tokens": 123,
"cost_usd": 123,
"extra": {}
},
"extra": {}
}
],
"session_id": "<string>",
"trajectory_id": "<string>",
"final_metrics": {
"total_prompt_tokens": 123,
"total_completion_tokens": 123,
"total_cached_tokens": 123,
"total_cost_usd": 123,
"total_steps": 123,
"extra": {}
},
"notes": "<string>",
"extra": {}
}{
"error": "prompt_required"
}{
"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 session id, returned as session_id by createSession and listSessions.
Query Parameters
Document format to export. ATIF v1.7 (Agent Trajectory Interchange Format) is the only one offered, so omitting it returns the same document.
atif Response
The complete ATIF trajectory for the session.
Full session trajectory conforming to the Agent Trajectory Interchange Format (ATIF v1.7, RFC 0001).
ATIF schema version.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Run-scoped session identifier.
Unique identifier for this trajectory document.
Show child attributes
Show child attributes

