REST API client · JavaScript plugins · Local workspaces

The programmable REST client.

Send and debug API requests, organize collections and environments, then extend the client with inspectable JavaScript plugins.

macOSAvailable now
WindowsAvailable now
LinuxAvailable now
AndroidAPK available
RESTRequests, responses, collections
LocalNo account required
JSInspectable extensions
BuildAPlugin REST client in its default light theme BuildAPlugin REST client in a blue theme with a JSON response BuildAPlugin REST client in a red theme with response tools BuildAPlugin REST workspace and Theme Studio in a purple theme BuildAPlugin REST client and visual app graph builder in a green theme

See it in 24 seconds

Most REST clients stop at Send. BuildAPlugin starts there.

Watch a real request move from response inspection into JavaScript plugins, visual app building, and device workflows.

Download

Build 7 is available for macOS, Windows, Linux, and Android.

Choose the package for your platform on the download page. No account, email address, or checkout is required; protected links expire after five minutes.

Apple notarized

All current platform builds

Download the Apple-notarized universal macOS app, portable Windows x64 ZIP, tested Linux x64 archive, or signed Android APK. Build 7 has no beta expiry deadline.

Every package has its SHA-256 checksum listed on the download page. macOS is Developer ID signed and Apple notarized.
Build 7

Four packages, one workspace

The desktop builds share the same adaptable API and plugin workspace. Android is a signed tablet-focused build for direct installation.

macOS universal · Windows x64 · Linux x64 · Android APK Release artifacts were launch-tested before publication.

Everything expected from a REST client

Start sending requests immediately.

The request composer, collections, environments, imports, exports, code samples, recorder, and response viewer are enabled from the first launch.

Local REST client

Work in a local desktop workspace without creating an account or putting every request in the cloud.

Programmable API client

Add focused controls, request hooks, response handling, and saved workflow settings with inspectable JavaScript.

Collections and environments

Organize saved requests, import existing Postman-style collections, and switch reusable variable sets.

Request and response tools

Work with headers, bodies, cURL/code samples, status, response headers, and formatted response content.

Start with the job you already know

A local API client first. A custom workflow when you need it.

Use BuildAPlugin like a familiar REST client on day one. Create requests, edit headers and bodies, inspect responses, and save collections. Add plugins only when repeated work deserves its own controls or automation.

1. Send and inspect

Build requests with methods, URLs, headers, bodies, variables, saved names, and a clear response viewer.

2. Bring your API work

Import Postman-style collections with folders and keep organized workflows portable through export.

3. Turn repetition into a tool

Add a plugin that stores settings, creates focused controls, updates requests, and handles the steps you repeat.

The reason to choose BuildAPlugin

Extend the REST client instead of outgrowing it.

JavaScript plugins can add focused UI, prepare requests, inspect responses, connect steps, and persist local state. Start with the complete REST workspace and add specialist behavior only when you need it.

Add only the controls you needCreate cards, inputs, buttons, modals, tabs, and workflow panels for a specific API job.
Automate repeated request stepsUse beforeRequest and afterResponse hooks for authentication, validation, transformations, and follow-up actions.
Keep the implementation inspectableWrite plugins in JavaScript or scaffold them from natural-language instructions, then review the source and permissions.
Connect APIs to the local machineUse app-managed actions for files, clipboard, network diagnostics, Bluetooth, camera, microphone, and visible OS workflows.
BuildAPlugin JavaScript plugin graph builder collapsed beneath the active REST workspace
Advanced plugin and visual-builder tools stay available without replacing the core REST client.

Optional advanced capabilities

Keep specialist tools available without cluttering the REST workflow.

The recorder, Theme Studio, and Visual App Graph Builder remain available in collapsed sections. Native and device integrations can be added through plugins when a workflow requires them.

Record repeated API work

Capture interactions, save recordings, and turn repeatable request sequences into inspectable plugin commands.

Build focused API panels

Use the collapsed visual graph builder to connect forms, API actions, decisions, and local state.

Adapt the workspace theme

Keep Theme Studio collapsed until needed, then change the active REST workspace without rebuilding the app.

Connect local capabilities

Plugins can opt into files, clipboard, secure storage, network diagnostics, Bluetooth, camera, microphone, and visible OS hand-offs.

Keep plugin source inspectable

Review the JavaScript, declared permissions, UI transformations, request hooks, and response handlers before installation.

Developer documentation

Build plugins that feel native.

BuildAPlugin plugins are CommonJS JavaScript files that can add UI, run commands, mutate the live workspace, inspect app values, chain requests, and pass data between plugins through the plugin bus. Use this as the quick-start reference for building reliable plugins by hand or with the AI builder.

1. Minimal plugin file

Every plugin exports a `manifest`, optional `transformApp`, command handlers, and optional request/response hooks. Use stable IDs for every UI node so Inspect, Recorder, and other plugins can target your components.

module.exports = {
  manifest: {
    id: "hello-plugin",
    name: "Hello Plugin",
    version: "1.0.0",
    priority: 100,
    permissions: ["ui.transform", "plugin.storage"]
  },

  transformApp: function(app, api) {
    api.ui.remove(app, "helloPluginCard");
    api.ui.append(app, "rightPanel", {
      type: "card",
      id: "helloPluginCard",
      children: [
        { type: "text", id: "helloPluginTitle", value: "Hello Plugin" },
        { type: "button", id: "helloPluginRun", text: "Run", command: "helloPlugin.run" }
      ]
    });
    return app;
  },

  commands: {
    "helloPlugin.run": function(ctx) {
      return { __action: "showMessage", title: "Hello", message: "Plugin ran." };
    }
  }
};

2. Add UI with `transformApp(app, api)`

Use `api.ui.append`, `api.ui.prepend`, `api.ui.insertBefore`, `api.ui.insertAfter`, and `api.ui.remove` to place plugin UI in the workspace. Common targets include `rightPanel`, `mainPanel`, `pluginList`, `requestTopBar`, `headersEditor`, `bodyEditor`, `responseViewer`, `urlInput`, and `sendButton`.

Common nodes`card`, `panel`, `row`, `column`, `section`, `text`, `selectableText`, `button`, `input`, `textarea`, `dropdown`, `checkbox`, `keyValueEditor`, `tabButton`, `webview`.
Stable targetingSet `id` and `targetId` where possible. Use plugin-prefixed names like `authHelperTokenInput` instead of generic names like `input1`.
State displayRender persisted plugin values from `app.pluginData`, request fields from `app.activeRequest`, and shared values from `app.pluginBus`.

3. Command return actions

Commands return action objects. Use `multi` when you need several operations in order.

return {
  __action: "multi",
  actions: [
    { __action: "ui.setValue", targetId: "urlInput", value: "https://api.example.com/users" },
    { __action: "setFields", fields: { "activeRequest.method": "GET" } },
    { __action: "triggerTarget", targetId: "core.request.sendButton" }
  ]
};
Messages`showMessage`, `showModal`, `showForm`.
Request edits`setFields`, `setRequest`, `request.set`, `saveActiveRequestToCollection`.
Native bridges`platform.run`, `bluetooth.run`, `media.requestCamera`, `media.requestMicrophone`, `media.startAudioRecording`, `media.stopAudioRecording`.
Runtime UI`ui.setText`, `ui.setValue`, `ui.setProps`, `ui.hide`, `ui.show`, `ui.disable`, `ui.enable`.
CRUD UI`ui.append`, `ui.prepend`, `ui.replaceWith`, `ui.empty`, `ui.remove`.
Execution`triggerTarget`, `runCommand`, `sendRequestById`, `request.send`.
Files and debug`pickTextFile`, `saveTextFile`, `debug.log`, `ui.ownership.inspect`.

4. Inspect, Recorder, and `ctx.dollar` selectors

Long-press a visible element in the app and choose Inspect. Copy the exact selector or command body from the inspect panel into your plugin or into the AI builder. Recorder uses the same target model, so recorded workflows can be replayed as plugin commands.

var url = ctx.dollar("#urlInput").val();
ctx.dollar("#requestNameInput").val("Copied from URL");
ctx.dollar("#bodyEditor").val("url=" + url);
return ctx.dollar("#bodyEditor");
Read and write values`.val()`, `.val(value)`, `.text()`, `.text(value)`, `.attr(name)`, `.attr(name, value)`.
Click and state`.click()`, `.hide()`, `.show()`, `.disable()`, `.enable()`.
CRUD`.append(node)`, `.prepend(node)`, `.replaceWith(node)`, `.empty()`, `.remove()`.
Classes and loops`.addClass(name)`, `.removeClass(name)`, `.each(function(index, node) { … })`.

Supported selectors are `#id`, `.className`, type names, role names, exact `id` or `targetId`, and exact label text. Prefer Inspect-provided IDs such as `#urlInput`, `#bodyEditor`, `#response.body.line.2`, `#kvTable.Headers.add.key`, and `#core.headers.addButton`.

5. Request and response hooks

Use hooks to prepare requests, validate data, store results, or chain follow-up requests. Hooks can return a request, a response, or an action.

module.exports = {
  manifest: { id: "response-tools", name: "Response Tools", version: "1.0.0" },

  hooks: {
    beforeRequest: function(ctx) {
      ctx.request.headers["X-From-Plugin"] = "yes";
      return ctx.request;
    },

    afterResponse: function(ctx) {
      return {
        __action: "multi",
        actions: [
          { __action: "setPluginData", key: "responseTools.lastBody", value: ctx.responseBody },
          { __action: "pluginBus.output", name: "response.lastBody", value: ctx.responseBody }
        ]
      };
    }
  }
};

To send and then show the response, call `core.request.send` with an explicit `afterSendCommand`, then read `ctx.responseBody`, `ctx.response`, or `ctx.payload.response` in that command.

6. Plugin bus: pass data between plugins

The plugin bus is the shared lane for plugin-to-plugin data. Use it when another plugin, request interpolation, or the inspector should be able to see an output.

commands: {
  "authTools.publishToken": function(ctx) {
    return {
      __action: "multi",
      actions: [
        { __action: "pluginBus.output", name: "auth.token", value: "abc123" },
        { __action: "pluginBus.publish", channel: "auth.token.changed", data: { source: "authTools" } }
      ]
    };
  },

  "authTools.useToken": function(ctx) {
    var token = ctx.bus.input("auth.token", "");
    return { __action: "setFields", fields: { "activeRequest.headers": { "Authorization": "Bearer " + token } } };
  }
}
Read`ctx.bus.input(name, fallback)` or `ctx.bus.read(name, fallback)`.
Write`ctx.bus.output(name, value)` or return `pluginBus.output`.
Publish`ctx.bus.publish(channel, data)` or return `pluginBus.publish`.
InterpolatePublic bus variables are available in requests as `{{auth.token}}`.

Private bus names start with `_` or contain `.private.`, `:private:`, or `/private/`. Use clear public names like `auth.token`, `customer.selected`, `response.cleaned`, or `pluginId.outputName`.

7. Performance pattern: make hot interactions native-speed

The request tabs became dramatically faster by moving the hot path out of plugin storage and full app rebuilds. Normal tab clicks now update request/tab state in RAM, repaint a tiny native tab strip, and avoid JavaScript execution, disk saves, and app-definition rebuilds.

Slow pathJS command → `setPluginData` → save → rebuild every plugin → relayout the page.
Fast pathUpdate in-memory state → notify the small widget that changed → keep the rest of the workspace still.

Plugin authors should use this principle too: use full `transformApp` rebuilds for structure, and lightweight runtime mutations for frequent interactions like tab switching, accordions, typing, selection, filters, hover state, and temporary workflow state.

// Good for frequent UI changes:
return { __action: "ui.setValue", targetId: "requestNameInput", value: "Fast update" };

// Good for durable settings:
return { __action: "setPluginData", key: "myPlugin.settings", value: { enabled: true } };

// Avoid this for every click or keystroke:
return { __action: "refresh" };

Rule of thumb: persist what must survive restart; keep temporary UI state in runtime memory; use `ui.*` mutations and `ctx.dollar` for immediate effects; rebuild only when the plugin’s structure actually changes.

Built for real API work.

BuildAPlugin starts as a practical REST workspace. Plugin and theme capabilities remain available when the standard request workflow needs to go further.

Successful HTTP 200 response in BuildAPlugin's blue theme
Send a real request and inspect its status, JSON body, and response headers.
The same BuildAPlugin API response recoloured with Theme Studio
Optional Theme Studio controls can adapt the same active REST workspace.
BuildAPlugin visual device workflow with connected inspection steps
Open the optional visual builder when repeated API work deserves a focused tool.

Start with the local API client. Extend it when your workflow demands more.

The free download requires no account or checkout. Pro access, licensing, and business rollout remain available through the store when paid plans launch.

BuildAPlugin The programmable REST client.