Science & Math — entry 024 of 28

Sunrise and Sunset

Verified Jul 2026

Sunrise-Sunset.org's v2 API is a free, keyless REST service returning sunrise, sunset, twilight, golden-hour, solar-position, and moon data for any latitude/longitude, as JSON over either HTTPS or plain HTTP (the latter aimed at TLS-incapable IoT devices like Arduino boards). No sign-up or key is required, but the provider asks callers to display a visible attribution link back to sunrise-sunset.org.

Sunrise-Sunset.org answers keyless GETs for a `lat`/`lng` pair with sunrise, sunset, twilight, golden/blue-hour, solar-position, and moon data for that day. Two versions answer today: v2 (this quickstart's baseUrl) is the version the provider's docs page at sunrise-sunset.org/api documents and points callers at first ("Make a GET request to https://api.sunrise-sunset.org/v2"), and where every newer feature lives — local timezone, ISO 8601, golden & blue hour, solar position, date ranges. The older `/json` endpoint (v1) still answers, and the provider is emphatic that it always will: that same page says "The API itself is unchanged and supported forever", and its v1 page adds "This is the stable v1 API, supported indefinitely. It will keep working forever, unchanged". Both pages were fetched live this run and neither carries any end-of-life or migration warning, so moving to v2 buys you the newer fields rather than an escape from a scheduled shutdown. v2 is not a drop-in superset — its error contract and its time formatting both differ from v1, so treat the two as separate APIs.

astronomygeolocationsolar-dataopen-data
AuthenticationNone requiredCall it straight away — no key, no signup.
HTTPSSupportedTraffic is encrypted in transit.
CORSEnabledCallable directly from browser JavaScript.
PricingFreeNo paid tier — free for the documented use case.
FormatsJSONResponses can be requested as JSON.

GreatAPIs Score

Score74out of 100
Authentication25/25No authentication required
Pricing20/20Free to use
Docs0/20No docs or spec available
Formats9/15Single response format
Freshness20/20Verified within 6 months

Embed this badge

Scored 74 on greatapis.com
<a href="https://greatapis.com/api/sunrise-and-sunset/"><img src="https://greatapis.com/badge/sunrise-and-sunset.svg" alt="Scored 74 on greatapis.com"></a>

Auth quickstart

  1. No account or key required — pass `lat`/`lng` as plain query parameters on a GET. The provider's docs page asks only that any page displaying the data show a visible attribution link back to sunrise-sunset.org.
  2. Don't bother with `formatted=0`: v2 always emits ISO 8601 timestamps and has no formatting switch. Confirmed live this run by fetching the same coordinates twice, once with `formatted=0` and once with the parameter omitted entirely — the two response bodies are byte-for-byte identical, and `formatted=1` changes nothing either. `formatted` is a v1-only parameter (on `/json` it really does toggle between ISO 8601 and a locale string), so copying it into a v2 call is harmless but misleading.
Stored keyNo key stored

Your key is stored only in this browser (localStorage) and sent directly to the API — never to greatapis.

Get today's sun and moon data for a location

GEThttps://api.sunrise-sunset.org/v2?lat=36.7201600&lng=-4.4203400

200 application/json

{"date":"2026-07-27","tzid":"Europe/Madrid","utc_offset":"+02:00","lat":36.72016,"lng":-4.42034,"sunrise":"2026-07-27T07:18:13+02:00","sunset":"2026-07-27T21:30:14+02:00","solar_noon":"2026-07-27T14:24:14+02:00","day_length":51121,"sun_status":"normal","civil_twilight_begin":"2026-07-27T06:50:43+02:00","civil_twilight_end":"2026-07-27T21:57:45+02:00","nautical_twilight_begin":"2026-07-27T06:15:18+02:00","nautical_twilight_end":"2026-07-27T22:33:09+02:00","astronomical_twilight_begin":"2026-07-27T05:36:56+02:00","astronomical_twilight_end":"2026-07-27T23:11:31+02:00","dawn":"2026-07-27T06:50:43+02:00","dusk":"2026-07-27T21:57:45+02:00","first_light":"2026-07-27T05:36:56+02:00","last_light":"2026-07-27T23:11:31+02:00","golden_hour":{"morning":{"begin":"2026-07-27T07:01:48+02:00","end":"2026-07-27T07:56:18+02:00"},"evening":{"begin":"2026-07-27T20:51:47+02:00","end":"2026-07-27T21:46:09+02:00"}},"blue_hour":{"morning":{"begin":"2026-07-27T06:50:43+02:00","end":"2026-07-27T07:01:48+02:00"},"evening":{"begin":"2026-07-27T21:46:09+02:00","end":"2026-07-27T21:57:45+02:00"}},"solar_position":{"sunrise_azimuth":64.9,"sunset_azimuth":294.99,"solar_noon_azimuth":180,"solar_noon_altitude":72.41},"moonrise":"2026-07-27T20:27:01+02:00","moonset":"2026-07-27T04:56:00+02:00","moon_phase":"Waxing Gibbous","moon_illumination":95.44}

Captured byte-for-byte from a live probe against Malaga's coordinates (36.72016, -4.42034) with no `formatted` parameter; the sunrise/sunset/golden-hour/moon values are specific to this run's date and location and will differ on any other call.

Developer reference

Base URLhttps://api.sunrise-sunset.org/v2
Rate limit

No fixed published ceiling — the provider's own docs page (sunrise-sunset.org/api) says it accommodates reasonable usage for free and that exceeding it returns HTTP 429 with a Retry-After header, and recommends batching a full year via date_start/date_end rather than polling daily for the same location.

Gotchas & limits

  • v2 rejects bad coordinates with a real HTTP error, and its bodies carry no `status` field at all — a live probe with `lat=999` returns HTTP 400 and `{"error":"invalid_lat","message":"Parameter 'lat' must be a decimal number between -90 and 90, got '999'.","docs":"https://sunrise-sunset.org/api#lat"}`; `lat=91` and `lat=abc` return the same `invalid_lat` shape, all confirmed live this run. Check the status code and the `error` key. Do not port a v1-style `status !== "OK"` guard onto v2 — there is no `status` key for it to read (the closest v2 field, `sun_status`, describes the sun's behaviour that day, not request validity). The legacy `/json` endpoint behaves the opposite way and is the trap this replaced: a live `/json?lat=abc` probe this run returned HTTP 200 with `"status":"OK"` and silently computed the result at latitude 0.
  • On polar days v2 returns JSON `null` for the time fields rather than a string or an epoch timestamp — a live probe for Svalbard at the summer solstice (`lat=78.22&lng=15.65&date=2026-06-21`) returned HTTP 200 with `"sunrise":null`, `"sunset":null`, every twilight/dawn/dusk field `null`, `"day_length":86400`, `"sun_status":"midnight_sun"`, and `"tzid":"Arctic/Longyearbyen"`. Code that assumes a parseable timestamp will break at high latitudes; branch on `sun_status` first.
  • v2 and the legacy `/json` endpoint diverge in what they return for identical coordinates: v2's response carries the true local `tzid` (`Europe/Madrid` for this run's Malaga probe) plus `golden_hour`, `blue_hour`, `solar_position`, and moon fields; a live `/json` probe against the same coordinates in this run returned only ten time fields under a `results` wrapper (sunrise, sunset, solar_noon, day_length, and the three twilight begin/end pairs) with hardcoded `"tzid":"UTC"` regardless of the actual location. Code relying on the extra fields, or on a real timezone, must call v2.
  • Only the legacy `/json` endpoint's response carries a `link: <https://api.sunrise-sunset.org/v2>; rel="successor-version"` header, confirmed live this run — a live signal (not just doc text) that v1 is being steered toward v2, even though v1 still answers normally. v2's own responses carry no such header.