SynapseOrch 2.0 is a release candidate; the stable release is 1.9.3. How to try 2.0

REST API Tools

A REST API tool wraps an HTTP endpoint as an agent tool. The agent provides the parameters, SynapseOrch makes the HTTP call, and the response is returned to the agent as the tool result.

Registering a REST API tool

Open Apps › Tools, press New tool and choose HTTP request (Python code builds a Python tool). Self-hosted, New Tool opens the editor in its HTTP mode; the other mode, Python, builds a Python tool.

The screens, step by step: Tools, in the Guides.

Fields

FieldDescription
General NameSelf-hosted only. Human-friendly name (e.g. Process Orders)
NameTool identifier the agent sees (e.g. process_orders); self-hosted, System Name (Snake Case)
DescriptionSelf-hosted, Description (For AI). What the tool does and critical rules — the agent reads this to decide when to call it
MethodPOST, GET, PUT or DELETE, and on Cloud PATCH
GroupOptional. A tool group to put it in, or a new one
n8n WorkflowSelf-hosted only. Shown once an n8n API key is saved. Picking a workflow fills in its webhook URL — see n8n
URLEndpoint URL. Type {{ to insert an argument or a variable
Request bodyOptional. What to send for POST and PUT — see below
HeadersKey/value pairs; add rows with Add header. Values may use {{ … }}
Input schemaSelf-hosted, Input Schema (JSON). JSON Schema describing what the agent must pass — see below

Click Save when done (on Cloud, Create for a new tool). The name and URL are required.

Input schema

The input schema is a literal JSON Schema describing the tool's arguments; the agent reads it to construct valid calls. A new tool starts with a single string argument, input. For example:

{
  "type": "object",
  "properties": {
    "city": {
      "type": "string",
      "description": "City name to get weather for"
    },
    "units": {
      "type": "string",
      "description": "metric or imperial"
    }
  },
  "required": ["city"]
}

What the tool says it does

Three answers on the tool tell your tool policy what a call does, so a risky call can wait for a person before it runs:

  • What it does: Reads only, Changes something or Deletes something.
  • Safe to repeat: calling it twice changes nothing the first call didn't. If it isn't, a workflow won't send the call again after a timeout. A tool that only reads can always be asked again.
  • Reaches outside this workspace: it talks to a system this workspace doesn't control.

An HTTP tool takes its method's answers until you say otherwise — the editor names where they came from, such as Set from GET api.example.com. Change them if that's wrong. — and Use the method's puts them back:

MethodWhat it doesSafe to repeatReaches outside
GET, HEAD, OPTIONSReads onlyYesYes
PUTChanges somethingYesYes
POST, PATCHChanges somethingNoYes
DELETEDeletes somethingYesYes

Every HTTP tool reaches outside until you untick it. For an address inside your network the editor says so: Untick "Reaches outside" if what it calls goes no further.

A tool made before these answers existed reads Not set until it is saved; saving gives it its method's answers.

URL and body templating

Reference the agent's arguments and your variables with double braces:

ReferenceMeans
{{ city }}The city argument
{{ body.data }}A key inside an argument
{{ args }}All the arguments, as JSON
{{ global.api_base }}A variable from Settings → Variables

{{ … }} works in the URL, the request body and header values. The older single-brace {city} still works in the URL only — in a body or header it is sent literally.

A variable reference that can't be resolved is left as written, so a missing variable shows up in the request rather than silently disappearing. Arguments are stricter:

  • A missing argument fails the call, and nothing is sent. The agent is told which: The call left out the argument city, which this tool's URL needs. Nothing was sent; call it again with it.
  • An optional argument that is a query parameter's whole value — ?page={{ page }} — is left out of the URL when the agent does not send it, rather than sent empty.

Where the arguments go

  • GET and DELETE — arguments the URL didn't use are sent as query parameters, after any query the URL already has. There is no body; a DELETE ignores the Request body field.
  • POST and PUT, Request body empty — arguments the URL didn't use are sent as the JSON body.
  • POST and PUT, Request body {{ body }} (one reference and nothing else) — that argument is the body.
  • POST and PUT, anything else — a JSON template. Put a reference where a value goes: {"text": {{ message }}} or {"text": "{{ message }}"} both send the message as a JSON string, and an object stays an object. A reference inside a longer string, such as "Hello {{ name }}", makes the template invalid JSON, and the body is then sent as plain text.
URL:  https://api.example.com/users/{{ user_id }}/posts?page={{ page }}
Body: {"title": {{ title }}, "content": {{ content }}}

What happens on a call

  • The request goes out with a 30-second timeout (SYNAPSE_HTTP_TOOL_TIMEOUT). Redirects are not followed.
  • Addresses on your own network are refused: loopback (localhost, 127.0.0.1), private ranges (10.x, 192.168.x, …), link-local — including cloud metadata endpoints — and shared address space. The error names the host and says to add it to the EGRESS_ALLOW_HOSTS environment variable (comma-separated) and restart, which is how you call a service on your own network. See Environment Variables.
  • The response is returned to the agent whatever its status code — a 404 or 500 body reaches the agent as the result, so describe error handling in the tool's description if it matters. In a Tool step, a 4xx or 5xx fails the call instead. A JSON response is returned as JSON; anything else as text.
  • A response longer than the vault threshold is saved to the vault, and the agent receives a reference to the file.

Worked examples

Each example ends with the tool as SynapseOrch stores it — the editor fills this in as you complete the form.

Weather API

  • General Name: Get Weather
  • Name: get_weather
  • Description: "Get current weather for a city"
  • Method: GET
  • URL: https://api.openweathermap.org/data/2.5/weather?appid={{ global.openweather_key }}
  • Input schema: q (required string, the city), units (optional string)

Neither argument appears in the URL, so both are sent as query parameters under their own names — which is why the schema uses the API's parameter name q rather than city.

Advanced: stored tool JSON

{
  "name": "get_weather",
  "generalName": "Get Weather",
  "description": "Get current weather for a city",
  "tool_type": "http",
  "method": "GET",
  "url": "https://api.openweathermap.org/data/2.5/weather?appid={{ global.openweather_key }}",
  "headers": {},
  "inputSchema": {
    "type": "object",
    "properties": {
      "q": { "type": "string", "description": "City name" },
      "units": { "type": "string", "description": "metric or imperial" }
    },
    "required": ["q"]
  }
}

Internal API with auth header

  • General Name: Get Customer
  • Name: get_customer
  • Method: GET
  • URL: https://api.internal.company.com/customers/{{ customer_id }}
  • Headers: Authorization: Bearer {{ global.crm_token }}, X-App-Version: 2.0
  • Input schema: customer_id (required string)

api.internal.company.com must resolve to a public address, or be listed in EGRESS_ALLOW_HOSTS.

Advanced: stored tool JSON

{
  "name": "get_customer",
  "generalName": "Get Customer",
  "description": "Fetch customer record by ID from our CRM",
  "tool_type": "http",
  "method": "GET",
  "url": "https://api.internal.company.com/customers/{{ customer_id }}",
  "headers": {
    "Authorization": "Bearer {{ global.crm_token }}",
    "X-App-Version": "2.0"
  },
  "inputSchema": {
    "type": "object",
    "properties": {
      "customer_id": { "type": "string", "description": "Customer UUID" }
    },
    "required": ["customer_id"]
  }
}

Webhook trigger (Slack)

  • General Name: Send Slack Alert
  • Name: send_slack_alert
  • Method: POST
  • URL: {{ global.slack_alerts_webhook }}
  • Request body: {"text": {{ message }}}
  • Input schema: message (required string)

Advanced: stored tool JSON

{
  "name": "send_slack_alert",
  "generalName": "Send Slack Alert",
  "description": "Send an alert message to the #alerts Slack channel",
  "tool_type": "http",
  "method": "POST",
  "url": "{{ global.slack_alerts_webhook }}",
  "headers": {},
  "body": "{\"text\": {{ message }}}",
  "inputSchema": {
    "type": "object",
    "properties": {
      "message": { "type": "string", "description": "Alert message text" }
    },
    "required": ["message"]
  }
}

Authentication

Keep secrets in Variables and reference them, rather than pasting them into the tool:

MethodHow to configure
Bearer tokenHeader Authorization: Bearer {{ global.my_token }}
API key headerHeader X-API-Key: {{ global.my_key }}
Query parameterIn the URL: ?api_key={{ global.my_key }}
No authLeave headers empty

Testing

REST API tools have no test button. To check templating and auth, give the tool to an agent and ask for a call in Chat — the Chat view shows the tool call and the response the agent received.

On this page