v0.5 Ask Claude, right inside the request

The API client
that weighs nothing.

ApiForge is a fast, local-first alternative to Postman. Collections, environments, a smart variables inspector, and a Claude sidekick that reads your requests — in a single 24 MB binary.

  • No account required
  • Postman import
  • MIT-licensed core
ApiForge — Billing API / List users
GET
https://api.acme.dev/v1/users?limit=25
Send
Params 3 Headers Auth Tests 200 · 142 ms · 3.1 kB
1 {
2 "data": [
3 { "id": "usr_8Kd2", "plan": "pro" },
4 { "id": "usr_1Qp7", "plan": "team" }
5 ],
6 "meta": { "total": 128, "has_more": true }
7 }
C Ask Claude

Response is paginated. Want me to add a cursor loop and save as a runner script?

Add loop Explain

A senior engineer reviewing every response.

Claude reads the request, the headers, and the body — then answers plainly. Ask why a 401 came back, generate a JSON-schema assertion, or turn a manual retry into a runner script.

  • Explain any status code with the exact header or body field to blame.
  • Generate assertions, mock data, and runner scripts in one turn.
  • Detect drift between environments and propose a variable fix.
  • Runs on your Anthropic key — nothing leaves your machine without it.
C claude · sonnet 4.5 context: request + response

Why is this endpoint returning 401 only in staging?

Your Authorization header uses {{prod_token}}, but the active environment is staging. Swap the variable to {{staging_token}}, or scope the token per-env.

Apply fix Show diff

Write a test asserting every user has an id and plan.

test("users have id + plan", () => { const rows = res.body.data; expect(rows).toBeArray(); for (const u of rows) { expect(u.id).toStartWith("usr_"); expect(u.plan).toBeOneOf(["free","pro","team"]); } });
Ask about this request…
Environment staging 12 vars
KEY VALUE SCOPE TYPE
base_url https://api.acme.dev/v1 global url
staging_token sk_stg_••••••••••••3fa2 secret staging secret
user_id {{ $randomFrom(user_ids) }} request dynamic
limit 25 staging int
prod_token sk_prd_••••••••••••8ac1 secret production secret
timeout_ms 5000 global int

Type {{token}}. See what resolves.

Every variable is scoped, typed, and previewed inline. Hover to see the resolved value; secrets stay masked in the URL bar and never touch your clipboard by accident.

SCOPES
Global · env · request

A predictable resolution order, shown next to every value.

TYPES
Typed, not stringly

url, int, secret, dynamic — validated before Send fires.

SECRETS
Masked by default

Never logged, never copied, never synced to the cloud unless you say so.

DYNAMIC
Functions, inline

randomFrom(), now(), jwt() — plus any JS you paste in.

The parts you already know from Postman — quieter, faster, on your machine.

Collections

Nested folders, drag to reorder, one-command Postman v2.1 import.

Runner

Sequence requests, iterate over CSV, assert responses. Runs offline.

Environments

Swap staging ↔ production with one keystroke. Diffs shown inline.

WebSocket & SSE

Persistent streams and Server-Sent Events with the same UI as REST.

Command palette

⌘K anywhere: jump to a request, run a test, ask Claude, change env.

Git-friendly

Collections and vars are plain JSON — reviewable in a PR, mergeable, diffable.

24 MB App size, cold. Postman 12 is 380 MB.
92 ms Median cold-start on M1. Under 200 ms on Win.
3 keys From open → typing a request. ⌘N · ⌘L · ⏎.
0 syncs Your data stays on disk until you connect a repo.

Completely free. No catch.

Every feature, every update, zero cost. If ApiForge saves you time, you can buy us a coffee.

Ship your next request in 30 seconds.

Free forever for personal use. No sign-up wall between you and Send.

First launch on macOS? See install guide (unsigned app).