The differences at a glance
| HTTP | HTTPS | |
|---|---|---|
| URL scheme | http:// | https:// |
| Default port | 80 | 443 |
| Encryption | None; sent as readable text | TLS |
| Can be read in transit | Yes | No |
| Can be altered in transit | Yes, undetectably | No; tampering breaks the connection |
| Server identity checked | No | Yes, by certificate |
| Needs a certificate | No | Yes |
| HTTP/2 and HTTP/3 in browsers | Not available | Available |
What TLS adds
TLS gives a connection three properties, and each defeats a different attack.
- Confidentiality. The traffic is encrypted, so a shared Wi-Fi network, an internet provider or a compromised router sees only scrambled bytes.
- Integrity. Every record is authenticated. If anything in between alters a byte — to inject an advert, or to change an account number — the receiver detects it and drops the connection.
- Authentication. The server presents a certificate, signed by an authority the client already trusts, proving it controls the domain name in the URL. Without this, encryption alone would only guarantee a private conversation with whoever answered.
All three are set up in the TLS handshake, before the first HTTP byte is sent. With TLS 1.3 that costs one extra round trip on a new connection, and nothing on a reused one.
What HTTPS hides, and what it does not
A common misreading is that HTTPS hides only the body. It hides nearly everything that belongs to HTTP, including the part of the URL after the host.
| Encrypted | Still visible to the network |
|---|---|
| URL path and query string | The server's IP address and port |
Request and response headers, including Authorization and cookies | The hostname, sent in the handshake's SNI field and in the DNS lookup before it |
| Request and response bodies | Roughly how much data moved, and when |
| The status code | That a TLS connection took place at all |
So an observer can tell that you connected to api.example.com, and cannot tell which
endpoint you called or what you sent. Encryption also ends at the server. A key placed in a query string
is protected on the wire and then written in clear to the server's access log, which is one reason to
send API keys in a header instead.
The redirect trap for API clients
Websites commonly answer a plain HTTP request with a redirect to the HTTPS address. For a person in a browser this is invisible. For an API call it causes two separate problems.
The secret has already gone. A redirect is a response, and a response comes after the
request. If your client sent Authorization: Bearer … to an http:// address,
the key crossed the network unencrypted before the server had any chance to say “use HTTPS”.
The request may be rewritten. On a 301 or
302, many clients change a POST into a
GET and drop the body, so a create request quietly turns into a read and comes back
405 or with unexpected data. Only
307 and 308 oblige the client
to repeat the method and body unchanged.
For those reasons many APIs do not redirect at all: they refuse plain HTTP with an error, or do not
listen on port 80. Treat https:// as part of the API's address, and if a request that
should work returns a redirect, check the scheme first. The
curl follow-redirect example shows how to see each hop.
Certificates, and how they fail
The certificate is what makes authentication work, and it is where HTTPS usually breaks. The client checks that the certificate is inside its validity dates, that it names the host in the URL, and that it chains up to an authority in the client's trust store. Any failure stops the connection before a request is sent, so there is no status code to read, only a client error.
| Symptom | Usual cause |
|---|---|
| Certificate has expired | Renewal failed or was forgotten |
| Hostname does not match | Calling by IP address, or a host the certificate does not list |
| Unable to get local issuer certificate | The server is not sending its intermediate certificate |
| Self-signed certificate | A development or internal server with no public authority behind it |
| Works in a browser, fails in a script | The script's runtime has an older or different trust store |
Switching verification off, as curl -k does, removes authentication and leaves only
encryption to an unknown party. It is acceptable against your own development server and nowhere else;
the curl ignore-certificate page covers the safer alternatives.
To see which of these applies to a particular server, the SSL checker connects to it and reports the chain, the names on the certificate and the days left before it expires.
HSTS: making the browser refuse HTTP
A redirect from HTTP to HTTPS still begins with one unprotected request, and an attacker on the network
can intercept that request and keep the victim on HTTP. The Strict-Transport-Security
response header closes the gap for browsers:
Strict-Transport-Security: max-age=31536000; includeSubDomains
After seeing it once over HTTPS, the browser rewrites every http:// link to that site into
https:// before sending anything, for as long as max-age says. It is a browser
feature: most HTTP libraries and command-line clients ignore the header, so API clients need the correct
scheme in their configuration. The HTTP headers guide covers the
related security headers.
When plain HTTP is still fine
On localhost during development, where the traffic never leaves your machine; browsers
treat it as a secure context for that reason. Inside a private network where TLS is handled by a load
balancer in front of the service, although many teams now encrypt internal hops as well. And for the
redirect listener on port 80 whose only job is to send browsers to HTTPS. A public API has no case for
it.
Check it yourself
Send a request to http://github.com from the API tester and read the
response: a 301 with a Location header pointing at
the HTTPS address. Then request https://github.com and look for
strict-transport-security among the response headers. From a terminal,
curl -v https://example.com prints the TLS version, the cipher and the certificate's
subject and expiry before the HTTP exchange; the curl HTTPS example
explains each line. One limit worth knowing: this site's tester sends requests from its own server, so
it shows how an endpoint answers the public internet, not what your own network does to the traffic.
References
- RFC 9110: the https URI scheme — How HTTP defines HTTPS, including the default port and certificate verification.
- RFC 8446: TLS 1.3 — The current version of the protocol underneath HTTPS.
- RFC 6797: HTTP Strict Transport Security — The specification for the HSTS header.
- MDN: Strict-Transport-Security — Syntax, directives and browser behaviour.
These links leave api-tester.com, which is independent of the organisations they point to.
Frequently asked questions
What is the difference between HTTP and HTTPS?
HTTPS is HTTP carried inside a TLS connection. The requests and responses are identical, but they are encrypted, protected against tampering, and sent only after the client has verified the server's certificate. Plain HTTP has none of those protections.
What port does HTTPS use?
Port 443 by default, where HTTP uses port 80. Either can run on another port if the URL names it, as in https://example.com:8443/.
Does HTTPS encrypt the URL?
It encrypts the path and query string, along with all headers and the body. The hostname is still visible to the network through DNS and the TLS handshake, and the full URL is visible to the server, which may log it.
Is HTTPS slower than HTTP?
Barely. A new TLS 1.3 connection needs one extra round trip, and reused connections need none. Because HTTP/2 and HTTP/3 are only offered by browsers over HTTPS, a secure site is often faster in practice.
Can an API be called over plain HTTP?
Only if the provider allows it, and it should not be. Any key or token in the request would cross the network unencrypted. Many APIs reject plain HTTP outright instead of redirecting, because a redirect arrives after the secret has already been sent.
Why does my POST fail after an HTTP to HTTPS redirect?
On a 301 or 302 redirect many clients resend the request as a GET without its body, so the server receives a different request from the one you wrote. Call the https:// address directly; 307 and 308 are the redirect codes that preserve the method.