See it in action

Examples

A few representative workflows, captured from the real app running against a local demo API.

Helena's Chain tab running a login request before the leaf

Compose and send a request

Pick a method, type a URL (with {{variables}}), fill in a body, hit Send. The response panel pretty-prints JSON with structured folding, search, and a raw view - and shows the status, size, and timing.

The Helena desktop app: a collection sidebar, a POST request with a JSON body, and the 201 Created response
A POST with a JSON body and the 201 Created response, alongside the collection sidebar.

Authenticate, nine schemes

Open the Auth tab and choose a scheme - Basic, Bearer, API Key, OAuth 2.0 (incl. auth-code + PKCE), OAuth 1.0a, WSSE, AWS SigV4, Digest, or NTLM. Credentials can come from {{variables}}, so secrets stay out of the collection YAML.

The Helena Auth tab set to Bearer Token, with the token sourced from a variable, and a 200 OK response
A Bearer token sourced from {{TOKEN}} - resolved on the wire, never written to disk.
// Post-response script
test("profile looks right", function () {
  expect(response.status).toBe(200);
  expect(response.json.role).toBe("admin");
  expect(response.json.tags).toContain("founder");
});

Headers, variables & a structured response

Add request headers (with {{$guid}} and other dynamic values), then read the response back as a folding JSON tree with search.

The Helena Headers tab with an Accept and an X-Request-Id header, and a nested JSON response
Request headers including a dynamic {{$guid}}, and a nested JSON response.

Chain requests together

A request can run other requests first. On the Chain tab, name a prior request by its path and give it an alias; Helena runs it before the leaf and binds the result as chain.<alias> for your headers, body, and scripts. So you can log in and place an order in a single Send - no copy-paste, no juggling tokens by hand.

Helena's Chain tab: a Place order request that runs Auth/Login first (aliased auth), with the 201 Created order response
"Place order" runs "Auth/Login" first (aliased auth); the order then reuses the login token and comes back 201 Created.

Reference the chained response anywhere a {{variable}} works - here, the token straight into an Authorization header:

Authorization: Bearer {{chain.auth.response.json.token}}

…or reach it from a script:

// Pull a value out of an earlier request's response
const token = chain.auth.response.json.token;

// Or stash it from the login's own post-response script, then use it by name
helena.env.set("TOKEN", response.json.token);   // -> {{TOKEN}} anywhere

Stream a WebSocket feed

Enter a wss:// URL and press Send - Helena opens a live session. Type messages to send; received messages stream into the transcript. Pings are answered automatically and fragmented messages are reassembled. Server-Sent Events have their own control: point at a text/event-stream endpoint and press Stream (SSE) - events append live into the response view.

Run a collection in CI

Run the whole collection headlessly - same resolution, scripts, and assertions as the GUI - and gate your pipeline on the exit code:

helena run ./collections/acme --env Staging
# exits non-zero if any request errors or any check fails

# machine-readable output for CI dashboards:
helena run ./collections/acme --format junit > report.xml
helena run ./collections/acme --format json  > report.json
ok    Users/Get user               GET    200  3ms
ok    Users/Create user            POST   201  5ms
        PASS  profile looks right
2 requests, 1 checks passed, 0 failed

The screenshots above are real captures of the app rendered against a local demo API - regenerate them any time with make screenshots (see website/README.md).