The command
curl -u ada:s3cret https://httpbin.org/post \
-H "Content-Type: application/json" \
-d '{"name":"report","format":"pdf"}'
Opens the request console with this request filled in. It is sent from api-tester.com's server rather than from your machine, so it shows what the endpoint returns, not how your own network or curl build behaves.
What the flags do
| Flag | What it does |
|---|---|
-u user:password | Adds the Authorization: Basic header and changes nothing else. |
-d data | The body. Its presence is what makes the request a POST. |
-H "Content-Type: ..." | Describes the body. Unrelated to the credentials. |
-i | Prints the status line, the quickest way to tell which half failed. |
Which half failed
Servers check the header before they look at the body. A 401 therefore tells you nothing about your data: it was never parsed. A 400, 415 or 422 means the opposite, that the login was accepted and the complaint is about the body or its Content-Type. Fix whichever half the status code points to and leave the other alone.
The body can be any kind. Here the same credentials accompany ordinary form fields instead of JSON.
curl -i -u ada:s3cret \
-d "title=Q3 report" -d "visibility=private" https://httpbin.org/post
The one you will meet most: an OAuth token request
The commonest real POST with Basic authentication is the OAuth client-credentials grant. The client id and client secret go in -u, the grant type goes in a form body, and the response is a JSON document containing an access token for later requests. If the secret contains characters such as +, / or % and the server rejects it, the specification's rule is that both values are URL-encoded before curl sees them.
curl -u "$CLIENT_ID:$CLIENT_SECRET" \
-d "grant_type=client_credentials" -d "scope=orders.read" \
https://auth.example.com/oauth/token
When the scheme is not Basic after all
With Basic, curl attaches the header up front and the POST happens in one request. Challenge-based schemes take two. With --digest curl knows the first attempt will be refused, so it sends that one with an empty body and transmits your data only on the second, authenticated request. With --anyauth it cannot know in advance and sends the full body both times, which fails for data piped in from standard input because a pipe cannot be read twice.
curl --digest -u ada:s3cret -d "title=Q3 report" https://api.example.com/reports
curl --anyauth -u ada:s3cret --data-binary @report.json https://api.example.com/reports
Common mistakes
- Username and password as body fields is a different mechanism. A website login form reads them from the body and answers with a cookie; it ignores
-uentirely. - A successful login says nothing about the write. If the request times out, check whether the record was created before posting it again.
- Over plain HTTP both halves are exposed: the password and the data travel readable by anyone on the path.
Related curl examples
Curl Basic Auth Example
-u takes a username and password and turns them into an Authorization: Basic header.
Curl POST Example
Curl switches to POST the moment you give it a body.
Curl POST JSON Example
Sending JSON takes two things: the JSON itself and a header saying that is what it is.
Curl -u Flag Example
-u hands curl a username and a password.
All Curl Examples
49 worked examples, grouped by what you are trying to do.
More under Authentication
References
- curl man page: -u — Supplying a username and password.
- RFC 6749: OAuth 2.0 — The specification behind the client-credentials token request.
These links leave api-tester.com, which is independent of the projects they point to.
FAQ
How do I send a POST request with Basic authentication in curl?
Combine -u username:password with a body flag, for example curl -u ada:s3cret -d "name=report" URL. Curl adds the Authorization header and sends the data as the POST body.
Do the username and password go in the POST body?
No. With Basic authentication they travel in the Authorization header. Only login forms expect credentials as body fields.
How do I POST JSON with Basic auth in curl?
Add -u username:password to a JSON POST: curl -u user:pass -H "Content-Type: application/json" -d '{"key":"value"}' URL.