cURL Command Builder — Generate HTTP Requests Without Guessing
curl Command Builder
Authentication
Headers
Request body
curl \ -H 'Accept: application/json' \ 'https://api.example.com/v1/items?page=2'
The command is assembled in your browser and never sent anywhere. Values containing spaces or shell metacharacters are single-quoted so the command runs safely as written; a literal quote inside a value is escaped the POSIX way.
What Is
curl — client URL — is the command line program for transferring data to and from a server using URL syntax. It ships inside macOS, it is part of the base install of Git for Windows, and it is present in practically every CI runner, container image and remote shell you will ever open. It began in 1998 as a way to fetch web pages from a terminal and grew into the universal HTTP client: HTTP/1.1 and HTTP/2, HTTPS, proxies, cookies, redirects, plus FTP and SFTP. Every cURL command reads the same way, because each flag corresponds to one part of the request: - The method flag. -X followed by a verb sets the HTTP method. For GET, curl's default, the flag can be omitted entirely — a bare curl URL already performs a GET — and the same is true of HEAD. For POST, PUT, PATCH, DELETE and OPTIONS the flag is what tells the server what is happening. - The header flags. Each -H 'Name: value' pair adds one HTTP header. Accept states which response format you want back, Content-Type describes the body you are sending, and any other name is passed through untouched. Header names are case-insensitive on the wire. - The auth flags. -u 'user:password' performs HTTP Basic authentication, base64-encoding the pair into an Authorization header for you.
There is no dedicated bearer flag: a bearer token is sent with -H 'Authorization: Bearer ...'. The distinction is worth internalising because -u is a shorthand for one specific header, not a separate credential system — hand-writing the same Authorization header produces byte-identical requests. - The data flags. -d, --data and --data-raw all attach a request body, and --data-urlencode percent-encodes a single name=value pair. A subtlety that catches people out: adding any data flag silently switches the method to POST unless you also pass -X explicitly, so a PUT with a body can come back as a create operation. This builder surfaces that behaviour — choose a body while the method is still GET and -X POST appears on its own. - The URL. It goes last, unquoted when it is plain, quoted when it carries a query string. Quoting is where hand-written commands usually break. Your shell parses the line before curl ever sees it, and it treats space, &, |, ;, $, >, *, ?, parentheses, ' and " as syntax rather than data. A URL pasted as https://api.example.com/search?q=a&b=2 is cut at the ampersand: curl fetches /search?q=a, and the shell then tries to execute the leftover token b=2, producing a command-not-found error that has nothing to do with the API. The same fate awaits any JSON body, because the spaces inside the braces split it into a dozen separate arguments. Wrapping the value in single quotes tells the shell to hand everything through literally.
Single quotes are the safest wrapper because nothing inside them is interpreted: not a dollar sign, not a backtick, not a second quote. The single problem is a value that itself contains a single quote, which cannot be escaped inside single quotes. POSIX solves it by closing the quote, inserting a backslash-escaped quote, and opening the quote again — the idiom this builder emits automatically when it meets an apostrophe in a header value or a password. One more concept matters when a command runs unattended: idempotency. GET, HEAD, PUT and DELETE are idempotent by definition, meaning that repeating the request leaves the server in the same state as sending it once, so a network retry is harmless. POST is not idempotent — a retried POST can create two records or charge a card twice. curl therefore retries only idempotent methods unless told otherwise, which is why --retry is safe in scripts that mix verbs. Reading the output matters too. By default curl draws a progress meter on standard error showing a percentage, bytes downloaded and total, current speed in bytes per second, and estimated time remaining; it disappears the moment you pipe or redirect the output, and --silent suppresses it entirely. -v prints the full conversation with < marking what curl sends and > marking what it receives — the request line, every header, the response status line, every response header. -i keeps response headers in the output instead of discarding them, and --fail makes curl exit non-zero on a 4xx or 5xx so a script can branch on failure.
How to Use
- Set the Method dropdown to the verb your endpoint expects — GET, POST, PUT, PATCH, DELETE, HEAD or OPTIONS. The command below rewrites itself as you work, and -X is left out automatically for GET and HEAD.
- Paste the complete URL into the URL field, including the scheme and any query string, for example https://api.example.com/v1/items?page=2.
- Under Authentication, click None, Basic or Bearer. Basic reveals Username and Password inputs and emits -u; Bearer reveals a single token field and emits an Authorization header built for you.
- Work in the Headers section: tick each row's checkbox to include or exclude it, fill in the Header name and Header value fields, press the × button to delete a row you do not need, or click + Add header to create another.
- Choose a body type under Request body — No body, JSON, Form fields or Raw text. JSON and Form fields add the matching Content-Type header for you unless you already typed a Content-Type header yourself.
- For JSON, tick Pretty-print to have the payload re-serialised with indentation, or leave it unticked to keep exactly what you typed. Form fields turns each name=value line into its own --data-urlencode flag.
- Read the assembled command in the Command block and press Copy to place the single-line version on your clipboard. Assembly happens in your browser, so credentials in the command are never transmitted anywhere.
Examples
Input: GET https://api.example.com/v1/items?page=2, header Accept: application/json
Process:
GET is curl's default so -X is omitted, the header is emitted with -H, and the URL keeps its query stringResult: curl \
-H 'Accept: application/json' \
https://api.example.com/v1/items?page=2
Input: POST https://api.example.com/v1/items with JSON body {"name":"example","active":true} and Bearer token
Process:
JSON body type adds -X POST and Content-Type, the token becomes an Authorization header, the payload is single-quotedResult: curl \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer eyJhbGciOi...' \
--data-raw '{
"name": "example",
"active": true
}' \
https://api.example.com/v1/items
Input: POST https://api.example.com/login with Form fields name=ada&password=secret, Basic auth ada:hunter2
Process:
Basic auth becomes -u, each form pair becomes its own --data-urlencode flag, urlencoded Content-Type is addedResult: curl \
-H 'Content-Type: application/x-www-form-urlencoded' \
-u 'ada:hunter2' \
--data-urlencode 'name=ada' \
--data-urlencode 'password=secret' \
https://api.example.com/login
Input: DELETE https://api.example.com/v1/items/42 with custom header X-Request-Id: 8f14e45f
Process:
DELETE has no body so -X DELETE is explicit, the custom header is quoted, nothing is added that the user did not ask forResult: curl \
-X DELETE \
-H 'X-Request-Id: 8f14e45f' \
https://api.example.com/v1/items/42
Related Searches
People also search for: curl command builder, generate curl command, curl request generator, curl syntax helper, curl with headers, curl basic auth command.
curl command buildergenerate curl commandcurl request generatorcurl syntax helpercurl with headerscurl basic auth commandcurl bearer tokencurl post jsoncurl data urlencodecurl command onlinehttp request generatorrest api curl exampleshell quoting guideterminal http clientapi debugging tooldeveloper tool freebrowser based curlcopy curl snippet
Frequently Asked Questions
Why does the builder leave -X out for GET requests?
Because a bare curl followed by a URL already performs a GET, so the flag would be pure noise. The same reasoning applies to HEAD, which curl sends when asked for headers only. For POST, PUT, PATCH, DELETE and OPTIONS the method has to be stated, so the flag is emitted. If you are ever talking to an unusual endpoint that expects a verb curl would not guess, add it yourself as a custom header row and the command will include it.
Should I use -u or write an Authorization header by hand?
They produce the same request. -u 'user:pass' is a shorthand that base64-encodes the pair and sends an Authorization: Basic header for you, so it saves you from doing that encoding yourself. A hand-written header is only preferable when the credential scheme is custom, when the token contains characters you would rather inject from a file, or when the password itself contains a colon, since everything after the first colon is treated as the password.
Why does my JSON body need to be wrapped in single quotes?
Because your shell parses the command line before curl receives it, and an unquoted JSON body contains spaces, braces, quotes and colons that the shell treats as syntax. Without quotes, the payload is torn into several separate arguments and curl reports a confusing missing-data error. Inside single quotes every character is passed through literally, including the double quotes that JSON needs. This builder quotes any value that is not purely alphanumeric-safe, so the command is safe to paste as-is.
Does the builder add a Content-Type header for me?
Yes, but only when you have not supplied one yourself. Selecting the JSON body type adds Content-Type: application/json, and selecting Form fields adds Content-Type: application/x-www-form-urlencoded. If you already created a Content-Type header row, the builder skips its own so you never send the header twice with conflicting values. Sending JSON without any Content-Type is a common source of 400 errors, because the server defaults to form encoding and fails to parse your payload.
Is it safe to paste a real bearer token or password here?
Yes, in the sense that nothing is uploaded. The command is generated by JavaScript running in your browser tab, and the URL, credentials and headers never leave your machine or reach our servers. Nothing is stored, nothing is logged, and closing the tab discards the values. You still need normal care: a token typed into any web page could be exposed by a browser extension, and a command you paste into a shell will live in your shell history, so use a placeholder in shared examples.
How do I send form fields instead of a JSON body?
Select Form fields in the Request body section and type one name=value pair per line; ampersands on a single line also work because the builder splits on them. Each pair becomes its own --data-urlencode 'name=value' flag, and the Content-Type is set to application/x-www-form-urlencoded for you. Use percent encoding rather than raw ampersands in values that themselves contain reserved characters, otherwise the server receives a truncated field.
Why does adding a body change my method to POST?
That is cURL's own behaviour: when you attach data with -d or --data-raw and do not state a method, curl assumes POST. The builder reproduces this honestly rather than hiding it, so if the method dropdown still says GET when you add a body you will see -X POST appear. Choose the real method in the dropdown first, or fix it afterwards, so the request does not quietly create a resource where you meant to update one.