Skip to content

🌐 OpenAPI → cURL Command Generator

Paste an OpenAPI 3.x specification (YAML or JSON) to instantly generate runnable cURL commands for every endpoint.

100% Free No signup Browser-only 5 languages Dark mode
🔒 Privacy guaranteed: Your OpenAPI spec is never uploaded. All parsing and conversion happen entirely inside your browser.

Generated cURL commands

🔗 Related Tools

📖 Where people get stuck

Paste an OpenAPI 3.x document in YAML or JSON and every endpoint comes back as a runnable cURL command. Parsing happens in the browser and the spec is never uploaded. All it does is mechanically rearrange what the document says into a command, and nothing guarantees the result will succeed as-is: the quality of what comes out is very nearly a function of how many example values the source spec bothered to write down.

Case What happens What to do
The request body comes out empty or as {} Almost always this means a $ref pointing at another file. A reference like $ref: "./schemas/user.yaml#/User" cannot be resolved from the single document you pasted, and splitting schemas across files is the norm for any sizeable API, so in practice this is the common case rather than the exception. Same-file references such as #/components/schemas/User do resolve, but allOf, oneOf and anyOf cannot be expanded fully — with oneOf the spec itself does not say which branch to pick. Bundle the spec into a single file before pasting itnpx @redocly/cli bundle openapi.yaml -o bundled.yaml or npx swagger-cli bundle openapi.yaml -o bundled.json -r pulls every external reference inline. This is a step worth having in CI anyway: a bundle that fails means a broken reference, so it doubles as a link check for your specification. If the spec leans on allOf, adding --dereferenced to flatten it completely brings the generated body much closer to what you actually need to send.
The generated command comes back 400 or 422 A property with no example can only be filled in mechanically from its type"string" for a string, 0 for a number. Real APIs, though, accept only "active" or "archived" in status, insist that created_at be date-time, and so on. A 400 is therefore usually not a defect in the tool but evidence that the spec omitted its examples. An enum or a format can be read, but constraints like this value must be consistent with that other field cannot be expressed in the spec at all, so nothing can fill them. The correct fix is to add example values to the spec. Every one you add also improves the Swagger UI samples, the responses from your mock server and the tests in generated clients. This is not busywork to satisfy a tool; it is a direct improvement to the API documentation. Authentication is often absent from the spec, so override it in the auth header field on this page. A 401 points at authentication and a 400 or 422 at the body, which separates the two cases cleanly — and adding curl -v to see the headers actually being sent is the fastest way to tell them apart.
Nothing at all is generated Check whether the document starts with swagger: "2.0". Swagger 2.0 is a different specification with a different shape: the server is host plus basePath plus schemes rather than servers, the request body lives in parameters as in: body rather than in requestBody, and the media type sits in a top-level consumes rather than under content. It is not a version bump; every place you would read from has moved. The other frequent cause is broken YAML indentation — a stray tab character makes YAML fail every time. Convert to 3.x firstnpx swagger2openapi swagger.yaml -o openapi.yaml does exactly that, and the existing content transfers almost mechanically. Swagger 2.0 has been in maintenance mode ever since 3.0 landed in 2017, so this conversion is work you will need sooner or later anyway. To find out whether YAML is to blame, convert to JSON and paste that instead — it separates the two cases immediately (YAML and JSON converter). If the JSON works, it was indentation; if it still does not, the problem is the version or the structure.

Do not hand the generated commands to anyone as they are. Overriding the auth header embeds your real token in plain text in every command produced — pasting that into Slack, an issue or a document is a credential leak in each case. When sharing, replace it with an environment variable first, as in -H "Authorization: Bearer $API_TOKEN". Even when you only run it yourself, the whole command stays in your shell history file in plain text (prefixing it with a single space keeps it out of the history in most shells). One more thing: if the spec only gives relative servers entries such as /api/v1, there is no host, so the commands cannot run unmodified — fill it in using the base URL override on this page.

📖 How to Use

  1. 1
    Paste your OpenAPI spec
    Paste your OpenAPI 3.x spec in YAML or JSON format. Use the Sample button to load an example.
  2. 2
    Configure options
    Optionally override the base URL or set an Authorization header. Choose multi-line or single-line output.
  3. 3
    Copy the cURL commands
    Every endpoint appears as a card with a copy button so you can send the command straight to your clipboard.

❓ Frequently Asked Questions

Is Swagger 2.0 supported?
OpenAPI 3.x is the primary target. Swagger 2.0 paths and methods will mostly work, but $ref resolution and complex schemas are only partially supported.
How is the request body filled in?
The tool uses the requestBody example or each property example / default first; otherwise it generates a sample by type (string becomes "string", integer becomes 0, etc.).
Can I run the generated commands as-is?
They contain sample values and placeholder tokens, so replace required parameters and credentials with real values before running them in production.
🐛 Found a bug or issue with this tool?

Free to use, no signup. Even just the steps to reproduce are helpful. Reports go directly to the operator and help us fix issues.

* Browser info (UA / screen / language / URL) is sent automatically to help reproduce the issue