The three places
A request opens its connection in one of three places. They are roles, not machines: the same setting means the same thing on every device.
Automatic is the default everywhere: the request runs on this device
when it can, otherwise on the one place that can. The place button shows
the resolved place, never the word “Automatic”.
The matrix
Which places can open a request depends only on the transport the request needs — a raw TCP socket, HTTP/2 trailers, a node-only knob — and on which places are connected right now.
An alternative is offered only while that place is connected: the
desktop app’s row appears when the extension is paired with a running
app, the server’s row when the workspace’s server is reachable.
A session over the browser socket cannot apply the node-only knobs —
custom handshake headers, disabled SSL verification, the credential’s
handshake header. The place button names the ones the request has set, so you
can move the session to a place that applies them.
Choosing a place
A place names this device’s topology — the desktop app on this machine, the server this device is signed in to — so it is kept on this device and never syncs to anyone else. Two layers, the more specific one winning:- The request. Click the place button and pick a row under Run on. The popover lists every place this surface knows — Browser extension, Desktop app, Server — each with its mark; the ones that cannot run the request stay visible but disabled, with the reason and the way to fix it (open or download the desktop app, open Backup and Sync for a server, or Available in a server workspace for a personal one). In a served browser tab the Browser extension and Desktop app rows are there for discovery alone — a tab reaches neither — under Install and Download; the tab’s one place is its server. A pick is a draft edit: the request runs there at once, and Save keeps it — with the request, on this device. The Runs on row on the request’s Settings tab is the same value; Reset to automatic in the popover clears it.
- Global. Settings › API Requests › Where requests run › Execution place, applying to every kind: Automatic and the same places the picker lists on this surface, in the same words. A request with no place of its own follows it; the picker selects the place it resolved to and offers no Reset to automatic. The served tab has one place, so it carries no global row.
mqtts://
session or a gRPC call on the extension — the disabled Send,
Connect or Invoke button says so on hover and offers Choose
where it runs, which opens the same popover: the desktop app, or a
server where no desktop app can be installed.
What a delegated send carries
The surface you sit at is the request’s context. It resolves everything it holds — variables, the environment, vault secrets, TOTP codes, client certificates, files, cookies, the pre-request script — and only then hands the fully resolved request to the chosen place, which opens the connection and streams the raw response or frames back. The context does everything after: the post-response script, cookie capture, publish-on-run, the saved response. Where the resolved values travel is stated in the place button’s popover:- To the desktop app on this device — nothing the vault does not already sync there. The popover reads “Runs on the desktop app. This browser fills in the request first, then hands it to the desktop app on this computer, which opens the connection.”
- To the server — the resolved values, secrets included, travel to it, as they would through any agent or proxy. The popover reads “Runs on server. The request is filled in here first, variables and secrets included, then sent to server, which opens the connection.”
{{vault.…}} reference the context does not hold fails before the
send leaves, with the message and the action to unlock it here — the
requirement is always on the surface you send from, never on the
place.
Scripts run where you are
Pre-request and post-response scripts run in the context, never at the place, whatever the place’s own script posture:- The extension runs them in its sandboxed Safe runtime.
- The desktop app runs them under the mode you choose on the request’s Settings tab — Safe mode or Developer mode, per workspace, on this device only.
- The web app runs them in the tab’s own sandboxed Safe runtime —
the
oh.*script API only, no filesystem, no process access, no module loader. A browser tab has no Developer mode, so the Settings tab states Safe mode as a fact rather than offering a choice.
Consent, attribution, refusal
The place that opens a connection on another surface’s behalf decides whether it does so. In the desktop app, under Backup and Sync › Your devices, two switches gate it: Allow this device’s browsers to send requests (on by default — pairing is the consent) and Allow other connected devices to send requests (off by default). A server has the same two tiers with the opposite default for other devices: it exists to serve the people it admitted, so Let connected devices run requests on this server starts on, and an admin turns it off or on under Server Admin › Server (headlessly,ohd config set backend.allowRemotePeerExecute false while the daemon is stopped).
Sending also requires write access to the request’s workspace at that
place, and every delegated send is audited there.
The device sending has a say too. A send to a server carries the
request fully resolved, secrets included, so Settings › API Requests
› Run requests on a server (on by default, never synced) lets you keep
every request from this device off any server: the Server place then
reads Turned off in Settings with a link back to the row, Automatic
never resolves to it, and a request that asked for the server says so
instead of running.
Every response and every session timeline says which place answered:
Sent from name on the meta strip, with the details in its popover.
A place that refuses shows the refusal on the response itself, naming
the switch to turn on and where — never a silent failure.
When the place button asks for the desktop app
On the extension, a request that no connected place can open — anmqtts:// session or a gRPC call with neither the desktop app nor the
workspace’s server connected — turns the place button the warning
colour and says Needs the desktop app on hover. The popover’s
action follows what is installed:
Composing and saving the request works regardless; only the connection
waits. For MQTT, switching the address to
ws:// or wss:// runs the
session here instead.