Science & Math — entry 024 of 28
Sunrise and Sunset
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.
GreatAPIs Score
Auth quickstart
- No account or key required — pass
lat/lngas 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. - 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 withformatted=0and once with the parameter omitted entirely — the two response bodies are byte-for-byte identical, andformatted=1changes nothing either.formattedis a v1-only parameter (on/jsonit really does toggle between ISO 8601 and a locale string), so copying it into a v2 call is harmless but misleading.
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
{"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
https://api.sunrise-sunset.org/v2No 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
statusfield at all — a live probe withlat=999returns 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=91andlat=abcreturn the sameinvalid_latshape, all confirmed live this run. Check the status code and theerrorkey. Do not port a v1-stylestatus !== "OK"guard onto v2 — there is nostatuskey for it to read (the closest v2 field,sun_status, describes the sun's behaviour that day, not request validity). The legacy/jsonendpoint behaves the opposite way and is the trap this replaced: a live/json?lat=abcprobe this run returned HTTP 200 with"status":"OK"and silently computed the result at latitude 0. - On polar days v2 returns JSON
nullfor 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 fieldnull,"day_length":86400,"sun_status":"midnight_sun", and"tzid":"Arctic/Longyearbyen". Code that assumes a parseable timestamp will break at high latitudes; branch onsun_statusfirst. - v2 and the legacy
/jsonendpoint diverge in what they return for identical coordinates: v2's response carries the true localtzid(Europe/Madridfor this run's Malaga probe) plusgolden_hour,blue_hour,solar_position, and moon fields; a live/jsonprobe against the same coordinates in this run returned only ten time fields under aresultswrapper (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
/jsonendpoint's response carries alink: <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.
Changelog
- gained rate limits