Postman Is a Desktop App: Testing APIs When You're Not at Your Desk
It's 11pm. Production is returning 502s on one endpoint and only one, and the person who noticed is asking you to confirm whether it's still happening. You are not at your laptop.
This sounds like a small problem. It isn't, because every option you have at 11pm is bad in a different way.
Termux and curl. Works fine. Becomes miserable the moment you need an auth header, a request body, or the same environment variables you used yesterday.
Wait until morning. Correct, and completely useless to the person currently waiting on you.
A cloud request tunnel. Sends production traffic and its auth headers through a third party's logs. I've done it. I don't love it.
A public API playground. Requires pasting an internal URL and a bearer token into someone else's website. I don't think any of us should do this, and the number of people who do it regularly is not the number who should.
So I built the option I kept wishing for: a real API client that runs on the phone in my hand.
What it does
It's called Taho. Android, Flutter, MIT. The client side is thorough, because that's the baseline and there's no point being interesting if the fundamentals are shaky:
- 15 HTTP methods, including the WebDAV verbs -
PROPFIND,LOCK,UNLOCK- that SOAP and XML services need and most clients quietly omit - OAuth 2.1: authorization code with PKCE S256, client credentials, and automatic token refresh with rotation
- GraphQL with live subscriptions, not just queries and mutations
- Server-Sent Events, WebSockets with hex-dumped binary frames, and an MQTT client
- Environments with
{{variable}}autocomplete, where the secrets live in the Android Keystore rather than in preferences - Import from cURL, Postman, OpenAPI, HAR, and Bruno
The part I didn't expect to build
I planned a security engine as a minor feature. Grade responses against OWASP-informed rules, flag what's missing, move on.
I went back and forth on whether a letter grade was too crude. It's lossy - a B doesn't tell you what was wrong, and reducing a security posture to a single letter feels like the kind of simplification that gets people killed. I shipped it anyway, for one reason: legibility. A wall of findings scrolls past. A C stops the scroll. And once you're looking at a C, you read the three findings underneath it, and you fix them. The grade is a hook for the detail, not a replacement for it.
Two constraints I held to:
- Grading is per-response, not per-app. One endpoint missing HSTS doesn't quietly poison the grade of eleven endpoints that are fine. That would have made the number meaningless.
- The findings name themselves. "Missing Strict-Transport-Security" is actionable. "Security issue detected" is not.
It also does boundary testing - deliberately malformed input against each field of your own request - because finding that your server 500s on a null byte is cheaper in QA than in production.
The constraint that shaped everything
There is no analytics SDK in the binary. Not "minimal", not "anonymous", not "opt-out". None. Usage events go to local preferences on a fixed allowlist that structurally cannot hold a URL, a header, a body, or a token. Capped at 2,000 entries. Deletable from settings. Never transmitted.
I wanted this and I'd defend it anyway, but it has a cost I don't pretend doesn't exist: I am partly blind about what's broken. I don't know which screen gets used, which feature gets ignored, or where people get stuck. When something breaks, the first report is usually a stranger's, and that's a worse feedback loop than any dashboard.
That's the trade. A privacy stance that costs you your own product analytics is a real stance with a real bill, and if you take it you should know what you're paying.
The account is optional, by the way. I only ask for one to bind a subscription across devices. You can use the whole app without it.
What's next
Scheduled monitors run through WorkManager and survive the app being killed. The first version alerted on every check, which trained me to mute it within a day - the fastest way to make a monitoring feature useless is to be annoying every thirty minutes. It now alerts only when something changes state.
There's also a headless CLI runner that exits non-zero on assertion failure, so the same collection definitions run in CI.
Try it
It's live on Google Play right now:
- Google Play: https://play.google.com/store/apps/details?id=com.eternal.taho
- Website: https://taho.co.in
Free tier is genuinely usable - the paid tier is ₹299/mo or ₹2,499/yr, and it unlocks 90-day history, PDF audit reports, unlimited environments, and response diffing.
If you find a bug, please say so in the comments. I read all of them, and I fixed a genuinely embarrassing one - every file picker in the app was unselectable for custom extensions - because someone here described the symptom better than I could.
Comments
No comments yet. Start the discussion.