Skip to content
Control Plane Labs

curl Command Builder Guide

Turn an HTTP request into a readable curl command, then check quoting, query encoding, redirects, authentication, and the browser fetch equivalent.

Control Plane Labs Staff

Published September 19, 2026

The curl command builder is a request composer, not an HTTP client. It does not send the URL you type or execute an imported command. That makes it useful when a browser’s “Copy as cURL” output is too dense to review, or when you want to prepare a request without accidentally mutating a production resource.

What belongs in a curl command?

The basic shape is:

curl [options] 'https://api.example.test/v1/widgets?limit=10' 

curl treats arguments that are not options as URLs, supports multiple URLs, and writes the response body to standard output by default. Its command-line manual also documents -- as the end of option parsing, which is useful when a URL begins with a dash-like value or when a generated command must make its boundary explicit.

For an API request, make four decisions before choosing flags:

  1. Target: the scheme, host, path, and query parameters.
  2. Method: usually GET, POST, PUT, PATCH, or DELETE.
  3. Headers: content type, accepted response type, correlation IDs, or an authorization header.
  4. Content: a JSON document, form fields, or a file upload.

The request method and content have meaning together. HTTP Semantics defines GET as retrieval, HEAD as the header-only counterpart to GET, POST as processing content by the target resource, and PUT as a request to create or replace the state of a target resource. A builder can emit the syntax, but only the API contract can tell you which method is safe for a particular endpoint.

Encode the URL before you encode the shell

There are two parsers to satisfy: the shell and the URI grammar. A query begins after ?, pairs are separated by &, and a fragment begins after #; those components are defined in RFC 3986, Section 3. Characters such as &, ?, *, {, and } can also have meaning to a shell or to curl’s URL globbing. Put the complete URL in quotes when it contains those characters, and disable curl globbing with --globoff when braces or brackets are literal URL data.

Percent-encoding is not the same as shell quoting. Percent-encoding represents an octet inside a URI component; shell quoting keeps the shell from splitting or expanding the argument. A value such as status=ready&owner=ops needs shell protection even though the query itself is valid. If a query value contains spaces, #, or a literal &, encode that value as a component rather than replacing the whole URL by hand. The URL encoder/decoder helps with one value; the curl manual’s URL section explains how curl treats the resulting URL.

The builder should emit one clearly quoted URL. In POSIX shells, single quotes preserve every character except a single quote. The POSIX shell language specification describes why an embedded quote must be closed, escaped, and reopened as '\''. That sequence is safer than double quotes for values containing $, backticks, or backslashes.

Pick the body flag that matches the payload

For a small JSON request, make the content type explicit and preserve the body as text:

curl 'https://api.example.test/v1/widgets' \
  --request POST \
  --header 'Content-Type: application/json' \
  --data-raw '{"name":"demo","enabled":true}'

The curl option reference distinguishes --data-raw, --data-binary, --data-urlencode, and multipart --form. That distinction matters:

  • --data-raw sends the supplied string without treating a leading @ as a local filename.
  • --data-binary is appropriate when newlines and bytes must remain unchanged, including a file supplied with @path.
  • --data-urlencode percent-encodes a field or value for form-style input.
  • --form builds a multipart/form-data request, commonly for a file plus fields.

Do not put a password, API key, or bearer token into a command you plan to paste into a ticket or commit: shell history, terminal recording, process inspection, and CI logs can retain arguments. Use a placeholder while composing, then inject the secret through a runtime secret store. A JSON formatter can check the body before you put it behind --data-raw.

Treat redirects and authentication as separate choices

curl does not follow HTTP redirects unless you ask it to with --location or -L. The curl HTTP scripting guide explains that following a redirect can issue a new request to a different URL. HTTP semantics also distinguish redirect status codes: 307 and 308 preserve the method and content, while the historical behavior associated with 301, 302, and 303 can result in a POST becoming a GET. RFC 9110, Section 15.4 defines those redirect semantics.

That is why a builder should show redirect behavior as an explicit checkbox instead of silently adding -L. When debugging, begin with:

curl --head --verbose 'https://api.example.test/v1/widgets'

--head asks for headers without a response body, while --verbose shows the request and response exchange. The curl documentation calls --verbose a practical first diagnostic.

Basic authentication is also not encryption. RFC 7617 defines credentials as a user ID and password encoded with Base64, and requires TLS for confidentiality. Prefer a secret-aware mechanism over embedding credentials in a URL: RFC 3986 warns that userinfo can be displayed, logged, or stored by intermediaries. If an API uses a bearer token, show the header shape with a placeholder:

curl 'https://api.example.test/v1/widgets' \
  --header 'Authorization: Bearer REPLACE_WITH_TOKEN'

Compare the shell command with browser fetch

The browser equivalent is useful for a frontend handoff, but it is not a mechanical translation of every curl option:

fetch("https://api.example.test/v1/widgets", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer REPLACE_WITH_TOKEN"
  },
  body: JSON.stringify({ name: "demo", enabled: true }),
  redirect: "manual"
});

The Fetch RequestInit reference defines follow, error, and manual redirect modes, while browser credentials and CORS rules add constraints that a terminal client does not have. A curl command can read a local file path, skip certificate verification with --insecure, or connect through a proxy in ways that browser JavaScript cannot safely reproduce. Treat an untranslatable option as a visible warning, not as a silently altered request.

A three-step review before you run it

  1. Read the target. Confirm hostname, path, query, method, and whether the request changes state. Compare it with the service contract.
  2. Inspect sensitive fields. Replace credentials with placeholders, check that the URL has no secret userinfo, and review the body for customer data. Use the HTTP header inspector for a response you control.
  3. Run a harmless diagnostic. Use --head or a read-only endpoint, add --verbose only when needed, and keep --location off until you review the target. The HTTP status reference explains an error code; it cannot decide whether retrying is safe.

Use the builder when you want an editable, shareable request shape. Then keep the generated command beside the runbook that explains its method, authorization, expected status, and rollback. For proxy changes, compare it with the Nginx and Caddy reverse proxy guide so the request tests the boundary you actually operate.

Frequently asked questions

Does curl follow redirects by default?+
No. Add `--location` or `-L` explicitly. Review the redirect status and target first, because method and body preservation differ between redirect codes.
What is the difference between --data-raw and --data-binary?+
`--data-raw` sends the supplied text without treating a leading `@` as a filename. `--data-binary` preserves the supplied bytes, which is useful for an exact file or newline-sensitive payload.
Is Basic authentication encrypted?+
No. Basic authentication encodes a user ID and password with Base64. Use it only over TLS and keep credentials out of URLs, shell history, tickets, and source control.
Can every curl option become browser fetch code?+
No. Browser security, CORS, file access, proxy behavior, and certificate handling limit the translation. A good converter marks options that need a manual browser-specific replacement.
Why should a URL be quoted in a shell?+
Quoting prevents the shell from splitting or expanding characters such as `&`, `?`, `*`, braces, and brackets. It is separate from percent-encoding the URI's query values.
How can I inspect what curl sends?+
Use `--verbose` for a readable request and response exchange. Use `--trace` or `--trace-ascii` for a fuller diagnostic, and remove sensitive trace files after review.

Tags: #curl, #http, #cli, #api, #web-development