If you run APIs over HTTPS, HSTS looks like an easy win. Set one header, tell clients to never use HTTP again, and reduce downgrade and cookie leakage risks. That’s the sales pitch.

For browser-facing traffic, I’m generally a fan. For API endpoints, the answer is more nuanced. HSTS absolutely helps in some API deployments, does almost nothing in others, and can create operational headaches if you roll it out carelessly.

Here’s the practical comparison.

What HSTS actually does

Strict-Transport-Security tells browsers that a host should only be contacted over HTTPS for a period of time.

Example:

Strict-Transport-Security: max-age=31536000; includeSubDomains

Once a browser sees that over HTTPS, future requests to the same host get upgraded to HTTPS before the request leaves the client.

That matters because a plain HTTP request can be intercepted or redirected before your app has a chance to respond with a 301 or 308.

The official spec is here:

The first big caveat: HSTS is mostly a browser control

This is the part teams miss all the time.

If your API is consumed by:

  • server-to-server clients
  • backend jobs
  • mobile apps using native networking stacks
  • CLI tools
  • SDKs
  • IoT devices

…HSTS often has little or no effect unless that client explicitly implements HSTS behavior.

Browsers enforce HSTS. Most non-browser API clients do not.

So if your API is purely machine-to-machine, HSTS is usually nice to have for consistency, not a primary defense.

If your API is called from browser JavaScript, loaded by SPAs, or used in authenticated web apps, HSTS matters a lot more.

Where HSTS helps for APIs

1. Browser-based API calls

If your frontend calls:

https://api.example.com

from a browser app, HSTS protects repeat visits from protocol downgrade attempts.

That matters for:

  • session-based APIs
  • browser clients using bearer tokens
  • cookie-authenticated API calls
  • internal admin APIs used from web dashboards

Without HSTS, a user typing example.com or following an old http:// bookmark can still hit insecure transport first, at least once.

2. Reducing accidental HTTP usage

Even inside engineering teams, people copy old URLs into docs, tests, and curl examples. HSTS helps browsers self-correct after the first secure response.

That won’t fix bad SDK defaults, but it does reduce human error in browser contexts.

3. Better alignment with a strict HTTPS-only posture

If your policy is “this domain never serves HTTP,” HSTS is the clean signal to back that up.

I like it when the infrastructure story is consistent:

  • HTTPS everywhere
  • secure cookies
  • redirects from HTTP to HTTPS
  • HSTS on HTTPS responses
  • no mixed-content nonsense
  • no legacy HTTP endpoints hanging around

Where HSTS does not help much

1. Pure server-to-server APIs

If one service calls another with a proper HTTPS base URL, certificate validation, and no fallback to HTTP, HSTS doesn’t buy you much.

Your real controls are:

  • hardcoded https:// endpoints
  • TLS validation
  • certificate pinning where justified
  • service discovery policy
  • mTLS where needed
  • network segmentation

I would not treat HSTS as meaningful protection for internal service mesh traffic.

2. Mobile apps and SDK clients

Many teams assume HSTS protects their mobile API traffic. Usually it doesn’t.

iOS and Android networking stacks may enforce their own transport security rules, but that is not the same thing as browser HSTS. If your mobile app must never use HTTP, enforce that in app config and code, not by hoping HSTS will save you.

3. First-visit protection without preload

HSTS only works after the browser has seen the header once, unless the domain is preloaded.

That first request problem is real. If a user’s first contact starts with plain HTTP, an attacker can interfere before the HSTS policy is learned.

For APIs on separate subdomains like api.example.com, this is easy to overlook.

Pros of enabling HSTS on API endpoints

Stronger browser-side transport guarantees

For browser-consumed APIs, this is the biggest win. After policy is cached, HTTP is effectively off the table.

Cheap to deploy

Compared to mTLS, cert lifecycle work, or auth redesigns, setting HSTS is easy.

For NGINX:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

For Apache:

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

For Express behind HTTPS:

app.use((req, res, next) => {
  res.setHeader(
    "Strict-Transport-Security",
    "max-age=31536000; includeSubDomains"
  );
  next();
});

Helps prevent insecure habits from sticking

Once browsers learn the policy, old http:// links and accidental insecure navigation stop being a problem for that host.

Works well with secure cookies

If your API uses cookies for auth, HSTS complements Secure cookies nicely. It reduces the chance of cookies ever being exposed over HTTP due to downgrade or user error.

Cons of enabling HSTS on API endpoints

Limited value for non-browser clients

This is the biggest downside conceptually: teams overestimate what it does.

If your consumers are machines, not browsers, HSTS can become security theater unless you’re honest about the threat model.

Bad rollouts can break subdomains

includeSubDomains is powerful and dangerous.

If you set:

Strict-Transport-Security: max-age=31536000; includeSubDomains

on example.com, you are saying every subdomain must be HTTPS-only for a year.

That can break:

  • old internal tools
  • forgotten staging environments
  • vanity subdomains
  • mail-related hosts with web interfaces
  • legacy partner integrations

I’ve seen teams lock themselves out of weird forgotten subdomains this way.

Hard to undo quickly

If you ship a long max-age, browsers cache it. You can later send max-age=0, but only to clients that can still reach you over HTTPS. If you’ve already broken access patterns, cleanup is not instant.

That’s why I prefer a staged rollout.

Preload is a serious commitment

Preloading can solve the first-visit problem, but it’s not a casual checkbox.

Preload means browsers ship your domain as HTTPS-only by default. Great when you’re ready. Painful if you’re not.

Typical preload requirements include:

  • valid HTTPS on the base domain
  • redirect from HTTP to HTTPS
  • HSTS with long max-age
  • includeSubDomains
  • preload

Example:

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

If you have any shaky subdomain hygiene, don’t rush this.

Official preload guidance is here:

Comparison: when HSTS is worth it for APIs

Public API used from browsers

Verdict: Yes, usually worth it.

Examples:

  • SPA calling api.example.com
  • admin dashboard using cookie auth
  • B2B portal making XHR/fetch requests from user browsers

You should treat HSTS as standard hardening here.

Public API used only by server-side clients

Verdict: Fine, but low impact.

Set it if you want consistency across your estate, but don’t pretend it materially secures your integrations.

Internal microservice API

Verdict: Usually low priority.

Focus on TLS enforcement, cert validation, identity, and network policy first.

Mobile-app backend API

Verdict: Helpful only if the same host is also used in browsers.

Otherwise, app transport controls matter more than HSTS.

A sane rollout strategy

I wouldn’t jump straight to one year plus includeSubDomains unless your inventory is clean.

Start small:

Strict-Transport-Security: max-age=300

Then increase after validation:

Strict-Transport-Security: max-age=86400

Then move to something long-lived:

Strict-Transport-Security: max-age=31536000

Only add includeSubDomains after you’ve audited all subdomains. Only add preload when you’re truly confident.

That staged approach avoids turning a good security header into an outage generator.

What to check before enabling it

  • Does every relevant hostname support HTTPS correctly?
  • Are any browser clients still using http:// URLs?
  • Do you rely on any legacy HTTP-only subdomains?
  • Are cookies marked Secure and ideally HttpOnly and SameSite where appropriate?
  • Do redirects from HTTP to HTTPS work cleanly?
  • Are staging and test domains separated from production policy decisions?

If you want a quick sanity check on your headers, run a scan at HeaderTest.

My rule of thumb

For APIs touched by browsers: enable HSTS unless you have a very specific reason not to.

For APIs that are purely machine-to-machine: enable it if you want consistency, but spend your actual security budget elsewhere first.

That’s the honest comparison. HSTS is great at what it does. People just keep expecting it to solve problems outside its lane.