mockfly logo

Import an OpenAPI or Swagger spec

If the API you want to mock already has an OpenAPI 3.x or a Swagger 2.0 specification, you do not need to recreate it endpoint by endpoint. Hand Mockfly the spec and it builds a whole project out of it: one endpoint per path and method, one response per documented status code, folders from your tags, and a body for every response — taken from the spec's examples, or generated from its schemas.

The result is a normal Mockfly project. Every endpoint, response and rule stays editable afterwards, and it can be exported again as Mockfly's own JSON format.

Importing a spec

Go to your projects page and click the Import project button at the top of the list. In the modal that opens, pick OpenAPI in the Format row — one button covers OpenAPI 3 and Swagger 2.0, in JSON or in YAML — and then choose how you want to hand the document over:

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 spec maps to a Mockfly project

This is what the importer does with each part of the document:

In the specIn Mockfly
info.titleThe project name. Falls back to Imported project when the spec has no title.
Each path + methodOne endpoint. GET, POST, PUT, PATCH, DELETE, OPTIONS and HEAD are imported; trace is skipped.
Path templates, /pet/{petId}Mockfly dynamic routes, /pet/:petId. See Dynamic Route Support.
basePath (Swagger 2) or servers[0].url (OpenAPI 3)Prefixed to every path, so a Petstore spec served from /api/v3 lands on /api/v3/pet/:petId. A server URL with variables in it is ignored rather than imported literally.
summary, or description when there is no summaryThe endpoint description, truncated to 500 characters.
tagsFolders. The first non-empty tag of each operation decides its folder.
responsesOne response per status code, named <status> <description>. The first 2xx becomes the endpoint's default response.
requestBody (or the in: body parameter in Swagger 2)The endpoint's body example, so the request editor is prefilled.

Where response bodies come from

For each response, Mockfly looks for a body in this order and stops at the first hit:

  1. the media type's example,
  2. the first entry of its examples map,
  3. a body generated from its schema$refs are resolved, allOf is merged, and the first branch of oneOf/anyOf is used.

Only JSON is imported. A response is matched when its media type is application/json or any application/…+json variant. Everything else — an application/octet-stream download, a text/plain body, an XML-only response — is left out and listed in the summary.

A worked example

Given this operation:

{
  "openapi": "3.0.3",
  "info": { "title": "Petstore", "version": "1.0.0" },
  "servers": [{ "url": "https://petstore3.swagger.io/api/v3" }],
  "paths": {
    "/pet/{petId}": {
      "get": {
        "tags": ["pet"],
        "summary": "Find pet by ID",
        "responses": {
          "200": {
            "description": "successful operation",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Pet" } }
            }
          },
          "404": { "description": "Pet not found" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Pet": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "format": "int64", "example": 10 },
          "name": { "type": "string", "example": "doggie" },
          "status": { "type": "string", "enum": ["available", "pending", "sold"] },
          "createdAt": { "type": "string", "format": "date-time" },
          "tags": { "type": "array", "items": { "$ref": "#/components/schemas/Tag" } }
        }
      },
      "Tag": {
        "type": "object",
        "properties": { "id": { "type": "integer" }, "name": { "type": "string" } }
      }
    }
  }
}

Mockfly creates a pet folder holding a GET /api/v3/pet/:petId endpoint described as "Find pet by ID", with two responses: 200 successful operation, which becomes the default one, and 404 Pet not found. Open the first one and this is the body waiting in the editor:

{
  "id": 10,
  "name": "doggie",
  "status": "available",
  "createdAt": "{{faker.date.recent().toISOString()}}",
  "tags": [{ "id": 1, "name": "{{lorem.word}}" }]
}

Note what happened to the fields with no example: an enum collapsed to its first value, and the date-time and plain strings became Faker placeholders rather than frozen text.

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, taken from the spec, and under it four counters:

If anything was left out, a "N requests were not imported" section appears below the counters. 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 skip was about one specific response rather than the whole operation.

Nothing is ever dropped silently: if an operation or a response is not in your project, it is in that list. An operation whose responses were all skipped turns up twice — once under the reason its responses failed, and once under "None of its responses could be imported.", because the endpoint it would have created was left empty.

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.

Skip reasons

ReasonWhen it happens
Only JSON responses can be imported.The response has no JSON media type — a binary download, XML only, plain text.
The response example is not a JSON object.The example or the generated body is a scalar — a schema of type: string, for instance.
The "default" response of OpenAPI has no status code to be mapped to.The operation declares a default response. Mockfly responses always carry a real status code.
The status code is not a valid HTTP status code.Wildcards like 2XX, or a code Mockfly does not know.
None of its responses could be imported.Every response of the operation was skipped, so there is no endpoint to create.
The HTTP method is not supported by Mockfly.In practice, trace operations.
Another operation is already mapped to the same path and method.Two spec paths collapse onto the same Mockfly path once the templates are converted.

Limits and things worth knowing

Imported mocks return live data

Bodies built from a schema use the same Faker placeholders the mock engine already understands, so an imported mock does not return the same frozen payload on every call. Formats map to sensible generators — {{string.uuid}} for uuid, {{internet.email}} for email, {{faker.date.recent().toISOString()}} for date-time — and any other string becomes {{lorem.word}}. Edit or remove them like any other placeholder; see Random Data Generation for the full list.

Schemas are walked up to 8 levels deep. Anything nested below that comes back as null, which keeps deeply recursive specs from blowing up the import.

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 spec with more than 4 endpoints, or an operation with more than 2 importable responses, is rejected outright: the modal shows the limit as an error and the projects list is untouched. Upgrading lifts both limits.

Importing from a URL

The URL tab does not fetch the spec from your browser — Mockfly downloads it from its own servers, so the document 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. Spec behind auth or on your intranet? Download it yourself and use the File or Paste tab instead.

Import your spec