API Versioning
CycleCalcs publishes two API versions. /v1 is closed to new development and will not change again. /v2 is the current, actively developed contract, and the one to build against. This page states what "change" means for each, how a breaking change ships, and how to pin your integration to a specific published contract.
On this page
Where things stand
| Path | Status | What that means |
|---|---|---|
/v1 | Frozen | No field is renamed, removed or retyped. No error code changes meaning. No cap tightens. Existing integrations keep working exactly as they do today, indefinitely. |
/v2 | Current | Every new endpoint, field and fix lands here. This is the version to build against. |
The API states this itself, as data rather than prose. GET /v2 reports:
"frozen_versions": [
{
"version": "1",
"base": "https://www.cyclecalcs.com/v1",
"status": "frozen",
"note": "Version 1 is unchanged and will not change. New work happens on /v2."
}
]
What counts as additive
These change /v2 at any time, without a version bump and without advance notice, because a client that ignores what it does not recognize is unaffected by them:
- A new field appended to a response. In CSV it is a new column after every existing column, so a reader that takes columns by position keeps reading the values it read before.
- A new warning code appended to the
warningsarray. - A new endpoint added under
/v2. - A new optional parameter. Leaving it out returns what the endpoint returned before.
- A newly accepted value of an existing parameter, one the endpoint refused before. Two examples:
at=jd:2461000.5, a Julian Day on the UT scale, read as UTC (2025-11-21T00:00:00Z) whereverat,startorendis read. It was refused asBAD_DATE.at=2026-09-25T00:00:00Z,2026-09-25T06:00:00Zon/v2/positions, a list of up to 24 instants answered in the order sent. It was refused asBAD_DATE.
- A loosened cap: a higher rate limit, a larger row cap, a longer range or search window. A request that was refused may now be answered, and a list cut short with a
truncated_resultswarning may return more rows.
None of these renames or removes anything you already depend on. If your client reads known fields by name and does not choke on an extra JSON key or an unrecognized warning code, additive changes are invisible to you.
One case is announced all the same. /v2 does not refuse a parameter it does not accept: it ignores it and says so with an unknown_parameter warning. So a caller who was already sending a parameter, or a value, that the API ignored gets different answers on the day it gains a meaning. Such a change is announced the way a correction is.
Corrections
A correction fixes an answer that was wrong. It keeps every field's name and type, so it is not on the breaking list below, but it changes what an existing request returns, so it is never silent. These are corrections:
- A corrected value: a number that was computed wrongly, or a constant restated to its measured figure.
- A reclassified row: an event whose kind was wrong, for example a
close_approachthat is really aconjunction. - A corrected catalog: a registered error or warning code that no shipped route has ever returned, removed from
/v2/enums, the OpenAPI enums and API Errors. No route ever returned it as an error or a warning, so no client can have met it on a failure path. A client that built its handling from/v2/enumsor an OpenAPI enum only loses a branch that could never run. - A corrected description: a map in
metathat describes the response, such asmeta.frames, which defines each frame the response uses, corrected to list only what the response contains. An entry for something the response never carried is dropped. The entries describe the answer and carry none of its data, so no data field changes.
Each correction ships as a minor contract version, with a changelog entry naming the old and the new behavior. Where that entry links a dated note, API Accuracy says at more length what was wrong and why.
What counts as breaking
These never happen inside /v2. Each one ships as a new major version path instead:
- Removing a field.
- Renaming a field.
- Changing a field's type, a number becoming a string, for instance.
- Changing the error
codereturned for a condition that already has one. - Tightening a published cap: a lower rate limit, a smaller row cap, a shorter search window.
If a change like this is ever needed, it appears at /v3. /v2 keeps its present behavior for the rest of its life, the same way /v1 does today.
Pin your integration
Every /v2 response carries meta.contract_version, a semantic version. Right now, every response reports:
"meta": { "contract_version": "2.7.0", ... }
GET /v2 also echoes it as data.contract_version, describing the API as a whole, but meta.contract_version is the one to check: it is present on every single 2xx response from every endpoint, so you can read it off the exact answer you just received rather than making a separate call to the index.
The three numbers mean:
- Patch (the third number) changes for a fix that does not alter behavior anything could depend on.
- Minor (the second number) changes when an additive change or a correction, as defined above, ships.
- Major (the first number) stays 2 for the entire life of this path. A change big enough to need a new major number ships at
/v3, per the policy above; it is never applied to/v2in place.
A caller that wants an early signal of an additive change can watch meta.contract_version across requests. A caller that only reads the fields it already knows about does not need to watch anything.
Deprecation
/v2 has not retired anything since launch. If an endpoint is ever retired, the response for that endpoint becomes 410 Gone with code ENDPOINT_RETIRED, and the hint on that response names the replacement endpoint directly, not a separate document you have to go find first.
/v2 does not send Deprecation or Sunset response headers. There is no header to poll for advance warning. A live endpoint tells you immediately, in its own response, if it has anything pending; this page is the other place to check.
Because breaking changes move to a new major version path rather than mutating /v2 in place, retiring an endpoint inside /v2 should be rare. Most future work is additive, and most callers will never see a 410 from this API.
Changelog
Every contract version since launch, newest first, grouped as additions, corrections and documentation. Each correction names the behavior it replaced; where it links a dated note, API Accuracy says at more length what was wrong and why.
2.7.0, 2026-10-30
One correction, to Espenak's supermoon verdict on /v2/phases, and three fields added beside it. Every other route answers as it did on 2.6.0 except meta.contract_version.
Added
- The orbit behind Espenak's verdict, on /v2/phases.
classification.espenakgainsrelative_distance, (apogee - distance) / (apogee - perigee) for the apogee and perigee nearest in time to the phase, the number Espenak's tables print: 0.9 or more is a supermoon under his rule. It also gainsorbit_perigee_kmandorbit_apogee_km, that perigee and apogee, so the verdict can be checked from the response alone. In CSV they are the last three columns, in that order, and underprecisionrelative_distancekeeps at least three decimals.
Corrected
- Espenak's supermoon rule.
classification.espenakdrew one line per calendar year, ten percent of the way from the year's closest perigee to its farthest apogee (361,617.6 km in 2026), and credited it to Fred Espenak. His tables apply Nolle's 90 percent rule to each orbit instead. They list 50 supermoons for 2024 to 2029, and the yearly line missed 18, among them the full Moon of 2026-01-03 at 362,300 km.qualifiesnow follows his rule and agrees with all 50 and with no other new or full Moon of those six years. Across 1700 to 2200, 1,372 new and full Moons turn fromfalsetotrue, about three a year, and none turns the other way;criteria_disagree,disagreement_noteand thesummarysentence follow.threshold_kmis the distance at a relative distance of 0.9 in that orbit, so it moves from one orbit to the next, andrule_definitionstates the per-orbit rule.threshold_year,closest_perigee_of_year_kmandfarthest_apogee_of_year_kmkeep their names and change from a number tonullon every new and full Moon: there is no yearly line to report, and a field is never removed inside/v2. A client that reads them as numbers must allownull; the orbit's own perigee and apogee are in the two fields added above. Dated note.
Documentation
- apis.json and both OpenAPI files say 2.7.0, and the Endpoint reference is regenerated. API Accuracy and the Postman collection describe the per-orbit rule, and the event-database sample is reissued as version 1.0.4.
2.6.0, 2026-10-18
One endpoint is added. Every existing endpoint answers as it did on 2.5.0 except meta.contract_version.
Added
- /v2/aurora. The live Kp index and NOAA storm level, the three-day Kp forecast, the solar wind and the OVATION auroral oval, all read from the NOAA Space Weather Prediction Center at request time. With a location (
latandlon, orplace) it also says whether the oval is overhead or on your horizon, whether it is dark enough to see it, and the forecast Kp over tonight's dark hours. It is the first live route in/v2: its cache class isnow_relativeand it takes noat. A feed NOAA cannot serve leaves its block null and adds the new warningfeed_unavailable; a stale feed addsfeed_stale; a located answer always carriesaurora_estimate. When every feed is down the route answers503 DATASET_UNAVAILABLE. - NOAA SWPC in /v2/attribution. A new source row, public domain, credited on every /v2/aurora response.
Corrected
- A place answer keeps a route's own sources. When
placeresolved,meta.attribution.sourceswas replaced by the GeoNames row alone. It now lists GeoNames first and keeps any source the route already named. No route before /v2/aurora named one, so no shipped response changes.
Documentation
- apis.json and both OpenAPI files say 2.6.0, and the Endpoint reference is regenerated.
2.5.0, 2026-10-15
What a place sees of a solar eclipse, and the central path, change by a few seconds and a few kilometers. Every field keeps its name and type. /v2/attribution gains one source.
Added
- NASA's eclipse predictions in /v2/attribution.
sourceslists the Five Millennium Canon of Solar Eclipses' Besselian elements, credited "Eclipse Predictions by Fred Espenak, NASA's GSFC", and the rows for/v2/eclipses,/v2/phasesand/v2/todayname it among their conditional sources. The data is public domain, so no response's rights change; NASA asks that its acknowledgment stay with the figures, and/v2/eclipsescarries it incentral_geometry_note.
Corrected
- Local solar eclipse circumstances.
include=localon/v2/eclipses, and every answer that carries what a place sees of a solar eclipse, came from the engine's own Sun and Moon, which put the shadow of 2 August 2027 1.7 to 2.5 km south of JPL's DE440, and from a contact search that collapsed every totality under about 26 s to 0 to 2 s. Tripoli read total where it sees a partial eclipse, Al Khums 87 s where it has 33 s, and the rings of 6 February 2027 ran 2.5 to 7.4 s short. They now come from NASA's Besselian elements for each eclipse of 1700 to 2200 (Eclipse Predictions by Fred Espenak, NASA's GSFC), evaluated at the IERS delta-T. Against DE440 at 191 places on both 2027 eclipses every verdict agrees and every contact is within 1.4 s. Totality, the ring and obscuration use NASA's lunar radius k2 = 0.272281 Earth radii, where the engine's mean radius ran totality about 3 s long; first and last contact use k1 = 0.272488. - Central paths and hybrids.
include=path, thegreatest_eclipse_*duration, width and Sun altitude, andhybridcome from the same elements, so the limits and the local verdict agree. The path of 2 August 2027 moves about 2 km north.hybridnow names all 51 hybrids NASA lists for 1700 to 2200, 2172-10-17 among them.
Documentation
- The central geometry note on
/v2/eclipsesnames the source and the radii. apis.json and the OpenAPI file say 2.5.0, and the Endpoint reference is regenerated.
2.4.0, 2026-10-11
Two summary sentences print a different number at about one instant in twenty. Every other field is unchanged except meta.contract_version.
Corrected
- Moon age in the /v2/moon summary. The sentence rounded
phase.age_days, already rounded to a hundredth, again to a tenth, and could be a tenth off in either direction: 14.95361 days after the new moon,age_daysis 14.95 and the sentence read "14.9 days into its cycle". It now rounds the elapsed time once and reads 15.0. This is thesummaryfield and theformat=txtstyle=sentencebody, for one instant or a range.age_dayskeeps two decimals. - Illumination in the /v2/today summary. The sentence rounded
moon.phase.illumination_percent, already rounded to a tenth, again to a whole percent, and could read a percent high: a Moon 49.46 percent lit publishes 49.5 and read "50 percent lit". It now rounds the illuminated fraction once and reads 49.illumination_percentkeeps one decimal.
Documentation
- apis.json and both OpenAPI files say 2.4.0, and the Endpoint reference is regenerated.
2.3.0, 2026-10-10
A request that sends neither an Authorization header carrying a Bearer value that starts CCK1. nor an X-Api-Key header gets the answers, the range caps and the rate quotas it got on 2.2.0. Four things differ for it. The rate windows are counted from their start, so the reset values in RateLimit (t=), X-RateLimit-Reset and Retry-After count to the end of the current window, and a request over any window's quota is refused (both under Corrected). Access-Control-Allow-Headers gains X-Api-Key. Vary and the header directive of Netlify-Vary each gain authorization and x-api-key after the two RapidAPI headers. /v2/conventions and /v2/enums gain the fields and codes listed under Added, and the api_keys reason is reworded.
Added
- CycleCalcs API keys. A key is read from
Authorization: Beareror fromX-Api-Key. The URL is never read for one:keyas a query parameter is still accepted, ignored and disclosed withparameter_ignored. A request through the RapidAPI gateway is served at its plan and a key beside it is not read. A key that verifies is served at the tier it names. A key that does not, or that is expired or past its transfer allowance, is still served, at the anonymous tier with a warning:INVALID_KEY,REVOKED_KEYandEXPIRED_KEYstill never fire. - Two tiers.
founding: 600 a minute, 5,000 an hour, 10,000 a day, with the pro range caps.professional: 1,200 a minute, 10,000 an hour, 20,000 a day, with the ultra range caps.RateLimit-Policynames them asfounding,founding-hourandfounding-day, and likewise for professional. Neither is reachable through a RapidAPI plan. - Five warning codes.
key_invalid,key_expired,key_revoked,key_expiring(inside the last 60 days of a key whose life is longer than that) andkey_transfer_spent. Each names the header it read infieldand never carries the key. - The transfer allowance. A key carries a monthly allowance in decimal gigabytes, counted from the bytes the origin serves it in the UTC month; CDN hits are not counted. Past it the key is served at the anonymous tier, on the limits of any caller without a key, until the month ends, with
key_transfer_spenton every response. - /v2/conventions.
limits.tiers_definedlists every tier in order, andrange_caps_by_shapecarries one column per tier,foundingandprofessionalincluded.keyed_tier_reachableis true when either the RapidAPI gateway or the key channel is configured, andkeyed_tier_note, like thecorssentence on/v2, describes the doors the serving deploy has. - Keyed CDN lifetime. A response to a request carrying a key claim has
Netlify-CDN-Cache-Controlpublic, s-maxage=300in every cache class, so a change in a key's state reaches the CDN within five minutes. Its browserCache-Controlis unchanged. - Key warnings on refusals. A refusal (a 400 such as
RANGE_TOO_LARGE, or a 429) to a request whose key was not honored carries awarningsmember afterdocs, holding thekey_*warnings a 200 would carry, so a drop to the anonymous tier is never silent. A refusal with no key warning has no such member.
Corrected
- Fixed windows. The rate limiter counted a trailing window for each policy, the last 60, 3,600 and 86,400 seconds. It now counts each window from its start: the minute, the hour and the UTC day. Every quota is unchanged, and within one window the request after the last one allowed is still refused.
RateLimitt=,X-RateLimit-ResetandRetry-Afternow count to the end of the current window, where they counted to the moment the oldest counted request left the trailing window. Across one window boundary up to twice a quota can be served, and on the same traffic the two limiters refuse different requests. - Every window enforced. A request was served when the minute window sat exactly at its quota while the hour or day window was already over its own, because the limiter judged each request against one window only. A request over any window's quota is now refused, and the refusal names the exceeded window that ends last.
- The api_keys reason.
/v2/enumsand API Errors gave the reason the three key codes never fire as the RapidAPI gateway alone. It now reads "These codes never fire: a key this deployment cannot verify is still served, at the anonymous tier with a warning."
Documentation
- The tier table gains the founding and professional columns.
- OpenAPI (
/v2/openapi.jsonand the RapidAPI 3.0.3 file): the warning enum gains the five key codes, andProblemgains the optionalwarningsmember. API Errors and the Endpoint reference are regenerated.
2.2.0, 2026-10-09
Every instant is now timed on the Earth's measured and predicted rotation. Request shapes, caps and fields are unchanged except as listed.
Added
- The delta-T statement.
/v2/conventionsgainstime_scales.delta_t_description, the model in full: its sources, how far each runs, and the years it blends back to the polynomial.
Corrected
- Delta-T. From 1972 to the end of the IERS prediction (2027-10-08 in this release), delta-T is the IERS value, measured (EOP 20 C04, then the Rapid Service) and predicted (Bulletin A), interpolated linearly; after the prediction it blends linearly back to the Espenak and Meeus polynomial by 2040. It was the polynomial everywhere, which ran 6.2 s high in 2026. An event computed for the present day (a phase, season, conjunction, station, apsis, node crossing or eclipse contact) now comes out about 6 s later in UTC; a rise, set, transit or twilight instant moves far less, by up to 1.4 s for the Moon at 66 degrees north and no more than 0.5 s at 60 degrees and below. Nothing before 1972 or after 2040 changes.
meta.time.delta_t_modelreads "IERS, Espenak-Meeus" in place of "Espenak and Meeus",/v2/timereportsdelta_t_model_residual_secondsof minusUT1 - UTC(-0.013 s at 2026-07-31, where it read 6.224), and the UT1 notes no longer say that no IERS bulletin is loaded. Dated note. - Conjunction end bound.
/v2/conjunctionsdecides whether an approach falls insideendby the millisecond the row prints. It used the unrounded instant, which can sit a fraction of a millisecond later, so an instant passed back asendcould lose its own row. - Neptune's stated accuracy.
meta.conventions.solar_angle_accuracy_noteon/v2/planet-eventsgives 5.6 minutes for Neptune against JPL Horizons, up from 5.5: the instants moved with delta-T, and the figure covers the largest measured difference plus the search precision.
2.1.0, 2026-09-25
No range 2.0.0 served is refused for its size on 2.1.0. A response is now refused only past 2,105,344 bytes, 8 KiB above the 2 MiB that every row bound is still computed against, so an answer 2.0.0 served a few bytes under the cap still serves with the bytes 2.1.0 adds to it (at most 140 in the answers measured at the size edge). For every route with a response size bound, the largest range 2.0.0 served was recorded in nested and flat JSON, in CSV and at precision=9, with wide ordinary rows (a southern location and a long zone name where the route takes them), and each of those 156 requests still serves, as do five more that 2.0.0 served within 129 bytes of the cap. A per-row field that would have pushed one of them past the size cap is carried only where it does not: on an answer for one instant, or once in meta. In CSV, every field added since 2.0.0 is a column after every 2.0.0 column.
Added
- Julian Days.
jd:followed by a Julian Day on the UT scale is accepted inat,startandendon every route and read as UTC:jd:2461000.5is 2025-11-21T00:00:00Z. It was refused asBAD_DATE. It never raisesassumed_utc. - A list of instants.
/v2/positionsacceptsat=t1,t2,..., up to 24 instants on every tier, and answersdata.seriesin the order sent withquery.mode"list". The cap isrange_caps_by_shape.instant_liston/v2/conventions. A list was refused asBAD_DATE. - Weekdays. A
/v2/timeanswer for one instant carriesdata.weekday(localandutc, each withdate,iso_weekday1 to 7 andname) andmeta.weekday_convention. A one-day/v2/rise-setanswer carrieswindow.weekday,/v2/twilightday windows carrywindow.local_dateandwindow.weekday, and/v2/dark-windownights carrynight_of_weekday, in JSON only./v2/timeseries rows, the day rows of a/v2/rise-setrange, and/v2/sunand/v2/moonday windows carry none: on those rows it would have refused requests 2.0.0 served. - Time zone warnings.
tzdb_lmt_intervalandtz_source_boundary_1970, registered and never emitted, are now emitted. The boundary warning is raised for a tz database link by the name sent, including links the runtime resolves to another name. - Named stars.
star:<name>andhr:<n>targets, from a full-precision reduction of the Bright Star Catalog (BSC5P) with IAU WGSN names, proper motion, parallax and radial velocity applied to the date, inbody,bodies,aandbon/v2/positions,/v2/rise-set,/v2/separationand/v2/rarity, and inbodiesandpairson/v2/conjunctions. The set is the 57 Nautical Almanac stars, Polaris, and the IAU-named stars of V 3.0 or brighter within 10.3 deg of the ecliptic, a close double counted at its combined light; the list and its count are at/v2/enums?set=stars(fields code, name, hr, v_magnitude, combined_v_magnitude and sets), and/v2/enums?endpoint=scopes it to the five star routes. These wereUNKNOWN_BODY. - Fixed-target rows on /v2/positions. After the row's 2.0.0 fields, a star row gains a
starblock (hr, magnitudes, the J2000 catalog place, proper motion, parallax with its kind and note, radial velocity, sets and sources),constellation, and row-levelecliptic(true of date and J2000) andgalacticblocks, and no distance. A radec row gainsconstellation,eclipticandgalacticthe same way. A body row keeps its ecliptic place insideposition. - Label origin.
/v2/positionsgainsmeta.conventions.label_origin, the place every row'stropical_signandconstellationwere taken from:geocentric, orheliocentricunderframe=heliocentric, never topocentric, one value per response, present when some row carries either label./v2/conventionsgainsfield_definitionsfor tropical_sign, constellation and origin, and OpenAPI gains the TropicalSign, Constellation and LabelOrigin schemas. - Placeholder distances.
/v2/separationrows gaindistance_is_placeholder{a,b}, anddistance_notewhen either target is a named star or radec pair. - Newly answered.
frame=eclipticwith a radec target on/v2/separation, and named stars on/v2/conjunctionsincludingframe=ecliptic, were refused with 400. A new refusal covers a new condition only: a/v2/separationrange search over two fixed targets when either is a named star isBAD_PAIR, and a radec-radec range keeps its answer and gains the new warningfixed_pair_minima. Two stars in one/v2/conjunctionspair areBAD_PAIR, and a star-star combination frombodiesis skipped. - Light deflection, stated.
corrections.light_deflection{ applied: false }with a note on/v2/conventions, andlight_deflection: falseinmeta.correctionson every position-bearing response. - Star sources.
/v2/attributionlists the Bright Star Catalog (BSC5P, via NASA HEASARC) and the IAU Catalog of Star Names (WGSN, CC BY 4.0), insourcesand in thesourcesandconditional_sourcesof the five routes that take a named star. No route'srightsvalue changes. - Pair longitudes.
longitude_conjunction_instants(every longitude crossing in the minimum's basin) andsky_separation_degon/v2/conjunctionsapproaches and/v2/separationrows.meta.conventionsgainscoincidence_rule,coincidence_rule_note,basin_cap_days,basin_stride_days,basin_stride_days_with_moonandsky_separation_note;/v2/phasesand/v2/seasonsgainmeta.method.definition, and/v2/conjunctionsgainsmeta.method.longitudes. - The Moon's extrapolated magnitude. Past 150 deg of phase angle, within about 2.4 days of new moon, the Moon's magnitude is an extrapolation of its observed phase curve, kept and flagged:
magnitude_extrapolatedon/v2/phasesrows (include=distance) and on a/v2/moonor/v2/positionsanswer for one instant, andmagnitudes_extrapolated{a,b} on/v2/conjunctionsrows (true or false in the Moon's slot, null for any other body). The rows of a/v2/moonor/v2/positionsrange or list carry no flag; a/v2/moonor/v2/positionsanswer that carries a Moon magnitude gives the threshold asmeta.conventions.moon_magnitude_observed_phase_angle_deg(150)./v2/conventionsgainsphotometry.moon_phase_lawandphotometry.moon_magnitude_observed_phase_angle_deg. - Planet events for Mars to Neptune.
/v2/planet-eventsacceptsmars,jupiter,saturn,uranusandneptune(BODY_NOT_SUPPORTED_HEREbefore), with the kindsconjunction_with_sun,quadrature_west,oppositionandquadrature_east: the instants the planet's apparent geocentric ecliptic longitude minus the Sun's reaches 0, 270, 180 and 90 deg. Each event carriesvalue_deg(the elongation),ecliptic_longitude_deg,constellation,distance_from_earth_au,magnitude,longitude_conventionandconvention_note, withinstant_precision_seconds2. Unasked, a superior planet gets these four kinds and Mercury and Venus keep their seven apparition kinds. There is no arbitrary-angle parameter. The Sun, the Moon, Pluto, named stars and radec targets are still refused. - Constellation entries. The kind
constellation_entryon/v2/planet-events, for Mercury to Neptune, returned only whenkindslists it: each crossing of an IAU 1930 constellation boundary by the planet's apparent geocentric place, withfrom_constellation,to_constellation,direction,ecliptic_longitude_deg,instant_precision_seconds1, andpass_indexandpass_count, which number a run of consecutive crossings of one boundary that ends at each conjunction with the Sun between retrograde loops (every conjunction for Mars to Neptune, the superior conjunction for Mercury and Venus), so a run never spans two loops: 3 for a loop that carries the planet over, back and over again, at most 7 over 1700-2200. The label reads "Uranus enters Gemini from Taurus". - Planet-events meta.
meta.conventionsgains thesolar_angle_*conventions only when a Sun-relative kind is walked, and theconstellation_*conventions only when constellation entries are asked for;meta.methodgainssolar_anglesandconstellation_entrieson the same conditions. The apparition family's heliocentric conventions andmeta.method.eventsappear when a Mercury or Venus apparition kind is walked, which covers every request 2.0.0 accepted, and an answer holding both families gainsconvention_scope_note. Akindstoken none of the requested bodies can have is ignored with aparameter_ignoredwarning. - Solar terms.
/v2/seasonsacceptsinclude=solar_terms: every instant the Sun's apparent geocentric ecliptic longitude reaches a multiple of 15 deg, 24 a year, on the same search as the equinoxes. The quarters and cross-quarters keep their kinds; the other sixteen are the new kindsolar_term, labeled by longitude, withsolar_longitude_degandsolar_longitude_is_definitional. The token bringseventsandcross_quarterswith it and addsmeta.method.solar_terms. - Event kinds.
/v2/enumsevent_kindsgainsconjunction_with_sun,quadrature_east,quadrature_west,constellation_entryandsolar_term. - Eclipse paths.
/v2/eclipsesinclude=pathreturns the central path of the central solar eclipses of 2027-02-06, 2027-08-02, 2028-01-26 and 2028-07-22 as inline GeoJSON (central line, northern and southern limits, and points carrying instant, central phase, duration, path width and Sun altitude). The geometry travels in nested JSON only, and is left out with a note under CSV orshape=flat, or with atruncated_resultswarning where it would push the response past the size limit; other eclipses returnavailable: falsewith the reason. Solar rows gainhybridandhybrid_transitions, central rows gaingreatest_eclipse_duration_seconds,greatest_eclipse_path_width_kmandgreatest_eclipse_sun_altitude_deg, and hybrid rows addhybrid_definition. New warninghybrid_eclipse; newdata.central_geometry_noteand central-path conventions;parameter_ignoredwheninclude=greatestcannot apply orcountis sent in range mode./v2/phasessolar eclipse objects and/v2/todaysolar_eclipse events gainhybrid. - Traditional precession figure. The axial_precession row of a
/v2/cyclesanswer for one instant gainstraditional_period_daysandtraditional_period_years, the traditional 360 x 72 years, afterpage_url; the rows of a range do not carry them. Every answer gainsmeta.conventions.precession_years_traditional. - MCP.
astro_eclipsestakes an optionalinclude(path,greatest), andastro_planet_eventstakes the seven planets and all twelve kinds. The server still has 11 tools.
Corrected
- Error catalog. 14 error codes no route has ever returned, registered for chart constructs this API does not publish, were listed in the error registry,
/v2/enumserror_codes, API Errors and the OpenAPIProblem.codeenum of both OpenAPI files. They are removed, and status 422, which only one of them used, leaves theProblem.statusenum. - Warning catalog. 16 warning codes no route has ever emitted, registered for the same unbuilt features, were listed in
/v2/enumswarning_codesand the OpenAPIWarning.codeenum. They are removed. - TIME_REQUIRED. It was listed as reachable; every route reads a missing
atas now, so/v2/enumsnow marks itknown_unreachable: true(surfacetime_defaults_to_now) and API Errors says it is not returned. Its hint named two time forms that never existed; it now reads "Send `at` as an ISO 8601 date or date-time, for example at=2026-08-12T21:00:00Z". - /v2/enums. A surface name for an unbuilt feature no longer appears in any
surfaceorreasonfield. 10 registered warning codes no route emits, listed as reachable, are markedknown_unreachable: true(surfacenot_detected). Thetime_formatisodefinition now states the UTC exception, and thecatalogswithheld reason is rewritten. - Local mean time. An instant whose zone offset has nonzero seconds (pre-1972 local mean time) was written with a truncated offset; it is now written in UTC with Z. For such offsets
utc_offset_isowas truncated and is now rounded to the nearest minute;utc_offset_secondsis unchanged. Summaries read clock digits and dates from the local wall clock. - Eclipse summary dates. With
time_format=unix, the/v2/eclipsessummary named the peak's unix seconds as its date; it now names the local date. - Range refusals. A
RANGE_TOO_LARGErefusal on a span cap now states the span cap and the remedy for the caller's own step, namescountwhencount=set the end, carries a legal first-pageexample, and takes precedence over the size refusal. Size refusals offeredfields=and paging, and no longer do; events-cap refusals offered a wider step orcount=, and no longer do. The catalog hint is rewritten. The code is unchanged. - BAD_DATE details. They now name the actual fault: signed or expanded years, offsets with seconds, years 0000-0099, a malformed
jd:, and a comma used as the decimal sign, which is now one value refused where it was split into a list. The offset refusal states the 24:00 bound. The code is unchanged. - Large historical offsets. A local wall time within 16 hours of a transition, on a zone whose historical offset exceeded 14 hours (Alaska, October 1867), resolved wrongly as ambiguous or nonexistent; it now resolves correctly.
- Phase instants. On
/v2/phases,/v2/moonnext_phases,/v2/today,/v2/cycles(synodic month) and/v2/apsides, a phase was timed with the Sun taken without aberration. It is now the instant the Moon's apparent ecliptic longitude minus the Sun's, as/v2/positionsreports them, reaches 0, 90, 180 or 270 deg, so every instant moves 34 to 46 s earlier;phase_angle_deg,age_daysand the lunation anchors move with them. The definition texts say so:phase.phase_angle_conventionon/v2/moon, and the synodic month'sfraction_methodon/v2/cycles, named the engine's MoonPhase elongation and now name the apparent longitudes, andmeta.method.definitioncredits USNO for the definition. Dated note. - Season instants.
/v2/seasonsequinoxes, solstices and cross-quarters used a fixed one-AU light time; they now use the apparent solar longitude/v2/positionsreports: June solstices about 8 s later, December solstices about 8 s earlier, equinoxes about 2 s. Dated note. - The Moon's phase angle.
phase.phase_angle_degon/v2/moonandgeometry.phase_angle_degon/v2/librationtook the Sun without aberration; they now use the apparent longitudes, as the phase instants do, and move by about 20 arcsec (0.006 deg). The Moon phase names on/v2/dark-windowand/v2/sky-qualityare read from the same angle. - Pair longitudes.
frame=eclipticlongitude differences on/v2/conjunctionsand/v2/separation,ecliptic_separation_from_sun_degon/v2/positionsandecliptic_separation_degon/v2/planet-boardleft out aberration and now use apparent longitudes, for named stars and radec targets as for bodies. Moon-pair crossings move by up to about 45 s, other values by about 20 arcsec at most. - Conjunction or close approach. A separation minimum was a conjunction only when the longitudes crossed within 24 hours of it. It is now a conjunction when the apparent longitudes cross anywhere in its basin, between the separation maxima either side, capped at 180 days, on
/v2/conjunctionsand on/v2/separationfor any pair with a Solar System body (a fixed target takes the apparent place/v2/positionsreports; two fixed targets are never searched). Someclose_approachrows becomeconjunction, for example Uranus-Neptune 1993-11-01, Saturn-Uranus 1988-06-28 and 1988-10-20, Venus-Saturn 2025-04-28 and Venus-Mars 2022-03-16.longitude_conjunction_instantis the nearest crossing and can be days or weeks from the minimum.meta.conventions.coincidence_tolerance_hourskeeps its value, 24, and no longer affects any row, as its note now says. Withframe=ecliptic,sky_separation_degand the text built on it are geocentric even with a location. The frame=ecliptic label,combined_apparent_noteand the/v2/separationsummary now describe the true sky separation, and the partialno_search_resultmessage says the listed pairs had no approach. Dated note. - Engine call accounting.
meta.budget.engine_callsnow counts an apparent pair-longitude evaluation as two calls, and counts the hybrid test this release added for each solar eclipse: about 270 calls an eclipse on/v2/eclipses, and 114 on/v2/phasesand/v2/today. At the edge of an accepted request the realized count can exceed the published budget (about 251,000 against 250,000 for the slowest pairs), as it could on 2.0.0. Pre-flight budgets and caps are unchanged. - Printed minutes. The site, the paid calendar and the ICS feeds truncated an instant to the minute; they now round it, and print the same minute. Every ICS event, free and paid, starts (DTSTART) on the minute its description prints. The feed revision constants are bumped, so ETags and DTSTAMPs change.
- One apparent place for a fixed target.
/v2/positionsrotated a radec target to the date with no aberration; it now takes annual aberration and annual parallax at the nominal 1000 light-years, the place/v2/separationand/v2/rise-setalready used, so values move by up to about 20 arcsec, andequatorial.j2000on a radec row is that apparent direction in the J2000 frame./v2/raritydark-walk altitudes for radec targets use the same place. Dated note. - meta.frames. Every
/v2/conjunctionsand/v2/separationresponse listed six frames, includingequatorial_j2000,ecliptic_j2000andgalactic, andhorizontalwithout a location, though those routes never return a position in them. It now listsequatorial_of_dateandecliptic, plushorizontalwith a location, and/v2/positionsreads its list off the rows. This is the corrected-description case under Corrections; no data field changes. Dated note. - meta.corrections.
aberrationandtopocentric_parallaxare true for fixed targets;light_travel_timeis true only when a Solar System body is present;proper_motionis true with a named star;scope_noteis rewritten;frame=geocentricwith a location no longer claims topocentric parallax on/v2/separationor/v2/conjunctions. - /v2/conventions.
proper_motionapplied is true; the light_travel_time note says the Sun and planets, and that the Moon's place is geometric; the tropical_sign definition gives the drift as about 1 deg every 71.6 years, from the measured IAU 2006 rate, where it used the traditional figure. - A body passing a fixed target. On
/v2/separationit is classified by the basin rule, and its ecliptic differences, which were null, are numbers, with new note text. - Retrograde constellations. On
/v2/retrogrades, a station'sconstellationandconstellations_crossedwere taken for a stand-in observer at latitude 0, longitude 0; they now come from the geocentric place. Between 1700 and 2200 the visible difference is Mercury's April-May 1793 loop. - UNKNOWN_BODY. For
star:andhr:it gainshint,exampleandsupported, and a bare star name gets a hint. - Eclipse conventions.
meta.conventions.umbra_enlargement_notecredited the 2 percent enlargement to Danjon; it now credits Chauvenet (Astronomical Almanac) and gives NASA's canon differences (about 0.006 umbral, 0.026 penumbral).meta.method.paths_of_totalityandmeta.method.hybrid_eclipsesdescribe the new behavior, and the century hybrid list is complete.not_visible_from_locationwas emitted for an eclipse type the request did not ask for and is now emitted only for the type requested; bothnext_visiblemembers are still published. A hybrid row'slabelreads "Solar eclipse (hybrid)" on/v2/eclipses, and a hybrid solar_eclipse event's reads "Hybrid solar eclipse" on/v2/today;kindandglobal_kindstay the engine's. - The precession period. On
/v2/cyclesaxial_precession,period_dayswas 9467280, the traditional 360 x 72 years, and is now 9413068, the measured turn at the IAU 2006 rate (1,296,000 / 50.28796195 x 365.25);period_textnamed the traditional round figure and now reads "about 25,772 years (IAU 2006 rate)";descriptionreads "once in about 25,772 years";state.rate_arcsec_per_yearwas 50.0 and is now 50.288;state.equinox_notegives the rate as about 50.3 arcseconds a year;meta.conventions.precession_yearsis 25772. Dated note. - Great conjunction description. Under
include=definition, its closing clause framed the trigon by signs and gave an 800-year return; it now ends "the beat, the 243-degree step, and the slowly turning trigon." Text only. - Opposition's surface.
/v2/enumsevent_kindspublishedoppositionas reachable on/v2/conjunctions, which answerskind=oppositionwith 400. Its surface is now/v2/planet-events, which emits it, with the label template "{body} at opposition, {value} from the Sun". - Planet-events refusals. The
BODY_NOT_SUPPORTED_HEREdetail told a caller asking for a superior planet that/v2/conjunctionsreports oppositions; it is now given only for the Sun, the Moon, Pluto and fixed targets, and the refusal'shint,exampleandsupportedname the seven planets. Akindsrefusal said "is not an apparition event kind" for an unknown token and now says "is not an event kind this endpoint reports."; an emptykindssaid to omit it for every kind and now says to omit it for each body's default kinds, since constellation_entry is returned only when listed;supportedlists all twelve kinds./v2/seasonsincluderefusals listsolar_terms. The codes are unchanged. - Companion note.
/v2/retrogradescompanion_event.convention_notesaid/v2/conjunctionsgives the geocentric instant of an outer planet's opposition; it now names/v2/planet-events(kinds=opposition). An inner planet's note names/v2/conjunctionswith the pair and themax_separation_degit needs. - OpenAPI.
/v2/planet-eventsbodyandbodiesoffered every engine body and radec targets, which the route refuses, and now list the seven planets./v2/eclipsescountis documented as 1 to 50 and theincludepattern with its leniency, the limits the endpoint always enforced.
Documentation
- This page: the additive list names newly accepted values with two examples and says a new CSV field is a column after every existing one; a caveat covers callers already sending an ignored parameter; the Corrections section lists corrected values, reclassified rows, corrected catalogs and corrected descriptions; and this changelog is new.
- Served descriptions: the
/v2index summaries of/v2/seasonsand/v2/planet-eventsname the solar terms and the Mars-to-Neptune events and constellation entries;/v2/phasesmeta.method.eventsdescribes the quarter walker without the engine's function names; and underframe=ecliptic,/v2/conjunctionsmeta.method.frameand/v2/separationdata.definitiondefineseparation_degand point tosky_separation_deg. - API Accuracy: named stars; phase and season instants on the apparent longitude; pre-1972 delta-T; pair-event accuracy; new-moon rows against JPL Horizons DE441 in TT and UT from 1700 to 2200; the Sun-relative planet events and constellation entries against JPL Horizons; and a dated note for each correction this changelog links there.
- Endpoint reference: the named-star grammar, the ecliptic frame for stars and radec targets, the basin rule and
sky_separation_deg, the field definitions withmeta.conventions.label_origin, the planet-events bodies and kinds, the seasons include list, the eclipse include list, and regenerated samples. - OpenAPI (
/v2/openapi.jsonand the RapidAPI 3.0.3 file): the star grammar only on the routes that take it; the time, tz, time_format and at descriptions; the TropicalSign, Constellation and LabelOrigin schemas; the warning enum gainsfixed_pair_minimaandhybrid_eclipse. - MCP: the server instructions carry the astronomy-only scope sentence and name the Mars-to-Neptune events and constellation entries;
astro_planet_eventsno longer promises stations and points toastro_planet_boardand/v2/retrogrades; the MCP page publishes a generated table of the routes the 11 tools reach; the date description namesjd:and the instant list;astro_positionssays the labels stay geocentric;astro_eclipsesstates the path size, about 65 to 90 KB per eclipse. /v2/attributionand NOTICE.md name the star sources.
All API documentation
- Developer hub: What to build and where every tool lives: API, MCP server, widgets.
- Overview and playground: What the API answers, the plans, and a live try-it panel.
- Endpoint reference: Every route, its parameters and a real captured response.
- Keys and plans: How to get a key, what each plan raises, and how quotas are counted.
- Error codes: The registered problem documents, one entry per code.
- Accuracy and residuals: Measured error against reference ephemerides, and the conventions every response states.
- Versioning policy: What is frozen, what may change, and how a change is announced.
- Status and limits: Rate windows, range caps and the current service position.
- MCP server: The same engine as tools an AI assistant can call directly.
- Version 1 (frozen): The original seven endpoints, still served and never changing shape.
- Terms of use: What you may do with the answers, including in commercial products.