Satellite imagery
Cloud-image tiles from the AHI instrument on the Japan Meteorological Agency (JMA) Himawari-9 satellite. The data comes through NOAA Open Data. Instrument channels have one scene every 10 minutes and are kept for about 48 hours. The same endpoints serve all 16 raw channels (B01–B16) and 20 derived layers. Coverage is the Earth disk Himawari-9 can see. Outside the disk is transparent.
Shared rules (coordinates, caching, attribution, and full map examples) are in Map tiles.
Data license
Section titled “Data license”AttributionData: JMA Himawari-9 via NOAA Open Data, ExpTech Studio (exptech.dev)
- JMA Himawari-9 (via NOAA Open Data): The terms JMA and NOAA Open Data set for Himawari data also apply.
- NOAA: U.S. government data, generally free of use restrictions; do not imply NOAA endorses your product.
Where to show it, examples and commercial-use requests: Data licensing and attribution.
Authentication
Section titled “Authentication”No API Token is required.
Available times
Section titled “Available times”channelChannel 1–16, or a derived-layer name (see Channels and layers below). Only the canonical form is accepted. For example, 13 is valid and 013 is not.
curl --compressed "https://api.core-tnn1.exptech.dev/api/v2/tiles/satellite/<channel>/list"const res = await fetch("https://api.core-tnn1.exptech.dev/api/v2/tiles/satellite/<channel>/list");if (!res.ok) throw new Error(`HTTP ${res.status}`);const data = await res.json();console.log(data);import requests
res = requests.get( "https://api.core-tnn1.exptech.dev/api/v2/tiles/satellite/<channel>/list", timeout=10,)res.raise_for_status()print(res.json())Success (an empty array [ ] when there is no data). Gzip-compressed when the client supports it
[ 1794641400, 600, 600, 600]channel is not valid
bad channelServer error (plain-text error message)text/plain
Try it
Response fields
Section titled “Response fields”The response is a delta-encoded array of integers, oldest first, in Unix seconds. See Map tiles for how to decode it. A derived layer returns times when every channel it is built from is present, so a listed time can be drawn.
| Field | Type | Description |
|---|---|---|
[0] | integer | Time of the oldest entry, in Unix seconds. |
[i](i ≥ 1) | integer | Gap from the previous entry, in seconds. Add these up to get each time. |
https://static.core-tnn1.exptech.dev/api/v2/tiles/satellite/{channel}/{style}/{time}/{z}/{x}/{y}.webp channelChannel 1–16, or a derived-layer name.
stylenormal, jma, or bd. This only affects channels 7–16. Use normal for channels 1–6 and for derived layers.
timeUnix seconds. Use a value from the list. Any second inside the same 10-minute window maps to the same scene.
zZoom level, 0–11. Outside that range the response is a 1 × 1 transparent GIF.
xXYZ tile column.
yXYZ tile row (north to south).
curl -o output.webp "https://static.core-tnn1.exptech.dev/api/v2/tiles/satellite/<channel>/<style>/<time>/<z>/<x>/<y>.webp"const res = await fetch("https://static.core-tnn1.exptech.dev/api/v2/tiles/satellite/<channel>/<style>/<time>/<z>/<x>/<y>.webp");if (!res.ok) throw new Error(`HTTP ${res.status}`);const blob = await res.blob();import requests
res = requests.get( "https://static.core-tnn1.exptech.dev/api/v2/tiles/satellite/<channel>/<style>/<time>/<z>/<x>/<y>.webp", timeout=10,)res.raise_for_status()with open("output.webp", "wb") as f: f.write(res.content)image/webp, 256 × 256, with an alpha channel, lossy or lossless depending on the layer. Includes Cache-Control: public, max-age=300. If z is outside 0–11, the response is a 1 × 1 transparent GIF (image/gif)binary image/webp
If-None-Match matches the ETag. No contentNo response body
channel, style, time, or the coordinates are not valid
bad styleNo data for that time: not stored yet, or past the retention window (application/json)
{ "error": "Data not found for specified timestamp"}Server error. The body is a single newlineNo response body
Try it
Channels and layers
Section titled “Channels and layers”channel can be a raw channel number or a derived-layer name. Both accept only the canonical form in the tables below. The wrong case or a leading zero returns 400.
Channels 1-16
Section titled “Channels 1-16”| channel | Wavelength | Type | What it shows |
|---|---|---|---|
1 |
0.47 µm | Visible (blue) | Aerosols, dust, and smoke. Daytime only |
2 |
0.51 µm | Visible (green) | Vegetation. The green channel of true color. Daytime only |
3 |
0.64 µm | Visible (red) | Highest resolution (0.5 km). Cloud texture and surface outlines. Daytime only |
4 |
0.86 µm | Near-infrared | Water is dark and vegetation is bright. Coastlines and flooded areas. Daytime only |
5 |
1.6 µm | Near-infrared | Ice cloud and snow are darker. Separates cloud phase. Daytime only |
6 |
2.3 µm | Near-infrared | Cloud microphysics and hot spots on the surface. Daytime only |
7 |
3.9 µm | Shortwave infrared | Fog and low cloud at night, and fire hotspots |
8 |
6.2 µm | Water vapor | Upper-level water vapor, jet streams, and dry-air intrusions |
9 |
6.9 µm | Water vapor | Mid-level water vapor |
10 |
7.3 µm | Water vapor | Low-level moisture transport |
11 |
8.6 µm | Infrared | Cloud phase and SO₂ |
12 |
9.6 µm | Ozone | Stratospheric ozone |
13 |
10.4 µm | Infrared (atmospheric window) | Closest to the actual cloud-top or surface temperature. The most used infrared image |
14 |
11.2 µm | Infrared | Longwave infrared |
15 |
12.4 µm | Infrared | The difference from channel 13 separates dust and volcanic ash |
16 |
13.3 µm | CO₂ | Cloud-top height and thin cirrus |
Channels 1–6 show reflectance in grayscale (0% transparent to 100% white). There is no image at night. Channels 7–16 have an image day and night. Use style to switch the color scale.
style (channels 7-16 only)
Section titled “style (channels 7-16 only)”| style | Notes |
|---|---|
normal |
The grayscale JMA usually uses. Colder is whiter: 290 K is transparent, and 208 K is opaque white |
jma |
Cloud-top emphasis: warmer clouds stay grayscale, and the coldest cloud tops are colored (blue at the warm end, red at the cold end, a continuous ramp) |
bd |
Dvorak BD curve: a stepped scale for typhoon intensity analysis. Breakpoints at +9, −30, −41, −53, −63, −69, −75, and −81 °C |
Channels 1–6 and every derived layer ignore style, but the URL still needs that segment. Use normal.
Derived layers (20)
Section titled “Derived layers (20)”| channel | Contents | Built from | Update |
|---|---|---|---|
truecolor |
True-color RGB (JMA recipe), close to what the eye sees. Daytime only | Channels 3/2/1 | 10 minutes |
naturalcolor |
Natural-color RGB: separates ice cloud from water cloud, and vegetation from bare ground. Daytime only | Channels 5/4/3 | 10 minutes |
ash |
Volcanic-ash RGB (JMA recipe): volcanic ash and SO₂ plumes | 13−15 / 11−13 / 13 | 10 minutes |
dust |
Dust RGB (JMA recipe): dust and yellow dust | 13−15 / 11−13 / 13 | 10 minutes |
airmass |
Air-mass RGB (JMA recipe): dry stratospheric-air intrusions and warm, moist air masses | 10−8 / 13−12 / 8 | 10 minutes |
nightmicrophysics |
Night-microphysics RGB (JMA recipe): fog and low cloud at night | 13−15 / 7−13 / 13 | 10 minutes |
watervapor |
Water vapor (6.2 µm). Available day and night | Channel 8 | 10 minutes |
btd_split |
Split-window difference: dust and volcanic ash have the opposite sign from ordinary cloud | 13 − 15 | 10 minutes |
btd_fog |
Fog and low cloud at night | 7 − 13 | 10 minutes |
btd_wvirw |
Overshooting tops (deep convection) | 8 − 13 | 10 minutes |
btd_so2 |
Volcanic SO₂ and cloud phase | 11 − 13 | 10 minutes |
btd_co2 |
Thin cirrus and cloud height | 16 − 13 | 10 minutes |
btd_ozone |
Ozone and tropopause folds | 12 − 13 | 10 minutes |
cloudtop |
Cloud-top temperature (NOAA retrieval), 190–300 K | NOAA cloud-top height product | Hourly |
cloudmask |
Four-level cloud mask (clear to cloudy) | NOAA cloud-mask product | Hourly |
sst |
Sea-surface temperature, 271.15–305.15 K | NOAA CoastWatch ACSPO | Hourly |
tpw |
Total precipitable water, 0–75 mm | NOAA NESDIS Blended TPW | Hourly |
ndvi |
Vegetation index (B04−B03)/(B04+B03). Cloudy pixels are transparent | Channels 4 and 3, plus the cloud mask | Hourly |
ndwi |
Water index (B02−B04)/(B02+B04). Cloudy pixels are transparent | Channels 2 and 4, plus the cloud mask | Hourly |
mndwi |
Modified water index (B02−B06)/(B02+B06). Separates water from built-up areas. Cloudy pixels are transparent | Channels 2 and 6, plus the cloud mask | Hourly |
ndvi, ndwi, and mndwi are top-of-atmosphere indices without atmospheric correction. They are useful for seeing change and extent. They are not calibrated surface quantities.
Advanced examples
Section titled “Advanced examples”Add the latest scene for a channel in MapLibre GL JS: fetch the list, sum it to the latest time, then add the tile URL template as a raster source. Animation works the same way as radar. See Map tiles.
const API = "https://api.core-tnn1.exptech.dev";const STATIC = "https://static.core-tnn1.exptech.dev";
async function addLatestSatellite(map, channel = "13", style = "normal") { const list = await (await fetch(`${API}/api/v2/tiles/satellite/${channel}/list`)).json(); if (list.length === 0) return null; let t = 0; for (const v of list) t += v;
map.addSource("satellite", { type: "raster", tiles: [`${STATIC}/api/v2/tiles/satellite/${channel}/${style}/${t}/{z}/{x}/{y}.webp`], tileSize: 256, minzoom: 0, maxzoom: 11, attribution: "Data: JMA Himawari-9 via NOAA Open Data, ExpTech Studio (exptech.dev)", }); map.addLayer({ id: "satellite", type: "raster", source: "satellite", paint: { "raster-opacity": 0.85 } }); return t;}- A missing time returns 404 JSON. A 404 is kept for about 10 seconds. Use only times from the list. Scenes older than about 48 hours drop off the list.
timeis aligned to the start of a 10-minute window. Any second in that window returns the same scene.- Visible channels (1–6),
truecolor,naturalcolor, and the index layers have an image only in daylight. The list still includes nighttime. Tiles are transparent on the night side. - Hourly layers (
cloudtop,cloudmask,sst,tpw, and the three indices) usually show up more than 1.5 hours after the instrument channels. When there is no data yet, the list is an empty array[]. - Use
normal,jma, orbdforstyle.grayis the old name ofnormal. The public tile host rejects it (400). - An invalid
channelorstylereturns 400. Atime,z,x, orythat is not an integer returns 404 (the path does not match). - On the map, credit the source with the suggested attribution in Data license. When you use
cloudtop,cloudmask,sst,tpw, or the index layers, also add NOAA.
