mockfly logo

Import a HAR capture

A HAR file is what the network tab of your browser records: every request a page made and every response it got back. If the API you want to mock has no specification but you can exercise it in a browser, you do not have to recreate it by hand — record the session, hand Mockfly the capture, and each request becomes an endpoint whose response carries the status code and the body the server really returned.

That is the difference with importing an OpenAPI spec: a spec describes what an API is supposed to answer, a capture holds what it actually answered. The bodies you get are the real payloads, not examples generated from a schema.

What comes out is a normal Mockfly project: every endpoint and response stays editable, and it can be exported again as Mockfly's own JSON format. If you only need one or two requests rather than a whole session, the Mockfly Chrome extension adds them to an existing project straight from DevTools.

Where a HAR comes from

You export it from the browser itself. Open DevTools on the page that talks to the API, go to the Network tab, and leave it open while you use the app — only what is recorded while the panel is open ends up in the file, so turn on Preserve log if the flow navigates between pages. When you are done:

Make sure the export includes response contents. A HAR saved without them still imports — you get the endpoints, the paths and the status codes — but every body arrives empty, as {}, and you have to fill them in yourself.

Importing the capture

Go to your projects page and click the Import project button above the list. In the modal that opens, pick HAR in the Format row — "A HAR capture from the network tab of the browser" — and choose how you want to hand the file over:

The two HAR fields

Picking HAR adds two fields to the modal that the other formats do not have:

Then hit Import. The button is disabled until there is something to import, turns into "Importing…" while the project is being built, and when it finishes the modal becomes the import summary — with your new project already sitting in the list behind it. If the import fails, nothing is created and the error comes back as a toast explaining why.

How a capture maps to a Mockfly project

Mockfly walks the entries of the capture in order and turns each one into an endpoint and a response:

In the captureIn Mockfly
The host of the requestThe project name, when the Domain field is empty. Filling it in both filters the capture and names the project.
The path of the requestThe endpoint path, exactly as captured. The query string is dropped, so /users?page=1 and /users?page=2 are the same endpoint.
The method of the requestThe endpoint method. GET, POST, PUT, PATCH, DELETE, OPTIONS and HEAD are imported; anything else is skipped.
The URL of the requestThe endpoint description, as Captured from … without the query string, so you can tell afterwards where each endpoint came from.
The status and status text of the responseOne response, named <status> <status text>200 OK, 404 Not Found. The first 2xx of an endpoint becomes its default response.
The body of the responseThe response body, verbatim. Bodies the browser stored in base64 are decoded first.
The body of the requestThe endpoint's body example, when it is JSON, so the request editor is prefilled with what the app really sent.

Two things a capture cannot give you. There are no folders, because a HAR carries no grouping — every endpoint lands at the root and you can group them yourself afterwards. And there are no environment variables, so that counter always comes back at 0 too.

Only JSON responses are imported. The entry is kept when its media type is application/json or an application/…+json variant, which by itself throws away the HTML documents, the scripts, the stylesheets, the images and the fonts that make up most of a capture. What is thrown away is never silent: it all shows up in the summary.

A worked example

Say the capture holds this entry, among a few hundred others:

{
  "log": {
    "version": "1.2",
    "entries": [
      {
        "request": {
          "method": "GET",
          "url": "https://api.example.com/users/42?include=orders"
        },
        "response": {
          "status": 200,
          "statusText": "OK",
          "content": {
            "mimeType": "application/json; charset=utf-8",
            "text": "{\"id\":42,\"name\":\"Ada Lovelace\",\"plan\":\"premium\"}"
          }
        }
      }
    ]
  }
}

Import it with api.example.com in the Domain field and you get a project called api.example.com holding a GET /users/42 endpoint described as "Captured from https://api.example.com/users/42", with a single response, 200 OK, and this body waiting in the editor:

{
  "id": 42,
  "name": "Ada Lovelace",
  "plan": "premium"
}

Note what did not happen. The query string is gone from the path. The body is frozen exactly as the server returned it — no Faker placeholders, unlike an OpenAPI import, though you can add them yourself with Faker templating. And the path is the literal one that was captured, /users/42 and not /users/:id: if you want the mock to answer for any user, turn it into a dynamic route after importing.

The import summary

When the import finishes, the modal turns into a summary of what just happened. At the top is the name of the new project, and under it four counters:

Below the counters sits a "N requests were not imported" section, and with a HAR it is normally the biggest part of the screen: a recording of a real page is mostly things that are not your API. It groups everything by reason, with a count next to each one; click a reason to unfold it and see every request behind it — its method, its path, and the status code when the entry was thrown out for what came back rather than for where it went.

Nothing is dropped silently, so it is worth skimming: a reason you did not expect, or a count that is far too high, usually means the Domain field is wrong. Responses merged away by Keep the last capture are the one thing that does not show up there — they were folded into an endpoint you did get, not skipped.

Skip reasons

ReasonWhen it happens
The request does not belong to the domain that was imported.You filled in Domain and the entry was captured from another host. In a normal session this is the biggest group by far.
Only JSON responses can be imported.The response is not JSON: the HTML document itself, scripts, stylesheets, images, fonts, plain text.
The response example is not a JSON object.The body did not parse — a capture cut short mid-response — or it parsed into a bare value rather than an object or an array.
The status code is not a valid HTTP status code.Requests the browser never completed. A blocked, cancelled or failed entry is recorded with status 0, which is not something a mock can answer with.
The HTTP method is not supported by Mockfly.Anything outside the seven methods above, in practice CONNECT and TRACE entries.
The request has no URL.A malformed entry whose URL cannot be parsed.

The summary is informative only; the project is already created and waiting in the list behind the modal. Close it with Done and open the project to start editing what came in.

Limits and things worth knowing

A capture of a logged in session carries your data

The modal says it as soon as you pick HAR, and it is the one thing to think about before importing: a capture recorded while you were logged in keeps the response bodies as they came back, so importing it copies that data into the project. Your user record, your teammates' names and emails, real customer rows, a token the API returned in a body — whatever the server answered while you were recording. Request bodies come along too, so a login call brings its credentials with it.

Mockfly imports bodies, not headers: cookies and Authorization headers are left behind, and so are the response headers, which keeps Set-Cookie out of the project. That also means a capture your browser exported with sensitive headers redacted can still be full of personal data — the redaction is about headers, and the bodies are the part Mockfly reads.

So treat an imported project as a copy of that data: it can be shared with the teammates of your workspace, and its mocks answer with those bodies to anyone who has the URL. Record the flow with a test account when you can, trim the capture to the calls you actually need before importing, and go through the imported bodies afterwards to clear out anything that should not be sitting in a mock.

Plan limits

Plan limits are checked before anything is written, so an import that exceeds them fails and leaves nothing behind — no half-created project you have to clean up. On the free plan that means a capture that would create more than 4 endpoints, or more than 2 responses on any single endpoint, is rejected outright: the error comes back as a toast and the projects list is untouched.

This bites much sooner with a HAR than with any other format. A couple of minutes of browsing goes past 4 endpoints without trying, and Keep every capture goes past 2 responses on the first endpoint that got polled. Narrow the capture with the Domain field, record just the flow you want to mock, or upgrade to lift both limits.

Importing from a URL

The URL tab does not fetch the capture from your browser — Mockfly downloads it from its own servers, so the file has to be publicly reachable. The fetch is deliberately conservative:

If any of those trip, the import fails with an error saying so and no project is created. That 10 MB ceiling is easy to hit with a HAR, and captures usually live on your disk anyway: use the File tab instead.

Import your capture