Docs menu

Reach a Workbench over HTTP

Goal: Call a hosted workbench's tools from any HTTP client: curl, Postman, or a backend.

A hosted workbench with its API mode on serves every tool method as a REST route. The author declares no routes: the same .Tools({...}) declaration that the MCP mode shows as tools, the API mode shows as paths. This page is for the caller. The overview of all three modes is Reach a Hosted Workbench.

Before you start

  • A hosted workbench with the API mode on: see Host Your Own Workbench.
  • A key from APIs -> API Keys, while the workspace's API identity (set in the API Manager) is Team (the default) or Hybrid. It needs no particular access right. Under App Identity, team keys are turned away and a caller needs an access token from an App Identity you trust.
  • Any HTTP client. Make the call from a server, not from a page: the key travels with every request, and code that runs in a visitor's browser shows it to the visitor.

The address

https://openx.fathym.com/ox-api/w/<workspace id>/workbenches/<apiSlug>/API/<tool>/<method>

Every tool method is a POST route. The tool and method names are lowercased in the path (a tool called Hello with a method Greet is .../API/hello/greet), and spaces in a tool name become hyphens. The API segment is the mode's key and is case-sensitive. The slug in the examples (api-sample) is a stand-in: use your own workbench's APISlug. <workspace id> is the ID shown in Workspace -> Settings.

Call it

curl -X POST 'https://openx.fathym.com/ox-api/w/<workspace id>/workbenches/api-sample/API/hello/greet' \
  -H 'Authorization: Bearer <YOUR_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{"arg0": "world"}'

The same call from code:

const res = await fetch('https://openx.fathym.com/ox-api/w/<workspace id>/workbenches/api-sample/API/hello/greet', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ arg0: 'world' }),
});

How arguments are sent

The body is a JSON object, and its shape follows how the method was declared:

The method takesSend
One object argumentThe object's fields directly: { "field": value, ... }
One or more plain valuesPositional keys: { "arg0": ..., "arg1": ... }
A tool the author gave no input schemaOne field holding JSON as text: { "input": "{\"id\": 7}" }

The first two rows cover a tool with a declared input schema. A tool that needs set-up before its methods run also accepts a Setup field in the body. The catalog below does not list argument names: they come from the author's code, so ask the author, or read the workbench's source.

The OpenAPI catalog

Every API-mode workbench describes its own routes:

GET https://openx.fathym.com/ox-api/w/<workspace id>/workbenches/<apiSlug>/API/openapi.json

It takes the same Authorization header as every other call. It lists each route with its summary, and its request and response bodies are empty objects: it carries no argument names and no types. Save it, then feed it to anything that reads OpenAPI:

curl 'https://openx.fathym.com/ox-api/w/<workspace id>/workbenches/api-sample/API/openapi.json' \
  -H 'Authorization: Bearer <YOUR_TOKEN>' -o api-sample.openapi.json

npx @hey-api/openapi-ts --input api-sample.openapi.json --output ./src/generated

The second command makes a TypeScript client with one function per route; its bodies are untyped, because the catalog has no schemas. It is an example of a generator, not part of OpenX. To explore the routes in Postman, import the saved file, and add the Authorization header at the collection level. Insomnia, Bruno and other OpenAPI tools work the same way.

In the API Manager

APIs -> API Manager -> Workbench APIs lists each workbench with its API mode on: the Base URL, and each route with a cURL line. The tab reads the catalog once, during the deploy. If it still says "No route catalog yet" after the deploy, deploy again; the live .../API/openapi.json above answers whenever the container is up.

One declaration, three doors

The API and MCP modes read the same tool declaration. Turn on both for one workbench and every method is both a REST route and an MCP tool, with the same code behind it. Each enabled mode runs in its own container.

What a call is checked against

Every call needs the key (the Authorization header). No access right is required: a caller the API identity admits reaches every route of every mode that is on. There is no per-mode or per-route right today.

If something's off

IssueDo
The client cannot connectCheck the address. The API segment is case-sensitive and must be a mode the workbench has turned on
401The key has expired, or the API identity is App Identity, which turns team keys away. Make a new key, or use an App Identity token
404 on a routeThe path is the tool name and method name, lowercased. Read the catalog to see what is served
An empty catalog in the API ManagerDeploy again. The tab reads the catalog once, during the deploy. The live .../API/openapi.json works whenever the container is up
503"is not deployed yet": the mode has no container yet. Deploy the workspace, or wait for a deploy that is running to finish
The first call after a quiet spell is slowA mode with a web address can scale down to no containers when idle (the default). The first call starts one; later calls are quick. Set Min replicas to 1 in the Hosting tab to keep one running
Arguments do not arriveMatch the table above: an object argument is sent as fields, plain values as arg0, arg1

Next steps

On this page