The developer's HTTP client.
It sends the request and shows you the DNS lookup, the TCP connect, the TLS handshake, the certificate chain and every byte in both directions — because when a request misbehaves, the body is the last place the answer is.
Free while in beta · No account · No telemetry
- REST & HTTPEvery method, body type and auth scheme
- GraphQLSchema-aware completion and docs
- SOAPWSDL import, envelopes, faults
- WebSocketUpgrade, frames, close codes
- Raw socketsTCP with the bytes shown
- Load testingConcurrency and percentiles
A request is a conversation, not a return value.
This is genuine output from Sendwire's engine — not a mock-up, not a redraw. It is what the Wire tab prints for a single GET.
0.3 * Resolving hostname api.github.com 40.5 * api.github.com → 140.82.116.5 (IPv4) 80.2 * Connected to api.github.com (140.82.116.5) port 443 80.2 * ALPN: offering http/1.1 127.6 * TLS handshake complete 127.6 * version: TLSv1.3 127.6 * cipher: TLS_AES_128_GCM_SHA256 127.6 * key exchange: X25519 253 bits 127.6 * Server certificate: 127.6 * subject: CN=*.github.com 127.6 * issuer: CN=Sectigo Public Server Authentication CA DV E36 127.6 * expire date: Sep 29 23:59:59 2026 GMT (59 days remaining) 127.6 * certificate verify ok. 127.6 * chain depth: 4 127.6 > GET /repos/nodejs/node HTTP/1.1 127.6 > Accept: */* 127.6 > Host: api.github.com 377.1 < HTTP/1.1 200 OK 377.1 < Content-Type: application/json; charset=utf-8 377.1 < Strict-Transport-Security: max-age=31536000
-
Where the time actually went
A waterfall splitting DNS, TCP, TLS, time-to-first-byte and download. When a call is slow, this is the difference between a slow server and a slow handshake.
-
The certificate chain, in full
Subject, issuer, validity, SANs and chain depth for every hop. Expiry is counted in days, because that is the number you actually needed.
-
Connection reuse, made visible
Whether keep-alive held, which IP answered, which ALPN protocol was agreed. A benchmark that silently reconnects every time is measuring the wrong thing.
-
Redirects you can inspect
Every hop is kept, with the method rewrites and the credential drops that RFC 9110 requires — rather than one opaque final answer.
Sep 29 23:59:59 2026 GMT is not a number
anyone can act on while looking at it.
Coming from Postman? Your collections come with you.
Folders, variables and — the part that usually does not survive a move — your scripts, rewritten rather than dropped. Postman exports one collection per file, so it is one import each.
Postman collections
v2 collections, with pre-request and post-response scripts rewritten from
pm to sw on the way in. If one slips through, the editor
underlines it and offers to convert it — you never find out at send time.
Environments export separately from Postman, and import separately here.
OpenAPI 3
JSON or YAML, grouped by tag, with parameters and body examples filled in.
WSDL
Every operation as a request, envelope scaffolded and SOAPAction set.
cURL
Paste a command — or whatever your browser's “Copy as cURL” gave you.
HAR
A browser's network export, browsable. Click any request to open it exactly as it was sent, with the recorded response already on screen.
Not yet: Swagger 2.0
Detected and refused rather than half-read — host, basePath and body parameters differ enough that guessing would send quietly wrong requests. Convert to OpenAPI 3 first.
REST is the easy half.
Most clients treat anything that isn't JSON over HTTP as somebody else's problem. Sendwire was built by someone who still has to call SOAP services.
SOAP & WSDL
Point it at a WSDL and every operation arrives as a request with the envelope scaffolded, SOAPAction set and 1.1/1.2 handled properly. Faults are parsed, not printed as XML soup.
OpenAPI & cURL
Import an OpenAPI 3 document and get a collection grouped by tag. Paste a cURL command and get a request. Export any request back out as cURL, or as code in thirteen languages.
WebSocket & raw sockets
The upgrade exchange in full, then frames in both directions with opcodes and payloads. Send text or binary from hex. Close with a code the server actually sees.
Auth that works
OAuth 2 with PKCE, mutual TLS with a client certificate, AWS SigV4, JWT, bearer, basic and API keys — plus an HTTP proxy when you need to sit behind one.
A real command line
Run a suite, a collection or a folder from CI. JSON and JUnit reporters, CSV or JSON data files, and a non-zero exit when anything fails — so it can gate a build.
Bring your collections
Postman collections import with their scripts translated, not discarded. Point it at a browser's HAR export too, and pick the handful of calls you care about out of the network trace.
101 and every header that came back with it —
then frames in both directions, each with its opcode and its size. The payloads are
heartbeats off a public market-data feed, a second apart. The next message sits in
the composer above, unsent.
Scripts are JavaScript. All of it.
Not a template language, not a subset, not a builder UI with an escape hatch. If it runs in JavaScript, it runs here — and the editor colours it with VS Code's own grammar and themes.
// Capture the session token for the next request. const data = sw.response.json().data; sw.environment.set("token", data.token); // Sign the next call — no declarative form could express this. sw.environment.set("sig", sw.crypto.hmacSha256( sw.environment.get("apiSecret"), JSON.stringify(data.user) )); for (const key of Object.keys(data)) { if (/^user_/.test(key)) sw.console.log(key); } sw.test("session is active", () => { sw.expect(sw.response.code).to.equal(200); });
-
Autocomplete from the real response
Type
response.json().and the fields offered are the ones the last response actually returned — with their types and their current values, not a guess from a schema. -
One namespace, and it's
swImporting a Postman collection rewrites
pmautomatically. Type it anyway and the editor underlines it before you ever hit send. -
Export it and run it anywhere
A suite exports to a standalone Node script that carries your scripts across verbatim — because it runs the same JavaScript, rather than trying to reconstruct your intent.
nodejs/node,
and 36,286 forks — read straight back out of the GET this page opens with.
Load testing, built in.
Chain requests into a suite so a value captured in one is spent by the next — then point a load test at that same suite. No second tool, no exporting to something else, no writing a k6 script to find out whether it holds up.
-
Real concurrency, real numbers
Fifty virtual users, or a fixed arrival rate if you want to know whether a service sustains one. Whatever cannot be dispatched on schedule is reported as a shortfall rather than quietly absorbed.
-
Checks, not just status codes
Assert on the body of every response. A service under load will happily answer 200 with an error page, and a run that only counted status codes would call that a pass.
-
Where the time actually went
DNS, TCP, TLS, time-to-first-byte and download, broken out across the whole run — so "it got slow" becomes "the handshake got slow".
Export it — to twelve languages, or a script that runs anywhere.
A request becomes cURL, Python, Go or any of ten others. A whole suite becomes a standalone Node script. A collection becomes one file. And the workspace was a readable JSON document the entire time.
-
The request on screen, as code
cURL, HTTP, JavaScript, Python, Go, C#, Java, Ruby, Rust, PHP, PowerShell and Dart — plus a written brief for Claude. Variables resolved so it runs as-is, or left as
{{name}}so it stays a template. Copy it, or save it. -
A suite becomes a Node script
Steps in order, values captured from one response and spent in the next, and your own JavaScript emitted verbatim rather than reconstructed. It runs the same code because it is the same language.
-
Collections travel as one file
A bundle carries its environments with it, so what arrives at the other end is not full of unresolved
{{variables}}— and what goes into it is chosen explicitly, so a secret never rides along by accident. -
And the workspace was always yours
One JSON file on your disk. If Sendwire vanished tomorrow you would still be able to read every request you ever wrote, in any text editor.
Built like the tool it is.
An HTTP client is where you go when something is wrong. It should be the one piece of software that never makes you wonder whether it is the problem.
-
Zero native dependencies
The whole engine is Node's own
http,tlsandnet. Nothing to compile, nothing to break on upgrade, no binary blobs in the package. -
Your workspace is a JSON file
On your disk, at a path the app will tell you, saved as you type. No account, no sync, no cloud that can go down or change its pricing.
-
Nothing phones home
No telemetry, no analytics, no crash reporting you did not ask for. The only requests Sendwire makes are the ones you tell it to.
$ sendwire run "Checkout flow" --env staging --reporter junit ok Log in 142 ms ok login worked ok Create order 211 ms ok order id captured ok List orders 88 ms ok status is active ok matches the schema 3 steps · 4 assertions · 441 ms · all passed
Read it before you download it.
The documentation is written rather than generated, and it is all up already — so you can find out whether this does what you need without installing anything.
sw API.
SOAP & WSDL
Envelopes, SOAPAction, faults, 1.1 and 1.2.
WebSocket & raw sockets
Frames, opcodes, close codes, bytes.
Authentication
OAuth 2, mutual TLS, SigV4, JWT and the rest.
Load testing
Concurrency, arrival rate, thresholds.
Command line
The same runs, in CI, with a real exit code.
Importing
Postman, OpenAPI, cURL, WSDL and HAR.
Get Sendwire
Free while in beta. No account, no licence key, no strings.
Not shipping yet. These buttons are live and the download path works end to end, but the builds behind them are placeholders. Follow one and you will get a text file that says so.
Also available in the app: ⌘K opens the command palette.