curl --request POST \
--url https://api.reasonmachines.com/v3/organizations/{orgId}/ephemeral-workspaces \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"reference": "<string>",
"ttl_minutes": 182,
"rcus": "<string>"
}
'import requests
url = "https://api.reasonmachines.com/v3/organizations/{orgId}/ephemeral-workspaces"
payload = {
"reference": "<string>",
"ttl_minutes": 182,
"rcus": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({reference: '<string>', ttl_minutes: 182, rcus: '<string>'})
};
fetch('https://api.reasonmachines.com/v3/organizations/{orgId}/ephemeral-workspaces', 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}/ephemeral-workspaces",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'reference' => '<string>',
'ttl_minutes' => 182,
'rcus' => '<string>'
]),
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.reasonmachines.com/v3/organizations/{orgId}/ephemeral-workspaces"
payload := strings.NewReader("{\n \"reference\": \"<string>\",\n \"ttl_minutes\": 182,\n \"rcus\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.reasonmachines.com/v3/organizations/{orgId}/ephemeral-workspaces")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"reference\": \"<string>\",\n \"ttl_minutes\": 182,\n \"rcus\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reasonmachines.com/v3/organizations/{orgId}/ephemeral-workspaces")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"reference\": \"<string>\",\n \"ttl_minutes\": 182,\n \"rcus\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"organization_id": "22222222-2222-4222-8222-222222222222",
"parent_organization_id": "11111111-1111-4111-8111-111111111111",
"reference": "harbor-0b6c",
"expires_at": "2026-10-03T04:00:00.000Z",
"retired_at": null,
"api_key": "ara_illustrative"
}{
"organization_id": "22222222-2222-4222-8222-222222222222",
"parent_organization_id": "11111111-1111-4111-8111-111111111111",
"reference": "harbor-0b6c",
"expires_at": "2026-10-03T04:00:00.000Z",
"retired_at": null,
"api_key": "ara_illustrative"
}{
"error": "prompt_required"
}{
"error": "missing_bearer",
"message": "Authorization required"
}{
"error": "missing_scope",
"required_scope": "sessions:read"
}{
"error": {
"type": "rate_limited",
"message": "This API key exceeded its request-rate limit"
}
}Create a single-use benchmark workspace
Creates an empty workspace for one trial, owned by the caller, with one scoped key. The parent pays for its usage: the workspace budget (rcus) is held on the parent’s wallet and settled for actual consumption after retirement; internal parents are not charged and runs use the parent’s connected provider accounts. It admits exactly one Session, created with mode ephemeral, and is retired at expiry or by the retire operation. Available only to enabled parent workspaces.
Scope:org:writecurl --request POST \
--url https://api.reasonmachines.com/v3/organizations/{orgId}/ephemeral-workspaces \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"reference": "<string>",
"ttl_minutes": 182,
"rcus": "<string>"
}
'import requests
url = "https://api.reasonmachines.com/v3/organizations/{orgId}/ephemeral-workspaces"
payload = {
"reference": "<string>",
"ttl_minutes": 182,
"rcus": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({reference: '<string>', ttl_minutes: 182, rcus: '<string>'})
};
fetch('https://api.reasonmachines.com/v3/organizations/{orgId}/ephemeral-workspaces', 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}/ephemeral-workspaces",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'reference' => '<string>',
'ttl_minutes' => 182,
'rcus' => '<string>'
]),
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.reasonmachines.com/v3/organizations/{orgId}/ephemeral-workspaces"
payload := strings.NewReader("{\n \"reference\": \"<string>\",\n \"ttl_minutes\": 182,\n \"rcus\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.reasonmachines.com/v3/organizations/{orgId}/ephemeral-workspaces")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"reference\": \"<string>\",\n \"ttl_minutes\": 182,\n \"rcus\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reasonmachines.com/v3/organizations/{orgId}/ephemeral-workspaces")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"reference\": \"<string>\",\n \"ttl_minutes\": 182,\n \"rcus\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"organization_id": "22222222-2222-4222-8222-222222222222",
"parent_organization_id": "11111111-1111-4111-8111-111111111111",
"reference": "harbor-0b6c",
"expires_at": "2026-10-03T04:00:00.000Z",
"retired_at": null,
"api_key": "ara_illustrative"
}{
"organization_id": "22222222-2222-4222-8222-222222222222",
"parent_organization_id": "11111111-1111-4111-8111-111111111111",
"reference": "harbor-0b6c",
"expires_at": "2026-10-03T04:00:00.000Z",
"retired_at": null,
"api_key": "ara_illustrative"
}{
"error": "prompt_required"
}{
"error": "missing_bearer",
"message": "Authorization required"
}{
"error": "missing_scope",
"required_scope": "sessions:read"
}{
"error": {
"type": "rate_limited",
"message": "This API key exceeded its request-rate limit"
}
}Authorizations
Your Reason API key from Settings > API. 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, automations:read, automations:write, agent_auth:read. 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.
Body
Caller trial identifier. The same request replays the same workspace and key; a different request with this reference conflicts.
1 - 200^[A-Za-z0-9._:-]+$Lifetime before the workspace is retired automatically. Defaults to 240.
5 <= x <= 360Workspace budget held on the parent's wallet and charged for actual use after retirement. Decimal string, defaults to 30, maximum 300; 0 runs only on the parent's connected provider accounts (BYOK).
Response
Replayed an identical request.
^([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)$^([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)$Key for the new workspace only. Scopes: run, sessions:read, devices:read, devices:write, devices:use, deployment:read.

