Swagger UI is a viewer that downloads your API description from a URL set in its configuration, or reads an object embedded in the page. To get the OpenAPI JSON, find that URL. The fastest way is the browser: open DevTools, switch to the Network tab, filter by "json", and reload the docs page. The request whose response starts with an "openapi" or "swagger" key is the file you want. If that does not work, the sections below cover framework defaults, the Swagger UI config, embedded specs, and the reasons a spec URL returns a 404.
Try the framework's default spec URL first
Most backends that ship Swagger UI generate the spec at a predictable path. If you know which framework serves the API, this table usually gets you the file in one request. Every path below can be changed in configuration, so treat it as a first guess.
| Framework | Swagger UI page | Spec URL | Setting that changes it |
|---|---|---|---|
| FastAPI | /docs | /openapi.json | openapi_url (set to None to disable the spec and the docs) |
| NestJS (@nestjs/swagger) | /api (the path passed to SwaggerModule.setup) | /api-json and /api-yaml | jsonDocumentUrl and yamlDocumentUrl |
| Spring Boot (springdoc-openapi) | /swagger-ui.html | /v3/api-docs and /v3/api-docs.yaml | springdoc.api-docs.path |
| ASP.NET Core with Swashbuckle | /swagger | /swagger/v1/swagger.json | SwaggerEndpoint in UseSwaggerUI options |
| ASP.NET Core 9+ built-in OpenAPI | none by default | /openapi/v1.json | the route passed to MapOpenApi |
Two details trip people up. NestJS appends -json to whatever path you gave the docs, so docs at /docs/v2 put the spec at /docs/v2-json. Swashbuckle uses the document name in the path, so a document registered as "public" lives at /swagger/public/swagger.json, not v1.
Read the spec URL from the Swagger UI configuration
When the defaults miss, the page itself tells you where the spec lives. Swagger UI accepts four configuration options that point at an API description, and every hosted docs page uses at least one of them:
- url: a single URL to the definition, usually swagger.json, swagger.yaml, or openapi.json.
- urls: an array of named definitions shown in a dropdown in the top bar. urls.primaryName picks which one loads first.
- configUrl: a URL to a separate JSON config document, which then contains url or urls.
- spec: the whole definition as a JavaScript object inside the page. No separate file exists in this case.
Find the config in the page source
Open the page source
Use View Source (Ctrl+U or Cmd+Option+U) on the docs page. Search for SwaggerUIBundle. Older pages call it inline with the options object right there.
Follow swagger-initializer.js
Swagger UI 4 and later moved the call into a separate file called swagger-initializer.js. Find its script tag, open the file, and look for the url or urls key.
Check for swagger-ui-init.js
NestJS and swagger-ui-express serve a file called swagger-ui-init.js. On those pages the full document often sits inside it under a "swaggerDoc" key instead of behind a URL.
Resolve relative paths
A value like ./v1/swagger.json is relative to the docs page, not the domain root. On https://example.com/docs/index.html it resolves to https://example.com/docs/v1/swagger.json.
window.onload = function () {
window.ui = SwaggerUIBundle({
url: "/internal/v2/openapi.json",
dom_id: "#swagger-ui",
presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],
layout: "StandaloneLayout"
});
};Use the Network tab when the config is minified
Some docs pages bundle and minify everything, so searching the source is slow. The Network tab skips that problem because it shows what the browser fetched. Open DevTools, select Network, tick Preserve log, and reload. Filter by Fetch/XHR, then click each JSON or YAML response and look at the first lines. An OpenAPI 3 file starts with an openapi field such as "3.0.3" or "3.1.0"; a Swagger 2.0 file starts with "swagger": "2.0". Right-click the request and choose Copy as cURL to replay it with the same cookies and headers, which matters when the docs sit behind a login.
Save the spec from the command line
Once you have the URL, download it and confirm it is a spec before you feed it to a generator or a linter. Servers sometimes answer a wrong path with an HTML error page and a 200 status, and tools then fail with confusing parse errors.
# Download the spec
curl -sSL https://api.example.com/openapi.json -o openapi.json
# Print the version field: "3.x" for OpenAPI, "2.0" for Swagger
jq -r '.openapi // .swagger' openapi.json
# Count the paths to confirm you got the full document
jq '.paths | length' openapi.jsonWhy the spec URL returns a 404 or HTML
Common causes and fixes
Work down this table when the docs page loads but the spec URL fails.
| Scenario | Recommendation | Alternative |
|---|---|---|
| The app sits behind a reverse proxy or in a virtual directory | The UI requests the spec from the domain root while the app lives under a prefix. Prepend the prefix, or configure a relative endpoint such as ./swagger/v1/swagger.json in Swashbuckle. | Check the proxy for a rewrite rule that strips the prefix. |
| Docs work locally but not on staging or production | Many templates enable the spec and the UI only in development. The ASP.NET Core template, for example, wraps UseSwagger in an IsDevelopment check. | Ask the API owner for an exported file instead of turning docs on in production. |
| FastAPI docs return 404 too | openapi_url is set to None, which disables the spec and both docs UIs. | Look for a custom openapi_url such as /api/v1/openapi.json. |
| The dropdown in the top bar lists several APIs | The page uses urls. Each entry has its own spec URL; pick the one you need from the initializer or the Network tab. | — |
| No spec request appears in the Network tab at all | The page uses the spec option or an embedded swaggerDoc. Copy the object from the page source, or let a tool extract it. | — |
Let APIForge find the spec for you
You can paste the Swagger UI page URL itself into the OpenAPI validator or the Swagger 2.0 validator. APIForge tries the URL you gave it, then works through the same steps described above: it reads an embedded swaggerDoc from swagger-ui-init.js, reads the url value from swagger-initializer.js, and for pages ending in /docs or index.html it tries common spec paths such as /swagger/v1/swagger.json, /openapi.json and /v3/api-docs. When it finds a document with operations, it loads every endpoint into the workspace.
The spec below is a small orders API of the kind you might pull from a staging server. APIForge scored it 78 out of 100. The reasons are concrete and fixable: /api/createOrder puts a verb in the path and uses camelCase, two operations document no 4xx or 5xx responses, the create operation has no summary, and no path carries a version prefix. The API quality score lists each issue with an example fix, and the guide to common OpenAPI errors explains the ones you are most likely to see in exported specs.
openapi: 3.0.3
info:
title: Orders API
version: 1.0.0
paths:
/api/orders:
get:
summary: List orders
responses:
"200":
description: A page of orders
/api/orders/{id}:
get:
summary: Get one order
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
"200":
description: The order
"404":
description: Order not found
/api/createOrder:
post:
responses:
"200":
description: CreatedWhat to check once you have the file
- Confirm the version. A swagger: "2.0" file and an openapi: "3.x" file need different tools; Swagger vs OpenAPI covers the differences.
- Validate the structure before generating code. The steps are in how to validate Swagger and OpenAPI specs.
- Check that every $ref resolves. Exported specs sometimes reference schemas from a second file that the server never exposes.
- Compare the servers list with the host you downloaded from. Specs copied between environments often still point at localhost.
- Keep the file in version control. A spec you downloaded once goes stale; regenerate it from the source or download it again as part of your build.
If you are new to the format, the OpenAPI glossary entry explains the document structure in a few paragraphs, and the good OpenAPI example shows a complete spec you can compare yours against.