/ SONDA · BUILD · TRUE REVERSE ENGINEERING

Use the application. Sonda writes the API behind it.

Every API client can import a HAR file: three hundred requests, dumped into a folder, exactly as the browser made them — the ids baked into the paths, the token pasted in every header, the analytics calls mixed in with the real ones. That is a recording, not an API. Discover reads the traffic the way an engineer would: it separates the calls from the noise, works out the shape of each endpoint, finds where the credential came from, follows the values from one answer into the next request, and writes a project you would have written by hand — with a flow that replays the session and a mock that answers like the real thing.

BROWSER OVER DEVTOOLS PROXY FOR PHONES AND APPS HAR UP TO 1 GB NOTHING WRITTEN TO DISK

Three ways in, one engine

BrowserSonda opens Chrome, Edge or Brave with a throwaway profile and reads it over the DevTools protocol — the browser does its own networking, Sonda only listens. No extension, no certificate, nothing intercepted.
ProxyFor a phone, a desktop app, a CLI, another browser. HTTPS is read through a certificate authority made for this capture, its key in memory, dead when the capture ends.
HARA DevTools export, a customer's file from a support ticket, another tool's. Read as a stream, one request at a time, up to a gigabyte.
ThenThe same analysis, the same review, the same project out — whichever way the traffic came in.
/ WHY IT IS NOT A HAR IMPORT

A recording is not an API.
The difference, row by row.

Sonda has a plain HAR import too — one folder per host, under Import, like everyone else's. Discover is the other thing.

A HAR import, in any clientDiscover
Where the traffic comes fromA file the browser exported, after the fact.Live, from a browser Sonda opens and reads over DevTools, or from any device pointed at Sonda's proxy — a phone on the same Wi-Fi, a desktop app, a script. Or a HAR, if that is what you have.
What a request becomesOne request per entry, verbatim. /customers/621 and /customers/817 are two requests.One operation per endpoint. /customers/621 and /customers/817 are /customers/{customerId} — templated only where a segment is plainly an id or sibling paths prove it. A lone /users/me stays as it is.
GraphQL and RPCEvery call to /graphql is the same request, a hundred times.Split by operation — batches, GET queries and persisted queries included. JSON-RPC split by method. Preflights folded into the call they precede; repeats folded into one, the richest sample kept.
The noiseAnalytics, session replay, error reporting, fonts, images, scripts — all in the folder.Pages, static files and preflights set apart. Thirty-four tracker patterns left out by default, and the list is yours to edit.
The credentialsA bearer token pasted into every header, as captured. Expires tomorrow.The token traced back to the answer that handed it out. That request gets the script that keeps it as {{accessToken}}, and every other request reads the variable. Basic, API keys in a header or the address, cookie sessions, a CSRF token copied from a cookie, and an OAuth 2.0 sign-in through an identity provider are recognised — with the option to sign in from Sonda instead of reusing the captured token.
The order of thingsRequests in a list. What one answer gave and the next one sent is yours to notice.A value one answer gave and a later request sent back — an id, a cursor, a tenant — is a wire by name. The project carries the journey, not just the stops.
What you end up withA folder of requests.A project with a folder per resource, the address and the credentials as variables, the answers kept as examples with credentials hidden; a flow that replays the session with every value wired; an Echo that answers like the API did; the session's cookies in Sonda's jar.
What touches your diskThe file.Nothing. A capture lives in memory until the next capture, Discard, an account switch or the app closing. The browser's throwaway profile is shredded when the capture ends.
/ THE CAPTURE, TECHNICALLY

How the traffic gets in.

One capture at a time. Every request becomes an entry — what was asked and what came back, the bodies of the API calls kept, none for the pictures, styles and scripts. The window follows the rows live, three times a second.

The browser, over DevTools

Chrome, Edge or Brave, launched with a profile made for this capture — nothing of your own browser in it, shredded when the capture ends, swept at the next start if Sonda crashed. Sonda attaches over the DevTools protocol on a loopback port only it was told, the way DevTools itself does: every request with its real kind — XHR, fetch, page, script — the bodies as the browser decoded them, WebSocket frames, event-stream messages, popups, frames and service workers. Nothing is intercepted and no certificate is involved. Chrome 136 and later refuse remote debugging on a person's own profile; the throwaway profile is what this needs anyway.

The proxy, for everything else

Listens on this computer only, or on its network addresses when you say so, for a phone on the same Wi-Fi. Plain HTTP is read as it passes. HTTPS is answered for the site with a certificate made for this capture, signed by an authority made for it too — an ECDSA key that lives in memory and dies with the capture. The device trusts that authority once; the proxy hands it out at http://sonda.cert. A device that kept trusting it trusts nothing anyone can sign again. Keep it for the next capture only if you ask, sealed under the account's password, and Forget removes it.

The proxy is not an open door

A request from any address but this computer's own waits for you: the device is shown — its address, what it says it is, what it first asked for — with Allow and Refuse, and nothing passes until it is allowed, the certificate page included. An allowed device reaches what this computer reaches, but never this computer's own services nor a link-local address such as a cloud's metadata service — checked on the address actually dialled, so a name that resolves to 127.0.0.1 does not get past it. Upstream, every request leaves through Sonda's own transport, and the real site's certificate is always checked: the device trusts Sonda blindly, so Sonda is the one that checks.

The HAR, as a stream

Read one request at a time, never whole: a string longer than a kept body could need is cut as it is read, so a HAR with a gigabyte of video holds a few megabytes at a time. Reading stops at the 20,000th request. A file over a gigabyte is refused before a byte of it is read.

The limits

512 KB per body, each way. 16 KB per WebSocket frame, 400 frames per socket, 400 messages per event stream. 20,000 entries and 256 MB of bodies per capture. A capture can go out through a tunnel, from a server you reach over SSH.

The review

A live table: search, API calls, pages or everything, by status. The headers and bodies of any call on click. Hosts outside the site flagged and left unticked. Then you pick the hosts and the operations, and build.

/ THE ANALYSIS

From traffic to a project, in six steps.

The engine is conservative on purpose: it templates a path only when the evidence is plain, and it flags what it is not sure of rather than guessing.

Separate the calls from the pages

The API calls are kept apart from the documents, the static files, the preflights and the trackers. The tracker list — analytics, session replay, error reporting, tag managers — is thirty-four host patterns you can edit. Preflights are folded into the call they precede.

Template the paths

A segment becomes a variable only where a value is plainly an id — digits, a UUID, an ObjectId, a long token, an email, a date — or where sibling paths prove it. The variable is named from the resource: /customers/{customerId}, /orders/{orderId}/lines/{lineId}.

Split the endpoints that hide many operations

GraphQL by operation name — batches, GET queries and persisted queries included. JSON-RPC by method. Repeats of the same operation are folded into one, the richest sample kept; the other answers become examples.

Find the credentials, and where they came from

A Bearer token is followed back to the answer that issued it; that request gets a post-response script that keeps the token as a variable, and every later request reads it. A Basic header, an API key in a header or the address, a cookie session, a CSRF token copied from a cookie, and a sign-in through an identity provider are each recognised and kept as variables and auth, never as pasted values.

Wire the journey

A value one answer gave and a later request sent back — an id, a cursor, a page token, a tenant — is a wire by name. That is what makes the replay flow a replay and not a list.

Build

A project with a folder per resource and the address and credentials in its variables; up to four examples per operation, one per status, credentials hidden. A "Replay the session" flow, call by call, in order, every wired value passed on by name. An Echo on a port that answers like the API did during the capture — point {{baseUrl}} at it and work without the real thing. The session's cookies in Sonda's jar. One project with a folder per host, or a project per host; new, or added into one you have.

/ GOVERNED

Three boxes before every capture.

That you are authorized to inspect the application's traffic — it is yours, or its owner allowed it, and doing so is within its terms of use. That you will treat what you see as confidential. That you are authorized to reverse engineer the site you will capture. Sonda refuses a capture without them.

In an organization

Discover is the owner's to grant, through the global permissions file only — never a division administrator's. App runners never see it.

The owner's rules

Wide open: anyone with the permission captures anything. Curated: up to 500 domains, and requests to any other domain are not kept.

Logged

"Captures an application with Discover" is an activity trigger: the administrators chosen are mailed the moment it happens.

Permissions
/ LOCKFLARE SONDA

Discover, in the free edition.

Discover, listed →