ScreenshotNeo

BlogHow-to

Basic Auth in cURL: A Complete Guide

Use HTTP Basic Auth safely with cURL: syntax, HTTPS, prompts, secret handling, redirects, proxies, troubleshooting, and automation examples.

By the ScreenshotNeo team1 October 20267 min read

Use --user (or -u) to send HTTP Basic Authentication with cURL:

curl --user 'username:password' https://example.com/

Use an https:// URL because Basic Auth only encodes the credentials; TLS protects them in transit. For interactive work, omit the password and let cURL prompt:

curl --user username https://example.com/

cURL splits the username:password value at the first colon, so this form cannot represent a username containing a colon. Basic Auth is for an HTTP server; it is different from a website login form that creates a session cookie.

What Basic Auth sends

The client sends an HTTP Authorization header containing the username and password encoded with Base64. Base64 is not encryption. Over plain HTTP, a network observer can recover the credentials, so credential-bearing requests should use HTTPS.

GET /private HTTP/1.1
Host: example.com
Authorization: Basic <base64(username:password)>

When you need to verify what the server supports, inspect the response headers:

curl -i https://example.com/private

A protected endpoint commonly returns 401 Unauthorized with a WWW-Authenticate challenge. Confirm that the challenge includes Basic before assuming this is the correct scheme.

Basic Auth command patterns

Known username and password

curl --user 'alice:s3cret' https://example.com/private

The short equivalent is:

curl -u 'alice:s3cret' https://example.com/private

Prompt for the password

Leaving out the password keeps it out of shell history and avoids putting it directly in the command line:

curl --user alice https://example.com/private

cURL prompts on the terminal. This is usually the safest interactive option.

Make the method explicit

Basic is cURL’s default HTTP authentication method when no other method is selected, but --basic makes the intent clear:

curl --basic --user 'alice:s3cret' https://example.com/private

Send a JSON request

curl --user 'alice:s3cret' \
  --header 'Content-Type: application/json' \
  --data '{"enabled":true}' \
  https://example.com/api/settings

Write the response to a file

curl --user 'alice:s3cret' https://example.com/report \
  --output report.json

Show request and response diagnostics

Use --verbose when debugging TLS, redirects, headers, or status codes. Be careful: verbose output can expose sensitive headers in logs.

curl --verbose --user alice https://example.com/private

Protecting credentials

Why command-line passwords can leak

Arguments may be visible in process listings, shell history, CI logs, terminal recordings, or monitoring systems. Avoid embedding a live password in a command that other users or automation can read.

Use a protected cURL config file

Put credentials in a file readable only by the account that needs them:

cat > ~/.curl-auth.conf <<'EOF'
user = "alice:s3cret"
url = "https://example.com/private"
EOF
chmod 600 ~/.curl-auth.conf
curl --config ~/.curl-auth.conf

Keep the file out of source control and delete or rotate it when it is no longer needed.

Use stdin or your runtime’s secret store

For automation, retrieve the secret from the CI platform, operating-system secret store, or another protected mechanism, then provide it without committing it to code. Do not print the variable or include it in diagnostic output.

read -r -s CURL_PASSWORD
printf '%s\n' "$CURL_PASSWORD" | \
curl --user "alice:$(cat)" https://example.com/private

For a non-interactive job, prefer the job runner’s secret injection and restrict environment and process visibility. Rotate credentials if they appear in logs or command history.

Choosing an authentication method

Situation cURL approach Trade-off
You know the endpoint requires Basic --basic --user Clear and direct.
The server’s scheme is unknown --anyauth --user cURL examines the challenge and chooses a supported method; this can add a request/response round trip.
The credentials are for an HTTP proxy --proxy-user or -U Authenticates to the proxy, not the destination server.
The site has a login page Use the site’s documented form, token, or cookie flow A form login is not automatically HTTP Basic Auth.

Let cURL discover the server method

curl --anyauth --user 'alice:s3cret' https://example.com/private

Use this only when discovery is useful. If the API documentation says Basic, selecting it explicitly avoids the extra negotiation.

Proxy authentication

Use separate proxy credentials when the proxy requests authentication:

curl --proxy http://proxy.example:8080 \
  --proxy-user 'proxyuser:proxypass' \
  https://example.com/private

If the proxy specifically requires Basic, add --proxy-basic. Destination credentials still use --user and should not be confused with proxy credentials.

Redirects and credential forwarding

--location follows HTTP redirects. cURL normally keeps supplied credentials scoped to the original host and does not forward them to a different host automatically.

curl --location --user 'alice:s3cret' https://example.com/start

--location-trusted permits forwarding credentials to other hosts. Use it only when every redirect destination is trusted and the behavior is intentional:

curl --location-trusted --user 'alice:s3cret' https://example.com/start

Do not use --location-trusted as a routine redirect fix. A compromised or unexpected redirect target could receive the credentials.

Complete runnable examples

Shell script with status handling

#!/usr/bin/env bash
set -euo pipefail

endpoint='https://example.com/private'
username='alice'

curl --fail-with-body \
  --silent --show-error \
  --user "$username" \
  --output response.json \
  "$endpoint"

echo 'Saved authenticated response to response.json'

This prompts for the password, fails on HTTP errors while preserving the response body, and avoids printing the response in the terminal.

cURL API request with an explicit header

You can construct the header yourself, but --user is less error-prone:

credentials=$(printf '%s' 'alice:s3cret' | base64)
curl --header "Authorization: Basic $credentials" \
  https://example.com/private

Use a portable Base64 implementation and protect the resulting command and variable. Never send the header over plain HTTP.

Common errors and fixes

Symptom Likely cause Fix
401 Unauthorized Wrong credentials, wrong endpoint, or the server expects another scheme. Check the username and password, inspect WWW-Authenticate with curl -i, and confirm the API documentation.
Credentials appear in logs Password was supplied as a command-line argument or verbose output was retained. Prompt for the password, use a protected config file or secret store, and remove or rotate exposed credentials.
Credentials work directly but fail after a redirect The redirect changes host or the server requires authentication at the final URL. Inspect redirects with --verbose; avoid cross-host forwarding unless trusted. Use --location-trusted only deliberately.
Proxy returns 407 Proxy Authentication Required The proxy needs credentials. Use --proxy-user and, if required, --proxy-basic. Keep proxy and server credentials separate.
It works in a browser but not cURL The browser used a form login, cookie, CSRF token, JavaScript flow, or a different endpoint. Use the service’s API authentication documentation; HTTP Basic Auth is not equivalent to a website login form.
Password contains shell punctuation The shell interpreted characters before cURL received them. Quote the value carefully, prefer an interactive prompt or protected config, and avoid embedding secrets in scripts.
Username contains a colon --user splits at the first colon. Use the server’s supported alternative or a different credential format; this syntax cannot represent that username unambiguously.
TLS or certificate errors Certificate validation, hostname, proxy, or local trust configuration is wrong. Fix the certificate or trust store. Do not disable verification as a password workaround.

Performance, reliability, and cost notes

  • Round trips: Explicit --basic avoids authentication discovery. --anyauth may require an additional challenge round trip.
  • Connection reuse: Reusing a cURL process or HTTP connection can reduce handshake overhead for multiple requests. Separate one-shot commands cannot share that connection.
  • Retries: Retry only requests that are safe to repeat or are protected by an idempotency mechanism. A retry does not fix invalid credentials and can repeat a state-changing request.
  • Timeouts: Set connection and total-operation limits in automation so a stuck network does not block a job indefinitely.
  • Logs: Keep verbose mode off in normal production runs and redact authorization headers in any captured diagnostics.
  • Cost: cURL itself does not require a per-request service charge. Your network, API provider, proxy, and server may have their own costs or limits.

Or skip the browser setup

If your next step is taking authenticated website screenshots, ScreenshotNeo provides a single GET request and accepts custom headers, cookies, user agents, and Authorization values. See the API documentation for all options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and each response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server lets Claude, Cursor, and other MCP clients call take_screenshot, get_page_info, and capture_pdf. The Free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000 shots.

Create a free ScreenshotNeo account and start with 1,000 screenshots per month at no charge.

FAQ

Does cURL encrypt Basic Auth?

No. Basic Auth is Base64 encoding. HTTPS encryption protects it while it travels between client and server.

Should I use -u or an Authorization header?

Use -u for normal requests. It lets cURL format the header correctly and keeps the command readable.

Can I use Basic Auth with POST, PUT, or DELETE?

Yes. Authentication is independent of the HTTP method; add the appropriate cURL method and request body.

Why does the server return 403 after accepting my credentials?

403 Forbidden usually means the identity is authenticated but lacks permission for that resource. Check roles, scopes, account status, and endpoint policy.

How do I know whether a proxy or the destination rejected the request?

A proxy authentication failure commonly uses 407; a destination authentication failure commonly uses 401. Use --verbose carefully to inspect the hop and response headers.

Where can I find the exact options supported by my cURL build?

Run curl --help and man curl, or consult the current cURL documentation. Build features such as some authentication methods can vary.