Heat index calculator
At 90 °F and 70% humidity it feels like 105.9 °F. Enter the air temperature and relative humidity to get the official heat index, with the full regression in hot weather and a simpler estimate when it is cool. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Temperature (°F)
- 90
- Relative humidity (%)
- 70
- Heat index (°F)
- 105.9
- Calculation mode
- rothfusz
NWS free online
What the heat index tells you
The heat index is an apparent temperature: how hot the air feels once humidity is taken into account. The calculator first makes a simple estimate from the temperature and the relative humidity. If that estimate is below 80 °F, it is used as it is, because the full formula is unreliable in cool conditions. Otherwise it switches to the nine-term regression behind the official charts of the US National Weather Service, so 90 °F at 70% humidity reads as 105.9 °F.
Why results can jump near the edges
Two corrections apply only inside exact windows. In very dry heat, with humidity under 13% and temperatures from 80 to 112 °F, the index is pulled down. In muggy air, with humidity over 85% and temperatures from 80 to 87 °F, it is nudged up. Outside those windows the main formula stands alone, which is why two readings a few degrees apart can round to noticeably different values near the limits. Results show one decimal by default, and you can choose none or two.
The two adjustment corrections
When RH is below 13% and T is between 80°F and 112°F inclusive, it subtracts ((13-RH)/4) * sqrt((17-|T-95|)/17), which pulls the index down in very dry heat. When RH is above 85% and T is between 80°F and 87°F inclusive, it adds ((RH-85)/10) * ((87-T)/5), nudging the index up in muggy but only moderately hot air. Both branches operate only inside their exact temperature and humidity windows; outside them the base polynomial stands alone.
This is why two readings a few degrees apart can round to noticeably different apparent temperatures near those boundaries.
What you can do with it
Weather and safety dashboards
Turn raw station temp and humidity into an NWS apparent temperature for heat-advisory banners and worker-safety alerts.
Fitness and outdoor apps
Show athletes the heat index before a run, using the deterministic rothfusz value that matches official NWS charts.
FAQ
What formula does it use?
The NWS Rothfusz nine-term regression above 80°F, with the dry-air and humid-air corrections; below 80°F it returns the Steadman simple estimate.
Why does the response include a mode field?
mode is 'simple' when the estimate is below 80°F and 'rothfusz' when the full polynomial runs, so you know which calculation produced the value.
Why is the heat index lower in very dry heat?
When humidity is below 13% and the temperature is between 80 and 112 °F, a correction is subtracted from the result. It pulls the index down in very dry heat, exactly as the official formula does.
Why does muggy but moderate heat get a small boost?
When humidity is above 85% and the temperature is between 80 and 87 °F, a small amount is added to the result. That nudges the index up in muggy air that is only moderately hot.
Can I enter the temperature in Celsius?
The calculator works in degrees Fahrenheit, both for the air temperature you enter and for the heat index it returns, as the official charts do. Humidity is a percentage from 0 to 100.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/dev/heat-index \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"temp_f":90,"humidity":70}'const res = await fetch("https://api.kit.forhosting.com/dev/heat-index", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"temp_f": 90,
"humidity": 70
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev/heat-index",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"temp_f": 90,
"humidity": 70
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev/heat-index", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"temp_f":90,"humidity":70}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"temp_f":90,"humidity":70}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev/heat-index", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"temp_f": 90,
"humidity": 70
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev.heat_index",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Computes the NWS heat index (apparent temperature) in Fahrenheit from an air temperature temp_f and a relative humidity percentage, returning the value plus the mode (simple or rothfusz) used.
The Rothfusz regression and its low-heat fallback
If that estimate is below 80°F the result is the simple value with mode set to 'simple', because the full regression is unreliable in cool conditions. It first evaluates the Steadman simple estimate simple = 0.5 * (T + 61 + (T-68)*1.2 + RH*0.094), where T is temp_f and RH is humidity. Otherwise it switches to mode 'rothfusz' and applies the nine-term polynomial HI = -42.379 + 2.04901523*T + 10.14333127*RH - 0.22475541*T*RH - 0.00683783*T² - 0.05481717*RH² + 0.00122874*T²*RH + 0.00085282*T*RH² - 0.00000199*T²*RH².
Inputs, validation and rounding
The optional decimals parameter defaults to 1 and must be an integer from 0 to 2; out-of-range values are rejected. temp_f must be a finite number and is accepted across the whole real range; humidity must be a finite number between 0 and 100 inclusive, and anything outside that band throws a typed invalid_input error naming the offending field. A non-finite intermediate result also raises invalid_input. The response echoes temp_f and humidity and reports which mode produced the number, so callers can tell a simple estimate from a full-regression value.
Integration use cases
IoT and HVAC telemetry
Batch thousands of sensor readings through the API to log felt temperature alongside measured temperature for comfort analytics.
Technical questions
What units are expected?
temp_f in degrees Fahrenheit and humidity as a relative humidity percentage from 0 to 100. The result heat_index_f is also in Fahrenheit.
How is the result rounded?
By a half-up rule to the decimals you pass (0 to 2, default 1), applied to the exact computed value rather than a toFixed string.
Is it free and how much is the API?
The on-page widget is free (tier A) and runs the same deterministic core; the API is billed per successful call from $0.002.