POST · TRANSIT WESTERN

Moon Phases

Endpoint POST https://starsapi.com/api/v3/transit/western/moon-phases

Returns tropical lunar phases (new moon, full moon, quarters, and intermediate phases) with status annotation and cycle grouping. Supply an optional natal block to get the house each phase falls in for a given birth chart, plus tight hits to natal planets.

Authentication

Required.

Request body

FieldTypeRequiredDescription
query_typestringNolive, current, date, range, month, year, cycles. Default current.
timezonestringNoIANA timezone. Default UTC.
datestring*Required for date.
from_date, to_datestring*Required for range.
month, yearinteger*Required for month/year.
countintegerNoLunation cycles for cycles query. Default 1, max 24.
phase_filterstringNoFilter: new_moon, full_moon, first_quarter, last_quarter, etc. Cannot combine with cycles.
group_by_cyclebooleanNoGroup phases into lunation cycles on any query type. Default false.
natalobjectNoBirth data for chart personalisation (see below). When present, every phase gains a natal block.

query_type: live

Returns the Moon's state at this exact instant (not the next phase event): current illumination, phase, sign, and the upcoming New and Full Moons. Shaped as { live, next_phase, next_new_moon, next_full_moon } rather than a phases array. Each of these carries a natal block when natal is supplied.

The natal object

FieldTypeRequiredDescription
year, month, dayintegerYesBirth date.
hour, minuteintegerYesBirth time (24h, local).
secondintegerNoDefault 0.
latitude, longitudenumberYesSigned decimals (N/E positive).
timezonestringYesIANA timezone of birth.
house_systemstringNoDefault placidus.

Response shape

Phase fields

FieldTypeDescription
phasestringDisplay name (e.g. New Moon).
phase_keystringMachine key (e.g. new_moon).
phase_emojistringUnicode moon-phase emoji.
datetime_utcstringExact phase time in UTC.
datetime_localstringConverted to requested timezone (already localised — do not append a tz label).
illumination_pctnumberPercent of the disc lit (0–100).
moon, sunobject{ sign, degree_in_sign, longitude }.
statusstringpast, current, or upcoming.
days_from_nownumberSigned days from now.
natalobjectPresent only when natal supplied: { house, house_theme, hits[] }. Each hit is { natal_planet, aspect, orb } (conjunction/opposition within 3° to natal planets, Ascendant or Midheaven).

Cycle fields (when grouped)

When group_by_cycle: true or query_type: cycles, phases are wrapped in lunation cycle objects. The new_moon/full_moon/lunation_* anchors are UTC; for display use the datetime_local of the phases themselves, or the ready-made status_label.

FieldTypeDescription
cycle_numberinteger1-based index within this response.
partialbooleantrue when the first cycle does not begin on a new moon (possible when grouping a month/range/year query).
new_moon, full_moonstringUTC instants of this lunation's principal events.
phase_countintegerPhase events in this cycle (normally 8).
duration_daysnumberSpan from the first to the last marked phase (≈26d). Not the lunation length — see below.
lunation_start, lunation_endstringUTC bounds of the true lunation: this new moon → the next new moon.
lunation_daysnumberTrue lunation length (≈29.5d).
statusstringpast, current, or upcoming.
lunation_dayintegerWhich day of the lunation today is. Set only when status: current; otherwise null.
next_new_moonstringUTC instant that closes this lunation.
days_to_next_newnumberDays until that next new moon.
status_labelstringReady-to-render string — e.g. Day 27 of 29 · next new moon in 2d, Begins in 2d, Complete. Display this rather than composing your own.
phasesarrayThe phase objects for this cycle.
duration_days vs lunation_days — these differ, and both are correct. duration_days (≈26d) measures only the marked phases, new moon through waning crescent. lunation_days (≈29.5d) measures the real lunar month, new moon to next new moon. After the last marked phase the Moon stays in the same lunation for roughly three more days — so a cycle whose phases are all past can still be status: current. That is not a bug: you are in the dark days before the next new moon.

The final cycle in a cycles response has no following new moon inside the slice, so its lunation_end, lunation_days, next_new_moon and days_to_next_new are null. Request a higher count if you need them.

See also