Sunset and sunrise times API v2
Our free API tells you when the sun rises and sets anywhere on Earth, plus twilight, golden hour, solar position and moon data. All you need is a latitude and longitude: you make a simple GET request and get the answer as JSON.
Times come in the local timezone of the place, and you can ask for a single day or up to a whole year in one request.
The API is free to use: no sign up or API key required. We do require attribution: display a visible link to sunrise-sunset.org in the app or page where you show the data.
/json) has moved to v1 documentation. The API itself is unchanged and supported forever. API documentation
Make a GET request to https://api.sunrise-sunset.org/v2. Try it right now, this link works in your browser:
https://api.sunrise-sunset.org/v2?lat=36.7201600&lng=-4.4203400
Plain HTTP is supported too: handy for IoT and embedded devices (Arduino, ESP8266, microcontrollers) that cannot make TLS connections.
More examples: a specific date, and a whole year in one request:
https://api.sunrise-sunset.org/v2?lat=36.7201600&lng=-4.4203400&date=2026-07-16 https://api.sunrise-sunset.org/v2?lat=36.7201600&lng=-4.4203400&date_start=2026-01-01&date_end=2026-12-31
Request parameters
- lat (float): Latitude in decimal degrees, -90 to 90. Required
- lng (float): Longitude in decimal degrees, -180 to 180. Required
- date (string):
YYYY-MM-DD,todayortomorrow. Defaults to today in the local timezone of the coordinates. Optional - date_start, date_end (string): Date range in
YYYY-MM-DDformat, up to 366 days in a single request. The response becomes an object with adaysarray. If you need the same location every day, request a full year once instead of one request per day. Optional - tz (string): You usually don't need this: by default the times already come in the location's own timezone. Set it only if you want the times expressed in a different one, using a standard timezone name like
Europe/MadridorAmerica/Los_Angeles(abbreviations likePSTare rejected). Coordinates in international waters resolve to nauticalEtc/GMT±Nzones (careful, the sign is inverted:Etc/GMT+8means UTC−8). Optional - time_format (string):
iso8601(default) orunix. Withunix, all event times are Unix epoch seconds (UTC by definition, handy for embedded clients);tzid/utc_offsetare still included as context, anddate/tzstill determine which local calendar day is computed. Events that do not occur staynull. Optional
Response
All times use the ISO 8601 format: 2026-01-15T08:27:43+01:00 means January 15 at 08:27:43 in the morning, local time (1 hour ahead of UTC). Every programming language understands it out of the box; in JavaScript, new Date(data.sunrise) just works. An example response:
{
"date": "2026-01-15",
"tzid": "Europe/Madrid",
"utc_offset": "+01:00",
"lat": 36.7202,
"lng": -4.4203,
"sunrise": "2026-01-15T08:27:43+01:00",
"sunset": "2026-01-15T18:26:27+01:00",
"solar_noon": "2026-01-15T13:27:05+01:00",
"day_length": 35924,
"sun_status": "normal",
"civil_twilight_begin": "2026-01-15T08:01:01+01:00",
"civil_twilight_end": "2026-01-15T18:53:09+01:00",
"nautical_twilight_begin": "2026-01-15T07:29:13+01:00",
"nautical_twilight_end": "2026-01-15T19:24:57+01:00",
"astronomical_twilight_begin": "2026-01-15T06:58:10+01:00",
"astronomical_twilight_end": "2026-01-15T19:56:00+01:00",
"dawn": "2026-01-15T08:01:01+01:00",
"dusk": "2026-01-15T18:53:09+01:00",
"first_light": "2026-01-15T07:29:13+01:00",
"last_light": "2026-01-15T19:24:57+01:00",
"golden_hour": {
"morning": { "begin": "2026-01-15T08:11:54+01:00", "end": "2026-01-15T09:08:17+01:00" },
"evening": { "begin": "2026-01-15T17:46:10+01:00", "end": "2026-01-15T18:42:33+01:00" }
},
"blue_hour": {
"morning": { "begin": "2026-01-15T08:01:01+01:00", "end": "2026-01-15T08:11:54+01:00" },
"evening": { "begin": "2026-01-15T18:42:33+01:00", "end": "2026-01-15T18:53:09+01:00" }
},
"solar_position": {
"sunrise_azimuth": 118.31,
"sunset_azimuth": 241.82,
"solar_noon_azimuth": 180.09,
"solar_noon_altitude": 32.06
},
"moonrise": "2026-01-15T06:01:54+01:00",
"moonset": "2026-01-15T15:14:23+01:00",
"moon_phase": "Waning Crescent",
"moon_illumination": 10.62
}
With date_start/date_end, the response is {"tzid", "lat", "lng", "days": […]} where each element of days has the fields above (minus tzid/lat/lng).
Field definitions
What each field means, in plain words, with the exact definition in parentheses (the same request always returns exactly the same times):
- sunrise / sunset: when the upper edge of the sun crosses the horizon (center of the sun at −0.833°, accounting for atmospheric refraction).
- dawn / dusk: when it's bright enough to be outdoors without artificial light (civil twilight, sun at −6°). Same values as
civil_twilight_begin/end. - first_light / last_light: the very first and very last hint of light in the sky: before first_light and after last_light the night is fully dark (astronomical twilight, sun at −18°). Same values as
astronomical_twilight_begin/end. - nautical twilight: the horizon is still visible at sea (sun at −12°).
- golden_hour: the warm, soft light right after sunrise and before sunset, the photographers' favourite (sun between −4° and +6°, morning and evening).
- blue_hour: the deep-blue sky just before dawn and just after dusk (sun between −6° and −4°, morning and evening).
- day_length: seconds between sunrise and sunset.
- solar_position: where the sun is in the sky: azimuth is the compass direction (degrees from north, clockwise: 90 is east, 270 is west) at sunrise, sunset and solar noon; altitude is how high above the horizon it gets at solar noon.
- moonrise / moonset: when the moon appears and disappears over the horizon, within that local calendar day. Roughly one day a month each event simply doesn't happen; then it's
null. (Technical: topocentric, upper limb, standard refraction; at high latitudes the moon can cross the horizon more than twice a day; the first rise and the last set are reported.) - moon_phase / moon_illumination: the phase name (New Moon, Waxing Crescent, First Quarter, Waxing Gibbous, Full Moon, Waning Gibbous, Last Quarter, Waning Crescent) and how much of the moon looks lit, in percent. Both evaluated at local noon.
Consult our glossary of astronomical definitions to learn more about each event.
Polar days and nullability
sun_status is normal, midnight_sun (the sun never sets: day_length is 86400) or polar_night (the sun never rises: day_length is 0). Events that do not occur are null. All events are independently nullable: near the polar circles there are transition days where the sun rises but does not set within the calendar day; then sunrise has a value, sunset is null, sun_status is normal and day_length is null. Never infer one event from another.
Errors
If something in your request is wrong, the API tells you what happened and how to fix it, in plain words:
{
"error": "invalid_tz",
"message": "Unknown tz 'PST'. Use IANA identifiers like 'America/Los_Angeles'.",
"docs": "https://sunrise-sunset.org/api#tz"
}
For the technically inclined: standard HTTP status codes are used: 400 for invalid input, 404 for unknown routes, 429 when you send too many requests too quickly.
Usage limits and attribution
The API is free of charge for reasonable request volumes. We require that you show attribution to us with a link to our site.
If you send too many requests too quickly the API answers 429 ("slow down") with a Retry-After header telling you how many seconds to wait before trying again. A date range counts as a single request, so if you show data for the same place every day, ask for the whole year once with date_start/date_end: faster for you, lighter for everyone.
Another tip to stay well under the limits: the times for a given date never change, so save the response and reuse it instead of asking again (browsers even do this automatically with our responses). (Technical details: explicit dates are served with Cache-Control: immutable, today/tomorrow with max-age until local midnight, and ETag is supported.)
Using the API from a web page (JavaScript)
You can call the API directly from your web page, no server or backend needed: requests from any website are allowed:
fetch('https://api.sunrise-sunset.org/v2?lat=36.72&lng=-4.42')
.then(response => response.json())
.then(data => {
console.log('Sunrise:', data.sunrise);
console.log('Sunset:', data.sunset);
});
Migrating from v1
| v1 (/json) | v2 (/v2) |
|---|---|
formatted=0 (ISO 8601) | always ISO 8601, no parameter needed |
formatted=1 (12h AM/PM) | removed |
tzid=X (invalid values silently fall back to UTC) | tz=X (invalid values return HTTP 400 invalid_tz) |
| times default to UTC | times default to the local timezone of the coordinates |
callback (JSONP) | removed (use CORS) |
errors as status: INVALID_* | errors as {error, message, docs} |
| polar days: epoch-1970 timestamps | null + sun_status |
lat=abc computed as 0 | HTTP 400 invalid_lat |
| one request per day | date_start/date_end (up to 366 days) |
| n/a | golden & blue hour, azimuth, solar altitude |
Announcements
Subscribe to our API newsletter to keep up to date with changes and announcements about the service:
Changelog
- July 8, 2026: Moon data (moonrise, moonset, phase, illumination) and
time_format=unixadded to v2. - April 5, 2026: API v2 released.
- Older updates in the v1 changelog.
Contact
Please contact us for all your API questions.
If you enjoy using our API please consider supporting the project by buying us a coffe!