curl --request DELETE \
--url https://api.reasonmachines.com/v3/organizations/{orgId}/plugins/{slug} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.reasonmachines.com/v3/organizations/{orgId}/plugins/{slug}"
headers = {"Authorization": "Bearer <token>"}
response = requests.delete(url, headers=headers)
print(response.text)const options = {method: 'DELETE', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.reasonmachines.com/v3/organizations/{orgId}/plugins/{slug}', 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}/plugins/{slug}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
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}/plugins/{slug}"
req, _ := http.NewRequest("DELETE", 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.delete("https://api.reasonmachines.com/v3/organizations/{orgId}/plugins/{slug}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reasonmachines.com/v3/organizations/{orgId}/plugins/{slug}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"ok": true,
"removed": [
{
"connection_id": "<string>",
"adapter": "mcp",
"scope": "personal"
}
],
"removed_skills": [
"<string>"
],
"plugin": {
"slug": "<string>",
"name": "<string>",
"description": "<string>",
"icon": "<string>",
"source": "curated",
"auth_type": "none",
"secret_names": [
"<string>"
],
"scope": "personal",
"supported_scopes": [
"personal"
],
"connectable": true,
"setup": {
"code": "<string>",
"owner": "<string>",
"message": "<string>"
},
"docs_url": "<string>",
"website_url": "<string>",
"verified": true,
"bundled_skills": [
{
"slug": "<string>",
"name": "<string>",
"description": "<string>",
"installed": true,
"installed_scopes": [
"personal"
]
}
],
"installed": true,
"mcp_server_id": "<string>",
"connection_state": "<string>",
"connection_checked_at": "<string>",
"accounts": [
{
"connection_id": "<string>",
"adapter": "mcp",
"mcp_server_id": "<string>",
"scope": "personal",
"reason_id": "<string>",
"account_id": "<string>",
"account_name": "<string>",
"connection_state": "<string>",
"connection_checked_at": "<string>",
"connection_error_code": "<string>",
"enabled": true,
"can_manage": true,
"reason_mode": "member"
}
]
}
}{
"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"
}
}Uninstall a plugin
Removes one installation of a plugin: mcp_server_id (or connection_id for a native connector) names it, or scope picks the caller’s personal one or the workspace’s (reason_id with scope=reason a Reason’s). With exactly one manageable installation neither is needed; with several it answers 409 listing them. Removing an MCP installation revokes its OAuth grant at the provider where supported and records connection.removed. Its bundled skills installed in the same scope are removed too unless keep_skills=true, or another installation of the plugin still uses them (an installation in the same scope, or the workspace’s shared skills for a legacy personal or Reason installation). Requires managing the installation (installation-policy: owners and admins, or the member who installed a personal one).
mcp:writecurl --request DELETE \
--url https://api.reasonmachines.com/v3/organizations/{orgId}/plugins/{slug} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.reasonmachines.com/v3/organizations/{orgId}/plugins/{slug}"
headers = {"Authorization": "Bearer <token>"}
response = requests.delete(url, headers=headers)
print(response.text)const options = {method: 'DELETE', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.reasonmachines.com/v3/organizations/{orgId}/plugins/{slug}', 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}/plugins/{slug}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
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}/plugins/{slug}"
req, _ := http.NewRequest("DELETE", 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.delete("https://api.reasonmachines.com/v3/organizations/{orgId}/plugins/{slug}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reasonmachines.com/v3/organizations/{orgId}/plugins/{slug}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"ok": true,
"removed": [
{
"connection_id": "<string>",
"adapter": "mcp",
"scope": "personal"
}
],
"removed_skills": [
"<string>"
],
"plugin": {
"slug": "<string>",
"name": "<string>",
"description": "<string>",
"icon": "<string>",
"source": "curated",
"auth_type": "none",
"secret_names": [
"<string>"
],
"scope": "personal",
"supported_scopes": [
"personal"
],
"connectable": true,
"setup": {
"code": "<string>",
"owner": "<string>",
"message": "<string>"
},
"docs_url": "<string>",
"website_url": "<string>",
"verified": true,
"bundled_skills": [
{
"slug": "<string>",
"name": "<string>",
"description": "<string>",
"installed": true,
"installed_scopes": [
"personal"
]
}
],
"installed": true,
"mcp_server_id": "<string>",
"connection_state": "<string>",
"connection_checked_at": "<string>",
"accounts": [
{
"connection_id": "<string>",
"adapter": "mcp",
"mcp_server_id": "<string>",
"scope": "personal",
"reason_id": "<string>",
"account_id": "<string>",
"account_name": "<string>",
"connection_state": "<string>",
"connection_checked_at": "<string>",
"connection_error_code": "<string>",
"enabled": true,
"can_manage": true,
"reason_mode": "member"
}
]
}
}{
"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, devices:read, devices:write, devices:use, computers:read, computers:write, ssh:write, knowledge:read, memory:read, memory:write, skills:read, skills:write, pages:read, pages: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. devices:write, devices:use, computers:read, computers:write, ssh:write, network:read and network:write are opt-in, excluded from default keys. computers:read lists visible cloud and connected computers without waking them or granting execution access. devices:read discovers local Device targets; devices:use separately consents to local execution, so a discover-and-run local workflow needs both. devices:write manages enrollment and device grants; computers:write creates or deletes cloud computers; ssh:write manages retained SSH access. 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).

